core_validation.cpp revision f85ac0ee54f3cfbac8bb9bf046de2f502e9b8bff
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" 70b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf#include "vk_typemap_helper.h" 715b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 725b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis#if defined __ANDROID__ 735b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis#include <android/log.h> 745b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis#define LOGCONSOLE(...) ((void)__android_log_print(ANDROID_LOG_INFO, "DS", __VA_ARGS__)) 755b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis#else 76cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski#define LOGCONSOLE(...) \ 77cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski { \ 78cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski printf(__VA_ARGS__); \ 79cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski printf("\n"); \ 80c1eb2a3736e03aaa15b849d217fd963021dc9780Michael Lentine } 815b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis#endif 825b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 835770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus// TODO: remove on NDK update (r15 will probably have proper STL impl) 845770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus#ifdef __ANDROID__ 855770f8ad21c40b2475201e73e9368a899b6886d0Petr Krausnamespace std { 865770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 875770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraustemplate <typename T> 885770f8ad21c40b2475201e73e9368a899b6886d0Petr Krausstd::string to_string(T var) { 895770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus std::ostringstream ss; 905770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus ss << var; 915770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus return ss.str(); 925770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus} 935770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus} 945770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus#endif 955770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 96d147a5463f8581604ca542aa1a44a27e512e0f60Mike Stroyan// This intentionally includes a cpp file 97d147a5463f8581604ca542aa1a44a27e512e0f60Mike Stroyan#include "vk_safe_struct.cpp" 98d147a5463f8581604ca542aa1a44a27e512e0f60Mike Stroyan 99ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbesusing mutex_t = std::mutex; 100ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbesusing lock_guard_t = std::lock_guard<mutex_t>; 101ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbesusing unique_lock_t = std::unique_lock<mutex_t>; 102ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes 103d16a2fd05d0b6bd20c7274560c88e37e4b3adefcChia-I Wunamespace core_validation { 104d16a2fd05d0b6bd20c7274560c88e37e4b3adefcChia-I Wu 1055b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlisusing std::unordered_map; 1065b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlisusing std::unordered_set; 1070c55adf45a81f44300db04ec71a797d790ef103cTobin Ehlisusing std::unique_ptr; 1080c55adf45a81f44300db04ec71a797d790ef103cTobin Ehlisusing std::vector; 1090c55adf45a81f44300db04ec71a797d790ef103cTobin Ehlisusing std::string; 1100c55adf45a81f44300db04ec71a797d790ef103cTobin Ehlisusing std::stringstream; 1110c55adf45a81f44300db04ec71a797d790ef103cTobin Ehlisusing std::max; 1125b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 1135b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// WSI Image Objects bypass usual Image Object creation methods. A special Memory 1145b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// Object value will be used to identify them internally. 1155b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlisstatic const VkDeviceMemory MEMTRACKER_SWAP_CHAIN_IMAGE_KEY = (VkDeviceMemory)(-1); 116888cae09036ec622d6014e18efbda55e6226cf22Tobin Ehlis// 2nd special memory handle used to flag object as unbound from memory 117888cae09036ec622d6014e18efbda55e6226cf22Tobin Ehlisstatic const VkDeviceMemory MEMORY_UNBOUND = VkDeviceMemory(~((uint64_t)(0)) - 1); 118b1b606d27e8c4179534d7bbb48ce217429e37414Tobin Ehlis 1192e935bbc6cacaff38c073f86594a1b56d1f8a800Jamie Madill// A special value of (0xFFFFFFFF, 0xFFFFFFFF) indicates that the surface size will be determined 1202e935bbc6cacaff38c073f86594a1b56d1f8a800Jamie Madill// by the extent of a swapchain targeting the surface. 1212e935bbc6cacaff38c073f86594a1b56d1f8a800Jamie Madillstatic const uint32_t kSurfaceSizeFromSwapchain = 0xFFFFFFFFu; 1222e935bbc6cacaff38c073f86594a1b56d1f8a800Jamie Madill 123f0f7d8aa2286bd7516d9fb5c2e58890505e3e5d4Chris Forbesstruct instance_layer_data { 124d3578035fec44db2380099c2f59d3e4d8e0b98d6Chris Forbes VkInstance instance = VK_NULL_HANDLE; 125d3578035fec44db2380099c2f59d3e4d8e0b98d6Chris Forbes debug_report_data *report_data = nullptr; 1265b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis std::vector<VkDebugReportCallbackEXT> logging_callback; 1279172b640a0ae6a92f24ad0609d92b2c228cde89cChris Forbes VkLayerInstanceDispatchTable dispatch_table; 1289172b640a0ae6a92f24ad0609d92b2c228cde89cChris Forbes 129219f00ffed576643641976122fa1db8e5fce5dc1Chris Forbes CALL_STATE vkEnumeratePhysicalDevicesState = UNCALLED; 130219f00ffed576643641976122fa1db8e5fce5dc1Chris Forbes uint32_t physical_devices_count = 0; 131b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young CALL_STATE vkEnumeratePhysicalDeviceGroupsState = UNCALLED; 132b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young uint32_t physical_device_groups_count = 0; 133219f00ffed576643641976122fa1db8e5fce5dc1Chris Forbes CHECK_DISABLED disabled = {}; 134219f00ffed576643641976122fa1db8e5fce5dc1Chris Forbes 135f0f7d8aa2286bd7516d9fb5c2e58890505e3e5d4Chris Forbes unordered_map<VkPhysicalDevice, PHYSICAL_DEVICE_STATE> physical_device_map; 136747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes unordered_map<VkSurfaceKHR, SURFACE_STATE> surface_map; 137747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes 1380cf009a4e2a5c22e4645f343c7a998f188a22015Chris Forbes InstanceExtensions extensions; 139f0f7d8aa2286bd7516d9fb5c2e58890505e3e5d4Chris Forbes}; 140f0f7d8aa2286bd7516d9fb5c2e58890505e3e5d4Chris Forbes 141f0f7d8aa2286bd7516d9fb5c2e58890505e3e5d4Chris Forbesstruct layer_data { 142f0f7d8aa2286bd7516d9fb5c2e58890505e3e5d4Chris Forbes debug_report_data *report_data = nullptr; 1434a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkLayerDispatchTable dispatch_table; 14494c53c062f0ccc70ef0ada8e98edc90eadc4cb45Tobin Ehlis 145a149f1a0cb39b48b19822c8cf9ef2426cd2251dfMark Lobodzinski DeviceExtensions extensions = {}; 146cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski unordered_set<VkQueue> queues; // All queues under given device 1475b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Layer specific data 148d31a44af6da568692a73201825459689c9431867Tobin Ehlis unordered_map<VkSampler, unique_ptr<SAMPLER_STATE>> samplerMap; 14979fde938178535f598e030a0e9d19a0cb61b72e0Tobin Ehlis unordered_map<VkImageView, unique_ptr<IMAGE_VIEW_STATE>> imageViewMap; 1501facd2c91911508b9fb61f54a56269841299f663Tobin Ehlis unordered_map<VkImage, unique_ptr<IMAGE_STATE>> imageMap; 15139267c0c27b8f032f05a6747eb02d4508247fdc1Tobin Ehlis unordered_map<VkBufferView, unique_ptr<BUFFER_VIEW_STATE>> bufferViewMap; 1525cca7b0a90e0b6fe1cc28ddbe9037c3ce3f3ee13Tobin Ehlis unordered_map<VkBuffer, unique_ptr<BUFFER_STATE>> bufferMap; 15363cddeb5593a0ead9ecd5f74d05f506b37d7ac66Chris Forbes unordered_map<VkPipeline, unique_ptr<PIPELINE_STATE>> pipelineMap; 1548d6a38de0389036581ada119e548180c614fe0efChris Forbes unordered_map<VkCommandPool, COMMAND_POOL_NODE> commandPoolMap; 155a21f0d8ac8389dc4e23749efc02d82a7ec1eaee3Tobin Ehlis unordered_map<VkDescriptorPool, DESCRIPTOR_POOL_STATE *> descriptorPoolMap; 156397d27da37095073c8b86f9ff5289d0a39ce486eTobin Ehlis unordered_map<VkDescriptorSet, cvdescriptorset::DescriptorSet *> setMap; 1573f75ec6fa8700769a790d84e07c270579ded5468Tobin Ehlis unordered_map<VkDescriptorSetLayout, std::shared_ptr<cvdescriptorset::DescriptorSetLayout const>> descriptorSetLayoutMap; 1585b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis unordered_map<VkPipelineLayout, PIPELINE_LAYOUT_NODE> pipelineLayoutMap; 15957fc8e28c2e16118f9827e3ae1b107a27e0451a2Tobin Ehlis unordered_map<VkDeviceMemory, unique_ptr<DEVICE_MEM_INFO>> memObjMap; 1605b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis unordered_map<VkFence, FENCE_NODE> fenceMap; 16136c3a4fe8455762d2dc0b2b9ece44675a3ee8d97Tobin Ehlis unordered_map<VkQueue, QUEUE_STATE> queueMap; 1624710dda89a1dd2e023334d4eda710a394b211cdcTobin Ehlis unordered_map<VkEvent, EVENT_STATE> eventMap; 1635b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis unordered_map<QueryObject, bool> queryToStateMap; 1645b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis unordered_map<VkQueryPool, QUERY_POOL_NODE> queryPoolMap; 1655b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis unordered_map<VkSemaphore, SEMAPHORE_NODE> semaphoreMap; 16672d66f0c1639cbaca92459498452d06db32d7aefTobin Ehlis unordered_map<VkCommandBuffer, GLOBAL_CB_NODE *> commandBufferMap; 167c54e405a4ce05f4de10bb78bfc3a4769c41d2d59Tobin Ehlis unordered_map<VkFramebuffer, unique_ptr<FRAMEBUFFER_STATE>> frameBufferMap; 1685b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis unordered_map<VkImage, vector<ImageSubresourcePair>> imageSubresourceMap; 1695b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis unordered_map<ImageSubresourcePair, IMAGE_LAYOUT_NODE> imageLayoutMap; 170ba9be0cec36d930fc0d5a0cbfbc00b0df49b08e4Tobin Ehlis unordered_map<VkRenderPass, std::shared_ptr<RENDER_PASS_STATE>> renderPassMap; 171918c283ac4f8c604b79abd0c8b5706d2a7352a34Chris Forbes unordered_map<VkShaderModule, unique_ptr<shader_module>> shaderModuleMap; 1726246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski unordered_map<VkDescriptorUpdateTemplateKHR, unique_ptr<TEMPLATE_STATE>> desc_template_map; 17316a1f8f9c4af479b1873e82ff02360817fb658acChris Forbes unordered_map<VkSwapchainKHR, std::unique_ptr<SWAPCHAIN_NODE>> swapchainMap; 17407059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski 175d3578035fec44db2380099c2f59d3e4d8e0b98d6Chris Forbes VkDevice device = VK_NULL_HANDLE; 176ec85232c4d8d9ddf7d2ae57cb8203c5ab52c1106Mark Lobodzinski VkPhysicalDevice physical_device = VK_NULL_HANDLE; 1775b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 178cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski instance_layer_data *instance_data = nullptr; // from device to enclosing instance 17907a464bd7fec9583f346b8c4b8d43c88d2e9ffa4Chris Forbes 180f71dd305f197826a61f398bff725267a20ea1d90Chris Forbes VkPhysicalDeviceFeatures enabled_features = {}; 1815b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Device specific data 182d3578035fec44db2380099c2f59d3e4d8e0b98d6Chris Forbes PHYS_DEV_PROPERTIES_NODE phys_dev_properties = {}; 183d3578035fec44db2380099c2f59d3e4d8e0b98d6Chris Forbes VkPhysicalDeviceMemoryProperties phys_dev_mem_props = {}; 184e47dbc3f3340fa177d877a67b2adb76a570027e5Mark Lobodzinski VkPhysicalDeviceProperties phys_dev_props = {}; 18585926a33d427ee62f395a50886db980127063c72Mike Schuchardt bool external_sync_warning = false; 1865b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis}; 1875b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 188b1b606d27e8c4179534d7bbb48ce217429e37414Tobin Ehlis// TODO : Do we need to guard access to layer_data_map w/ lock? 189b1b606d27e8c4179534d7bbb48ce217429e37414Tobin Ehlisstatic unordered_map<void *, layer_data *> layer_data_map; 190f0f7d8aa2286bd7516d9fb5c2e58890505e3e5d4Chris Forbesstatic unordered_map<void *, instance_layer_data *> instance_layer_data_map; 191b1b606d27e8c4179534d7bbb48ce217429e37414Tobin Ehlis 192b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Youngstatic uint32_t loader_layer_if_version = CURRENT_LOADER_LAYER_INTERFACE_VERSION; 193b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young 194e11120777bcd1543455d1de54b89292879bcd2bbChia-I Wustatic const VkLayerProperties global_layer = { 195f1ea418f193d10a8455cdf47e0eeeeb1f4d8b5bfJon Ashburn "VK_LAYER_LUNARG_core_validation", VK_LAYER_API_VERSION, 1, "LunarG Validation Layer", 196e11120777bcd1543455d1de54b89292879bcd2bbChia-I Wu}; 1975b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 198fe772548f7a48b12772483e8faecc956fb76eb42Chris Forbesstatic const VkExtensionProperties device_extensions[] = { 199fe772548f7a48b12772483e8faecc956fb76eb42Chris Forbes { VK_EXT_VALIDATION_CACHE_EXTENSION_NAME, VK_EXT_VALIDATION_CACHE_SPEC_VERSION }, 200fe772548f7a48b12772483e8faecc956fb76eb42Chris Forbes}; 201fe772548f7a48b12772483e8faecc956fb76eb42Chris Forbes 202cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinskitemplate <class TCreateInfo> 203cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinskivoid ValidateLayerOrdering(const TCreateInfo &createInfo) { 2045b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis bool foundLayer = false; 2055b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t i = 0; i < createInfo.enabledLayerCount; ++i) { 206e11120777bcd1543455d1de54b89292879bcd2bbChia-I Wu if (!strcmp(createInfo.ppEnabledLayerNames[i], global_layer.layerName)) { 2075b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis foundLayer = true; 2085b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 2095b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // This has to be logged to console as we don't have a callback at this point. 2105b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (!foundLayer && !strcmp(createInfo.ppEnabledLayerNames[0], "VK_LAYER_GOOGLE_unique_objects")) { 211bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski LOGCONSOLE("Cannot activate layer VK_LAYER_GOOGLE_unique_objects prior to activating %s.", global_layer.layerName); 2125b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 2135b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 2145b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 2155b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 2165b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// TODO : This can be much smarter, using separate locks for separate global data 217ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbesstatic mutex_t global_lock; 218593c857d8db57cf9ae2c590b75e22dadd51bd3d4Tobin Ehlis 21979fde938178535f598e030a0e9d19a0cb61b72e0Tobin Ehlis// Return IMAGE_VIEW_STATE ptr for specified imageView or else NULL 2209a9a0db2a973034d4286b6d4c62a46beb7641791Tobin EhlisIMAGE_VIEW_STATE *GetImageViewState(const layer_data *dev_data, VkImageView image_view) { 2212c59c1d90b22aa759d785e4233e468616990ff92Tobin Ehlis auto iv_it = dev_data->imageViewMap.find(image_view); 2222c59c1d90b22aa759d785e4233e468616990ff92Tobin Ehlis if (iv_it == dev_data->imageViewMap.end()) { 2232c59c1d90b22aa759d785e4233e468616990ff92Tobin Ehlis return nullptr; 2242c59c1d90b22aa759d785e4233e468616990ff92Tobin Ehlis } 2252c59c1d90b22aa759d785e4233e468616990ff92Tobin Ehlis return iv_it->second.get(); 2262c59c1d90b22aa759d785e4233e468616990ff92Tobin Ehlis} 2279a55ca3674bb3fac3fbdfca9515a16a224aa9055Tobin Ehlis// Return sampler node ptr for specified sampler or else NULL 2289a9a0db2a973034d4286b6d4c62a46beb7641791Tobin EhlisSAMPLER_STATE *GetSamplerState(const layer_data *dev_data, VkSampler sampler) { 2292c59c1d90b22aa759d785e4233e468616990ff92Tobin Ehlis auto sampler_it = dev_data->samplerMap.find(sampler); 2302c59c1d90b22aa759d785e4233e468616990ff92Tobin Ehlis if (sampler_it == dev_data->samplerMap.end()) { 2319a55ca3674bb3fac3fbdfca9515a16a224aa9055Tobin Ehlis return nullptr; 2329a55ca3674bb3fac3fbdfca9515a16a224aa9055Tobin Ehlis } 2339a55ca3674bb3fac3fbdfca9515a16a224aa9055Tobin Ehlis return sampler_it->second.get(); 2349a55ca3674bb3fac3fbdfca9515a16a224aa9055Tobin Ehlis} 2355cca7b0a90e0b6fe1cc28ddbe9037c3ce3f3ee13Tobin Ehlis// Return image state ptr for specified image or else NULL 2369a9a0db2a973034d4286b6d4c62a46beb7641791Tobin EhlisIMAGE_STATE *GetImageState(const layer_data *dev_data, VkImage image) { 2376d1373829eded68f6e080ff2c33e03231360ed57Tobin Ehlis auto img_it = dev_data->imageMap.find(image); 2386d1373829eded68f6e080ff2c33e03231360ed57Tobin Ehlis if (img_it == dev_data->imageMap.end()) { 2396d1373829eded68f6e080ff2c33e03231360ed57Tobin Ehlis return nullptr; 2406d1373829eded68f6e080ff2c33e03231360ed57Tobin Ehlis } 2416d1373829eded68f6e080ff2c33e03231360ed57Tobin Ehlis return img_it->second.get(); 2426d1373829eded68f6e080ff2c33e03231360ed57Tobin Ehlis} 2435cca7b0a90e0b6fe1cc28ddbe9037c3ce3f3ee13Tobin Ehlis// Return buffer state ptr for specified buffer or else NULL 2449a9a0db2a973034d4286b6d4c62a46beb7641791Tobin EhlisBUFFER_STATE *GetBufferState(const layer_data *dev_data, VkBuffer buffer) { 2452c59c1d90b22aa759d785e4233e468616990ff92Tobin Ehlis auto buff_it = dev_data->bufferMap.find(buffer); 2462c59c1d90b22aa759d785e4233e468616990ff92Tobin Ehlis if (buff_it == dev_data->bufferMap.end()) { 2478718070cf3e206488c168f1e6b9dd06d6880c9bcTobin Ehlis return nullptr; 2488718070cf3e206488c168f1e6b9dd06d6880c9bcTobin Ehlis } 2498718070cf3e206488c168f1e6b9dd06d6880c9bcTobin Ehlis return buff_it->second.get(); 2508718070cf3e206488c168f1e6b9dd06d6880c9bcTobin Ehlis} 251b110cb87b9478586719d7f7dc769b350857366baTobin Ehlis// Return swapchain node for specified swapchain or else NULL 2529a9a0db2a973034d4286b6d4c62a46beb7641791Tobin EhlisSWAPCHAIN_NODE *GetSwapchainNode(const layer_data *dev_data, VkSwapchainKHR swapchain) { 25316a1f8f9c4af479b1873e82ff02360817fb658acChris Forbes auto swp_it = dev_data->swapchainMap.find(swapchain); 25416a1f8f9c4af479b1873e82ff02360817fb658acChris Forbes if (swp_it == dev_data->swapchainMap.end()) { 255b110cb87b9478586719d7f7dc769b350857366baTobin Ehlis return nullptr; 256b110cb87b9478586719d7f7dc769b350857366baTobin Ehlis } 2573f687bf405355f3eec6bd1bc0e8d04daba37a0f9Tobin Ehlis return swp_it->second.get(); 258b110cb87b9478586719d7f7dc769b350857366baTobin Ehlis} 2592f2db584f5d79892bd84d0a24b8ca3499985a5c2Tobin Ehlis// Return buffer node ptr for specified buffer or else NULL 2609a9a0db2a973034d4286b6d4c62a46beb7641791Tobin EhlisBUFFER_VIEW_STATE *GetBufferViewState(const layer_data *dev_data, VkBufferView buffer_view) { 26151ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis auto bv_it = dev_data->bufferViewMap.find(buffer_view); 26251ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis if (bv_it == dev_data->bufferViewMap.end()) { 2632f2db584f5d79892bd84d0a24b8ca3499985a5c2Tobin Ehlis return nullptr; 2642f2db584f5d79892bd84d0a24b8ca3499985a5c2Tobin Ehlis } 2652f2db584f5d79892bd84d0a24b8ca3499985a5c2Tobin Ehlis return bv_it->second.get(); 2662f2db584f5d79892bd84d0a24b8ca3499985a5c2Tobin Ehlis} 2678718070cf3e206488c168f1e6b9dd06d6880c9bcTobin Ehlis 2689a9a0db2a973034d4286b6d4c62a46beb7641791Tobin EhlisFENCE_NODE *GetFenceNode(layer_data *dev_data, VkFence fence) { 26966fb98d19a758f79dd11ba354e47d0c66c6aac1eChris Forbes auto it = dev_data->fenceMap.find(fence); 27066fb98d19a758f79dd11ba354e47d0c66c6aac1eChris Forbes if (it == dev_data->fenceMap.end()) { 27166fb98d19a758f79dd11ba354e47d0c66c6aac1eChris Forbes return nullptr; 27266fb98d19a758f79dd11ba354e47d0c66c6aac1eChris Forbes } 27366fb98d19a758f79dd11ba354e47d0c66c6aac1eChris Forbes return &it->second; 27466fb98d19a758f79dd11ba354e47d0c66c6aac1eChris Forbes} 27566fb98d19a758f79dd11ba354e47d0c66c6aac1eChris Forbes 2769a9a0db2a973034d4286b6d4c62a46beb7641791Tobin EhlisEVENT_STATE *GetEventNode(layer_data *dev_data, VkEvent event) { 2779556936067fd0c4eb74c4a13631bc163b154faedTobin Ehlis auto it = dev_data->eventMap.find(event); 2789556936067fd0c4eb74c4a13631bc163b154faedTobin Ehlis if (it == dev_data->eventMap.end()) { 2799556936067fd0c4eb74c4a13631bc163b154faedTobin Ehlis return nullptr; 2809556936067fd0c4eb74c4a13631bc163b154faedTobin Ehlis } 2819556936067fd0c4eb74c4a13631bc163b154faedTobin Ehlis return &it->second; 2829556936067fd0c4eb74c4a13631bc163b154faedTobin Ehlis} 2839556936067fd0c4eb74c4a13631bc163b154faedTobin Ehlis 2849a9a0db2a973034d4286b6d4c62a46beb7641791Tobin EhlisQUERY_POOL_NODE *GetQueryPoolNode(layer_data *dev_data, VkQueryPool query_pool) { 285ccdcc9686c664e9407dd03262f3aaf3245b23be2Tobin Ehlis auto it = dev_data->queryPoolMap.find(query_pool); 286ccdcc9686c664e9407dd03262f3aaf3245b23be2Tobin Ehlis if (it == dev_data->queryPoolMap.end()) { 287ccdcc9686c664e9407dd03262f3aaf3245b23be2Tobin Ehlis return nullptr; 288ccdcc9686c664e9407dd03262f3aaf3245b23be2Tobin Ehlis } 289ccdcc9686c664e9407dd03262f3aaf3245b23be2Tobin Ehlis return &it->second; 290ccdcc9686c664e9407dd03262f3aaf3245b23be2Tobin Ehlis} 291ccdcc9686c664e9407dd03262f3aaf3245b23be2Tobin Ehlis 2929a9a0db2a973034d4286b6d4c62a46beb7641791Tobin EhlisQUEUE_STATE *GetQueueState(layer_data *dev_data, VkQueue queue) { 29366fb98d19a758f79dd11ba354e47d0c66c6aac1eChris Forbes auto it = dev_data->queueMap.find(queue); 29466fb98d19a758f79dd11ba354e47d0c66c6aac1eChris Forbes if (it == dev_data->queueMap.end()) { 29566fb98d19a758f79dd11ba354e47d0c66c6aac1eChris Forbes return nullptr; 29666fb98d19a758f79dd11ba354e47d0c66c6aac1eChris Forbes } 29766fb98d19a758f79dd11ba354e47d0c66c6aac1eChris Forbes return &it->second; 29866fb98d19a758f79dd11ba354e47d0c66c6aac1eChris Forbes} 29966fb98d19a758f79dd11ba354e47d0c66c6aac1eChris Forbes 3009a9a0db2a973034d4286b6d4c62a46beb7641791Tobin EhlisSEMAPHORE_NODE *GetSemaphoreNode(layer_data *dev_data, VkSemaphore semaphore) { 3015e92f3cfdca6a52a3dcefd053c41f728bd036cebChris Forbes auto it = dev_data->semaphoreMap.find(semaphore); 3025e92f3cfdca6a52a3dcefd053c41f728bd036cebChris Forbes if (it == dev_data->semaphoreMap.end()) { 3035e92f3cfdca6a52a3dcefd053c41f728bd036cebChris Forbes return nullptr; 3045e92f3cfdca6a52a3dcefd053c41f728bd036cebChris Forbes } 3055e92f3cfdca6a52a3dcefd053c41f728bd036cebChris Forbes return &it->second; 3065e92f3cfdca6a52a3dcefd053c41f728bd036cebChris Forbes} 3075e92f3cfdca6a52a3dcefd053c41f728bd036cebChris Forbes 3089a9a0db2a973034d4286b6d4c62a46beb7641791Tobin EhlisCOMMAND_POOL_NODE *GetCommandPoolNode(layer_data *dev_data, VkCommandPool pool) { 3098d6a38de0389036581ada119e548180c614fe0efChris Forbes auto it = dev_data->commandPoolMap.find(pool); 3108d6a38de0389036581ada119e548180c614fe0efChris Forbes if (it == dev_data->commandPoolMap.end()) { 3118d6a38de0389036581ada119e548180c614fe0efChris Forbes return nullptr; 3128d6a38de0389036581ada119e548180c614fe0efChris Forbes } 3138d6a38de0389036581ada119e548180c614fe0efChris Forbes return &it->second; 3148d6a38de0389036581ada119e548180c614fe0efChris Forbes} 3153bb2c67470811e4eaf908b3eade82f73aa3f87bcChris Forbes 3169a9a0db2a973034d4286b6d4c62a46beb7641791Tobin EhlisPHYSICAL_DEVICE_STATE *GetPhysicalDeviceState(instance_layer_data *instance_data, VkPhysicalDevice phys) { 317f0f7d8aa2286bd7516d9fb5c2e58890505e3e5d4Chris Forbes auto it = instance_data->physical_device_map.find(phys); 318f0f7d8aa2286bd7516d9fb5c2e58890505e3e5d4Chris Forbes if (it == instance_data->physical_device_map.end()) { 3193bb2c67470811e4eaf908b3eade82f73aa3f87bcChris Forbes return nullptr; 3203bb2c67470811e4eaf908b3eade82f73aa3f87bcChris Forbes } 3213bb2c67470811e4eaf908b3eade82f73aa3f87bcChris Forbes return &it->second; 3223bb2c67470811e4eaf908b3eade82f73aa3f87bcChris Forbes} 3233bb2c67470811e4eaf908b3eade82f73aa3f87bcChris Forbes 3249a9a0db2a973034d4286b6d4c62a46beb7641791Tobin EhlisSURFACE_STATE *GetSurfaceState(instance_layer_data *instance_data, VkSurfaceKHR surface) { 325747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes auto it = instance_data->surface_map.find(surface); 326747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes if (it == instance_data->surface_map.end()) { 327747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes return nullptr; 328747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes } 329747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes return &it->second; 330747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes} 331747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes 332d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris ForbesDeviceExtensions const *GetEnabledExtensions(layer_data const *dev_data) { 333d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes return &dev_data->extensions; 334d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes} 335d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes 336f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis// Return ptr to memory binding for given handle of specified type 3377a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinskistatic BINDABLE *GetObjectMemBinding(layer_data *dev_data, uint64_t handle, VulkanObjectType type) { 3385b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis switch (type) { 3397a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski case kVulkanObjectTypeImage: 3409a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis return GetImageState(dev_data, VkImage(handle)); 3417a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski case kVulkanObjectTypeBuffer: 3429a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis return GetBufferState(dev_data, VkBuffer(handle)); 343cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski default: 344cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 3455b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 34694c53c062f0ccc70ef0ada8e98edc90eadc4cb45Tobin Ehlis return nullptr; 3475b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 34872d66f0c1639cbaca92459498452d06db32d7aefTobin Ehlis// prototype 3499a9a0db2a973034d4286b6d4c62a46beb7641791Tobin EhlisGLOBAL_CB_NODE *GetCBNode(layer_data const *, const VkCommandBuffer); 35072d66f0c1639cbaca92459498452d06db32d7aefTobin Ehlis 3515b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// Return ptr to info in map container containing mem, or NULL if not found 3525b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// Calls to this function should be wrapped in mutex 3539a9a0db2a973034d4286b6d4c62a46beb7641791Tobin EhlisDEVICE_MEM_INFO *GetMemObjInfo(const layer_data *dev_data, const VkDeviceMemory mem) { 35457fc8e28c2e16118f9827e3ae1b107a27e0451a2Tobin Ehlis auto mem_it = dev_data->memObjMap.find(mem); 35557fc8e28c2e16118f9827e3ae1b107a27e0451a2Tobin Ehlis if (mem_it == dev_data->memObjMap.end()) { 3565b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return NULL; 3575b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 35857fc8e28c2e16118f9827e3ae1b107a27e0451a2Tobin Ehlis return mem_it->second.get(); 3595b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 3605b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 36151ea774638f432bd8e700ec8291a980f405f429eTobin Ehlisstatic void add_mem_obj_info(layer_data *dev_data, void *object, const VkDeviceMemory mem, 3625b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis const VkMemoryAllocateInfo *pAllocateInfo) { 3635b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis assert(object != NULL); 3645b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 36551ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis dev_data->memObjMap[mem] = unique_ptr<DEVICE_MEM_INFO>(new DEVICE_MEM_INFO(object, mem, pAllocateInfo)); 366ee0b33024b1641ad3bb153259cf71d42675e4652Mike Schuchardt 367ee0b33024b1641ad3bb153259cf71d42675e4652Mike Schuchardt if (pAllocateInfo->pNext) { 368ee0b33024b1641ad3bb153259cf71d42675e4652Mike Schuchardt auto struct_header = reinterpret_cast<const GENERIC_HEADER *>(pAllocateInfo->pNext); 369ee0b33024b1641ad3bb153259cf71d42675e4652Mike Schuchardt while (struct_header) { 370ee0b33024b1641ad3bb153259cf71d42675e4652Mike Schuchardt if (VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR == struct_header->sType || 371ee0b33024b1641ad3bb153259cf71d42675e4652Mike Schuchardt VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR == struct_header->sType) { 372ee0b33024b1641ad3bb153259cf71d42675e4652Mike Schuchardt dev_data->memObjMap[mem]->global_valid = true; 373ee0b33024b1641ad3bb153259cf71d42675e4652Mike Schuchardt break; 374ee0b33024b1641ad3bb153259cf71d42675e4652Mike Schuchardt } 375ee0b33024b1641ad3bb153259cf71d42675e4652Mike Schuchardt struct_header = reinterpret_cast<const GENERIC_HEADER *>(struct_header->pNext); 376ee0b33024b1641ad3bb153259cf71d42675e4652Mike Schuchardt } 377ee0b33024b1641ad3bb153259cf71d42675e4652Mike Schuchardt } 3785b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 379dc21d4c322604e04e0b8433970f6a1ced6a0b647Tobin Ehlis 380cf17f50f6489504c0d8151c46d6f77404ce2ffffTobin Ehlis// For given bound_object_handle, bound to given mem allocation, verify that the range for the bound object is valid 3817a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinskistatic bool ValidateMemoryIsValid(layer_data *dev_data, VkDeviceMemory mem, uint64_t bound_object_handle, VulkanObjectType type, 3827a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski const char *functionName) { 3839a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis DEVICE_MEM_INFO *mem_info = GetMemObjInfo(dev_data, mem); 384f989de4217bce0f293121d0da53dc8328276370fTobin Ehlis if (mem_info) { 385f989de4217bce0f293121d0da53dc8328276370fTobin Ehlis if (!mem_info->bound_ranges[bound_object_handle].valid) { 386f48a83f5b5548cd46a12770c7542ff902537ad3eKarl Schultz return log_msg(dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 3879b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(mem), __LINE__, MEMTRACK_INVALID_MEM_REGION, "MEM", 388dc21d4c322604e04e0b8433970f6a1ced6a0b647Tobin Ehlis "%s: Cannot read invalid region of memory allocation 0x%" PRIx64 " for bound %s object 0x%" PRIx64 389dc21d4c322604e04e0b8433970f6a1ced6a0b647Tobin Ehlis ", please fill the memory before using.", 3909b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus functionName, HandleToUint64(mem), object_string[type], bound_object_handle); 391f989de4217bce0f293121d0da53dc8328276370fTobin Ehlis } 392f989de4217bce0f293121d0da53dc8328276370fTobin Ehlis } 393f989de4217bce0f293121d0da53dc8328276370fTobin Ehlis return false; 394f989de4217bce0f293121d0da53dc8328276370fTobin Ehlis} 3951facd2c91911508b9fb61f54a56269841299f663Tobin Ehlis// For given image_state 3961facd2c91911508b9fb61f54a56269841299f663Tobin Ehlis// If mem is special swapchain key, then verify that image_state valid member is true 397f989de4217bce0f293121d0da53dc8328276370fTobin Ehlis// Else verify that the image's bound memory range is valid 39860568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinskibool ValidateImageMemoryIsValid(layer_data *dev_data, IMAGE_STATE *image_state, const char *functionName) { 399e46491ee6f16b9d29e68914fc6522aba2fde0ad4Tobin Ehlis if (image_state->binding.mem == MEMTRACKER_SWAP_CHAIN_IMAGE_KEY) { 4001facd2c91911508b9fb61f54a56269841299f663Tobin Ehlis if (!image_state->valid) { 401f48a83f5b5548cd46a12770c7542ff902537ad3eKarl Schultz return log_msg(dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 4029b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(image_state->binding.mem), __LINE__, MEMTRACK_INVALID_MEM_REGION, "MEM", 403414e9a4117b500eac650d8b8f01a6e1b22d05aaeMark Mueller "%s: Cannot read invalid swapchain image 0x%" PRIx64 ", please fill the memory before using.", 4049b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus functionName, HandleToUint64(image_state->image)); 4055b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 4065b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } else { 4079b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus return ValidateMemoryIsValid(dev_data, image_state->binding.mem, HandleToUint64(image_state->image), kVulkanObjectTypeImage, 4089b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus functionName); 4095b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 4105b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return false; 4115b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 4125cca7b0a90e0b6fe1cc28ddbe9037c3ce3f3ee13Tobin Ehlis// For given buffer_state, verify that the range it's bound to is valid 413c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinskibool ValidateBufferMemoryIsValid(layer_data *dev_data, BUFFER_STATE *buffer_state, const char *functionName) { 4149b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus return ValidateMemoryIsValid(dev_data, buffer_state->binding.mem, HandleToUint64(buffer_state->buffer), kVulkanObjectTypeBuffer, 4159b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus functionName); 416f989de4217bce0f293121d0da53dc8328276370fTobin Ehlis} 417f989de4217bce0f293121d0da53dc8328276370fTobin Ehlis// For the given memory allocation, set the range bound by the given handle object to the valid param value 418f989de4217bce0f293121d0da53dc8328276370fTobin Ehlisstatic void SetMemoryValid(layer_data *dev_data, VkDeviceMemory mem, uint64_t handle, bool valid) { 4199a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis DEVICE_MEM_INFO *mem_info = GetMemObjInfo(dev_data, mem); 420f989de4217bce0f293121d0da53dc8328276370fTobin Ehlis if (mem_info) { 421f989de4217bce0f293121d0da53dc8328276370fTobin Ehlis mem_info->bound_ranges[handle].valid = valid; 422f989de4217bce0f293121d0da53dc8328276370fTobin Ehlis } 423f989de4217bce0f293121d0da53dc8328276370fTobin Ehlis} 424f989de4217bce0f293121d0da53dc8328276370fTobin Ehlis// For given image node 4251facd2c91911508b9fb61f54a56269841299f663Tobin Ehlis// If mem is special swapchain key, then set entire image_state to valid param value 426f989de4217bce0f293121d0da53dc8328276370fTobin Ehlis// Else set the image's bound memory range to valid param value 427623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinskivoid SetImageMemoryValid(layer_data *dev_data, IMAGE_STATE *image_state, bool valid) { 428e46491ee6f16b9d29e68914fc6522aba2fde0ad4Tobin Ehlis if (image_state->binding.mem == MEMTRACKER_SWAP_CHAIN_IMAGE_KEY) { 4291facd2c91911508b9fb61f54a56269841299f663Tobin Ehlis image_state->valid = valid; 4305b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } else { 4319b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus SetMemoryValid(dev_data, image_state->binding.mem, HandleToUint64(image_state->image), valid); 4325b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 4335b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 434f989de4217bce0f293121d0da53dc8328276370fTobin Ehlis// For given buffer node set the buffer's bound memory range to valid param value 435c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinskivoid SetBufferMemoryValid(layer_data *dev_data, BUFFER_STATE *buffer_state, bool valid) { 4369b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus SetMemoryValid(dev_data, buffer_state->binding.mem, HandleToUint64(buffer_state->buffer), valid); 437f989de4217bce0f293121d0da53dc8328276370fTobin Ehlis} 438ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis 43956f8a8f9b7e8c01d76d73be117ebcb66035db6dfTobin Ehlis// Create binding link between given sampler and command buffer node 440d31a44af6da568692a73201825459689c9431867Tobin Ehlisvoid AddCommandBufferBindingSampler(GLOBAL_CB_NODE *cb_node, SAMPLER_STATE *sampler_state) { 441d31a44af6da568692a73201825459689c9431867Tobin Ehlis sampler_state->cb_bindings.insert(cb_node); 4429b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus cb_node->object_bindings.insert({HandleToUint64(sampler_state->sampler), kVulkanObjectTypeSampler}); 44356f8a8f9b7e8c01d76d73be117ebcb66035db6dfTobin Ehlis} 44456f8a8f9b7e8c01d76d73be117ebcb66035db6dfTobin Ehlis 44556f8a8f9b7e8c01d76d73be117ebcb66035db6dfTobin Ehlis// Create binding link between given image node and command buffer node 4461facd2c91911508b9fb61f54a56269841299f663Tobin Ehlisvoid AddCommandBufferBindingImage(const layer_data *dev_data, GLOBAL_CB_NODE *cb_node, IMAGE_STATE *image_state) { 447ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis // Skip validation if this image was created through WSI 448e46491ee6f16b9d29e68914fc6522aba2fde0ad4Tobin Ehlis if (image_state->binding.mem != MEMTRACKER_SWAP_CHAIN_IMAGE_KEY) { 449ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis // First update CB binding in MemObj mini CB list 450d87d172d120ea3f00bfd34335537332d7ce61a89Tobin Ehlis for (auto mem_binding : image_state->GetBoundMemory()) { 4519a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis DEVICE_MEM_INFO *pMemInfo = GetMemObjInfo(dev_data, mem_binding); 452d87d172d120ea3f00bfd34335537332d7ce61a89Tobin Ehlis if (pMemInfo) { 453d87d172d120ea3f00bfd34335537332d7ce61a89Tobin Ehlis pMemInfo->cb_bindings.insert(cb_node); 454d87d172d120ea3f00bfd34335537332d7ce61a89Tobin Ehlis // Now update CBInfo's Mem reference list 455d87d172d120ea3f00bfd34335537332d7ce61a89Tobin Ehlis cb_node->memObjs.insert(mem_binding); 456d87d172d120ea3f00bfd34335537332d7ce61a89Tobin Ehlis } 457ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis } 458f940225c9e5e3e14b3f5a32d3ea360b585614600Tobin Ehlis // Now update cb binding for image 4599b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus cb_node->object_bindings.insert({HandleToUint64(image_state->image), kVulkanObjectTypeImage}); 4601facd2c91911508b9fb61f54a56269841299f663Tobin Ehlis image_state->cb_bindings.insert(cb_node); 461ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis } 462ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis} 463ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis 46403ea795b83fdf0099594808a1a57064dea7f02a1Tobin Ehlis// Create binding link between given image view node and its image with command buffer node 46503ea795b83fdf0099594808a1a57064dea7f02a1Tobin Ehlisvoid AddCommandBufferBindingImageView(const layer_data *dev_data, GLOBAL_CB_NODE *cb_node, IMAGE_VIEW_STATE *view_state) { 46603ea795b83fdf0099594808a1a57064dea7f02a1Tobin Ehlis // First add bindings for imageView 46703ea795b83fdf0099594808a1a57064dea7f02a1Tobin Ehlis view_state->cb_bindings.insert(cb_node); 4689b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus cb_node->object_bindings.insert({HandleToUint64(view_state->image_view), kVulkanObjectTypeImageView}); 4699a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto image_state = GetImageState(dev_data, view_state->create_info.image); 47003ea795b83fdf0099594808a1a57064dea7f02a1Tobin Ehlis // Add bindings for image within imageView 4711facd2c91911508b9fb61f54a56269841299f663Tobin Ehlis if (image_state) { 4721facd2c91911508b9fb61f54a56269841299f663Tobin Ehlis AddCommandBufferBindingImage(dev_data, cb_node, image_state); 47303ea795b83fdf0099594808a1a57064dea7f02a1Tobin Ehlis } 47403ea795b83fdf0099594808a1a57064dea7f02a1Tobin Ehlis} 47503ea795b83fdf0099594808a1a57064dea7f02a1Tobin Ehlis 476ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis// Create binding link between given buffer node and command buffer node 4775cca7b0a90e0b6fe1cc28ddbe9037c3ce3f3ee13Tobin Ehlisvoid AddCommandBufferBindingBuffer(const layer_data *dev_data, GLOBAL_CB_NODE *cb_node, BUFFER_STATE *buffer_state) { 478ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis // First update CB binding in MemObj mini CB list 4795cca7b0a90e0b6fe1cc28ddbe9037c3ce3f3ee13Tobin Ehlis for (auto mem_binding : buffer_state->GetBoundMemory()) { 4809a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis DEVICE_MEM_INFO *pMemInfo = GetMemObjInfo(dev_data, mem_binding); 481d87d172d120ea3f00bfd34335537332d7ce61a89Tobin Ehlis if (pMemInfo) { 482d87d172d120ea3f00bfd34335537332d7ce61a89Tobin Ehlis pMemInfo->cb_bindings.insert(cb_node); 483d87d172d120ea3f00bfd34335537332d7ce61a89Tobin Ehlis // Now update CBInfo's Mem reference list 484d87d172d120ea3f00bfd34335537332d7ce61a89Tobin Ehlis cb_node->memObjs.insert(mem_binding); 485d87d172d120ea3f00bfd34335537332d7ce61a89Tobin Ehlis } 486ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis } 487ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis // Now update cb binding for buffer 4889b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus cb_node->object_bindings.insert({HandleToUint64(buffer_state->buffer), kVulkanObjectTypeBuffer}); 4895cca7b0a90e0b6fe1cc28ddbe9037c3ce3f3ee13Tobin Ehlis buffer_state->cb_bindings.insert(cb_node); 490ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis} 491ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis 49277b6217754b9c167b08cb151e70b41a948e36277Tobin Ehlis// Create binding link between given buffer view node and its buffer with command buffer node 49377b6217754b9c167b08cb151e70b41a948e36277Tobin Ehlisvoid AddCommandBufferBindingBufferView(const layer_data *dev_data, GLOBAL_CB_NODE *cb_node, BUFFER_VIEW_STATE *view_state) { 49477b6217754b9c167b08cb151e70b41a948e36277Tobin Ehlis // First add bindings for bufferView 49577b6217754b9c167b08cb151e70b41a948e36277Tobin Ehlis view_state->cb_bindings.insert(cb_node); 4969b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus cb_node->object_bindings.insert({HandleToUint64(view_state->buffer_view), kVulkanObjectTypeBufferView}); 4979a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto buffer_state = GetBufferState(dev_data, view_state->create_info.buffer); 49877b6217754b9c167b08cb151e70b41a948e36277Tobin Ehlis // Add bindings for buffer within bufferView 4995cca7b0a90e0b6fe1cc28ddbe9037c3ce3f3ee13Tobin Ehlis if (buffer_state) { 5005cca7b0a90e0b6fe1cc28ddbe9037c3ce3f3ee13Tobin Ehlis AddCommandBufferBindingBuffer(dev_data, cb_node, buffer_state); 50177b6217754b9c167b08cb151e70b41a948e36277Tobin Ehlis } 50277b6217754b9c167b08cb151e70b41a948e36277Tobin Ehlis} 50377b6217754b9c167b08cb151e70b41a948e36277Tobin Ehlis 504400cff9fad0e19c80f6c9ed1181795d411a4bec5Tobin Ehlis// For every mem obj bound to particular CB, free bindings related to that CB 505d74f8771414d9e80618cd7604ea4b1c459dfa42eTobin Ehlisstatic void clear_cmd_buf_and_mem_references(layer_data *dev_data, GLOBAL_CB_NODE *cb_node) { 506d74f8771414d9e80618cd7604ea4b1c459dfa42eTobin Ehlis if (cb_node) { 507d74f8771414d9e80618cd7604ea4b1c459dfa42eTobin Ehlis if (cb_node->memObjs.size() > 0) { 508d74f8771414d9e80618cd7604ea4b1c459dfa42eTobin Ehlis for (auto mem : cb_node->memObjs) { 5099a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis DEVICE_MEM_INFO *pInfo = GetMemObjInfo(dev_data, mem); 5105b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pInfo) { 511d74f8771414d9e80618cd7604ea4b1c459dfa42eTobin Ehlis pInfo->cb_bindings.erase(cb_node); 5125b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5135b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 514d74f8771414d9e80618cd7604ea4b1c459dfa42eTobin Ehlis cb_node->memObjs.clear(); 5155b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5165b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5175b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 5185b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 519f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis// Clear a single object binding from given memory object, or report error if binding is missing 5207a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinskistatic bool ClearMemoryObjectBinding(layer_data *dev_data, uint64_t handle, VulkanObjectType type, VkDeviceMemory mem) { 5219a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis DEVICE_MEM_INFO *mem_info = GetMemObjInfo(dev_data, mem); 522f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis // This obj is bound to a memory object. Remove the reference to this object in that memory object's list 523d4cd34fd49caa759cf01cafa5fa271401b17c3b9Jeremy Hayes if (mem_info) { 524d4cd34fd49caa759cf01cafa5fa271401b17c3b9Jeremy Hayes mem_info->obj_bindings.erase({handle, type}); 525f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis } 526f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis return false; 527f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis} 528f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis 529f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis// ClearMemoryObjectBindings clears the binding of objects to memory 530f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis// For the given object it pulls the memory bindings and makes sure that the bindings 531f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis// no longer refer to the object being cleared. This occurs when objects are destroyed. 5327a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinskibool ClearMemoryObjectBindings(layer_data *dev_data, uint64_t handle, VulkanObjectType type) { 533f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis bool skip = false; 534f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis BINDABLE *mem_binding = GetObjectMemBinding(dev_data, handle, type); 535f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis if (mem_binding) { 536f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis if (!mem_binding->sparse) { 537f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis skip = ClearMemoryObjectBinding(dev_data, handle, type, mem_binding->binding.mem); 538cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } else { // Sparse, clear all bindings 539bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski for (auto &sparse_mem_binding : mem_binding->sparse_bindings) { 540f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis skip |= ClearMemoryObjectBinding(dev_data, handle, type, sparse_mem_binding.mem); 5415b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5425b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5435b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 544f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis return skip; 5455b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 5465b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 547888cae09036ec622d6014e18efbda55e6226cf22Tobin Ehlis// For given mem object, verify that it is not null or UNBOUND, if it is, report error. Return skip value. 548888cae09036ec622d6014e18efbda55e6226cf22Tobin Ehlisbool VerifyBoundMemoryIsValid(const layer_data *dev_data, VkDeviceMemory mem, uint64_t handle, const char *api_name, 54935ec5e14e463d342b74ffe33ee542be13d5c6639Tobin Ehlis const char *type_name, UNIQUE_VALIDATION_ERROR_CODE error_code) { 550888cae09036ec622d6014e18efbda55e6226cf22Tobin Ehlis bool result = false; 551888cae09036ec622d6014e18efbda55e6226cf22Tobin Ehlis if (VK_NULL_HANDLE == mem) { 552888cae09036ec622d6014e18efbda55e6226cf22Tobin Ehlis result = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, handle, 553cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski __LINE__, error_code, "MEM", "%s: Vk%s object 0x%" PRIxLEAST64 554cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski " used with no memory bound. Memory should be bound by calling " 555cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "vkBind%sMemory(). %s", 55635ec5e14e463d342b74ffe33ee542be13d5c6639Tobin Ehlis api_name, type_name, handle, type_name, validation_error_map[error_code]); 557888cae09036ec622d6014e18efbda55e6226cf22Tobin Ehlis } else if (MEMORY_UNBOUND == mem) { 558888cae09036ec622d6014e18efbda55e6226cf22Tobin Ehlis result = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, handle, 559cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski __LINE__, error_code, "MEM", "%s: Vk%s object 0x%" PRIxLEAST64 560cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski " used with no memory bound and previously bound memory was freed. " 561cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "Memory must not be freed prior to this operation. %s", 56235ec5e14e463d342b74ffe33ee542be13d5c6639Tobin Ehlis api_name, type_name, handle, validation_error_map[error_code]); 563888cae09036ec622d6014e18efbda55e6226cf22Tobin Ehlis } 564888cae09036ec622d6014e18efbda55e6226cf22Tobin Ehlis return result; 565888cae09036ec622d6014e18efbda55e6226cf22Tobin Ehlis} 566888cae09036ec622d6014e18efbda55e6226cf22Tobin Ehlis 567b3c2024e0ed61d7f68630d7eb7c8c03100689bb1Mark Lobodzinski// Check to see if memory was ever bound to this image 56835ec5e14e463d342b74ffe33ee542be13d5c6639Tobin Ehlisbool ValidateMemoryIsBoundToImage(const layer_data *dev_data, const IMAGE_STATE *image_state, const char *api_name, 56935ec5e14e463d342b74ffe33ee542be13d5c6639Tobin Ehlis UNIQUE_VALIDATION_ERROR_CODE error_code) { 570b3c2024e0ed61d7f68630d7eb7c8c03100689bb1Mark Lobodzinski bool result = false; 5711facd2c91911508b9fb61f54a56269841299f663Tobin Ehlis if (0 == (static_cast<uint32_t>(image_state->createInfo.flags) & VK_IMAGE_CREATE_SPARSE_BINDING_BIT)) { 5729b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus result = VerifyBoundMemoryIsValid(dev_data, image_state->binding.mem, HandleToUint64(image_state->image), api_name, "Image", 5739b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus error_code); 574b3c2024e0ed61d7f68630d7eb7c8c03100689bb1Mark Lobodzinski } 575b3c2024e0ed61d7f68630d7eb7c8c03100689bb1Mark Lobodzinski return result; 576b3c2024e0ed61d7f68630d7eb7c8c03100689bb1Mark Lobodzinski} 577b3c2024e0ed61d7f68630d7eb7c8c03100689bb1Mark Lobodzinski 578b3c2024e0ed61d7f68630d7eb7c8c03100689bb1Mark Lobodzinski// Check to see if memory was bound to this buffer 57935ec5e14e463d342b74ffe33ee542be13d5c6639Tobin Ehlisbool ValidateMemoryIsBoundToBuffer(const layer_data *dev_data, const BUFFER_STATE *buffer_state, const char *api_name, 58035ec5e14e463d342b74ffe33ee542be13d5c6639Tobin Ehlis UNIQUE_VALIDATION_ERROR_CODE error_code) { 581b3c2024e0ed61d7f68630d7eb7c8c03100689bb1Mark Lobodzinski bool result = false; 5825cca7b0a90e0b6fe1cc28ddbe9037c3ce3f3ee13Tobin Ehlis if (0 == (static_cast<uint32_t>(buffer_state->createInfo.flags) & VK_BUFFER_CREATE_SPARSE_BINDING_BIT)) { 5839b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus result = VerifyBoundMemoryIsValid(dev_data, buffer_state->binding.mem, HandleToUint64(buffer_state->buffer), api_name, 5849b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "Buffer", error_code); 585b3c2024e0ed61d7f68630d7eb7c8c03100689bb1Mark Lobodzinski } 586b3c2024e0ed61d7f68630d7eb7c8c03100689bb1Mark Lobodzinski return result; 587b3c2024e0ed61d7f68630d7eb7c8c03100689bb1Mark Lobodzinski} 588b3c2024e0ed61d7f68630d7eb7c8c03100689bb1Mark Lobodzinski 5893a6c2a8f5135475de5be6de7675ffd9dd27b30d3Cort Stratton// SetMemBinding is used to establish immutable, non-sparse binding between a single image/buffer object and memory object. 5903a6c2a8f5135475de5be6de7675ffd9dd27b30d3Cort Stratton// Corresponding valid usage checks are in ValidateSetMemBinding(). 5917a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinskistatic void SetMemBinding(layer_data *dev_data, VkDeviceMemory mem, uint64_t handle, VulkanObjectType type, const char *apiName) { 592c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton if (mem != VK_NULL_HANDLE) { 593c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton BINDABLE *mem_binding = GetObjectMemBinding(dev_data, handle, type); 594c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton assert(mem_binding); 595c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton DEVICE_MEM_INFO *mem_info = GetMemObjInfo(dev_data, mem); 596c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton if (mem_info) { 597c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton mem_info->obj_bindings.insert({handle, type}); 598c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton // For image objects, make sure default memory state is correctly set 599c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton // TODO : What's the best/correct way to handle this? 6007a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski if (kVulkanObjectTypeImage == type) { 601c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton auto const image_state = GetImageState(dev_data, VkImage(handle)); 602c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton if (image_state) { 603c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton VkImageCreateInfo ici = image_state->createInfo; 604c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton if (ici.usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) { 605c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton // TODO:: More memory state transition stuff. 606c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton } 607c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton } 608c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton } 609c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton mem_binding->binding.mem = mem; 610c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton } 611c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton } 612c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton} 6133a6c2a8f5135475de5be6de7675ffd9dd27b30d3Cort Stratton 6143a6c2a8f5135475de5be6de7675ffd9dd27b30d3Cort Stratton// Valid usage checks for a call to SetMemBinding(). 6153a6c2a8f5135475de5be6de7675ffd9dd27b30d3Cort Stratton// For NULL mem case, output warning 6163a6c2a8f5135475de5be6de7675ffd9dd27b30d3Cort Stratton// Make sure given object is in global object map 6173a6c2a8f5135475de5be6de7675ffd9dd27b30d3Cort Stratton// IF a previous binding existed, output validation error 6183a6c2a8f5135475de5be6de7675ffd9dd27b30d3Cort Stratton// Otherwise, add reference from objectInfo to memoryInfo 6193a6c2a8f5135475de5be6de7675ffd9dd27b30d3Cort Stratton// Add reference off of objInfo 6203a6c2a8f5135475de5be6de7675ffd9dd27b30d3Cort Stratton// TODO: We may need to refactor or pass in multiple valid usage statements to handle multiple valid usage conditions. 6217a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinskistatic bool ValidateSetMemBinding(layer_data *dev_data, VkDeviceMemory mem, uint64_t handle, VulkanObjectType type, 622c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton const char *apiName) { 6233251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 624f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis // It's an error to bind an object to NULL memory 625d3876b4ff7c293a14f73fe3622513d1fa91bf2d0Jeremy Hayes if (mem != VK_NULL_HANDLE) { 626f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis BINDABLE *mem_binding = GetObjectMemBinding(dev_data, handle, type); 627888cae09036ec622d6014e18efbda55e6226cf22Tobin Ehlis assert(mem_binding); 62810ffe2d353eaff714ed92a2835af77d8b5042d31Cort if (mem_binding->sparse) { 629315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis UNIQUE_VALIDATION_ERROR_CODE error_code = VALIDATION_ERROR_1740082a; 63010ffe2d353eaff714ed92a2835af77d8b5042d31Cort const char *handle_type = "IMAGE"; 63174300755ed9ec780d6073af71e47f201217008d6Cort Stratton if (strcmp(apiName, "vkBindBufferMemory()") == 0) { 632315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis error_code = VALIDATION_ERROR_1700080c; 63310ffe2d353eaff714ed92a2835af77d8b5042d31Cort handle_type = "BUFFER"; 63410ffe2d353eaff714ed92a2835af77d8b5042d31Cort } else { 63574300755ed9ec780d6073af71e47f201217008d6Cort Stratton assert(strcmp(apiName, "vkBindImageMemory()") == 0); 63610ffe2d353eaff714ed92a2835af77d8b5042d31Cort } 6373251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 6389b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(mem), __LINE__, error_code, "MEM", 6393251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "In %s, attempting to bind memory (0x%" PRIxLEAST64 ") to object (0x%" PRIxLEAST64 6403251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski ") which was created with sparse memory flags (VK_%s_CREATE_SPARSE_*_BIT). %s", 6419b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus apiName, HandleToUint64(mem), handle, handle_type, validation_error_map[error_code]); 64210ffe2d353eaff714ed92a2835af77d8b5042d31Cort } 6439a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis DEVICE_MEM_INFO *mem_info = GetMemObjInfo(dev_data, mem); 644888cae09036ec622d6014e18efbda55e6226cf22Tobin Ehlis if (mem_info) { 6459a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis DEVICE_MEM_INFO *prev_binding = GetMemObjInfo(dev_data, mem_binding->binding.mem); 646888cae09036ec622d6014e18efbda55e6226cf22Tobin Ehlis if (prev_binding) { 647315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis UNIQUE_VALIDATION_ERROR_CODE error_code = VALIDATION_ERROR_17400828; 64874300755ed9ec780d6073af71e47f201217008d6Cort Stratton if (strcmp(apiName, "vkBindBufferMemory()") == 0) { 649315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis error_code = VALIDATION_ERROR_1700080a; 65098c2a17e1a549df84f4239f619bc0955f632cb43Cort } else { 65174300755ed9ec780d6073af71e47f201217008d6Cort Stratton assert(strcmp(apiName, "vkBindImageMemory()") == 0); 65298c2a17e1a549df84f4239f619bc0955f632cb43Cort } 6533251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 6549b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(mem), __LINE__, error_code, "MEM", 6553251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "In %s, attempting to bind memory (0x%" PRIxLEAST64 ") to object (0x%" PRIxLEAST64 6563251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski ") which has already been bound to mem object 0x%" PRIxLEAST64 ". %s", 6579b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus apiName, HandleToUint64(mem), handle, HandleToUint64(prev_binding->mem), 6583251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski validation_error_map[error_code]); 659f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis } else if (mem_binding->binding.mem == MEMORY_UNBOUND) { 6603251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 6619b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(mem), __LINE__, MEMTRACK_REBIND_OBJECT, "MEM", 6623251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "In %s, attempting to bind memory (0x%" PRIxLEAST64 ") to object (0x%" PRIxLEAST64 6633251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski ") which was previous bound to memory that has since been freed. Memory bindings are immutable in " 6643251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Vulkan so this attempt to bind to new memory is not allowed.", 6659b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus apiName, HandleToUint64(mem), handle); 6665b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 6675b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 6685b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 6693251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 6705b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 6715b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 6725b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// For NULL mem case, clear any previous binding Else... 6735b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// Make sure given object is in its object map 6745b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// IF a previous binding existed, update binding 6755b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// Add reference from objectInfo to memoryInfo 6765b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// Add reference off of object's binding info 6770a1ce3dfd81c9f4efbe46f5ba5ddaea70bc4aa61Chris Forbes// Return VK_TRUE if addition is successful, VK_FALSE otherwise 678ece0e981ee4a5ad2572d146a89fc64d699d79f36Chris Forbesstatic bool SetSparseMemBinding(layer_data *dev_data, MEM_BINDING binding, uint64_t handle, VulkanObjectType type) { 6793251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = VK_FALSE; 6805b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Handle NULL case separately, just clear previous binding & decrement reference 681f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis if (binding.mem == VK_NULL_HANDLE) { 682f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis // TODO : This should cause the range of the resource to be unbound according to spec 6835b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } else { 684f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis BINDABLE *mem_binding = GetObjectMemBinding(dev_data, handle, type); 685f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis assert(mem_binding); 686f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis assert(mem_binding->sparse); 6879a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis DEVICE_MEM_INFO *mem_info = GetMemObjInfo(dev_data, binding.mem); 688f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis if (mem_info) { 689f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis mem_info->obj_bindings.insert({handle, type}); 6902e415b757c1e43fda35311aad026af8d5c96681cTobin Ehlis // Need to set mem binding for this object 691f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis mem_binding->sparse_bindings.insert(binding); 6925b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 6935b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 6943251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 695caf05e0db4959ae196ab34b024f352d9c0326870Tobin Ehlis} 696caf05e0db4959ae196ab34b024f352d9c0326870Tobin Ehlis 6975b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// Check object status for selected flag state 69851ea774638f432bd8e700ec8291a980f405f429eTobin Ehlisstatic bool validate_status(layer_data *dev_data, GLOBAL_CB_NODE *pNode, CBStatusFlags status_mask, VkFlags msg_flags, 6994f5a71335df5361d740a23b4548d54fc72a28d4fJeremy Hayes const char *fail_msg, UNIQUE_VALIDATION_ERROR_CODE const msg_code) { 7003d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis if (!(pNode->status & status_mask)) { 7014f5a71335df5361d740a23b4548d54fc72a28d4fJeremy Hayes char const *const message = validation_error_map[msg_code]; 70251ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis return log_msg(dev_data->report_data, msg_flags, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 7039b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pNode->commandBuffer), __LINE__, msg_code, "DS", "command buffer object 0x%p: %s. %s.", 7049b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus pNode->commandBuffer, fail_msg, message); 7055b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 706e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves return false; 7075b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 7085b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 7095b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// Retrieve pipeline node ptr for given pipeline object 71051ea774638f432bd8e700ec8291a980f405f429eTobin Ehlisstatic PIPELINE_STATE *getPipelineState(layer_data const *dev_data, VkPipeline pipeline) { 71151ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis auto it = dev_data->pipelineMap.find(pipeline); 71251ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis if (it == dev_data->pipelineMap.end()) { 713ea8349eeee76ae2859c10870fd8bd9e60309eb28Chris Forbes return nullptr; 7145b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 71563cddeb5593a0ead9ecd5f74d05f506b37d7ac66Chris Forbes return it->second.get(); 7165b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 7175b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 7189a9a0db2a973034d4286b6d4c62a46beb7641791Tobin EhlisRENDER_PASS_STATE *GetRenderPassState(layer_data const *dev_data, VkRenderPass renderpass) { 71951ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis auto it = dev_data->renderPassMap.find(renderpass); 72051ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis if (it == dev_data->renderPassMap.end()) { 72116387282d11e414ae7cb9ddf3d0c1bebf8f2c74dChris Forbes return nullptr; 72216387282d11e414ae7cb9ddf3d0c1bebf8f2c74dChris Forbes } 723fb13c2c4174108223d9f8e43084020eb09115ed6Chris Forbes return it->second.get(); 72416387282d11e414ae7cb9ddf3d0c1bebf8f2c74dChris Forbes} 72516387282d11e414ae7cb9ddf3d0c1bebf8f2c74dChris Forbes 726e6852f66a1f1eb57097dbf98b8218104849fda0fTobin Ehlisstd::shared_ptr<RENDER_PASS_STATE> GetRenderPassStateSharedPtr(layer_data const *dev_data, VkRenderPass renderpass) { 727ba9be0cec36d930fc0d5a0cbfbc00b0df49b08e4Tobin Ehlis auto it = dev_data->renderPassMap.find(renderpass); 728ba9be0cec36d930fc0d5a0cbfbc00b0df49b08e4Tobin Ehlis if (it == dev_data->renderPassMap.end()) { 729ba9be0cec36d930fc0d5a0cbfbc00b0df49b08e4Tobin Ehlis return nullptr; 730ba9be0cec36d930fc0d5a0cbfbc00b0df49b08e4Tobin Ehlis } 731ba9be0cec36d930fc0d5a0cbfbc00b0df49b08e4Tobin Ehlis return it->second; 732ba9be0cec36d930fc0d5a0cbfbc00b0df49b08e4Tobin Ehlis} 733ba9be0cec36d930fc0d5a0cbfbc00b0df49b08e4Tobin Ehlis 7349a9a0db2a973034d4286b6d4c62a46beb7641791Tobin EhlisFRAMEBUFFER_STATE *GetFramebufferState(const layer_data *dev_data, VkFramebuffer framebuffer) { 73551ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis auto it = dev_data->frameBufferMap.find(framebuffer); 73651ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis if (it == dev_data->frameBufferMap.end()) { 737f40ab6d10b8d755ce0e461c33916b0d4d5a5d437Chris Forbes return nullptr; 738f40ab6d10b8d755ce0e461c33916b0d4d5a5d437Chris Forbes } 73904861caca7eb93a5241b164e8480bb93c826902cTobin Ehlis return it->second.get(); 740f40ab6d10b8d755ce0e461c33916b0d4d5a5d437Chris Forbes} 741f40ab6d10b8d755ce0e461c33916b0d4d5a5d437Chris Forbes 7423f75ec6fa8700769a790d84e07c270579ded5468Tobin Ehlisstd::shared_ptr<cvdescriptorset::DescriptorSetLayout const> const GetDescriptorSetLayout(layer_data const *dev_data, 7433f75ec6fa8700769a790d84e07c270579ded5468Tobin Ehlis VkDescriptorSetLayout dsLayout) { 74451ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis auto it = dev_data->descriptorSetLayoutMap.find(dsLayout); 74551ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis if (it == dev_data->descriptorSetLayoutMap.end()) { 74611f1fde2721c198a619e4a22fff60eef9a16fae8Chris Forbes return nullptr; 74711f1fde2721c198a619e4a22fff60eef9a16fae8Chris Forbes } 748d34b2c191243c1646f1ccc2378262383e9ec1348Tobin Ehlis return it->second; 74911f1fde2721c198a619e4a22fff60eef9a16fae8Chris Forbes} 75011f1fde2721c198a619e4a22fff60eef9a16fae8Chris Forbes 75151ea774638f432bd8e700ec8291a980f405f429eTobin Ehlisstatic PIPELINE_LAYOUT_NODE const *getPipelineLayout(layer_data const *dev_data, VkPipelineLayout pipeLayout) { 75251ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis auto it = dev_data->pipelineLayoutMap.find(pipeLayout); 75351ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis if (it == dev_data->pipelineLayoutMap.end()) { 7544a45a42023b281f55953222c1a6c3e80f50e5f2aChris Forbes return nullptr; 7554a45a42023b281f55953222c1a6c3e80f50e5f2aChris Forbes } 7564a45a42023b281f55953222c1a6c3e80f50e5f2aChris Forbes return &it->second; 7574a45a42023b281f55953222c1a6c3e80f50e5f2aChris Forbes} 7584a45a42023b281f55953222c1a6c3e80f50e5f2aChris Forbes 759d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbesshader_module const *GetShaderModuleState(layer_data const *dev_data, VkShaderModule module) { 760d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes auto it = dev_data->shaderModuleMap.find(module); 761d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes if (it == dev_data->shaderModuleMap.end()) { 762d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes return nullptr; 763d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes } 764d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes return it->second.get(); 765d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes} 766d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes 767e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves// Return true if for a given PSO, the given state enum is dynamic, else return false 7684c0df90de562aa248b524a28b355765d8e3eff25Tobin Ehlisstatic bool isDynamic(const PIPELINE_STATE *pPipeline, const VkDynamicState state) { 7695b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pPipeline && pPipeline->graphicsPipelineCI.pDynamicState) { 7705b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t i = 0; i < pPipeline->graphicsPipelineCI.pDynamicState->dynamicStateCount; i++) { 771cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (state == pPipeline->graphicsPipelineCI.pDynamicState->pDynamicStates[i]) return true; 7725b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 7735b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 774e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves return false; 7755b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 7765b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 7775b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// Validate state stored as flags at time of draw call 7784f5a71335df5361d740a23b4548d54fc72a28d4fJeremy Hayesstatic bool validate_draw_state_flags(layer_data *dev_data, GLOBAL_CB_NODE *pCB, const PIPELINE_STATE *pPipe, bool indexed, 7794f5a71335df5361d740a23b4548d54fc72a28d4fJeremy Hayes UNIQUE_VALIDATION_ERROR_CODE const msg_code) { 7809c4006684a13db43f0dbc8d0015a9ef34872ca09Chris Forbes bool result = false; 781ca546210846c65808717f8875deae39bd227c240Tobin Ehlis if (pPipe->graphicsPipelineCI.pInputAssemblyState && 782ca546210846c65808717f8875deae39bd227c240Tobin Ehlis ((pPipe->graphicsPipelineCI.pInputAssemblyState->topology == VK_PRIMITIVE_TOPOLOGY_LINE_LIST) || 783ca546210846c65808717f8875deae39bd227c240Tobin Ehlis (pPipe->graphicsPipelineCI.pInputAssemblyState->topology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP))) { 7843d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis result |= validate_status(dev_data, pCB, CBSTATUS_LINE_WIDTH_SET, VK_DEBUG_REPORT_ERROR_BIT_EXT, 7854f5a71335df5361d740a23b4548d54fc72a28d4fJeremy Hayes "Dynamic line width state not set for this command buffer", msg_code); 7863d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis } 78745824955f3d4d2baee6d225f84ac9c2553981b3eDustin Graves if (pPipe->graphicsPipelineCI.pRasterizationState && 78845824955f3d4d2baee6d225f84ac9c2553981b3eDustin Graves (pPipe->graphicsPipelineCI.pRasterizationState->depthBiasEnable == VK_TRUE)) { 7893d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis result |= validate_status(dev_data, pCB, CBSTATUS_DEPTH_BIAS_SET, VK_DEBUG_REPORT_ERROR_BIT_EXT, 7904f5a71335df5361d740a23b4548d54fc72a28d4fJeremy Hayes "Dynamic depth bias state not set for this command buffer", msg_code); 7913d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis } 7923d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis if (pPipe->blendConstantsEnabled) { 7933d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis result |= validate_status(dev_data, pCB, CBSTATUS_BLEND_CONSTANTS_SET, VK_DEBUG_REPORT_ERROR_BIT_EXT, 7944f5a71335df5361d740a23b4548d54fc72a28d4fJeremy Hayes "Dynamic blend constants state not set for this command buffer", msg_code); 7953d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis } 79645824955f3d4d2baee6d225f84ac9c2553981b3eDustin Graves if (pPipe->graphicsPipelineCI.pDepthStencilState && 79745824955f3d4d2baee6d225f84ac9c2553981b3eDustin Graves (pPipe->graphicsPipelineCI.pDepthStencilState->depthBoundsTestEnable == VK_TRUE)) { 7983d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis result |= validate_status(dev_data, pCB, CBSTATUS_DEPTH_BOUNDS_SET, VK_DEBUG_REPORT_ERROR_BIT_EXT, 7994f5a71335df5361d740a23b4548d54fc72a28d4fJeremy Hayes "Dynamic depth bounds state not set for this command buffer", msg_code); 8003d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis } 80145824955f3d4d2baee6d225f84ac9c2553981b3eDustin Graves if (pPipe->graphicsPipelineCI.pDepthStencilState && 80245824955f3d4d2baee6d225f84ac9c2553981b3eDustin Graves (pPipe->graphicsPipelineCI.pDepthStencilState->stencilTestEnable == VK_TRUE)) { 8033d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis result |= validate_status(dev_data, pCB, CBSTATUS_STENCIL_READ_MASK_SET, VK_DEBUG_REPORT_ERROR_BIT_EXT, 8044f5a71335df5361d740a23b4548d54fc72a28d4fJeremy Hayes "Dynamic stencil read mask state not set for this command buffer", msg_code); 8053d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis result |= validate_status(dev_data, pCB, CBSTATUS_STENCIL_WRITE_MASK_SET, VK_DEBUG_REPORT_ERROR_BIT_EXT, 8064f5a71335df5361d740a23b4548d54fc72a28d4fJeremy Hayes "Dynamic stencil write mask state not set for this command buffer", msg_code); 8073d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis result |= validate_status(dev_data, pCB, CBSTATUS_STENCIL_REFERENCE_SET, VK_DEBUG_REPORT_ERROR_BIT_EXT, 8084f5a71335df5361d740a23b4548d54fc72a28d4fJeremy Hayes "Dynamic stencil reference state not set for this command buffer", msg_code); 8093d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis } 8101c130ea631a82716dc7334de17767536525f2292Tobin Ehlis if (indexed) { 8113d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis result |= validate_status(dev_data, pCB, CBSTATUS_INDEX_BUFFER_BOUND, VK_DEBUG_REPORT_ERROR_BIT_EXT, 8124f5a71335df5361d740a23b4548d54fc72a28d4fJeremy Hayes "Index buffer object not bound to this command buffer when Indexed Draw attempted", msg_code); 8133d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis } 8144f5a71335df5361d740a23b4548d54fc72a28d4fJeremy Hayes 8155b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 8165b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 8175b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 818b4ab35582a070b18e22c0bd6cb8811c455f5b7ffTobin Ehlisstatic bool logInvalidAttachmentMessage(layer_data const *dev_data, const char *type1_string, const RENDER_PASS_STATE *rp1_state, 8199d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis const char *type2_string, const RENDER_PASS_STATE *rp2_state, uint32_t primary_attach, 8209d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis uint32_t secondary_attach, const char *msg, const char *caller, 8219d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis UNIQUE_VALIDATION_ERROR_CODE error_code) { 8229d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis return log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, 8239d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis HandleToUint64(rp1_state->renderPass), __LINE__, error_code, "DS", 8249d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis "%s: RenderPasses incompatible between %s w/ renderPass 0x%" PRIx64 " and %s w/ renderPass 0x%" PRIx64 8259d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis " Attachment %u is not compatible with %u: %s. %s", 8269d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis caller, type1_string, HandleToUint64(rp1_state->renderPass), type2_string, HandleToUint64(rp2_state->renderPass), 8279d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis primary_attach, secondary_attach, msg, validation_error_map[error_code]); 8289d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis} 8299d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis 830b4ab35582a070b18e22c0bd6cb8811c455f5b7ffTobin Ehlisstatic bool validateAttachmentCompatibility(layer_data const *dev_data, const char *type1_string, 831b4ab35582a070b18e22c0bd6cb8811c455f5b7ffTobin Ehlis const RENDER_PASS_STATE *rp1_state, const char *type2_string, 832b4ab35582a070b18e22c0bd6cb8811c455f5b7ffTobin Ehlis const RENDER_PASS_STATE *rp2_state, uint32_t primary_attach, uint32_t secondary_attach, 83311926a9087773a853b9b2cefbe80c17347cf36caTobin Ehlis const char *caller, UNIQUE_VALIDATION_ERROR_CODE error_code) { 8349d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis bool skip = false; 8359d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis const auto &primaryPassCI = rp1_state->createInfo; 8369d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis const auto &secondaryPassCI = rp2_state->createInfo; 8379d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis if (primaryPassCI.attachmentCount <= primary_attach) { 8389d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis primary_attach = VK_ATTACHMENT_UNUSED; 8399d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis } 8409d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis if (secondaryPassCI.attachmentCount <= secondary_attach) { 8419d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis secondary_attach = VK_ATTACHMENT_UNUSED; 8429d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis } 8439d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis if (primary_attach == VK_ATTACHMENT_UNUSED && secondary_attach == VK_ATTACHMENT_UNUSED) { 8449d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis return skip; 8459d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis } 8469d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis if (primary_attach == VK_ATTACHMENT_UNUSED) { 8479d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis skip |= logInvalidAttachmentMessage(dev_data, type1_string, rp1_state, type2_string, rp2_state, primary_attach, 8489d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis secondary_attach, "The first is unused while the second is not.", caller, error_code); 8499d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis return skip; 8509d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis } 8519d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis if (secondary_attach == VK_ATTACHMENT_UNUSED) { 8529d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis skip |= logInvalidAttachmentMessage(dev_data, type1_string, rp1_state, type2_string, rp2_state, primary_attach, 8539d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis secondary_attach, "The second is unused while the first is not.", caller, error_code); 8549d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis return skip; 8559d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis } 8569d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis if (primaryPassCI.pAttachments[primary_attach].format != secondaryPassCI.pAttachments[secondary_attach].format) { 8579d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis skip |= logInvalidAttachmentMessage(dev_data, type1_string, rp1_state, type2_string, rp2_state, primary_attach, 8589d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis secondary_attach, "They have different formats.", caller, error_code); 8599d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis } 8609d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis if (primaryPassCI.pAttachments[primary_attach].samples != secondaryPassCI.pAttachments[secondary_attach].samples) { 8619d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis skip |= logInvalidAttachmentMessage(dev_data, type1_string, rp1_state, type2_string, rp2_state, primary_attach, 8629d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis secondary_attach, "They have different samples.", caller, error_code); 8639d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis } 86411926a9087773a853b9b2cefbe80c17347cf36caTobin Ehlis if (primaryPassCI.pAttachments[primary_attach].flags != secondaryPassCI.pAttachments[secondary_attach].flags) { 8659d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis skip |= 8669d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis logInvalidAttachmentMessage(dev_data, type1_string, rp1_state, type2_string, rp2_state, primary_attach, secondary_attach, 8679d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis "They have different flags.", caller, error_code); 8689d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis } 8699d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis 8709d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis return skip; 8719d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis} 8729d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis 873b4ab35582a070b18e22c0bd6cb8811c455f5b7ffTobin Ehlisstatic bool validateSubpassCompatibility(layer_data const *dev_data, const char *type1_string, const RENDER_PASS_STATE *rp1_state, 8749d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis const char *type2_string, const RENDER_PASS_STATE *rp2_state, const int subpass, 87511926a9087773a853b9b2cefbe80c17347cf36caTobin Ehlis const char *caller, UNIQUE_VALIDATION_ERROR_CODE error_code) { 8769d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis bool skip = false; 8779d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis const auto &primary_desc = rp1_state->createInfo.pSubpasses[subpass]; 8789d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis const auto &secondary_desc = rp2_state->createInfo.pSubpasses[subpass]; 8799d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis uint32_t maxInputAttachmentCount = std::max(primary_desc.inputAttachmentCount, secondary_desc.inputAttachmentCount); 8809d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis for (uint32_t i = 0; i < maxInputAttachmentCount; ++i) { 8819d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis uint32_t primary_input_attach = VK_ATTACHMENT_UNUSED, secondary_input_attach = VK_ATTACHMENT_UNUSED; 8829d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis if (i < primary_desc.inputAttachmentCount) { 8839d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis primary_input_attach = primary_desc.pInputAttachments[i].attachment; 8849d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis } 8859d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis if (i < secondary_desc.inputAttachmentCount) { 8869d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis secondary_input_attach = secondary_desc.pInputAttachments[i].attachment; 8879d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis } 8889d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis skip |= validateAttachmentCompatibility(dev_data, type1_string, rp1_state, type2_string, rp2_state, primary_input_attach, 88911926a9087773a853b9b2cefbe80c17347cf36caTobin Ehlis secondary_input_attach, caller, error_code); 8909d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis } 8919d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis uint32_t maxColorAttachmentCount = std::max(primary_desc.colorAttachmentCount, secondary_desc.colorAttachmentCount); 8929d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis for (uint32_t i = 0; i < maxColorAttachmentCount; ++i) { 8939d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis uint32_t primary_color_attach = VK_ATTACHMENT_UNUSED, secondary_color_attach = VK_ATTACHMENT_UNUSED; 8949d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis if (i < primary_desc.colorAttachmentCount) { 8959d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis primary_color_attach = primary_desc.pColorAttachments[i].attachment; 8969d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis } 8979d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis if (i < secondary_desc.colorAttachmentCount) { 8989d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis secondary_color_attach = secondary_desc.pColorAttachments[i].attachment; 8999d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis } 9009d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis skip |= validateAttachmentCompatibility(dev_data, type1_string, rp1_state, type2_string, rp2_state, primary_color_attach, 90111926a9087773a853b9b2cefbe80c17347cf36caTobin Ehlis secondary_color_attach, caller, error_code); 9029d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis uint32_t primary_resolve_attach = VK_ATTACHMENT_UNUSED, secondary_resolve_attach = VK_ATTACHMENT_UNUSED; 9039d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis if (i < primary_desc.colorAttachmentCount && primary_desc.pResolveAttachments) { 9049d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis primary_resolve_attach = primary_desc.pResolveAttachments[i].attachment; 9059d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis } 9069d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis if (i < secondary_desc.colorAttachmentCount && secondary_desc.pResolveAttachments) { 9079d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis secondary_resolve_attach = secondary_desc.pResolveAttachments[i].attachment; 9089d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis } 9099d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis skip |= validateAttachmentCompatibility(dev_data, type1_string, rp1_state, type2_string, rp2_state, primary_resolve_attach, 91011926a9087773a853b9b2cefbe80c17347cf36caTobin Ehlis secondary_resolve_attach, caller, error_code); 9119d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis } 9129d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis uint32_t primary_depthstencil_attach = VK_ATTACHMENT_UNUSED, secondary_depthstencil_attach = VK_ATTACHMENT_UNUSED; 9139d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis if (primary_desc.pDepthStencilAttachment) { 9149d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis primary_depthstencil_attach = primary_desc.pDepthStencilAttachment[0].attachment; 9159d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis } 9169d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis if (secondary_desc.pDepthStencilAttachment) { 9179d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis secondary_depthstencil_attach = secondary_desc.pDepthStencilAttachment[0].attachment; 9189d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis } 9199d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis skip |= validateAttachmentCompatibility(dev_data, type1_string, rp1_state, type2_string, rp2_state, primary_depthstencil_attach, 92011926a9087773a853b9b2cefbe80c17347cf36caTobin Ehlis secondary_depthstencil_attach, caller, error_code); 9219d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis return skip; 9229d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis} 9239d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis 9249d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis// Verify that given renderPass CreateInfo for primary and secondary command buffers are compatible. 9259d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis// This function deals directly with the CreateInfo, there are overloaded versions below that can take the renderPass handle and 9269d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis// will then feed into this function 927b4ab35582a070b18e22c0bd6cb8811c455f5b7ffTobin Ehlisstatic bool validateRenderPassCompatibility(layer_data const *dev_data, const char *type1_string, 928b4ab35582a070b18e22c0bd6cb8811c455f5b7ffTobin Ehlis const RENDER_PASS_STATE *rp1_state, const char *type2_string, 929b4ab35582a070b18e22c0bd6cb8811c455f5b7ffTobin Ehlis const RENDER_PASS_STATE *rp2_state, const char *caller, 9309d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis UNIQUE_VALIDATION_ERROR_CODE error_code) { 9319d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis bool skip = false; 9329d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis 9339d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis if (rp1_state->createInfo.subpassCount != rp2_state->createInfo.subpassCount) { 9349d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis skip |= 9359d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, 9369d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis HandleToUint64(rp1_state->renderPass), __LINE__, error_code, "DS", 9379d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis "%s: RenderPasses incompatible between %s w/ renderPass 0x%" PRIx64 9389d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis " with a subpassCount of %u and %s w/ renderPass 0x%" PRIx64 " with a subpassCount of %u. %s", 9399d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis caller, type1_string, HandleToUint64(rp1_state->renderPass), rp1_state->createInfo.subpassCount, type2_string, 9409d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis HandleToUint64(rp2_state->renderPass), rp2_state->createInfo.subpassCount, validation_error_map[error_code]); 9419d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis } else { 9429d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis for (uint32_t i = 0; i < rp1_state->createInfo.subpassCount; ++i) { 94311926a9087773a853b9b2cefbe80c17347cf36caTobin Ehlis skip |= validateSubpassCompatibility(dev_data, type1_string, rp1_state, type2_string, rp2_state, i, caller, error_code); 9449d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis } 9459d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis } 9469d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis return skip; 9479d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis} 9489d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis 9495b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// Return Set node ptr for specified set or else NULL 9509a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehliscvdescriptorset::DescriptorSet *GetSetNode(const layer_data *dev_data, VkDescriptorSet set) { 95151ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis auto set_it = dev_data->setMap.find(set); 95251ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis if (set_it == dev_data->setMap.end()) { 9535b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return NULL; 9545b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 955104ab082916e41467ef60baaab7a5a8b2e02c59cTobin Ehlis return set_it->second; 9565b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 9575b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 958eca2d52a6bfa3f9d63a86ca9fd30abc0adf775b7Mark Young// For given pipeline, return number of MSAA samples, or one if MSAA disabled 9594c0df90de562aa248b524a28b355765d8e3eff25Tobin Ehlisstatic VkSampleCountFlagBits getNumSamples(PIPELINE_STATE const *pipe) { 960ea8349eeee76ae2859c10870fd8bd9e60309eb28Chris Forbes if (pipe->graphicsPipelineCI.pMultisampleState != NULL && 961ea8349eeee76ae2859c10870fd8bd9e60309eb28Chris Forbes VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO == pipe->graphicsPipelineCI.pMultisampleState->sType) { 962eca2d52a6bfa3f9d63a86ca9fd30abc0adf775b7Mark Young return pipe->graphicsPipelineCI.pMultisampleState->rasterizationSamples; 963eca2d52a6bfa3f9d63a86ca9fd30abc0adf775b7Mark Young } 964eca2d52a6bfa3f9d63a86ca9fd30abc0adf775b7Mark Young return VK_SAMPLE_COUNT_1_BIT; 965eca2d52a6bfa3f9d63a86ca9fd30abc0adf775b7Mark Young} 966eca2d52a6bfa3f9d63a86ca9fd30abc0adf775b7Mark Young 967bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinskistatic void list_bits(std::ostream &s, uint32_t bits) { 968b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes for (int i = 0; i < 32 && bits; i++) { 969b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes if (bits & (1 << i)) { 970b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes s << i; 971b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes bits &= ~(1 << i); 972b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes if (bits) { 973b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes s << ","; 974b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes } 975b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes } 976b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes } 977b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes} 978b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes 979eca2d52a6bfa3f9d63a86ca9fd30abc0adf775b7Mark Young// Validate draw-time state related to the PSO 98051ea774638f432bd8e700ec8291a980f405f429eTobin Ehlisstatic bool ValidatePipelineDrawtimeState(layer_data const *dev_data, LAST_BOUND_STATE const &state, const GLOBAL_CB_NODE *pCB, 981b4ab35582a070b18e22c0bd6cb8811c455f5b7ffTobin Ehlis CMD_TYPE cmd_type, PIPELINE_STATE const *pPipeline, const char *caller) { 9823251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 98329d196e071b2dc1db47702085469396f2b956820Chris Forbes 984d79335137b414d5f89284a9ab3e014beb4ada3ebMike Weiblen // Verify vertex binding 98529d196e071b2dc1db47702085469396f2b956820Chris Forbes if (pPipeline->vertexBindingDescriptions.size() > 0) { 98629d196e071b2dc1db47702085469396f2b956820Chris Forbes for (size_t i = 0; i < pPipeline->vertexBindingDescriptions.size(); i++) { 987312129ec52e6249aa453e27e6be17a8dab1e98b8Tobin Ehlis auto vertex_binding = pPipeline->vertexBindingDescriptions[i].binding; 988312129ec52e6249aa453e27e6be17a8dab1e98b8Tobin Ehlis if ((pCB->currentDrawData.buffers.size() < (vertex_binding + 1)) || 989312129ec52e6249aa453e27e6be17a8dab1e98b8Tobin Ehlis (pCB->currentDrawData.buffers[vertex_binding] == VK_NULL_HANDLE)) { 9903251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= 991df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 9929b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pCB->commandBuffer), __LINE__, DRAWSTATE_VTX_INDEX_OUT_OF_BOUNDS, "DS", 993cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "The Pipeline State Object (0x%" PRIxLEAST64 994cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski ") expects that this Command Buffer's vertex binding Index %u " 995cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "should be set via vkCmdBindVertexBuffers. This is because VkVertexInputBindingDescription struct " 996cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "at index " PRINTF_SIZE_T_SPECIFIER " of pVertexBindingDescriptions has a binding value of %u.", 9979b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(state.pipeline_state->pipeline), vertex_binding, i, vertex_binding); 99829d196e071b2dc1db47702085469396f2b956820Chris Forbes } 99929d196e071b2dc1db47702085469396f2b956820Chris Forbes } 100029d196e071b2dc1db47702085469396f2b956820Chris Forbes } else { 100158b923895f7f6be1b7d48bd4ee3e85e0b3dd0c4dTobin Ehlis if (!pCB->currentDrawData.buffers.empty() && !pCB->vertex_buffer_used) { 10023251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, 10039b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, HandleToUint64(pCB->commandBuffer), __LINE__, 10049b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus DRAWSTATE_VTX_INDEX_OUT_OF_BOUNDS, "DS", 10053251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Vertex buffers are bound to command buffer (0x%p" 10063251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski ") but no vertex buffers are attached to this Pipeline State Object (0x%" PRIxLEAST64 ").", 10079b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus pCB->commandBuffer, HandleToUint64(state.pipeline_state->pipeline)); 100829d196e071b2dc1db47702085469396f2b956820Chris Forbes } 100929d196e071b2dc1db47702085469396f2b956820Chris Forbes } 101029d196e071b2dc1db47702085469396f2b956820Chris Forbes // If Viewport or scissors are dynamic, verify that dynamic count matches PSO count. 101129d196e071b2dc1db47702085469396f2b956820Chris Forbes // Skip check if rasterization is disabled or there is no viewport. 101229d196e071b2dc1db47702085469396f2b956820Chris Forbes if ((!pPipeline->graphicsPipelineCI.pRasterizationState || 101329d196e071b2dc1db47702085469396f2b956820Chris Forbes (pPipeline->graphicsPipelineCI.pRasterizationState->rasterizerDiscardEnable == VK_FALSE)) && 101429d196e071b2dc1db47702085469396f2b956820Chris Forbes pPipeline->graphicsPipelineCI.pViewportState) { 101529d196e071b2dc1db47702085469396f2b956820Chris Forbes bool dynViewport = isDynamic(pPipeline, VK_DYNAMIC_STATE_VIEWPORT); 101629d196e071b2dc1db47702085469396f2b956820Chris Forbes bool dynScissor = isDynamic(pPipeline, VK_DYNAMIC_STATE_SCISSOR); 1017b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes 101829d196e071b2dc1db47702085469396f2b956820Chris Forbes if (dynViewport) { 1019b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes auto requiredViewportsMask = (1 << pPipeline->graphicsPipelineCI.pViewportState->viewportCount) - 1; 1020b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes auto missingViewportMask = ~pCB->viewportMask & requiredViewportsMask; 1021b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes if (missingViewportMask) { 1022b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes std::stringstream ss; 1023b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes ss << "Dynamic viewport(s) "; 1024b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes list_bits(ss, missingViewportMask); 1025d79335137b414d5f89284a9ab3e014beb4ada3ebMike Weiblen ss << " are used by pipeline state object, but were not provided via calls to vkCmdSetViewport()."; 10263251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 10273251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski __LINE__, DRAWSTATE_VIEWPORT_SCISSOR_MISMATCH, "DS", "%s", ss.str().c_str()); 102829d196e071b2dc1db47702085469396f2b956820Chris Forbes } 102929d196e071b2dc1db47702085469396f2b956820Chris Forbes } 1030b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes 103129d196e071b2dc1db47702085469396f2b956820Chris Forbes if (dynScissor) { 1032b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes auto requiredScissorMask = (1 << pPipeline->graphicsPipelineCI.pViewportState->scissorCount) - 1; 1033b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes auto missingScissorMask = ~pCB->scissorMask & requiredScissorMask; 1034b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes if (missingScissorMask) { 1035b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes std::stringstream ss; 1036b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes ss << "Dynamic scissor(s) "; 1037b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes list_bits(ss, missingScissorMask); 1038d79335137b414d5f89284a9ab3e014beb4ada3ebMike Weiblen ss << " are used by pipeline state object, but were not provided via calls to vkCmdSetScissor()."; 10393251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 10403251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski __LINE__, DRAWSTATE_VIEWPORT_SCISSOR_MISMATCH, "DS", "%s", ss.str().c_str()); 104129d196e071b2dc1db47702085469396f2b956820Chris Forbes } 104229d196e071b2dc1db47702085469396f2b956820Chris Forbes } 104329d196e071b2dc1db47702085469396f2b956820Chris Forbes } 104429d196e071b2dc1db47702085469396f2b956820Chris Forbes 104529d196e071b2dc1db47702085469396f2b956820Chris Forbes // Verify that any MSAA request in PSO matches sample# in bound FB 104629d196e071b2dc1db47702085469396f2b956820Chris Forbes // Skip the check if rasterization is disabled. 104729d196e071b2dc1db47702085469396f2b956820Chris Forbes if (!pPipeline->graphicsPipelineCI.pRasterizationState || 104829d196e071b2dc1db47702085469396f2b956820Chris Forbes (pPipeline->graphicsPipelineCI.pRasterizationState->rasterizerDiscardEnable == VK_FALSE)) { 104929d196e071b2dc1db47702085469396f2b956820Chris Forbes VkSampleCountFlagBits pso_num_samples = getNumSamples(pPipeline); 105029d196e071b2dc1db47702085469396f2b956820Chris Forbes if (pCB->activeRenderPass) { 1051fb13c2c4174108223d9f8e43084020eb09115ed6Chris Forbes auto const render_pass_info = pCB->activeRenderPass->createInfo.ptr(); 105229d196e071b2dc1db47702085469396f2b956820Chris Forbes const VkSubpassDescription *subpass_desc = &render_pass_info->pSubpasses[pCB->activeSubpass]; 105329d196e071b2dc1db47702085469396f2b956820Chris Forbes uint32_t i; 105476957dd352738b7ceec82c38be8b1b1347a90040Chris Forbes unsigned subpass_num_samples = 0; 10550a7ed0466d3d3c6c71be07d66c200482d9a9d073Chris Forbes 105629d196e071b2dc1db47702085469396f2b956820Chris Forbes for (i = 0; i < subpass_desc->colorAttachmentCount; i++) { 105776957dd352738b7ceec82c38be8b1b1347a90040Chris Forbes auto attachment = subpass_desc->pColorAttachments[i].attachment; 105876957dd352738b7ceec82c38be8b1b1347a90040Chris Forbes if (attachment != VK_ATTACHMENT_UNUSED) 105976957dd352738b7ceec82c38be8b1b1347a90040Chris Forbes subpass_num_samples |= (unsigned)render_pass_info->pAttachments[attachment].samples; 106029d196e071b2dc1db47702085469396f2b956820Chris Forbes } 10610a7ed0466d3d3c6c71be07d66c200482d9a9d073Chris Forbes 106276957dd352738b7ceec82c38be8b1b1347a90040Chris Forbes if (subpass_desc->pDepthStencilAttachment && 106376957dd352738b7ceec82c38be8b1b1347a90040Chris Forbes subpass_desc->pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) { 106476957dd352738b7ceec82c38be8b1b1347a90040Chris Forbes auto attachment = subpass_desc->pDepthStencilAttachment->attachment; 106576957dd352738b7ceec82c38be8b1b1347a90040Chris Forbes subpass_num_samples |= (unsigned)render_pass_info->pAttachments[attachment].samples; 106629d196e071b2dc1db47702085469396f2b956820Chris Forbes } 1067eca2d52a6bfa3f9d63a86ca9fd30abc0adf775b7Mark Young 1068497e33d6b0547f5dccca245a5b6777831fbb0de0Maciej Jesionowski if (!dev_data->extensions.vk_amd_mixed_attachment_samples && 1069497e33d6b0547f5dccca245a5b6777831fbb0de0Maciej Jesionowski ((subpass_num_samples & static_cast<unsigned>(pso_num_samples)) != subpass_num_samples)) { 10703251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 10719b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pPipeline->pipeline), __LINE__, DRAWSTATE_NUM_SAMPLES_MISMATCH, "DS", 10729b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "Num samples mismatch! At draw-time in Pipeline (0x%" PRIxLEAST64 10739b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus ") with %u samples while current RenderPass (0x%" PRIxLEAST64 ") w/ %u samples!", 10749b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pPipeline->pipeline), pso_num_samples, 10759b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pCB->activeRenderPass->renderPass), subpass_num_samples); 1076eca2d52a6bfa3f9d63a86ca9fd30abc0adf775b7Mark Young } 107729d196e071b2dc1db47702085469396f2b956820Chris Forbes } else { 10783251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 10799b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pPipeline->pipeline), __LINE__, DRAWSTATE_NUM_SAMPLES_MISMATCH, "DS", 10803251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "No active render pass found at draw-time in Pipeline (0x%" PRIxLEAST64 ")!", 10819b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pPipeline->pipeline)); 1082eca2d52a6bfa3f9d63a86ca9fd30abc0adf775b7Mark Young } 1083eca2d52a6bfa3f9d63a86ca9fd30abc0adf775b7Mark Young } 1084528f623d935b0ab102a2f9c1c82787a8810ca360Tobin Ehlis // Verify that PSO creation renderPass is compatible with active renderPass 1085528f623d935b0ab102a2f9c1c82787a8810ca360Tobin Ehlis if (pCB->activeRenderPass) { 1086b4ab35582a070b18e22c0bd6cb8811c455f5b7ffTobin Ehlis // TODO: Move all of the error codes common across different Draws into a LUT accessed by cmd_type 1087b4ab35582a070b18e22c0bd6cb8811c455f5b7ffTobin Ehlis // TODO: AMD extension codes are included here, but actual function entrypoints are not yet intercepted 1088b4ab35582a070b18e22c0bd6cb8811c455f5b7ffTobin Ehlis // Error codes for renderpass and subpass mismatches 1089b4ab35582a070b18e22c0bd6cb8811c455f5b7ffTobin Ehlis auto rp_error = VALIDATION_ERROR_1a200366, sp_error = VALIDATION_ERROR_1a200368; 1090b4ab35582a070b18e22c0bd6cb8811c455f5b7ffTobin Ehlis switch (cmd_type) { 1091b4ab35582a070b18e22c0bd6cb8811c455f5b7ffTobin Ehlis case CMD_DRAWINDEXED: 1092b4ab35582a070b18e22c0bd6cb8811c455f5b7ffTobin Ehlis rp_error = VALIDATION_ERROR_1a40038c; 1093b4ab35582a070b18e22c0bd6cb8811c455f5b7ffTobin Ehlis sp_error = VALIDATION_ERROR_1a40038e; 1094b4ab35582a070b18e22c0bd6cb8811c455f5b7ffTobin Ehlis break; 1095b4ab35582a070b18e22c0bd6cb8811c455f5b7ffTobin Ehlis case CMD_DRAWINDIRECT: 1096b4ab35582a070b18e22c0bd6cb8811c455f5b7ffTobin Ehlis rp_error = VALIDATION_ERROR_1aa003be; 1097b4ab35582a070b18e22c0bd6cb8811c455f5b7ffTobin Ehlis sp_error = VALIDATION_ERROR_1aa003c0; 1098b4ab35582a070b18e22c0bd6cb8811c455f5b7ffTobin Ehlis break; 1099b4ab35582a070b18e22c0bd6cb8811c455f5b7ffTobin Ehlis case CMD_DRAWINDIRECTCOUNTAMD: 1100b4ab35582a070b18e22c0bd6cb8811c455f5b7ffTobin Ehlis rp_error = VALIDATION_ERROR_1ac003f6; 1101b4ab35582a070b18e22c0bd6cb8811c455f5b7ffTobin Ehlis sp_error = VALIDATION_ERROR_1ac003f8; 1102b4ab35582a070b18e22c0bd6cb8811c455f5b7ffTobin Ehlis break; 1103b4ab35582a070b18e22c0bd6cb8811c455f5b7ffTobin Ehlis case CMD_DRAWINDEXEDINDIRECT: 1104b4ab35582a070b18e22c0bd6cb8811c455f5b7ffTobin Ehlis rp_error = VALIDATION_ERROR_1a600426; 1105b4ab35582a070b18e22c0bd6cb8811c455f5b7ffTobin Ehlis sp_error = VALIDATION_ERROR_1a600428; 1106b4ab35582a070b18e22c0bd6cb8811c455f5b7ffTobin Ehlis break; 1107b4ab35582a070b18e22c0bd6cb8811c455f5b7ffTobin Ehlis case CMD_DRAWINDEXEDINDIRECTCOUNTAMD: 1108b4ab35582a070b18e22c0bd6cb8811c455f5b7ffTobin Ehlis rp_error = VALIDATION_ERROR_1a800460; 1109b4ab35582a070b18e22c0bd6cb8811c455f5b7ffTobin Ehlis sp_error = VALIDATION_ERROR_1a800462; 1110b4ab35582a070b18e22c0bd6cb8811c455f5b7ffTobin Ehlis break; 1111b4ab35582a070b18e22c0bd6cb8811c455f5b7ffTobin Ehlis default: 1112b4ab35582a070b18e22c0bd6cb8811c455f5b7ffTobin Ehlis assert(CMD_DRAW == cmd_type); 1113b4ab35582a070b18e22c0bd6cb8811c455f5b7ffTobin Ehlis break; 1114b4ab35582a070b18e22c0bd6cb8811c455f5b7ffTobin Ehlis } 1115528f623d935b0ab102a2f9c1c82787a8810ca360Tobin Ehlis std::string err_string; 1116cafebcdd40427a0713a3564dc8f39e47edbdb02fTobin Ehlis if (pCB->activeRenderPass->renderPass != pPipeline->rp_state->renderPass) { 1117528f623d935b0ab102a2f9c1c82787a8810ca360Tobin Ehlis // renderPass that PSO was created with must be compatible with active renderPass that PSO is being used with 1118b4ab35582a070b18e22c0bd6cb8811c455f5b7ffTobin Ehlis skip |= validateRenderPassCompatibility(dev_data, "active render pass", pCB->activeRenderPass, "pipeline state object", 1119cafebcdd40427a0713a3564dc8f39e47edbdb02fTobin Ehlis pPipeline->rp_state.get(), caller, rp_error); 1120528f623d935b0ab102a2f9c1c82787a8810ca360Tobin Ehlis } 1121c307df2953e6b023531a6ef7fd11e3ee2f2c58b0Chris Forbes if (pPipeline->graphicsPipelineCI.subpass != pCB->activeSubpass) { 11223251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 1123b4ab35582a070b18e22c0bd6cb8811c455f5b7ffTobin Ehlis HandleToUint64(pPipeline->pipeline), __LINE__, sp_error, "DS", 1124b4ab35582a070b18e22c0bd6cb8811c455f5b7ffTobin Ehlis "Pipeline was built for subpass %u but used in subpass %u. %s", pPipeline->graphicsPipelineCI.subpass, 1125b4ab35582a070b18e22c0bd6cb8811c455f5b7ffTobin Ehlis pCB->activeSubpass, validation_error_map[sp_error]); 1126c307df2953e6b023531a6ef7fd11e3ee2f2c58b0Chris Forbes } 1127528f623d935b0ab102a2f9c1c82787a8810ca360Tobin Ehlis } 112829d196e071b2dc1db47702085469396f2b956820Chris Forbes 11293251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 1130eca2d52a6bfa3f9d63a86ca9fd30abc0adf775b7Mark Young} 1131eca2d52a6bfa3f9d63a86ca9fd30abc0adf775b7Mark Young 1132d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes// For given cvdescriptorset::DescriptorSet, verify that its Set is compatible w/ the setLayout corresponding to 1133d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes// pipelineLayout[layoutIndex] 1134d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbesstatic bool verify_set_layout_compatibility(const cvdescriptorset::DescriptorSet *descriptor_set, 1135d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes PIPELINE_LAYOUT_NODE const *pipeline_layout, const uint32_t layoutIndex, 1136d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes string &errorMsg) { 1137d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes auto num_sets = pipeline_layout->set_layouts.size(); 1138d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes if (layoutIndex >= num_sets) { 1139d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes stringstream errorStr; 1140d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes errorStr << "VkPipelineLayout (" << pipeline_layout->layout << ") only contains " << num_sets 1141d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes << " setLayouts corresponding to sets 0-" << num_sets - 1 << ", but you're attempting to bind set to index " 1142d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes << layoutIndex; 1143d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes errorMsg = errorStr.str(); 1144d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes return false; 1145d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes } 11462d4a3c28bf95f00fa2aac7d07288f6faf22208abMark Lobodzinski if (descriptor_set->IsPushDescriptor()) return true; 1147d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes auto layout_node = pipeline_layout->set_layouts[layoutIndex]; 114888224335ef7965e89477c393331ef5fa628a9335Tobin Ehlis return descriptor_set->IsCompatible(layout_node.get(), &errorMsg); 1149d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes} 1150d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes 11515b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// Validate overall state at the time of a draw call 1152b4ab35582a070b18e22c0bd6cb8811c455f5b7ffTobin Ehlisstatic bool ValidateDrawState(layer_data *dev_data, GLOBAL_CB_NODE *cb_node, CMD_TYPE cmd_type, const bool indexed, 11534f5a71335df5361d740a23b4548d54fc72a28d4fJeremy Hayes const VkPipelineBindPoint bind_point, const char *function, 11544f5a71335df5361d740a23b4548d54fc72a28d4fJeremy Hayes UNIQUE_VALIDATION_ERROR_CODE const msg_code) { 1155e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves bool result = false; 11561c130ea631a82716dc7334de17767536525f2292Tobin Ehlis auto const &state = cb_node->lastBound[bind_point]; 11574c0df90de562aa248b524a28b355765d8e3eff25Tobin Ehlis PIPELINE_STATE *pPipe = state.pipeline_state; 115822fb3c0393ef588b11f8313f01c508028d77dec0Tobin Ehlis if (nullptr == pPipe) { 115922fb3c0393ef588b11f8313f01c508028d77dec0Tobin Ehlis result |= log_msg( 1160df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 11619b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(cb_node->commandBuffer), __LINE__, DRAWSTATE_INVALID_PIPELINE, "DS", 116222fb3c0393ef588b11f8313f01c508028d77dec0Tobin Ehlis "At Draw/Dispatch time no valid VkPipeline is bound! This is illegal. Please bind one with vkCmdBindPipeline()."); 116322fb3c0393ef588b11f8313f01c508028d77dec0Tobin Ehlis // Early return as any further checks below will be busted w/o a pipeline 1164cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (result) return true; 116522fb3c0393ef588b11f8313f01c508028d77dec0Tobin Ehlis } 11663d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis // First check flag states 11671c130ea631a82716dc7334de17767536525f2292Tobin Ehlis if (VK_PIPELINE_BIND_POINT_GRAPHICS == bind_point) 116851ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis result = validate_draw_state_flags(dev_data, cb_node, pPipe, indexed, msg_code); 11697a3985a8a9d255dcca9f5992ca2262c7e5df41c6Tobin Ehlis 11705b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Now complete other state checks 117169b71d9c89447ec87d823669ee9edbfc58af174aTobin Ehlis if (VK_NULL_HANDLE != state.pipeline_layout.layout) { 117222fb3c0393ef588b11f8313f01c508028d77dec0Tobin Ehlis string errorString; 117369b71d9c89447ec87d823669ee9edbfc58af174aTobin Ehlis auto pipeline_layout = pPipe->pipeline_layout; 1174169c4506062f06d6676eb4da3c9e0437d1d9d659Chris Forbes 11751c130ea631a82716dc7334de17767536525f2292Tobin Ehlis for (const auto &set_binding_pair : pPipe->active_slots) { 11761c130ea631a82716dc7334de17767536525f2292Tobin Ehlis uint32_t setIndex = set_binding_pair.first; 117722fb3c0393ef588b11f8313f01c508028d77dec0Tobin Ehlis // If valid set is not bound throw an error 117822fb3c0393ef588b11f8313f01c508028d77dec0Tobin Ehlis if ((state.boundDescriptorSets.size() <= setIndex) || (!state.boundDescriptorSets[setIndex])) { 11799b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus result |= 11809b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 11819b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(cb_node->commandBuffer), __LINE__, DRAWSTATE_DESCRIPTOR_SET_NOT_BOUND, "DS", 11829b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "VkPipeline 0x%" PRIxLEAST64 " uses set #%u but that set is not bound.", 11839b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pPipe->pipeline), setIndex); 118412b7fc342b53fbdd399aae4a85959e37685936acChris Forbes } else if (!verify_set_layout_compatibility(state.boundDescriptorSets[setIndex], &pipeline_layout, setIndex, 118569b71d9c89447ec87d823669ee9edbfc58af174aTobin Ehlis errorString)) { 118669b71d9c89447ec87d823669ee9edbfc58af174aTobin Ehlis // Set is bound but not compatible w/ overlapping pipeline_layout from PSO 118771511c5a10533c910bfe62c3bcf58e2a4054e7acTobin Ehlis VkDescriptorSet setHandle = state.boundDescriptorSets[setIndex]->GetSet(); 118822fb3c0393ef588b11f8313f01c508028d77dec0Tobin Ehlis result |= 118951ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, 11909b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(setHandle), __LINE__, DRAWSTATE_PIPELINE_LAYOUTS_INCOMPATIBLE, "DS", 1191414e9a4117b500eac650d8b8f01a6e1b22d05aaeMark Mueller "VkDescriptorSet (0x%" PRIxLEAST64 1192414e9a4117b500eac650d8b8f01a6e1b22d05aaeMark Mueller ") bound as set #%u is not compatible with overlapping VkPipelineLayout 0x%" PRIxLEAST64 " due to: %s", 11939b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(setHandle), setIndex, HandleToUint64(pipeline_layout.layout), errorString.c_str()); 1194cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } else { // Valid set is bound and layout compatible, validate that it's updated 119522fb3c0393ef588b11f8313f01c508028d77dec0Tobin Ehlis // Pull the set node 11961c130ea631a82716dc7334de17767536525f2292Tobin Ehlis cvdescriptorset::DescriptorSet *descriptor_set = state.boundDescriptorSets[setIndex]; 11977433ab60c7ff16d37edb0f8b17b606ccd363e210Tobin Ehlis // Validate the draw-time state for this descriptor set 11987433ab60c7ff16d37edb0f8b17b606ccd363e210Tobin Ehlis std::string err_str; 11992d4a3c28bf95f00fa2aac7d07288f6faf22208abMark Lobodzinski if (!descriptor_set->IsPushDescriptor() && 12002d4a3c28bf95f00fa2aac7d07288f6faf22208abMark Lobodzinski !descriptor_set->ValidateDrawState(set_binding_pair.second, state.dynamicOffsets[setIndex], cb_node, function, 12010db18ab1345f9e10907913b22ea5d57bd48077ebTobin Ehlis &err_str)) { 12021c130ea631a82716dc7334de17767536525f2292Tobin Ehlis auto set = descriptor_set->GetSet(); 12030db18ab1345f9e10907913b22ea5d57bd48077ebTobin Ehlis result |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 12049b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, HandleToUint64(set), __LINE__, 12059b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus DRAWSTATE_DESCRIPTOR_SET_NOT_UPDATED, "DS", 12060db18ab1345f9e10907913b22ea5d57bd48077ebTobin Ehlis "Descriptor set 0x%" PRIxLEAST64 " encountered the following validation error at %s time: %s", 12079b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(set), function, err_str.c_str()); 12087433ab60c7ff16d37edb0f8b17b606ccd363e210Tobin Ehlis } 12095b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 121022fb3c0393ef588b11f8313f01c508028d77dec0Tobin Ehlis } 121122fb3c0393ef588b11f8313f01c508028d77dec0Tobin Ehlis } 1212eca2d52a6bfa3f9d63a86ca9fd30abc0adf775b7Mark Young 1213eca2d52a6bfa3f9d63a86ca9fd30abc0adf775b7Mark Young // Check general pipeline state that needs to be validated at drawtime 1214b4ab35582a070b18e22c0bd6cb8811c455f5b7ffTobin Ehlis if (VK_PIPELINE_BIND_POINT_GRAPHICS == bind_point) 1215b4ab35582a070b18e22c0bd6cb8811c455f5b7ffTobin Ehlis result |= ValidatePipelineDrawtimeState(dev_data, state, cb_node, cmd_type, pPipe, function); 1216eca2d52a6bfa3f9d63a86ca9fd30abc0adf775b7Mark Young 12175b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 12185b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 12195b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 122051ea774638f432bd8e700ec8291a980f405f429eTobin Ehlisstatic void UpdateDrawState(layer_data *dev_data, GLOBAL_CB_NODE *cb_state, const VkPipelineBindPoint bind_point) { 12211c130ea631a82716dc7334de17767536525f2292Tobin Ehlis auto const &state = cb_state->lastBound[bind_point]; 1222ec2ff49aea47929f28679d7bbe598ec439db7bb5Tobin Ehlis PIPELINE_STATE *pPipe = state.pipeline_state; 1223ec2ff49aea47929f28679d7bbe598ec439db7bb5Tobin Ehlis if (VK_NULL_HANDLE != state.pipeline_layout.layout) { 12241c130ea631a82716dc7334de17767536525f2292Tobin Ehlis for (const auto &set_binding_pair : pPipe->active_slots) { 12251c130ea631a82716dc7334de17767536525f2292Tobin Ehlis uint32_t setIndex = set_binding_pair.first; 1226ec2ff49aea47929f28679d7bbe598ec439db7bb5Tobin Ehlis // Pull the set node 12271c130ea631a82716dc7334de17767536525f2292Tobin Ehlis cvdescriptorset::DescriptorSet *descriptor_set = state.boundDescriptorSets[setIndex]; 12282d4a3c28bf95f00fa2aac7d07288f6faf22208abMark Lobodzinski if (!descriptor_set->IsPushDescriptor()) { 12292d4a3c28bf95f00fa2aac7d07288f6faf22208abMark Lobodzinski // Bind this set and its active descriptor resources to the command buffer 12302d4a3c28bf95f00fa2aac7d07288f6faf22208abMark Lobodzinski descriptor_set->BindCommandBuffer(cb_state, set_binding_pair.second); 12312d4a3c28bf95f00fa2aac7d07288f6faf22208abMark Lobodzinski // For given active slots record updated images & buffers 12322d4a3c28bf95f00fa2aac7d07288f6faf22208abMark Lobodzinski descriptor_set->GetStorageUpdates(set_binding_pair.second, &cb_state->updateBuffers, &cb_state->updateImages); 12332d4a3c28bf95f00fa2aac7d07288f6faf22208abMark Lobodzinski } 1234ec2ff49aea47929f28679d7bbe598ec439db7bb5Tobin Ehlis } 1235ec2ff49aea47929f28679d7bbe598ec439db7bb5Tobin Ehlis } 123658b923895f7f6be1b7d48bd4ee3e85e0b3dd0c4dTobin Ehlis if (pPipe->vertexBindingDescriptions.size() > 0) { 123758b923895f7f6be1b7d48bd4ee3e85e0b3dd0c4dTobin Ehlis cb_state->vertex_buffer_used = true; 123858b923895f7f6be1b7d48bd4ee3e85e0b3dd0c4dTobin Ehlis } 1239ec2ff49aea47929f28679d7bbe598ec439db7bb5Tobin Ehlis} 1240ec2ff49aea47929f28679d7bbe598ec439db7bb5Tobin Ehlis 12413d67a6d0f5c42da03d838178741ef10928cd6397Chris Forbesstatic bool ValidatePipelineLocked(layer_data *dev_data, std::vector<std::unique_ptr<PIPELINE_STATE>> const &pPipelines, int pipelineIndex) { 12423251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 12435b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 12443d67a6d0f5c42da03d838178741ef10928cd6397Chris Forbes PIPELINE_STATE *pPipeline = pPipelines[pipelineIndex].get(); 12455b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 12465b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // If create derivative bit is set, check that we've specified a base 12475b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // pipeline correctly, and that the base pipeline was created to allow 12485b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // derivatives. 12495b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pPipeline->graphicsPipelineCI.flags & VK_PIPELINE_CREATE_DERIVATIVE_BIT) { 12504c0df90de562aa248b524a28b355765d8e3eff25Tobin Ehlis PIPELINE_STATE *pBasePipeline = nullptr; 12515b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (!((pPipeline->graphicsPipelineCI.basePipelineHandle != VK_NULL_HANDLE) ^ 12525b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis (pPipeline->graphicsPipelineCI.basePipelineIndex != -1))) { 1253315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis // This check is a superset of VALIDATION_ERROR_096005a8 and VALIDATION_ERROR_096005aa 12543251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 12559b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pPipeline->pipeline), __LINE__, DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS", 12569b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "Invalid Pipeline CreateInfo: exactly one of base pipeline index and handle must be specified"); 12575b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } else if (pPipeline->graphicsPipelineCI.basePipelineIndex != -1) { 12585b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pPipeline->graphicsPipelineCI.basePipelineIndex >= pipelineIndex) { 12593251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= 1260df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 1261315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pPipeline->pipeline), __LINE__, VALIDATION_ERROR_208005a0, "DS", 1262f62c50f00d7d03e27fbc3769e582761e8a4944ddMike Schuchardt "Invalid Pipeline CreateInfo: base pipeline must occur earlier in array than derivative pipeline. %s", 1263315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_208005a0]); 12645b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } else { 12653d67a6d0f5c42da03d838178741ef10928cd6397Chris Forbes pBasePipeline = pPipelines[pPipeline->graphicsPipelineCI.basePipelineIndex].get(); 12665b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 12675b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } else if (pPipeline->graphicsPipelineCI.basePipelineHandle != VK_NULL_HANDLE) { 126851ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis pBasePipeline = getPipelineState(dev_data, pPipeline->graphicsPipelineCI.basePipelineHandle); 12695b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 12705b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 12715b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pBasePipeline && !(pBasePipeline->graphicsPipelineCI.flags & VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT)) { 12723251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 12739b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pPipeline->pipeline), __LINE__, DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS", 12749b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "Invalid Pipeline CreateInfo: base pipeline does not allow derivatives."); 12755b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 12765b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 12775b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 1278c3e70f769bd4aa0988652050444d57cab4925c16Chris Forbes return skip; 1279c3e70f769bd4aa0988652050444d57cab4925c16Chris Forbes} 1280c3e70f769bd4aa0988652050444d57cab4925c16Chris Forbes 1281c3e70f769bd4aa0988652050444d57cab4925c16Chris Forbes// UNLOCKED pipeline validation. DO NOT lookup objects in the layer_data->* maps in this function. 12823d67a6d0f5c42da03d838178741ef10928cd6397Chris Forbesstatic bool ValidatePipelineUnlocked(layer_data *dev_data, std::vector<std::unique_ptr<PIPELINE_STATE>> const &pPipelines, int pipelineIndex) { 1283c3e70f769bd4aa0988652050444d57cab4925c16Chris Forbes bool skip = false; 1284c3e70f769bd4aa0988652050444d57cab4925c16Chris Forbes 12853d67a6d0f5c42da03d838178741ef10928cd6397Chris Forbes PIPELINE_STATE *pPipeline = pPipelines[pipelineIndex].get(); 1286c3e70f769bd4aa0988652050444d57cab4925c16Chris Forbes 1287fa30cd33537b2773dae129822b4e7c654a027929Chris Forbes // Ensure the subpass index is valid. If not, then validate_and_capture_pipeline_shader_state 1288fa30cd33537b2773dae129822b4e7c654a027929Chris Forbes // produces nonsense errors that confuse users. Other layers should already 1289fa30cd33537b2773dae129822b4e7c654a027929Chris Forbes // emit errors for renderpass being invalid. 1290146a87545e7b707b1dbddbd9cb8b41869ad402ccChris Forbes auto subpass_desc = &pPipeline->render_pass_ci.pSubpasses[pPipeline->graphicsPipelineCI.subpass]; 1291146a87545e7b707b1dbddbd9cb8b41869ad402ccChris Forbes if (pPipeline->graphicsPipelineCI.subpass >= pPipeline->render_pass_ci.subpassCount) { 1292fa30cd33537b2773dae129822b4e7c654a027929Chris Forbes skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 1293fa30cd33537b2773dae129822b4e7c654a027929Chris Forbes HandleToUint64(pPipeline->pipeline), __LINE__, VALIDATION_ERROR_096005ee, "DS", 1294fa30cd33537b2773dae129822b4e7c654a027929Chris Forbes "Invalid Pipeline CreateInfo State: Subpass index %u " 1295fa30cd33537b2773dae129822b4e7c654a027929Chris Forbes "is out of range for this renderpass (0..%u). %s", 1296146a87545e7b707b1dbddbd9cb8b41869ad402ccChris Forbes pPipeline->graphicsPipelineCI.subpass, pPipeline->render_pass_ci.subpassCount - 1, 1297fa30cd33537b2773dae129822b4e7c654a027929Chris Forbes validation_error_map[VALIDATION_ERROR_096005ee]); 1298146a87545e7b707b1dbddbd9cb8b41869ad402ccChris Forbes subpass_desc = nullptr; 1299fa30cd33537b2773dae129822b4e7c654a027929Chris Forbes } 1300fa30cd33537b2773dae129822b4e7c654a027929Chris Forbes 13015b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pPipeline->graphicsPipelineCI.pColorBlendState != NULL) { 1302fb4e70f35eef785ce77fca908d4d64f60539893dTobin Ehlis const safe_VkPipelineColorBlendStateCreateInfo *color_blend_state = pPipeline->graphicsPipelineCI.pColorBlendState; 1303fb4e70f35eef785ce77fca908d4d64f60539893dTobin Ehlis if (color_blend_state->attachmentCount != subpass_desc->colorAttachmentCount) { 13043251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg( 130551ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 1306315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pPipeline->pipeline), __LINE__, VALIDATION_ERROR_096005d4, "DS", 1307fb4e70f35eef785ce77fca908d4d64f60539893dTobin Ehlis "vkCreateGraphicsPipelines(): Render pass (0x%" PRIxLEAST64 1308fb4e70f35eef785ce77fca908d4d64f60539893dTobin Ehlis ") subpass %u has colorAttachmentCount of %u which doesn't match the pColorBlendState->attachmentCount of %u. %s", 1309cafebcdd40427a0713a3564dc8f39e47edbdb02fTobin Ehlis HandleToUint64(pPipeline->rp_state->renderPass), pPipeline->graphicsPipelineCI.subpass, 1310fb4e70f35eef785ce77fca908d4d64f60539893dTobin Ehlis subpass_desc->colorAttachmentCount, color_blend_state->attachmentCount, 1311315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_096005d4]); 1312fb4e70f35eef785ce77fca908d4d64f60539893dTobin Ehlis } 131351ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis if (!dev_data->enabled_features.independentBlend) { 13143d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis if (pPipeline->attachments.size() > 1) { 131526c548826ff0f83d12c769b51e7d6f76d1265c0eChris Forbes VkPipelineColorBlendAttachmentState *pAttachments = &pPipeline->attachments[0]; 1316c7bd67f06427b08ba65cdf2dd529c8234beebdd5Mark Lobodzinski for (size_t i = 1; i < pPipeline->attachments.size(); i++) { 131706811df0256552cd7da9d7297672af377463fc4aMark Mueller // Quoting the spec: "If [the independent blend] feature is not enabled, the VkPipelineColorBlendAttachmentState 131806811df0256552cd7da9d7297672af377463fc4aMark Mueller // settings for all color attachments must be identical." VkPipelineColorBlendAttachmentState contains 131906811df0256552cd7da9d7297672af377463fc4aMark Mueller // only attachment state, so memcmp is best suited for the comparison 132006811df0256552cd7da9d7297672af377463fc4aMark Mueller if (memcmp(static_cast<const void *>(pAttachments), static_cast<const void *>(&pAttachments[i]), 132106811df0256552cd7da9d7297672af377463fc4aMark Mueller sizeof(pAttachments[0]))) { 13223251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= 1323df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 1324315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pPipeline->pipeline), __LINE__, VALIDATION_ERROR_0f4004ba, "DS", 1325df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski "Invalid Pipeline CreateInfo: If independent blend feature not " 1326df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski "enabled, all elements of pAttachments must be identical. %s", 1327315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_0f4004ba]); 132806811df0256552cd7da9d7297672af377463fc4aMark Mueller break; 1329c7bd67f06427b08ba65cdf2dd529c8234beebdd5Mark Lobodzinski } 13305b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 13315b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 13325b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 133351ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis if (!dev_data->enabled_features.logicOp && (pPipeline->graphicsPipelineCI.pColorBlendState->logicOpEnable != VK_FALSE)) { 13343251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= 1335df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 1336315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pPipeline->pipeline), __LINE__, VALIDATION_ERROR_0f4004bc, "DS", 1337f62c50f00d7d03e27fbc3769e582761e8a4944ddMike Schuchardt "Invalid Pipeline CreateInfo: If logic operations feature not enabled, logicOpEnable must be VK_FALSE. %s", 1338315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_0f4004bc]); 13395b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 13405b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 13415b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 134259ae0ccadec962d9ca2cce7584fad6c57c1a4458Tobin Ehlis if (validate_and_capture_pipeline_shader_state(dev_data, pPipeline)) { 13433251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip = true; 13445b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 134552156ec29c88c0e52eb89fb42867adacb1dd31bbChris Forbes // Each shader's stage must be unique 134652156ec29c88c0e52eb89fb42867adacb1dd31bbChris Forbes if (pPipeline->duplicate_shaders) { 134752156ec29c88c0e52eb89fb42867adacb1dd31bbChris Forbes for (uint32_t stage = VK_SHADER_STAGE_VERTEX_BIT; stage & VK_SHADER_STAGE_ALL_GRAPHICS; stage <<= 1) { 134852156ec29c88c0e52eb89fb42867adacb1dd31bbChris Forbes if (pPipeline->duplicate_shaders & stage) { 13499b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 13509b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pPipeline->pipeline), __LINE__, DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS", 13519b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "Invalid Pipeline CreateInfo State: Multiple shaders provided for stage %s", 13529b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus string_VkShaderStageFlagBits(VkShaderStageFlagBits(stage))); 135352156ec29c88c0e52eb89fb42867adacb1dd31bbChris Forbes } 135452156ec29c88c0e52eb89fb42867adacb1dd31bbChris Forbes } 135552156ec29c88c0e52eb89fb42867adacb1dd31bbChris Forbes } 13565b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // VS is required 13575b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (!(pPipeline->active_shaders & VK_SHADER_STAGE_VERTEX_BIT)) { 1358315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 1359315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pPipeline->pipeline), __LINE__, VALIDATION_ERROR_096005ae, "DS", 1360315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis "Invalid Pipeline CreateInfo State: Vertex Shader required. %s", 1361315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_096005ae]); 13625b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 13635b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Either both or neither TC/TE shaders should be defined 13643067e46adf202d2cc3ce1e06909dc7fadf0c8c3bCort Stratton bool has_control = (pPipeline->active_shaders & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0; 13653067e46adf202d2cc3ce1e06909dc7fadf0c8c3bCort Stratton bool has_eval = (pPipeline->active_shaders & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0; 13663067e46adf202d2cc3ce1e06909dc7fadf0c8c3bCort Stratton if (has_control && !has_eval) { 13673251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 1368315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pPipeline->pipeline), __LINE__, VALIDATION_ERROR_096005b2, "DS", 13693251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Invalid Pipeline CreateInfo State: TE and TC shaders must be included or excluded as a pair. %s", 1370315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_096005b2]); 1371f62c50f00d7d03e27fbc3769e582761e8a4944ddMike Schuchardt } 13723067e46adf202d2cc3ce1e06909dc7fadf0c8c3bCort Stratton if (!has_control && has_eval) { 13733251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 1374315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pPipeline->pipeline), __LINE__, VALIDATION_ERROR_096005b4, "DS", 13753251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Invalid Pipeline CreateInfo State: TE and TC shaders must be included or excluded as a pair. %s", 1376315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_096005b4]); 13775b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 13785b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Compute shaders should be specified independent of Gfx shaders 1379f62c50f00d7d03e27fbc3769e582761e8a4944ddMike Schuchardt if (pPipeline->active_shaders & VK_SHADER_STAGE_COMPUTE_BIT) { 13803251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 1381315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pPipeline->pipeline), __LINE__, VALIDATION_ERROR_096005b0, "DS", 13823251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Invalid Pipeline CreateInfo State: Do not specify Compute Shader for Gfx Pipeline. %s", 1383315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_096005b0]); 13845b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 13855b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // VK_PRIMITIVE_TOPOLOGY_PATCH_LIST primitive topology is only valid for tessellation pipelines. 13865b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Mismatching primitive topology and tessellation fails graphics pipeline creation. 13873067e46adf202d2cc3ce1e06909dc7fadf0c8c3bCort Stratton if (has_control && has_eval && 1388ca546210846c65808717f8875deae39bd227c240Tobin Ehlis (!pPipeline->graphicsPipelineCI.pInputAssemblyState || 1389ca546210846c65808717f8875deae39bd227c240Tobin Ehlis pPipeline->graphicsPipelineCI.pInputAssemblyState->topology != VK_PRIMITIVE_TOPOLOGY_PATCH_LIST)) { 13903251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 1391315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pPipeline->pipeline), __LINE__, VALIDATION_ERROR_096005c0, "DS", 13923251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Invalid Pipeline CreateInfo State: " 13933251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "VK_PRIMITIVE_TOPOLOGY_PATCH_LIST must be set as IA " 13943251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "topology for tessellation pipelines. %s", 1395315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_096005c0]); 13965b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 1397ca546210846c65808717f8875deae39bd227c240Tobin Ehlis if (pPipeline->graphicsPipelineCI.pInputAssemblyState && 1398ca546210846c65808717f8875deae39bd227c240Tobin Ehlis pPipeline->graphicsPipelineCI.pInputAssemblyState->topology == VK_PRIMITIVE_TOPOLOGY_PATCH_LIST) { 13993067e46adf202d2cc3ce1e06909dc7fadf0c8c3bCort Stratton if (!has_control || !has_eval) { 14003251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 1401315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pPipeline->pipeline), __LINE__, VALIDATION_ERROR_096005c2, "DS", 14023251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Invalid Pipeline CreateInfo State: " 14033251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "VK_PRIMITIVE_TOPOLOGY_PATCH_LIST primitive " 14043251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "topology is only valid for tessellation pipelines. %s", 1405315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_096005c2]); 14065b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 14075b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 1408f62c50f00d7d03e27fbc3769e582761e8a4944ddMike Schuchardt 14096b8d2b83e8400e5238705a0856b5e3acff8df742Mike Weiblen // If a rasterization state is provided... 1410a27508babf63d50aea75883a3702979193c23683Mark Young if (pPipeline->graphicsPipelineCI.pRasterizationState) { 141158c5552c73679f81f57a64a809f7d4d6d52f4ce3Mark Lobodzinski if ((pPipeline->graphicsPipelineCI.pRasterizationState->depthClampEnable == VK_TRUE) && 141258c5552c73679f81f57a64a809f7d4d6d52f4ce3Mark Lobodzinski (!dev_data->enabled_features.depthClamp)) { 14133251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 1414315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pPipeline->pipeline), __LINE__, VALIDATION_ERROR_1020061c, "DS", 14153251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkCreateGraphicsPipelines(): the depthClamp device feature is disabled: the depthClampEnable " 14163251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "member of the VkPipelineRasterizationStateCreateInfo structure must be set to VK_FALSE. %s", 1417315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_1020061c]); 141858c5552c73679f81f57a64a809f7d4d6d52f4ce3Mark Lobodzinski } 141958c5552c73679f81f57a64a809f7d4d6d52f4ce3Mark Lobodzinski 1420434c3e2a778a3ca5a0a5414cbedd7c0f20a883b7Mark Lobodzinski if (!isDynamic(pPipeline, VK_DYNAMIC_STATE_DEPTH_BIAS) && 1421434c3e2a778a3ca5a0a5414cbedd7c0f20a883b7Mark Lobodzinski (pPipeline->graphicsPipelineCI.pRasterizationState->depthBiasClamp != 0.0) && 1422434c3e2a778a3ca5a0a5414cbedd7c0f20a883b7Mark Lobodzinski (!dev_data->enabled_features.depthBiasClamp)) { 14233251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 14249b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pPipeline->pipeline), __LINE__, DRAWSTATE_INVALID_FEATURE, "DS", 14253251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkCreateGraphicsPipelines(): the depthBiasClamp device feature is disabled: the depthBiasClamp " 14263251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "member of the VkPipelineRasterizationStateCreateInfo structure must be set to 0.0 unless the " 14273251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "VK_DYNAMIC_STATE_DEPTH_BIAS dynamic state is enabled"); 1428434c3e2a778a3ca5a0a5414cbedd7c0f20a883b7Mark Lobodzinski } 1429434c3e2a778a3ca5a0a5414cbedd7c0f20a883b7Mark Lobodzinski 14306b8d2b83e8400e5238705a0856b5e3acff8df742Mike Weiblen // If rasterization is enabled... 14316b8d2b83e8400e5238705a0856b5e3acff8df742Mike Weiblen if (pPipeline->graphicsPipelineCI.pRasterizationState->rasterizerDiscardEnable == VK_FALSE) { 1432148e8028deee2b4b00ccd4a69210897add328265Mark Lobodzinski if ((pPipeline->graphicsPipelineCI.pMultisampleState->alphaToOneEnable == VK_TRUE) && 1433148e8028deee2b4b00ccd4a69210897add328265Mark Lobodzinski (!dev_data->enabled_features.alphaToOne)) { 14343251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 1435315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pPipeline->pipeline), __LINE__, VALIDATION_ERROR_10000622, "DS", 14363251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkCreateGraphicsPipelines(): the alphaToOne device feature is disabled: the alphaToOneEnable " 14373251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "member of the VkPipelineMultisampleStateCreateInfo structure must be set to VK_FALSE. %s", 1438315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_10000622]); 1439148e8028deee2b4b00ccd4a69210897add328265Mark Lobodzinski } 1440148e8028deee2b4b00ccd4a69210897add328265Mark Lobodzinski 14416b8d2b83e8400e5238705a0856b5e3acff8df742Mike Weiblen // If subpass uses a depth/stencil attachment, pDepthStencilState must be a pointer to a valid structure 14426b8d2b83e8400e5238705a0856b5e3acff8df742Mike Weiblen if (subpass_desc && subpass_desc->pDepthStencilAttachment && 14436b8d2b83e8400e5238705a0856b5e3acff8df742Mike Weiblen subpass_desc->pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) { 14446b8d2b83e8400e5238705a0856b5e3acff8df742Mike Weiblen if (!pPipeline->graphicsPipelineCI.pDepthStencilState) { 14453251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 1446315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pPipeline->pipeline), __LINE__, VALIDATION_ERROR_096005e0, "DS", 14473251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Invalid Pipeline CreateInfo State: pDepthStencilState is NULL when rasterization is " 14483251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "enabled and subpass uses a depth/stencil attachment. %s", 1449315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_096005e0]); 14509580629edfc5154cc9e36974cca12966fbd748b9Mark Lobodzinski 14519580629edfc5154cc9e36974cca12966fbd748b9Mark Lobodzinski } else if ((pPipeline->graphicsPipelineCI.pDepthStencilState->depthBoundsTestEnable == VK_TRUE) && 14529580629edfc5154cc9e36974cca12966fbd748b9Mark Lobodzinski (!dev_data->enabled_features.depthBounds)) { 14533251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg( 1454df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 14559b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pPipeline->pipeline), __LINE__, DRAWSTATE_INVALID_FEATURE, "DS", 14569580629edfc5154cc9e36974cca12966fbd748b9Mark Lobodzinski "vkCreateGraphicsPipelines(): the depthBounds device feature is disabled: the depthBoundsTestEnable " 14579580629edfc5154cc9e36974cca12966fbd748b9Mark Lobodzinski "member of the VkPipelineDepthStencilStateCreateInfo structure must be set to VK_FALSE."); 14586b8d2b83e8400e5238705a0856b5e3acff8df742Mike Weiblen } 14595dcdd90e54199dfeb29938a3a03d998397c22664Chris Forbes } 1460326fc9f00659303e0a5b3fc4019db2bda641c7bdMike Weiblen 1461326fc9f00659303e0a5b3fc4019db2bda641c7bdMike Weiblen // If subpass uses color attachments, pColorBlendState must be valid pointer 1462326fc9f00659303e0a5b3fc4019db2bda641c7bdMike Weiblen if (subpass_desc) { 1463326fc9f00659303e0a5b3fc4019db2bda641c7bdMike Weiblen uint32_t color_attachment_count = 0; 1464326fc9f00659303e0a5b3fc4019db2bda641c7bdMike Weiblen for (uint32_t i = 0; i < subpass_desc->colorAttachmentCount; ++i) { 1465326fc9f00659303e0a5b3fc4019db2bda641c7bdMike Weiblen if (subpass_desc->pColorAttachments[i].attachment != VK_ATTACHMENT_UNUSED) { 1466326fc9f00659303e0a5b3fc4019db2bda641c7bdMike Weiblen ++color_attachment_count; 1467326fc9f00659303e0a5b3fc4019db2bda641c7bdMike Weiblen } 1468326fc9f00659303e0a5b3fc4019db2bda641c7bdMike Weiblen } 1469326fc9f00659303e0a5b3fc4019db2bda641c7bdMike Weiblen if (color_attachment_count > 0 && pPipeline->graphicsPipelineCI.pColorBlendState == nullptr) { 14703251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 1471315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pPipeline->pipeline), __LINE__, VALIDATION_ERROR_096005e2, "DS", 14723251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Invalid Pipeline CreateInfo State: pColorBlendState is NULL when rasterization is " 14733251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "enabled and subpass uses color attachments. %s", 1474315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_096005e2]); 1475326fc9f00659303e0a5b3fc4019db2bda641c7bdMike Weiblen } 1476326fc9f00659303e0a5b3fc4019db2bda641c7bdMike Weiblen } 14775dcdd90e54199dfeb29938a3a03d998397c22664Chris Forbes } 14785b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 14796b8d2b83e8400e5238705a0856b5e3acff8df742Mike Weiblen 1480740a9cdda3aa9cc7a4124184bd58146e6e99d772Chris Forbes auto vi = pPipeline->graphicsPipelineCI.pVertexInputState; 1481740a9cdda3aa9cc7a4124184bd58146e6e99d772Chris Forbes if (vi != NULL) { 1482740a9cdda3aa9cc7a4124184bd58146e6e99d772Chris Forbes for (uint32_t j = 0; j < vi->vertexAttributeDescriptionCount; j++) { 1483740a9cdda3aa9cc7a4124184bd58146e6e99d772Chris Forbes VkFormat format = vi->pVertexAttributeDescriptions[j].format; 1484740a9cdda3aa9cc7a4124184bd58146e6e99d772Chris Forbes // Internal call to get format info. Still goes through layers, could potentially go directly to ICD. 1485740a9cdda3aa9cc7a4124184bd58146e6e99d772Chris Forbes VkFormatProperties properties; 1486740a9cdda3aa9cc7a4124184bd58146e6e99d772Chris Forbes dev_data->instance_data->dispatch_table.GetPhysicalDeviceFormatProperties(dev_data->physical_device, format, &properties); 1487740a9cdda3aa9cc7a4124184bd58146e6e99d772Chris Forbes if ((properties.bufferFeatures & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT) == 0) { 1488740a9cdda3aa9cc7a4124184bd58146e6e99d772Chris Forbes skip |= log_msg( 1489740a9cdda3aa9cc7a4124184bd58146e6e99d772Chris Forbes dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 1490740a9cdda3aa9cc7a4124184bd58146e6e99d772Chris Forbes __LINE__, VALIDATION_ERROR_14a004de, "IMAGE", 1491740a9cdda3aa9cc7a4124184bd58146e6e99d772Chris Forbes "vkCreateGraphicsPipelines: pCreateInfo[%d].pVertexInputState->vertexAttributeDescriptions[%d].format " 1492740a9cdda3aa9cc7a4124184bd58146e6e99d772Chris Forbes "(%s) is not a supported vertex buffer format. %s", 1493740a9cdda3aa9cc7a4124184bd58146e6e99d772Chris Forbes pipelineIndex, j, string_VkFormat(format), validation_error_map[VALIDATION_ERROR_14a004de]); 1494740a9cdda3aa9cc7a4124184bd58146e6e99d772Chris Forbes } 1495740a9cdda3aa9cc7a4124184bd58146e6e99d772Chris Forbes } 1496740a9cdda3aa9cc7a4124184bd58146e6e99d772Chris Forbes } 1497740a9cdda3aa9cc7a4124184bd58146e6e99d772Chris Forbes 1498497e33d6b0547f5dccca245a5b6777831fbb0de0Maciej Jesionowski if (dev_data->extensions.vk_amd_mixed_attachment_samples) { 1499497e33d6b0547f5dccca245a5b6777831fbb0de0Maciej Jesionowski VkSampleCountFlagBits max_sample_count = static_cast<VkSampleCountFlagBits>(0); 1500497e33d6b0547f5dccca245a5b6777831fbb0de0Maciej Jesionowski for (uint32_t i = 0; i < subpass_desc->colorAttachmentCount; ++i) { 1501497e33d6b0547f5dccca245a5b6777831fbb0de0Maciej Jesionowski if (subpass_desc->pColorAttachments[i].attachment != VK_ATTACHMENT_UNUSED) { 1502497e33d6b0547f5dccca245a5b6777831fbb0de0Maciej Jesionowski max_sample_count = std::max(max_sample_count, pPipeline->render_pass_ci.pAttachments[subpass_desc->pColorAttachments[i].attachment].samples); 1503497e33d6b0547f5dccca245a5b6777831fbb0de0Maciej Jesionowski } 1504497e33d6b0547f5dccca245a5b6777831fbb0de0Maciej Jesionowski } 1505497e33d6b0547f5dccca245a5b6777831fbb0de0Maciej Jesionowski if (subpass_desc->pDepthStencilAttachment && subpass_desc->pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) { 1506497e33d6b0547f5dccca245a5b6777831fbb0de0Maciej Jesionowski max_sample_count = std::max(max_sample_count, pPipeline->render_pass_ci.pAttachments[subpass_desc->pDepthStencilAttachment->attachment].samples); 1507497e33d6b0547f5dccca245a5b6777831fbb0de0Maciej Jesionowski } 1508497e33d6b0547f5dccca245a5b6777831fbb0de0Maciej Jesionowski if (pPipeline->graphicsPipelineCI.pMultisampleState->rasterizationSamples != max_sample_count) { 1509497e33d6b0547f5dccca245a5b6777831fbb0de0Maciej Jesionowski skip |= 1510497e33d6b0547f5dccca245a5b6777831fbb0de0Maciej Jesionowski log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 1511497e33d6b0547f5dccca245a5b6777831fbb0de0Maciej Jesionowski HandleToUint64(pPipeline->pipeline), __LINE__, VALIDATION_ERROR_09600bc2, "DS", 1512497e33d6b0547f5dccca245a5b6777831fbb0de0Maciej Jesionowski "vkCreateGraphicsPipelines: pCreateInfo[%d].pMultisampleState->rasterizationSamples (%s) != max attachment samples (%s) " 1513497e33d6b0547f5dccca245a5b6777831fbb0de0Maciej Jesionowski "used in subpass %u. %s", 1514497e33d6b0547f5dccca245a5b6777831fbb0de0Maciej Jesionowski pipelineIndex, string_VkSampleCountFlagBits(pPipeline->graphicsPipelineCI.pMultisampleState->rasterizationSamples), 1515497e33d6b0547f5dccca245a5b6777831fbb0de0Maciej Jesionowski string_VkSampleCountFlagBits(max_sample_count), pPipeline->graphicsPipelineCI.subpass, 1516497e33d6b0547f5dccca245a5b6777831fbb0de0Maciej Jesionowski validation_error_map[VALIDATION_ERROR_09600bc2]); 1517497e33d6b0547f5dccca245a5b6777831fbb0de0Maciej Jesionowski } 1518497e33d6b0547f5dccca245a5b6777831fbb0de0Maciej Jesionowski } 1519497e33d6b0547f5dccca245a5b6777831fbb0de0Maciej Jesionowski 15203251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 15215b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 15225b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 15235b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// Block of code at start here specifically for managing/tracking DSs 15245b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 15255b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// Return Pool node ptr for specified pool or else NULL 15269a9a0db2a973034d4286b6d4c62a46beb7641791Tobin EhlisDESCRIPTOR_POOL_STATE *GetDescriptorPoolState(const layer_data *dev_data, const VkDescriptorPool pool) { 1527bb7ea477706f90eb2a72887f652795bc79f60ddeTobin Ehlis auto pool_it = dev_data->descriptorPoolMap.find(pool); 1528bb7ea477706f90eb2a72887f652795bc79f60ddeTobin Ehlis if (pool_it == dev_data->descriptorPoolMap.end()) { 15295b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return NULL; 15305b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 1531bb7ea477706f90eb2a72887f652795bc79f60ddeTobin Ehlis return pool_it->second; 15325b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 15335b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 15345b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// Validate that given set is valid and that it's not being used by an in-flight CmdBuffer 15355b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// func_str is the name of the calling function 1536e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves// Return false if no errors occur 1537e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves// Return true if validation error occurs and callback returns true (to skip upcoming API call down the chain) 15380dcd0f7b37456e2e552d37094ba503c0d089b906Tobin Ehlisstatic bool validateIdleDescriptorSet(const layer_data *dev_data, VkDescriptorSet set, std::string func_str) { 1539cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.idle_descriptor_set) return false; 15403251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 15410dcd0f7b37456e2e552d37094ba503c0d089b906Tobin Ehlis auto set_node = dev_data->setMap.find(set); 15420dcd0f7b37456e2e552d37094ba503c0d089b906Tobin Ehlis if (set_node == dev_data->setMap.end()) { 15433251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, 15449b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(set), __LINE__, DRAWSTATE_DOUBLE_DESTROY, "DS", 15453251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Cannot call %s() on descriptor set 0x%" PRIxLEAST64 " that has not been allocated.", func_str.c_str(), 15469b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(set)); 15475b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } else { 15481c48e214b2ed50690da7f42f2013be3a6ef267dfTobin Ehlis // TODO : This covers various error cases so should pass error enum into this function and use passed in enum here 15495b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (set_node->second->in_use.load()) { 15503251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, 1551315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(set), __LINE__, VALIDATION_ERROR_2860026a, "DS", 15523251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Cannot call %s() on descriptor set 0x%" PRIxLEAST64 " that is in use by a command buffer. %s", 1553315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis func_str.c_str(), HandleToUint64(set), validation_error_map[VALIDATION_ERROR_2860026a]); 15545b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 15555b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 15563251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 15575b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 1558f80bf38f4fb3f177b3e1be11b7b1c5edcdbf7d9bChris Forbes 1559e6651096ed8f07840447783c66827cc16d659a49Tobin Ehlis// Remove set from setMap and delete the set 15609dd448578d59cb5ce692e833ba230783b30f3550Tobin Ehlisstatic void freeDescriptorSet(layer_data *dev_data, cvdescriptorset::DescriptorSet *descriptor_set) { 15619dd448578d59cb5ce692e833ba230783b30f3550Tobin Ehlis dev_data->setMap.erase(descriptor_set->GetSet()); 15629dd448578d59cb5ce692e833ba230783b30f3550Tobin Ehlis delete descriptor_set; 15639dd448578d59cb5ce692e833ba230783b30f3550Tobin Ehlis} 15645b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// Free all DS Pools including their Sets & related sub-structs 15655b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// NOTE : Calls to this function should be wrapped in mutex 156651ea774638f432bd8e700ec8291a980f405f429eTobin Ehlisstatic void deletePools(layer_data *dev_data) { 1567ee7e96d032744c1db89cab21362ac8ecad6eec5aGabríel Arthúr Pétursson for (auto ii = dev_data->descriptorPoolMap.begin(); ii != dev_data->descriptorPoolMap.end();) { 1568c5f47f0a54e14c47d402aeabc6498d981ecda9ccTobin Ehlis // Remove this pools' sets from setMap and delete them 1569ee7e96d032744c1db89cab21362ac8ecad6eec5aGabríel Arthúr Pétursson for (auto ds : ii->second->sets) { 157051ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis freeDescriptorSet(dev_data, ds); 15715b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 1572ee7e96d032744c1db89cab21362ac8ecad6eec5aGabríel Arthúr Pétursson ii->second->sets.clear(); 1573ee7e96d032744c1db89cab21362ac8ecad6eec5aGabríel Arthúr Pétursson delete ii->second; 1574ee7e96d032744c1db89cab21362ac8ecad6eec5aGabríel Arthúr Pétursson ii = dev_data->descriptorPoolMap.erase(ii); 15755b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 15765b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 15775b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 157851ea774638f432bd8e700ec8291a980f405f429eTobin Ehlisstatic void clearDescriptorPool(layer_data *dev_data, const VkDevice device, const VkDescriptorPool pool, 15795b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis VkDescriptorPoolResetFlags flags) { 15809a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis DESCRIPTOR_POOL_STATE *pPool = GetDescriptorPoolState(dev_data, pool); 1581de7672b6b749c09c5991bd8038b3a35ef82a69dcTobin Ehlis // TODO: validate flags 1582de7672b6b749c09c5991bd8038b3a35ef82a69dcTobin Ehlis // For every set off of this pool, clear it, remove from setMap, and free cvdescriptorset::DescriptorSet 1583de7672b6b749c09c5991bd8038b3a35ef82a69dcTobin Ehlis for (auto ds : pPool->sets) { 158451ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis freeDescriptorSet(dev_data, ds); 1585de7672b6b749c09c5991bd8038b3a35ef82a69dcTobin Ehlis } 1586de7672b6b749c09c5991bd8038b3a35ef82a69dcTobin Ehlis pPool->sets.clear(); 1587de7672b6b749c09c5991bd8038b3a35ef82a69dcTobin Ehlis // Reset available count for each type and available sets for this pool 1588de7672b6b749c09c5991bd8038b3a35ef82a69dcTobin Ehlis for (uint32_t i = 0; i < pPool->availableDescriptorTypeCount.size(); ++i) { 1589de7672b6b749c09c5991bd8038b3a35ef82a69dcTobin Ehlis pPool->availableDescriptorTypeCount[i] = pPool->maxDescriptorTypeCount[i]; 15905b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 1591de7672b6b749c09c5991bd8038b3a35ef82a69dcTobin Ehlis pPool->availableSets = pPool->maxSets; 15925b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 15935b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 15945b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// For given CB object, fetch associated CB Node from map 15959a9a0db2a973034d4286b6d4c62a46beb7641791Tobin EhlisGLOBAL_CB_NODE *GetCBNode(layer_data const *dev_data, const VkCommandBuffer cb) { 159651ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis auto it = dev_data->commandBufferMap.find(cb); 159751ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis if (it == dev_data->commandBufferMap.end()) { 15985b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return NULL; 15995b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 16005121a8dcacb23766ba4455b4eea429f0a3d62099Chris Forbes return it->second; 16015b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 16025b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 160329f880e9c3c837307e7a19c0ef7275448d483e04Tobin Ehlis// If a renderpass is active, verify that the given command type is appropriate for current subpass state 160429f880e9c3c837307e7a19c0ef7275448d483e04Tobin Ehlisbool ValidateCmdSubpassState(const layer_data *dev_data, const GLOBAL_CB_NODE *pCB, const CMD_TYPE cmd_type) { 1605cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (!pCB->activeRenderPass) return false; 16063251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 1607d0d8e333806eaac08bdc87ddeff886dc2b0f09e7Tobin Ehlis if (pCB->activeSubpassContents == VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS && 1608d0d8e333806eaac08bdc87ddeff886dc2b0f09e7Tobin Ehlis (cmd_type != CMD_EXECUTECOMMANDS && cmd_type != CMD_NEXTSUBPASS && cmd_type != CMD_ENDRENDERPASS)) { 16093251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 16109b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pCB->commandBuffer), __LINE__, DRAWSTATE_INVALID_COMMAND_BUFFER, "DS", 16113251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Commands cannot be called in a subpass using secondary command buffers."); 16125b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } else if (pCB->activeSubpassContents == VK_SUBPASS_CONTENTS_INLINE && cmd_type == CMD_EXECUTECOMMANDS) { 16133251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 16149b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pCB->commandBuffer), __LINE__, DRAWSTATE_INVALID_COMMAND_BUFFER, "DS", 16153251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkCmdExecuteCommands() cannot be called in a subpass using inline commands."); 16165b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 16173251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 16185b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 16195b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 1620e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlisbool ValidateCmdQueueFlags(layer_data *dev_data, const GLOBAL_CB_NODE *cb_node, const char *caller_name, 1621e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis VkQueueFlags required_flags, UNIQUE_VALIDATION_ERROR_CODE error_code) { 1622baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt auto pool = GetCommandPoolNode(dev_data, cb_node->createInfo.commandPool); 1623baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt if (pool) { 1624baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt VkQueueFlags queue_flags = dev_data->phys_dev_properties.queue_family_properties[pool->queueFamilyIndex].queueFlags; 1625baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt if (!(required_flags & queue_flags)) { 1626baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt string required_flags_string; 1627baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt for (auto flag : {VK_QUEUE_TRANSFER_BIT, VK_QUEUE_GRAPHICS_BIT, VK_QUEUE_COMPUTE_BIT}) { 1628baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt if (flag & required_flags) { 1629baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt if (required_flags_string.size()) { 1630baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt required_flags_string += " or "; 1631baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt } 1632baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt required_flags_string += string_VkQueueFlagBits(flag); 1633baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt } 1634baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt } 1635baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt return log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 16369b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(cb_node->commandBuffer), __LINE__, error_code, "DS", 1637baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt "Cannot call %s on a command buffer allocated from a pool without %s capabilities. %s.", caller_name, 1638baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt required_flags_string.c_str(), validation_error_map[error_code]); 1639baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt } 1640baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt } 16415b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return false; 16425b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 16435b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 1644d00947f5dcd29a4d8aab59e62f72df50444d2537Chris Forbesstatic char const * GetCauseStr(VK_OBJECT obj) { 1645d00947f5dcd29a4d8aab59e62f72df50444d2537Chris Forbes if (obj.type == kVulkanObjectTypeDescriptorSet) 1646d00947f5dcd29a4d8aab59e62f72df50444d2537Chris Forbes return "destroyed or updated"; 1647d00947f5dcd29a4d8aab59e62f72df50444d2537Chris Forbes if (obj.type == kVulkanObjectTypeCommandBuffer) 1648d00947f5dcd29a4d8aab59e62f72df50444d2537Chris Forbes return "destroyed or rerecorded"; 1649d00947f5dcd29a4d8aab59e62f72df50444d2537Chris Forbes return "destroyed"; 1650d00947f5dcd29a4d8aab59e62f72df50444d2537Chris Forbes} 1651d00947f5dcd29a4d8aab59e62f72df50444d2537Chris Forbes 1652e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlisstatic bool ReportInvalidCommandBuffer(layer_data *dev_data, const GLOBAL_CB_NODE *cb_state, const char *call_source) { 1653ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski bool skip = false; 1654ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski for (auto obj : cb_state->broken_bindings) { 16557a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski const char *type_str = object_string[obj.type]; 1656d00947f5dcd29a4d8aab59e62f72df50444d2537Chris Forbes const char *cause_str = GetCauseStr(obj); 1657ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 16589b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(cb_state->commandBuffer), __LINE__, DRAWSTATE_INVALID_COMMAND_BUFFER, "DS", 1659ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski "You are adding %s to command buffer 0x%p that is invalid because bound %s 0x%" PRIxLEAST64 " was %s.", 1660ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski call_source, cb_state->commandBuffer, type_str, obj.handle, cause_str); 1661ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski } 1662ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski return skip; 1663ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski} 1664ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski 1665623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski// Validate the given command being added to the specified cmd buffer, flagging errors if CB is not in the recording state or if 1666623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski// there's an issue with the Cmd ordering 1667e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlisbool ValidateCmd(layer_data *dev_data, const GLOBAL_CB_NODE *cb_state, const CMD_TYPE cmd, const char *caller_name) { 166833f3623e8124c3a6081b60f68b9d39a19a5840aeChris Forbes switch (cb_state->state) { 166933f3623e8124c3a6081b60f68b9d39a19a5840aeChris Forbes case CB_RECORDING: 167033f3623e8124c3a6081b60f68b9d39a19a5840aeChris Forbes return ValidateCmdSubpassState(dev_data, cb_state, cmd); 167133f3623e8124c3a6081b60f68b9d39a19a5840aeChris Forbes 167246daa701a01b92ae19e3ee9e661d677128fe7e6dChris Forbes case CB_INVALID_COMPLETE: 167346daa701a01b92ae19e3ee9e661d677128fe7e6dChris Forbes case CB_INVALID_INCOMPLETE: 167433f3623e8124c3a6081b60f68b9d39a19a5840aeChris Forbes return ReportInvalidCommandBuffer(dev_data, cb_state, caller_name); 167533f3623e8124c3a6081b60f68b9d39a19a5840aeChris Forbes 167633f3623e8124c3a6081b60f68b9d39a19a5840aeChris Forbes default: 167733f3623e8124c3a6081b60f68b9d39a19a5840aeChris Forbes return log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 16789b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(cb_state->commandBuffer), __LINE__, DRAWSTATE_NO_BEGIN_COMMAND_BUFFER, "DS", 167933f3623e8124c3a6081b60f68b9d39a19a5840aeChris Forbes "You must call vkBeginCommandBuffer() before this call to %s", caller_name); 16805b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 16815b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 168229f880e9c3c837307e7a19c0ef7275448d483e04Tobin Ehlis 16837e5c0c26004626cf6826dfe2779a738a1f9f1fffTobin Ehlis// For given object struct return a ptr of BASE_NODE type for its wrapping struct 16847e5c0c26004626cf6826dfe2779a738a1f9f1fffTobin EhlisBASE_NODE *GetStateStructPtrFromObject(layer_data *dev_data, VK_OBJECT object_struct) { 16857e5c0c26004626cf6826dfe2779a738a1f9f1fffTobin Ehlis BASE_NODE *base_ptr = nullptr; 16867e5c0c26004626cf6826dfe2779a738a1f9f1fffTobin Ehlis switch (object_struct.type) { 1687ed832a346f5de647635da80bcdb95e29634c70d2Chris Forbes case kVulkanObjectTypeDescriptorSet: { 16889a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis base_ptr = GetSetNode(dev_data, reinterpret_cast<VkDescriptorSet &>(object_struct.handle)); 1689cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 1690cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } 1691ed832a346f5de647635da80bcdb95e29634c70d2Chris Forbes case kVulkanObjectTypeSampler: { 16929a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis base_ptr = GetSamplerState(dev_data, reinterpret_cast<VkSampler &>(object_struct.handle)); 1693cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 1694cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } 1695ed832a346f5de647635da80bcdb95e29634c70d2Chris Forbes case kVulkanObjectTypeQueryPool: { 16969a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis base_ptr = GetQueryPoolNode(dev_data, reinterpret_cast<VkQueryPool &>(object_struct.handle)); 1697cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 1698cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } 1699ed832a346f5de647635da80bcdb95e29634c70d2Chris Forbes case kVulkanObjectTypePipeline: { 1700cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski base_ptr = getPipelineState(dev_data, reinterpret_cast<VkPipeline &>(object_struct.handle)); 1701cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 1702cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } 1703ed832a346f5de647635da80bcdb95e29634c70d2Chris Forbes case kVulkanObjectTypeBuffer: { 17049a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis base_ptr = GetBufferState(dev_data, reinterpret_cast<VkBuffer &>(object_struct.handle)); 1705cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 1706cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } 1707ed832a346f5de647635da80bcdb95e29634c70d2Chris Forbes case kVulkanObjectTypeBufferView: { 17089a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis base_ptr = GetBufferViewState(dev_data, reinterpret_cast<VkBufferView &>(object_struct.handle)); 1709cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 1710cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } 1711ed832a346f5de647635da80bcdb95e29634c70d2Chris Forbes case kVulkanObjectTypeImage: { 17129a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis base_ptr = GetImageState(dev_data, reinterpret_cast<VkImage &>(object_struct.handle)); 1713cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 1714cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } 1715ed832a346f5de647635da80bcdb95e29634c70d2Chris Forbes case kVulkanObjectTypeImageView: { 17169a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis base_ptr = GetImageViewState(dev_data, reinterpret_cast<VkImageView &>(object_struct.handle)); 1717cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 1718cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } 1719ed832a346f5de647635da80bcdb95e29634c70d2Chris Forbes case kVulkanObjectTypeEvent: { 17209a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis base_ptr = GetEventNode(dev_data, reinterpret_cast<VkEvent &>(object_struct.handle)); 1721cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 1722cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } 1723ed832a346f5de647635da80bcdb95e29634c70d2Chris Forbes case kVulkanObjectTypeDescriptorPool: { 17249a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis base_ptr = GetDescriptorPoolState(dev_data, reinterpret_cast<VkDescriptorPool &>(object_struct.handle)); 1725cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 1726cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } 1727ed832a346f5de647635da80bcdb95e29634c70d2Chris Forbes case kVulkanObjectTypeCommandPool: { 17289a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis base_ptr = GetCommandPoolNode(dev_data, reinterpret_cast<VkCommandPool &>(object_struct.handle)); 1729cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 1730cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } 1731ed832a346f5de647635da80bcdb95e29634c70d2Chris Forbes case kVulkanObjectTypeFramebuffer: { 17329a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis base_ptr = GetFramebufferState(dev_data, reinterpret_cast<VkFramebuffer &>(object_struct.handle)); 1733cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 1734cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } 1735ed832a346f5de647635da80bcdb95e29634c70d2Chris Forbes case kVulkanObjectTypeRenderPass: { 17369a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis base_ptr = GetRenderPassState(dev_data, reinterpret_cast<VkRenderPass &>(object_struct.handle)); 1737cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 1738cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } 1739ed832a346f5de647635da80bcdb95e29634c70d2Chris Forbes case kVulkanObjectTypeDeviceMemory: { 17409a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis base_ptr = GetMemObjInfo(dev_data, reinterpret_cast<VkDeviceMemory &>(object_struct.handle)); 1741cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 1742cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } 1743cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski default: 1744cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski // TODO : Any other objects to be handled here? 1745cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski assert(0); 1746cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 1747bf66bca5d96f2721897c5f3100da2df741da9addTobin Ehlis } 17487e5c0c26004626cf6826dfe2779a738a1f9f1fffTobin Ehlis return base_ptr; 17497e5c0c26004626cf6826dfe2779a738a1f9f1fffTobin Ehlis} 17507e5c0c26004626cf6826dfe2779a738a1f9f1fffTobin Ehlis 17517e5c0c26004626cf6826dfe2779a738a1f9f1fffTobin Ehlis// Tie the VK_OBJECT to the cmd buffer which includes: 17527e5c0c26004626cf6826dfe2779a738a1f9f1fffTobin Ehlis// Add object_binding to cmd buffer 17537e5c0c26004626cf6826dfe2779a738a1f9f1fffTobin Ehlis// Add cb_binding to object 17547e5c0c26004626cf6826dfe2779a738a1f9f1fffTobin Ehlisstatic void addCommandBufferBinding(std::unordered_set<GLOBAL_CB_NODE *> *cb_bindings, VK_OBJECT obj, GLOBAL_CB_NODE *cb_node) { 17557e5c0c26004626cf6826dfe2779a738a1f9f1fffTobin Ehlis cb_bindings->insert(cb_node); 17567e5c0c26004626cf6826dfe2779a738a1f9f1fffTobin Ehlis cb_node->object_bindings.insert(obj); 17577e5c0c26004626cf6826dfe2779a738a1f9f1fffTobin Ehlis} 17587e5c0c26004626cf6826dfe2779a738a1f9f1fffTobin Ehlis// For a given object, if cb_node is in that objects cb_bindings, remove cb_node 17597e5c0c26004626cf6826dfe2779a738a1f9f1fffTobin Ehlisstatic void removeCommandBufferBinding(layer_data *dev_data, VK_OBJECT const *object, GLOBAL_CB_NODE *cb_node) { 17607e5c0c26004626cf6826dfe2779a738a1f9f1fffTobin Ehlis BASE_NODE *base_obj = GetStateStructPtrFromObject(dev_data, *object); 1761cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (base_obj) base_obj->cb_bindings.erase(cb_node); 1762bf66bca5d96f2721897c5f3100da2df741da9addTobin Ehlis} 17635b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// Reset the command buffer state 17645b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// Maintain the createInfo and set state to CB_NEW, but clear all other state 17657cb00fa300f2563ae3e8eb506bca912c11216953John Zulaufstatic void ResetCommandBufferState(layer_data *dev_data, const VkCommandBuffer cb) { 1766400cff9fad0e19c80f6c9ed1181795d411a4bec5Tobin Ehlis GLOBAL_CB_NODE *pCB = dev_data->commandBufferMap[cb]; 17675b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pCB) { 1768b3d308d63ba34f40839f009ac83b33962d7f26b2Michael Lentine pCB->in_use.store(0); 17695b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Reset CB state (note that createInfo is not cleared) 17705b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->commandBuffer = cb; 17715b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis memset(&pCB->beginInfo, 0, sizeof(VkCommandBufferBeginInfo)); 17725b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis memset(&pCB->inheritanceInfo, 0, sizeof(VkCommandBufferInheritanceInfo)); 1773b68b13ed4952bce61f6ebb0023542660c26b0562Chris Forbes pCB->hasDrawCmd = false; 17745b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->state = CB_NEW; 17755b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->submitCount = 0; 17765b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->status = 0; 177714494d322787d939bf6a9d3a03fc3938009592e0Chris Forbes pCB->static_status = 0; 1778b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes pCB->viewportMask = 0; 1779b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes pCB->scissorMask = 0; 178093c396d566d722dc5c6f438eae212da0e9337ba3Mark Lobodzinski 178172d66f0c1639cbaca92459498452d06db32d7aefTobin Ehlis for (uint32_t i = 0; i < VK_PIPELINE_BIND_POINT_RANGE_SIZE; ++i) { 178272d66f0c1639cbaca92459498452d06db32d7aefTobin Ehlis pCB->lastBound[i].reset(); 178372d66f0c1639cbaca92459498452d06db32d7aefTobin Ehlis } 178493c396d566d722dc5c6f438eae212da0e9337ba3Mark Lobodzinski 17855b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis memset(&pCB->activeRenderPassBeginInfo, 0, sizeof(pCB->activeRenderPassBeginInfo)); 1786ee691f5c5fa87aac3750454d2bca2cb582e4e817Chris Forbes pCB->activeRenderPass = nullptr; 17875b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->activeSubpassContents = VK_SUBPASS_CONTENTS_INLINE; 17885b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->activeSubpass = 0; 1789e1cc7cf9e8a7808209ecc45df2421f3a494dacccTobin Ehlis pCB->broken_bindings.clear(); 17905b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->waitedEvents.clear(); 17915b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->events.clear(); 1792c7e6bc41aa9c6e5a677b138b9459b252cd3bedf2Mark Lobodzinski pCB->writeEventsBeforeWait.clear(); 17935b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->waitedEventsBeforeQueryReset.clear(); 17945b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->queryToStateMap.clear(); 17955b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->activeQueries.clear(); 17965b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->startedQueries.clear(); 17975b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->imageLayoutMap.clear(); 17985b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->eventToStageMap.clear(); 17995b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->drawData.clear(); 18005b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->currentDrawData.buffers.clear(); 180158b923895f7f6be1b7d48bd4ee3e85e0b3dd0c4dTobin Ehlis pCB->vertex_buffer_used = false; 18025b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->primaryCommandBuffer = VK_NULL_HANDLE; 18031a3660584634742a3297915c94768d73f360e794Chris Forbes // If secondary, invalidate any primary command buffer that may call us. 18041a3660584634742a3297915c94768d73f360e794Chris Forbes if (pCB->createInfo.level == VK_COMMAND_BUFFER_LEVEL_SECONDARY) { 18051a3660584634742a3297915c94768d73f360e794Chris Forbes invalidateCommandBuffers(dev_data, 18061a3660584634742a3297915c94768d73f360e794Chris Forbes pCB->linkedCommandBuffers, 18071a3660584634742a3297915c94768d73f360e794Chris Forbes {HandleToUint64(cb), kVulkanObjectTypeCommandBuffer}); 18081a3660584634742a3297915c94768d73f360e794Chris Forbes } 18091a3660584634742a3297915c94768d73f360e794Chris Forbes 18101a3660584634742a3297915c94768d73f360e794Chris Forbes // Remove reverse command buffer links. 18111a3660584634742a3297915c94768d73f360e794Chris Forbes for (auto pSubCB : pCB->linkedCommandBuffers) { 18121a3660584634742a3297915c94768d73f360e794Chris Forbes pSubCB->linkedCommandBuffers.erase(pCB); 18131a3660584634742a3297915c94768d73f360e794Chris Forbes } 18141a3660584634742a3297915c94768d73f360e794Chris Forbes pCB->linkedCommandBuffers.clear(); 18157a3985a8a9d255dcca9f5992ca2262c7e5df41c6Tobin Ehlis pCB->updateImages.clear(); 18167a3985a8a9d255dcca9f5992ca2262c7e5df41c6Tobin Ehlis pCB->updateBuffers.clear(); 1817400cff9fad0e19c80f6c9ed1181795d411a4bec5Tobin Ehlis clear_cmd_buf_and_mem_references(dev_data, pCB); 1818d807198f24437c1b2478ff1d06a33ce4873a1451Tobin Ehlis pCB->queue_submit_functions.clear(); 181979fc00370d55e7cbfd4052b579120e64b0a1a4beTobin Ehlis pCB->cmd_execute_commands_functions.clear(); 1820b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine pCB->eventUpdates.clear(); 1821d78749ee260a3ce7244cbfd97c11aacc2250f8d3Michael Lentine pCB->queryUpdates.clear(); 182293c396d566d722dc5c6f438eae212da0e9337ba3Mark Lobodzinski 1823bf66bca5d96f2721897c5f3100da2df741da9addTobin Ehlis // Remove object bindings 1824bf66bca5d96f2721897c5f3100da2df741da9addTobin Ehlis for (auto obj : pCB->object_bindings) { 1825bf66bca5d96f2721897c5f3100da2df741da9addTobin Ehlis removeCommandBufferBinding(dev_data, &obj, pCB); 1826bf66bca5d96f2721897c5f3100da2df741da9addTobin Ehlis } 1827a45bdcb94b2fbda36bc191e12cc20218f62fb0e0Tobin Ehlis pCB->object_bindings.clear(); 182893c396d566d722dc5c6f438eae212da0e9337ba3Mark Lobodzinski // Remove this cmdBuffer's reference from each FrameBuffer's CB ref list 182993c396d566d722dc5c6f438eae212da0e9337ba3Mark Lobodzinski for (auto framebuffer : pCB->framebuffers) { 18309a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto fb_state = GetFramebufferState(dev_data, framebuffer); 1831cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (fb_state) fb_state->cb_bindings.erase(pCB); 183293c396d566d722dc5c6f438eae212da0e9337ba3Mark Lobodzinski } 183393c396d566d722dc5c6f438eae212da0e9337ba3Mark Lobodzinski pCB->framebuffers.clear(); 18347003b38da5cc27a063af3c45080f3a35438283eeTobin Ehlis pCB->activeFramebuffer = VK_NULL_HANDLE; 18355b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 18365b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 18375b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 1838dd004f4889b468d675579c61aaf97136d882e1bcChris ForbesCBStatusFlags MakeStaticStateMask(VkPipelineDynamicStateCreateInfo const *ds) { 1839dd004f4889b468d675579c61aaf97136d882e1bcChris Forbes // initially assume everything is static state 1840dd004f4889b468d675579c61aaf97136d882e1bcChris Forbes CBStatusFlags flags = CBSTATUS_ALL_STATE_SET; 1841dd004f4889b468d675579c61aaf97136d882e1bcChris Forbes 1842dd004f4889b468d675579c61aaf97136d882e1bcChris Forbes if (ds) { 1843dd004f4889b468d675579c61aaf97136d882e1bcChris Forbes for (uint32_t i = 0; i < ds->dynamicStateCount; i++) { 1844dd004f4889b468d675579c61aaf97136d882e1bcChris Forbes switch (ds->pDynamicStates[i]) { 1845cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski case VK_DYNAMIC_STATE_LINE_WIDTH: 1846dd004f4889b468d675579c61aaf97136d882e1bcChris Forbes flags &= ~CBSTATUS_LINE_WIDTH_SET; 1847cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 1848cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski case VK_DYNAMIC_STATE_DEPTH_BIAS: 1849dd004f4889b468d675579c61aaf97136d882e1bcChris Forbes flags &= ~CBSTATUS_DEPTH_BIAS_SET; 1850cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 1851cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski case VK_DYNAMIC_STATE_BLEND_CONSTANTS: 1852dd004f4889b468d675579c61aaf97136d882e1bcChris Forbes flags &= ~CBSTATUS_BLEND_CONSTANTS_SET; 1853cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 1854cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski case VK_DYNAMIC_STATE_DEPTH_BOUNDS: 1855dd004f4889b468d675579c61aaf97136d882e1bcChris Forbes flags &= ~CBSTATUS_DEPTH_BOUNDS_SET; 1856cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 1857cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski case VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK: 1858dd004f4889b468d675579c61aaf97136d882e1bcChris Forbes flags &= ~CBSTATUS_STENCIL_READ_MASK_SET; 1859cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 1860cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski case VK_DYNAMIC_STATE_STENCIL_WRITE_MASK: 1861dd004f4889b468d675579c61aaf97136d882e1bcChris Forbes flags &= ~CBSTATUS_STENCIL_WRITE_MASK_SET; 1862cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 1863cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski case VK_DYNAMIC_STATE_STENCIL_REFERENCE: 1864dd004f4889b468d675579c61aaf97136d882e1bcChris Forbes flags &= ~CBSTATUS_STENCIL_REFERENCE_SET; 1865cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 18663c81367b48899b9b1dbdf9813b8aa99f16ccb823Chris Forbes case VK_DYNAMIC_STATE_SCISSOR: 18673c81367b48899b9b1dbdf9813b8aa99f16ccb823Chris Forbes flags &= ~CBSTATUS_SCISSOR_SET; 18683c81367b48899b9b1dbdf9813b8aa99f16ccb823Chris Forbes break; 18693c81367b48899b9b1dbdf9813b8aa99f16ccb823Chris Forbes case VK_DYNAMIC_STATE_VIEWPORT: 18703c81367b48899b9b1dbdf9813b8aa99f16ccb823Chris Forbes flags &= ~CBSTATUS_VIEWPORT_SET; 18713c81367b48899b9b1dbdf9813b8aa99f16ccb823Chris Forbes break; 1872cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski default: 1873cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 18745b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 18755b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 18765b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 1877dd004f4889b468d675579c61aaf97136d882e1bcChris Forbes 1878dd004f4889b468d675579c61aaf97136d882e1bcChris Forbes return flags; 1879dd004f4889b468d675579c61aaf97136d882e1bcChris Forbes} 1880dd004f4889b468d675579c61aaf97136d882e1bcChris Forbes 1881623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski// Flags validation error if the associated call is made inside a render pass. The apiName routine should ONLY be called outside a 1882623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski// render pass. 1883e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlisbool insideRenderPass(const layer_data *dev_data, const GLOBAL_CB_NODE *pCB, const char *apiName, 1884e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis UNIQUE_VALIDATION_ERROR_CODE msgCode) { 1885e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves bool inside = false; 18865b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pCB->activeRenderPass) { 188751ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis inside = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 18889b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pCB->commandBuffer), __LINE__, msgCode, "DS", 1889ff97d1b78192ab7853965cd7a0462273c4813333Mike Weiblen "%s: It is invalid to issue this call inside an active render pass (0x%" PRIxLEAST64 "). %s", apiName, 18909b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pCB->activeRenderPass->renderPass), validation_error_map[msgCode]); 18915b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 18925b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return inside; 18935b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 18945b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 18955b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// Flags validation error if the associated call is made outside a render pass. The apiName 18965b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// routine should ONLY be called inside a render pass. 189751ea774638f432bd8e700ec8291a980f405f429eTobin Ehlisbool outsideRenderPass(const layer_data *dev_data, GLOBAL_CB_NODE *pCB, const char *apiName, UNIQUE_VALIDATION_ERROR_CODE msgCode) { 1898e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves bool outside = false; 18995b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (((pCB->createInfo.level == VK_COMMAND_BUFFER_LEVEL_PRIMARY) && (!pCB->activeRenderPass)) || 19005b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis ((pCB->createInfo.level == VK_COMMAND_BUFFER_LEVEL_SECONDARY) && (!pCB->activeRenderPass) && 19015b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis !(pCB->beginInfo.flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT))) { 190251ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis outside = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 19039b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pCB->commandBuffer), __LINE__, msgCode, "DS", 1904ff97d1b78192ab7853965cd7a0462273c4813333Mike Weiblen "%s: This call must be issued inside an active render pass. %s", apiName, validation_error_map[msgCode]); 19055b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 19065b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return outside; 19075b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 19085b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 1909f0f7d8aa2286bd7516d9fb5c2e58890505e3e5d4Chris Forbesstatic void init_core_validation(instance_layer_data *instance_data, const VkAllocationCallbacks *pAllocator) { 1910b1b606d27e8c4179534d7bbb48ce217429e37414Tobin Ehlis layer_debug_actions(instance_data->report_data, instance_data->logging_callback, pAllocator, "lunarg_core_validation"); 19115b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 19125b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 19137a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlis// For the given ValidationCheck enum, set all relevant instance disabled flags to true 1914b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulaufvoid SetDisabledFlags(instance_layer_data *instance_data, const VkValidationFlagsEXT *val_flags_struct) { 19157a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlis for (uint32_t i = 0; i < val_flags_struct->disabledValidationCheckCount; ++i) { 19167a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlis switch (val_flags_struct->pDisabledValidationChecks[i]) { 191759ae0ccadec962d9ca2cce7584fad6c57c1a4458Tobin Ehlis case VK_VALIDATION_CHECK_SHADERS_EXT: 191859ae0ccadec962d9ca2cce7584fad6c57c1a4458Tobin Ehlis instance_data->disabled.shader_validation = true; 191959ae0ccadec962d9ca2cce7584fad6c57c1a4458Tobin Ehlis break; 19207a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlis case VK_VALIDATION_CHECK_ALL_EXT: 19217a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlis // Set all disabled flags to true 19227a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlis instance_data->disabled.SetAll(true); 19237a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlis break; 19247a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlis default: 19257a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlis break; 19267a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlis } 19277a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlis } 19287a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlis} 19297a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlis 1930bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL CreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, 1931bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkInstance *pInstance) { 19325b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO); 19335b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 19345b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis assert(chain_info->u.pLayerInfo); 19355b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr; 19365b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance)fpGetInstanceProcAddr(NULL, "vkCreateInstance"); 1937cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (fpCreateInstance == NULL) return VK_ERROR_INITIALIZATION_FAILED; 19385b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 19395b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Advance the link info for the next element on the chain 19405b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext; 19415b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 19425b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance); 1943cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (result != VK_SUCCESS) return result; 19445b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 194556e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(*pInstance), instance_layer_data_map); 194656a5ba3e60a723781945959ffc10e2e215350de5Chia-I Wu instance_data->instance = *pInstance; 19479172b640a0ae6a92f24ad0609d92b2c228cde89cChris Forbes layer_init_instance_dispatch_table(*pInstance, &instance_data->dispatch_table, fpGetInstanceProcAddr); 19489172b640a0ae6a92f24ad0609d92b2c228cde89cChris Forbes instance_data->report_data = debug_report_create_instance( 19499172b640a0ae6a92f24ad0609d92b2c228cde89cChris Forbes &instance_data->dispatch_table, *pInstance, pCreateInfo->enabledExtensionCount, pCreateInfo->ppEnabledExtensionNames); 19500cf009a4e2a5c22e4645f343c7a998f188a22015Chris Forbes instance_data->extensions.InitFromInstanceCreateInfo(pCreateInfo); 1951b1b606d27e8c4179534d7bbb48ce217429e37414Tobin Ehlis init_core_validation(instance_data, pAllocator); 1952825ac70f99460ccb9494d34f93d8ee7ec303e5deMark Lobodzinski 19535b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis ValidateLayerOrdering(*pCreateInfo); 19547a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlis // Parse any pNext chains 1955b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf const auto *validation_flags_ext = lvl_find_in_chain<VkValidationFlagsEXT>(pCreateInfo->pNext); 1956b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf if (validation_flags_ext) { 1957b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf SetDisabledFlags(instance_data, validation_flags_ext); 19587a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlis } 19595b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 19605b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 19615b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 19625b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 196325002b75574f762c62b1a00a595bab04ebb25452Mark Lobodzinski// Hook DestroyInstance to remove tableInstanceMap entry 196489d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR void VKAPI_CALL DestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) { 19655b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // TODOSC : Shouldn't need any customization here 19665b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis dispatch_key key = get_dispatch_key(instance); 19675b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // TBD: Need any locking this early, in case this function is called at the 19685b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // same time by more than one thread? 196956e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis instance_layer_data *instance_data = GetLayerDataPtr(key, instance_layer_data_map); 19709172b640a0ae6a92f24ad0609d92b2c228cde89cChris Forbes instance_data->dispatch_table.DestroyInstance(instance, pAllocator); 19715b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 1972ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 19735b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Clean up logging callback, if any 19749172b640a0ae6a92f24ad0609d92b2c228cde89cChris Forbes while (instance_data->logging_callback.size() > 0) { 19759172b640a0ae6a92f24ad0609d92b2c228cde89cChris Forbes VkDebugReportCallbackEXT callback = instance_data->logging_callback.back(); 19769172b640a0ae6a92f24ad0609d92b2c228cde89cChris Forbes layer_destroy_msg_callback(instance_data->report_data, callback, pAllocator); 19779172b640a0ae6a92f24ad0609d92b2c228cde89cChris Forbes instance_data->logging_callback.pop_back(); 19785b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 19795b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 19809172b640a0ae6a92f24ad0609d92b2c228cde89cChris Forbes layer_debug_report_destroy_instance(instance_data->report_data); 1981d27b109eaf4da0a5514dc2ae2f3dd6a76976ba0dGabríel Arthúr Pétursson FreeLayerDataPtr(key, instance_layer_data_map); 19825b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 19835b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 19845770f8ad21c40b2475201e73e9368a899b6886d0Petr Krausstatic bool ValidatePhysicalDeviceQueueFamily(instance_layer_data *instance_data, const PHYSICAL_DEVICE_STATE *pd_state, 19855770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus uint32_t requested_queue_family, int32_t err_code, const char *cmd_name, 19865770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus const char *queue_family_var_name, const char *vu_note = nullptr) { 19873251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 19885770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 19895770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus if (!vu_note) vu_note = validation_error_map[err_code]; 19905770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 19915770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus const char *conditional_ext_cmd = 1992d4eaca34eca7f4b4e34190c441a579347bb2016aMark Lobodzinski instance_data->extensions.vk_khr_get_physical_device_properties_2 ? "or vkGetPhysicalDeviceQueueFamilyProperties2KHR" : ""; 19935770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 19945770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus std::string count_note = (UNCALLED == pd_state->vkGetPhysicalDeviceQueueFamilyPropertiesState) 19955770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus ? "the pQueueFamilyPropertyCount was never obtained" 19965770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus : "i.e. is not less than " + std::to_string(pd_state->queue_family_count); 19975770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 19985770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus if (requested_queue_family >= pd_state->queue_family_count) { 19993251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 20009b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pd_state->phys_device), __LINE__, err_code, "DL", 20019b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "%s: %s (= %" PRIu32 20029b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus ") is not less than any previously obtained pQueueFamilyPropertyCount from " 20035770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus "vkGetPhysicalDeviceQueueFamilyProperties%s (%s). %s", 20045770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus cmd_name, queue_family_var_name, requested_queue_family, conditional_ext_cmd, count_note.c_str(), vu_note); 20055770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus } 20065770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus return skip; 20075770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus} 20085770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 20095770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus// Verify VkDeviceQueueCreateInfos 20105770f8ad21c40b2475201e73e9368a899b6886d0Petr Krausstatic bool ValidateDeviceQueueCreateInfos(instance_layer_data *instance_data, const PHYSICAL_DEVICE_STATE *pd_state, 20115770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus uint32_t info_count, const VkDeviceQueueCreateInfo *infos) { 20125770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus bool skip = false; 20135770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 20145770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus for (uint32_t i = 0; i < info_count; ++i) { 20155770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus const auto requested_queue_family = infos[i].queueFamilyIndex; 20165770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 20175770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus // Verify that requested queue family is known to be valid at this point in time 20185770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus std::string queue_family_var_name = "pCreateInfo->pQueueCreateInfos[" + std::to_string(i) + "].queueFamilyIndex"; 2019315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidatePhysicalDeviceQueueFamily(instance_data, pd_state, requested_queue_family, VALIDATION_ERROR_06c002fa, 20205770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus "vkCreateDevice", queue_family_var_name.c_str()); 20215770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 20225770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus // Verify that requested queue count of queue family is known to be valid at this point in time 20235770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus if (requested_queue_family < pd_state->queue_family_count) { 20245770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus const auto requested_queue_count = infos[i].queueCount; 20255770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus const auto queue_family_props_count = pd_state->queue_family_properties.size(); 20265770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus const bool queue_family_has_props = requested_queue_family < queue_family_props_count; 2027d4eaca34eca7f4b4e34190c441a579347bb2016aMark Lobodzinski const char *conditional_ext_cmd = instance_data->extensions.vk_khr_get_physical_device_properties_2 20285770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus ? "or vkGetPhysicalDeviceQueueFamilyProperties2KHR" 20295770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus : ""; 20305770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus std::string count_note = 20315770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus !queue_family_has_props 20325770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus ? "the pQueueFamilyProperties[" + std::to_string(requested_queue_family) + "] was never obtained" 20335770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus : "i.e. is not less than or equal to " + 20345770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus std::to_string(pd_state->queue_family_properties[requested_queue_family].queueCount); 20355770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 20365770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus if (!queue_family_has_props || 20375770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus requested_queue_count > pd_state->queue_family_properties[requested_queue_family].queueCount) { 20383251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 20399b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, HandleToUint64(pd_state->phys_device), __LINE__, 2040315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_06c002fc, "DL", 20419b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "vkCreateDevice: pCreateInfo->pQueueCreateInfos[%" PRIu32 "].queueCount (=%" PRIu32 20429b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus ") is not " 20435770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus "less than or equal to available queue count for this " 20449b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "pCreateInfo->pQueueCreateInfos[%" PRIu32 "].queueFamilyIndex} (=%" PRIu32 20459b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus ") obtained previously " 20465770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus "from vkGetPhysicalDeviceQueueFamilyProperties%s (%s). %s", 20475770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus i, requested_queue_count, i, requested_queue_family, conditional_ext_cmd, count_note.c_str(), 2048315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_06c002fc]); 2049838e3917bc1a0479174dd753b5c28b8b2cf1954dMark Lobodzinski } 2050838e3917bc1a0479174dd753b5c28b8b2cf1954dMark Lobodzinski } 2051838e3917bc1a0479174dd753b5c28b8b2cf1954dMark Lobodzinski } 20525770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 20533251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 2054838e3917bc1a0479174dd753b5c28b8b2cf1954dMark Lobodzinski} 2055838e3917bc1a0479174dd753b5c28b8b2cf1954dMark Lobodzinski 2056f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski// Verify that features have been queried and that they are available 20575770f8ad21c40b2475201e73e9368a899b6886d0Petr Krausstatic bool ValidateRequestedFeatures(instance_layer_data *instance_data, const PHYSICAL_DEVICE_STATE *pd_state, 2058bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkPhysicalDeviceFeatures *requested_features) { 20593251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 2060f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski 20615770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus const VkBool32 *actual = reinterpret_cast<const VkBool32 *>(&pd_state->features); 2062825ac70f99460ccb9494d34f93d8ee7ec303e5deMark Lobodzinski const VkBool32 *requested = reinterpret_cast<const VkBool32 *>(requested_features); 2063f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski // TODO : This is a nice, compact way to loop through struct, but a bad way to report issues 2064f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski // Need to provide the struct member name with the issue. To do that seems like we'll 2065f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski // have to loop through each struct member which should be done w/ codegen to keep in synch. 2066f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski uint32_t errors = 0; 2067f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski uint32_t total_bools = sizeof(VkPhysicalDeviceFeatures) / sizeof(VkBool32); 2068f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski for (uint32_t i = 0; i < total_bools; i++) { 2069f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski if (requested[i] > actual[i]) { 20705770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus skip |= log_msg(instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 20715770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_INVALID_FEATURE_REQUESTED, "DL", 207291c2ca58e9ab21299931a4eadf03baf93118242bMark Lobodzinski "While calling vkCreateDevice(), requesting feature '%s' in VkPhysicalDeviceFeatures struct, " 20733251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "which is not available on this device.", 207491c2ca58e9ab21299931a4eadf03baf93118242bMark Lobodzinski GetPhysDevFeatureString(i)); 2075f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski errors++; 2076f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski } 2077f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski } 20785770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus if (errors && (UNCALLED == pd_state->vkGetPhysicalDeviceFeaturesState)) { 2079f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski // If user didn't request features, notify them that they should 2080f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski // TODO: Verify this against the spec. I believe this is an invalid use of the API and should return an error 20815770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus skip |= log_msg(instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 20825770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 0, __LINE__, DEVLIMITS_INVALID_FEATURE_REQUESTED, "DL", 20833251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "You requested features that are unavailable on this device. You should first query feature " 20843251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "availability by calling vkGetPhysicalDeviceFeatures()."); 2085f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski } 20863251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 2087f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski} 2088f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski 208989d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR VkResult VKAPI_CALL CreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo *pCreateInfo, 209089d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I Wu const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) { 20913251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 20925770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(gpu), instance_layer_data_map); 2093f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 2094ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 2095f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus auto pd_state = GetPhysicalDeviceState(instance_data, gpu); 2096f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 2097f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus // TODO: object_tracker should perhaps do this instead 2098f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus // and it does not seem to currently work anyway -- the loader just crashes before this point 2099f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus if (!GetPhysicalDeviceState(instance_data, gpu)) { 2100f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus skip |= log_msg(instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 2101f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 0, __LINE__, DEVLIMITS_MUST_QUERY_COUNT, "DL", 2102f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus "Invalid call to vkCreateDevice() w/o first calling vkEnumeratePhysicalDevices()."); 2103f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus } 2104f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski 2105f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski // Check that any requested features are available 210656514e97bb296ac4612cae610a16cd46ac152dd8John Zulauf // The enabled features can come from either pEnabledFeatures, or from the pNext chain 210756514e97bb296ac4612cae610a16cd46ac152dd8John Zulauf const VkPhysicalDeviceFeatures *enabled_features_found = pCreateInfo->pEnabledFeatures; 210856514e97bb296ac4612cae610a16cd46ac152dd8John Zulauf if (nullptr == enabled_features_found) { 2109b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf const auto *features2 = lvl_find_in_chain<VkPhysicalDeviceFeatures2KHR>(pCreateInfo->pNext); 2110b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf if (features2) { 2111b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf enabled_features_found = &(features2->features); 211256514e97bb296ac4612cae610a16cd46ac152dd8John Zulauf } 211356514e97bb296ac4612cae610a16cd46ac152dd8John Zulauf } 211456514e97bb296ac4612cae610a16cd46ac152dd8John Zulauf 211556514e97bb296ac4612cae610a16cd46ac152dd8John Zulauf if (enabled_features_found) { 211656514e97bb296ac4612cae610a16cd46ac152dd8John Zulauf skip |= ValidateRequestedFeatures(instance_data, pd_state, enabled_features_found); 2117f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski } 211856514e97bb296ac4612cae610a16cd46ac152dd8John Zulauf 21195770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus skip |= 21205770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus ValidateDeviceQueueCreateInfos(instance_data, pd_state, pCreateInfo->queueCreateInfoCount, pCreateInfo->pQueueCreateInfos); 2121f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski 21225770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 21231d659b4113b77a95325df10d602a03f1e7abf8b7Mark Mueller 21245b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO); 21255b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 21265b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis assert(chain_info->u.pLayerInfo); 21275b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr; 21285b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr; 212956e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice)fpGetInstanceProcAddr(instance_data->instance, "vkCreateDevice"); 21305b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (fpCreateDevice == NULL) { 21315b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return VK_ERROR_INITIALIZATION_FAILED; 21325b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 21335b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 21345b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Advance the link info for the next element on the chain 21355b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext; 21365b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 21375770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus lock.unlock(); 21385770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 21395b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis VkResult result = fpCreateDevice(gpu, pCreateInfo, pAllocator, pDevice); 21405b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (result != VK_SUCCESS) { 21415b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 21425b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 21435b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 21445770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus lock.lock(); 214556e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *device_data = GetLayerDataPtr(get_dispatch_key(*pDevice), layer_data_map); 21465b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 214756e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis device_data->instance_data = instance_data; 21485b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Setup device dispatch table 214956e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_init_device_dispatch_table(*pDevice, &device_data->dispatch_table, fpGetDeviceProcAddr); 215056e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis device_data->device = *pDevice; 2151ec85232c4d8d9ddf7d2ae57cb8203c5ab52c1106Mark Lobodzinski // Save PhysicalDevice handle 215256e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis device_data->physical_device = gpu; 21535b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 215456e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis device_data->report_data = layer_debug_report_create_device(instance_data->report_data, *pDevice); 2155a149f1a0cb39b48b19822c8cf9ef2426cd2251dfMark Lobodzinski device_data->extensions.InitFromDeviceCreateInfo(&instance_data->extensions, pCreateInfo); 2156d4eaca34eca7f4b4e34190c441a579347bb2016aMark Lobodzinski 21575b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Get physical device limits for this device 215856e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis instance_data->dispatch_table.GetPhysicalDeviceProperties(gpu, &(device_data->phys_dev_properties.properties)); 21595b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis uint32_t count; 216056e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis instance_data->dispatch_table.GetPhysicalDeviceQueueFamilyProperties(gpu, &count, nullptr); 216156e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis device_data->phys_dev_properties.queue_family_properties.resize(count); 216256e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis instance_data->dispatch_table.GetPhysicalDeviceQueueFamilyProperties( 216356e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis gpu, &count, &device_data->phys_dev_properties.queue_family_properties[0]); 21645b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // TODO: device limits should make sure these are compatible 216556514e97bb296ac4612cae610a16cd46ac152dd8John Zulauf if (enabled_features_found) { 216656514e97bb296ac4612cae610a16cd46ac152dd8John Zulauf device_data->enabled_features = *enabled_features_found; 21675b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } else { 216856e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis memset(&device_data->enabled_features, 0, sizeof(VkPhysicalDeviceFeatures)); 21695b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 2170e47dbc3f3340fa177d877a67b2adb76a570027e5Mark Lobodzinski // Store physical device properties and physical device mem limits into device layer_data structs 217156e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis instance_data->dispatch_table.GetPhysicalDeviceMemoryProperties(gpu, &device_data->phys_dev_mem_props); 217256e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis instance_data->dispatch_table.GetPhysicalDeviceProperties(gpu, &device_data->phys_dev_props); 2173b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 21745b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 21755b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis ValidateLayerOrdering(*pCreateInfo); 21765b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 21775b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 21785b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 21795b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 21805b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// prototype 218189d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR void VKAPI_CALL DestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) { 21825b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // TODOSC : Shouldn't need any customization here 21835b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis dispatch_key key = get_dispatch_key(device); 218456e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(key, layer_data_map); 21855b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Free all the memory 2186ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 218763cddeb5593a0ead9ecd5f74d05f506b37d7ac66Chris Forbes dev_data->pipelineMap.clear(); 2188fb13c2c4174108223d9f8e43084020eb09115ed6Chris Forbes dev_data->renderPassMap.clear(); 21899b36ac77fbf55bd7ffdeb9020f2277fff3a5a807Chris Forbes for (auto ii = dev_data->commandBufferMap.begin(); ii != dev_data->commandBufferMap.end(); ++ii) { 21909b36ac77fbf55bd7ffdeb9020f2277fff3a5a807Chris Forbes delete (*ii).second; 21919b36ac77fbf55bd7ffdeb9020f2277fff3a5a807Chris Forbes } 21929b36ac77fbf55bd7ffdeb9020f2277fff3a5a807Chris Forbes dev_data->commandBufferMap.clear(); 2193f13bee0887f3c3d1d597c82869864be3be836737Tobin Ehlis // This will also delete all sets in the pool & remove them from setMap 21945b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis deletePools(dev_data); 2195f13bee0887f3c3d1d597c82869864be3be836737Tobin Ehlis // All sets should be removed 2196f13bee0887f3c3d1d597c82869864be3be836737Tobin Ehlis assert(dev_data->setMap.empty()); 2197fce842878e9ddcc7f37e1c457a4b018d52358087Tobin Ehlis dev_data->descriptorSetLayoutMap.clear(); 21985b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis dev_data->imageViewMap.clear(); 21995b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis dev_data->imageMap.clear(); 22005b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis dev_data->imageSubresourceMap.clear(); 22015b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis dev_data->imageLayoutMap.clear(); 22025b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis dev_data->bufferViewMap.clear(); 22035b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis dev_data->bufferMap.clear(); 22041344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis // Queues persist until device is destroyed 22051344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis dev_data->queueMap.clear(); 22065b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Report any memory leaks 22075b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis layer_debug_report_destroy_device(device); 2208b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 22095b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 22105b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis#if DISPATCH_MAP_DEBUG 2211414e9a4117b500eac650d8b8f01a6e1b22d05aaeMark Mueller fprintf(stderr, "Device: 0x%p, key: 0x%p\n", device, key); 22125b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis#endif 2213d27b109eaf4da0a5514dc2ae2f3dd6a76976ba0dGabríel Arthúr Pétursson 2214d27b109eaf4da0a5514dc2ae2f3dd6a76976ba0dGabríel Arthúr Pétursson dev_data->dispatch_table.DestroyDevice(device, pAllocator); 2215d27b109eaf4da0a5514dc2ae2f3dd6a76976ba0dGabríel Arthúr Pétursson FreeLayerDataPtr(key, layer_data_map); 22165b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 22175b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 22185b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlisstatic const VkExtensionProperties instance_extensions[] = {{VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION}}; 22195b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 2220208aecf4cb59762be429488d7d4484f138c2cd81Tobin Ehlis// For given stage mask, if Geometry shader stage is on w/o GS being enabled, report geo_error_id 2221208aecf4cb59762be429488d7d4484f138c2cd81Tobin Ehlis// and if Tessellation Control or Evaluation shader stages are on w/o TS being enabled, report tess_error_id 2222208aecf4cb59762be429488d7d4484f138c2cd81Tobin Ehlisstatic bool ValidateStageMaskGsTsEnables(layer_data *dev_data, VkPipelineStageFlags stageMask, const char *caller, 2223208aecf4cb59762be429488d7d4484f138c2cd81Tobin Ehlis UNIQUE_VALIDATION_ERROR_CODE geo_error_id, UNIQUE_VALIDATION_ERROR_CODE tess_error_id) { 2224208aecf4cb59762be429488d7d4484f138c2cd81Tobin Ehlis bool skip = false; 2225208aecf4cb59762be429488d7d4484f138c2cd81Tobin Ehlis if (!dev_data->enabled_features.geometryShader && (stageMask & VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT)) { 2226208aecf4cb59762be429488d7d4484f138c2cd81Tobin Ehlis skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 2227cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski geo_error_id, "DL", 2228cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "%s call includes a stageMask with VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT bit set when " 2229cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "device does not have geometryShader feature enabled. %s", 2230208aecf4cb59762be429488d7d4484f138c2cd81Tobin Ehlis caller, validation_error_map[geo_error_id]); 2231208aecf4cb59762be429488d7d4484f138c2cd81Tobin Ehlis } 2232208aecf4cb59762be429488d7d4484f138c2cd81Tobin Ehlis if (!dev_data->enabled_features.tessellationShader && 2233208aecf4cb59762be429488d7d4484f138c2cd81Tobin Ehlis (stageMask & (VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT | VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT))) { 2234208aecf4cb59762be429488d7d4484f138c2cd81Tobin Ehlis skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 2235cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski tess_error_id, "DL", 2236cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "%s call includes a stageMask with VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT " 2237cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "and/or VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT bit(s) set when device " 2238cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "does not have tessellationShader feature enabled. %s", 2239208aecf4cb59762be429488d7d4484f138c2cd81Tobin Ehlis caller, validation_error_map[tess_error_id]); 2240208aecf4cb59762be429488d7d4484f138c2cd81Tobin Ehlis } 2241208aecf4cb59762be429488d7d4484f138c2cd81Tobin Ehlis return skip; 2242208aecf4cb59762be429488d7d4484f138c2cd81Tobin Ehlis} 2243208aecf4cb59762be429488d7d4484f138c2cd81Tobin Ehlis 2244ad97d033b614e6265aaa8c8f0d21a044982d4de7Jeremy Hayes// Loop through bound objects and increment their in_use counts. 2245ad97d033b614e6265aaa8c8f0d21a044982d4de7Jeremy Hayesstatic void IncrementBoundObjects(layer_data *dev_data, GLOBAL_CB_NODE const *cb_node) { 2246a45bdcb94b2fbda36bc191e12cc20218f62fb0e0Tobin Ehlis for (auto obj : cb_node->object_bindings) { 2247a317e7593a0fe227635fc8241908471acb36c952Chris Forbes auto base_obj = GetStateStructPtrFromObject(dev_data, obj); 2248ad97d033b614e6265aaa8c8f0d21a044982d4de7Jeremy Hayes if (base_obj) { 224951920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour base_obj->in_use.fetch_add(1); 2250162dac96d3883e8fffaa1f988043f62c06662d2eTobin Ehlis } 2251a45bdcb94b2fbda36bc191e12cc20218f62fb0e0Tobin Ehlis } 2252a45bdcb94b2fbda36bc191e12cc20218f62fb0e0Tobin Ehlis} 22535b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// Track which resources are in-flight by atomically incrementing their "in_use" count 225451920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbourstatic void incrementResources(layer_data *dev_data, GLOBAL_CB_NODE *cb_node) { 225551920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour cb_node->submitCount++; 22569a61300d900fe3e43e9a03c7fa6876934bc1264eTobin Ehlis cb_node->in_use.fetch_add(1); 2257a2d08a743ac1178e4d46da4d41c73fb73b5e79d7Chris Forbes 2258a45bdcb94b2fbda36bc191e12cc20218f62fb0e0Tobin Ehlis // First Increment for all "generic" objects bound to cmd buffer, followed by special-case objects below 2259ad97d033b614e6265aaa8c8f0d21a044982d4de7Jeremy Hayes IncrementBoundObjects(dev_data, cb_node); 2260a45bdcb94b2fbda36bc191e12cc20218f62fb0e0Tobin Ehlis // TODO : We should be able to remove the NULL look-up checks from the code below as long as 2261a45bdcb94b2fbda36bc191e12cc20218f62fb0e0Tobin Ehlis // all the corresponding cases are verified to cause CB_INVALID state and the CB_INVALID state 2262a45bdcb94b2fbda36bc191e12cc20218f62fb0e0Tobin Ehlis // should then be flagged prior to calling this function 22639a61300d900fe3e43e9a03c7fa6876934bc1264eTobin Ehlis for (auto drawDataElement : cb_node->drawData) { 22645b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (auto buffer : drawDataElement.buffers) { 22659a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto buffer_state = GetBufferState(dev_data, buffer); 226651920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour if (buffer_state) { 22675cca7b0a90e0b6fe1cc28ddbe9037c3ce3f3ee13Tobin Ehlis buffer_state->in_use.fetch_add(1); 22685b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 22695b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 22705b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 22719a61300d900fe3e43e9a03c7fa6876934bc1264eTobin Ehlis for (auto event : cb_node->writeEventsBeforeWait) { 22729a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto event_state = GetEventNode(dev_data, event); 2273cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (event_state) event_state->write_in_use++; 2274c1eb2a3736e03aaa15b849d217fd963021dc9780Michael Lentine } 22755b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 22765b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 2277b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlis// Note: This function assumes that the global lock is held by the calling thread. 2278b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlis// For the given queue, verify the queue state up to the given seq number. 2279b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlis// Currently the only check is to make sure that if there are events to be waited on prior to 2280b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlis// a QueryReset, make sure that all such events have been signalled. 2281d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbesstatic bool VerifyQueueStateToSeq(layer_data *dev_data, QUEUE_STATE *initial_queue, uint64_t initial_seq) { 2282b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlis bool skip = false; 2283d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes 2284d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes // sequence number we want to validate up to, per queue 2285d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes std::unordered_map<QUEUE_STATE *, uint64_t> target_seqs { { initial_queue, initial_seq } }; 2286d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes // sequence number we've completed validation for, per queue 2287d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes std::unordered_map<QUEUE_STATE *, uint64_t> done_seqs; 2288d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes std::vector<QUEUE_STATE *> worklist { initial_queue }; 2289d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes 2290d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes while (worklist.size()) { 2291d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes auto queue = worklist.back(); 2292d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes worklist.pop_back(); 2293d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes 2294d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes auto target_seq = target_seqs[queue]; 2295d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes auto seq = std::max(done_seqs[queue], queue->seq); 2296d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes auto sub_it = queue->submissions.begin() + int(seq - queue->seq); // seq >= queue->seq 2297d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes 2298d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes for (; seq < target_seq; ++sub_it, ++seq) { 2299d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes for (auto &wait : sub_it->waitSemaphores) { 2300d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes auto other_queue = GetQueueState(dev_data, wait.queue); 2301d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes 2302d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes if (other_queue == queue) 2303d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes continue; // semaphores /always/ point backwards, so no point here. 2304d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes 2305d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes auto other_target_seq = std::max(target_seqs[other_queue], wait.seq); 2306d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes auto other_done_seq = std::max(done_seqs[other_queue], other_queue->seq); 2307d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes 2308d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes // if this wait is for another queue, and covers new sequence 2309d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes // numbers beyond what we've already validated, mark the new 2310d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes // target seq and (possibly-re)add the queue to the worklist. 2311d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes if (other_done_seq < other_target_seq) { 2312d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes target_seqs[other_queue] = other_target_seq; 2313d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes worklist.push_back(other_queue); 2314d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes } 2315d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes } 2316d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes 2317d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes for (auto cb : sub_it->cbs) { 2318d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes auto cb_node = GetCBNode(dev_data, cb); 2319d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes if (cb_node) { 2320d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes for (auto queryEventsPair : cb_node->waitedEventsBeforeQueryReset) { 2321d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes for (auto event : queryEventsPair.second) { 2322d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes if (dev_data->eventMap[event].needsSignaled) { 2323d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 2324d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT, 0, 0, DRAWSTATE_INVALID_QUERY, "DS", 2325d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes "Cannot get query results on queryPool 0x%" PRIx64 2326d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes " with index %d which was guarded by unsignaled event 0x%" PRIx64 ".", 23279b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(queryEventsPair.first.pool), queryEventsPair.first.index, 23289b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(event)); 2329d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes } 2330b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlis } 2331b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlis } 2332b3d308d63ba34f40839f009ac83b33962d7f26b2Michael Lentine } 2333b3d308d63ba34f40839f009ac83b33962d7f26b2Michael Lentine } 2334b3d308d63ba34f40839f009ac83b33962d7f26b2Michael Lentine } 2335d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes 2336d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes // finally mark the point we've now validated this queue to. 2337d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes done_seqs[queue] = seq; 233892b1701c552e96e96fdbbb77e4b106a9526f3b8cTobin Ehlis } 2339d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes 2340b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlis return skip; 2341b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlis} 2342b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlis 2343b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlis// When the given fence is retired, verify outstanding queue operations through the point of the fence 2344b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlisstatic bool VerifyQueueStateToFence(layer_data *dev_data, VkFence fence) { 23459a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto fence_state = GetFenceNode(dev_data, fence); 2346804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt if (fence_state->scope == kSyncScopeInternal && VK_NULL_HANDLE != fence_state->signaler.first) { 23479a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis return VerifyQueueStateToSeq(dev_data, GetQueueState(dev_data, fence_state->signaler.first), fence_state->signaler.second); 2348b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlis } 2349b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlis return false; 2350b3d308d63ba34f40839f009ac83b33962d7f26b2Michael Lentine} 23517d33205c3aa4aba751a2c07f956634aac616f916Chris Forbes 2352a45bdcb94b2fbda36bc191e12cc20218f62fb0e0Tobin Ehlis// Decrement in-use count for objects bound to command buffer 23532f8cbf3b166e175174877a59929902e005953d6dTobin Ehlisstatic void DecrementBoundResources(layer_data *dev_data, GLOBAL_CB_NODE const *cb_node) { 235400e8ce2e6c1c191758f7b7c15eeaf350e5b4a3b6Tobin Ehlis BASE_NODE *base_obj = nullptr; 2355a45bdcb94b2fbda36bc191e12cc20218f62fb0e0Tobin Ehlis for (auto obj : cb_node->object_bindings) { 23567e5c0c26004626cf6826dfe2779a738a1f9f1fffTobin Ehlis base_obj = GetStateStructPtrFromObject(dev_data, obj); 235700e8ce2e6c1c191758f7b7c15eeaf350e5b4a3b6Tobin Ehlis if (base_obj) { 235800e8ce2e6c1c191758f7b7c15eeaf350e5b4a3b6Tobin Ehlis base_obj->in_use.fetch_sub(1); 235900e8ce2e6c1c191758f7b7c15eeaf350e5b4a3b6Tobin Ehlis } 2360a45bdcb94b2fbda36bc191e12cc20218f62fb0e0Tobin Ehlis } 2361a45bdcb94b2fbda36bc191e12cc20218f62fb0e0Tobin Ehlis} 2362da8f07baf262972eb3e719fa07b073c180dff157Chris Forbes 236336c3a4fe8455762d2dc0b2b9ece44675a3ee8d97Tobin Ehlisstatic void RetireWorkOnQueue(layer_data *dev_data, QUEUE_STATE *pQueue, uint64_t seq) { 23649867daedbf52debc77d6568162ee21e071699b80Chris Forbes std::unordered_map<VkQueue, uint64_t> otherQueueSeqs; 23659867daedbf52debc77d6568162ee21e071699b80Chris Forbes 23669867daedbf52debc77d6568162ee21e071699b80Chris Forbes // Roll this queue forward, one submission at a time. 23679867daedbf52debc77d6568162ee21e071699b80Chris Forbes while (pQueue->seq < seq) { 2368bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski auto &submission = pQueue->submissions.front(); 23699867daedbf52debc77d6568162ee21e071699b80Chris Forbes 2370bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski for (auto &wait : submission.waitSemaphores) { 23719a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pSemaphore = GetSemaphoreNode(dev_data, wait.semaphore); 2372c91c376e7f18eba22f2996e514eb4714417fb343Mark Lobodzinski if (pSemaphore) { 2373c91c376e7f18eba22f2996e514eb4714417fb343Mark Lobodzinski pSemaphore->in_use.fetch_sub(1); 2374c91c376e7f18eba22f2996e514eb4714417fb343Mark Lobodzinski } 2375bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski auto &lastSeq = otherQueueSeqs[wait.queue]; 23769867daedbf52debc77d6568162ee21e071699b80Chris Forbes lastSeq = std::max(lastSeq, wait.seq); 2377da8f07baf262972eb3e719fa07b073c180dff157Chris Forbes } 2378cdb1ea0ff0d966dda02543468377eae93b9e2f8fChris Forbes 2379bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski for (auto &semaphore : submission.signalSemaphores) { 23809a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pSemaphore = GetSemaphoreNode(dev_data, semaphore); 2381c91c376e7f18eba22f2996e514eb4714417fb343Mark Lobodzinski if (pSemaphore) { 2382c91c376e7f18eba22f2996e514eb4714417fb343Mark Lobodzinski pSemaphore->in_use.fetch_sub(1); 2383c91c376e7f18eba22f2996e514eb4714417fb343Mark Lobodzinski } 23849867daedbf52debc77d6568162ee21e071699b80Chris Forbes } 2385cdb1ea0ff0d966dda02543468377eae93b9e2f8fChris Forbes 238606d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt for (auto &semaphore : submission.externalSemaphores) { 238706d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt auto pSemaphore = GetSemaphoreNode(dev_data, semaphore); 238806d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt if (pSemaphore) { 238906d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt pSemaphore->in_use.fetch_sub(1); 239006d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt } 239106d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt } 239206d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt 23939867daedbf52debc77d6568162ee21e071699b80Chris Forbes for (auto cb : submission.cbs) { 23949a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto cb_node = GetCBNode(dev_data, cb); 2395c91c376e7f18eba22f2996e514eb4714417fb343Mark Lobodzinski if (!cb_node) { 2396c91c376e7f18eba22f2996e514eb4714417fb343Mark Lobodzinski continue; 2397c91c376e7f18eba22f2996e514eb4714417fb343Mark Lobodzinski } 2398a45bdcb94b2fbda36bc191e12cc20218f62fb0e0Tobin Ehlis // First perform decrement on general case bound objects 23999a61300d900fe3e43e9a03c7fa6876934bc1264eTobin Ehlis DecrementBoundResources(dev_data, cb_node); 24009a61300d900fe3e43e9a03c7fa6876934bc1264eTobin Ehlis for (auto drawDataElement : cb_node->drawData) { 24019867daedbf52debc77d6568162ee21e071699b80Chris Forbes for (auto buffer : drawDataElement.buffers) { 24029a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto buffer_state = GetBufferState(dev_data, buffer); 24035cca7b0a90e0b6fe1cc28ddbe9037c3ce3f3ee13Tobin Ehlis if (buffer_state) { 24045cca7b0a90e0b6fe1cc28ddbe9037c3ce3f3ee13Tobin Ehlis buffer_state->in_use.fetch_sub(1); 24059867daedbf52debc77d6568162ee21e071699b80Chris Forbes } 24069867daedbf52debc77d6568162ee21e071699b80Chris Forbes } 2407da8f07baf262972eb3e719fa07b073c180dff157Chris Forbes } 24089a61300d900fe3e43e9a03c7fa6876934bc1264eTobin Ehlis for (auto event : cb_node->writeEventsBeforeWait) { 24099867daedbf52debc77d6568162ee21e071699b80Chris Forbes auto eventNode = dev_data->eventMap.find(event); 24109867daedbf52debc77d6568162ee21e071699b80Chris Forbes if (eventNode != dev_data->eventMap.end()) { 24119867daedbf52debc77d6568162ee21e071699b80Chris Forbes eventNode->second.write_in_use--; 24129867daedbf52debc77d6568162ee21e071699b80Chris Forbes } 24139867daedbf52debc77d6568162ee21e071699b80Chris Forbes } 24149a61300d900fe3e43e9a03c7fa6876934bc1264eTobin Ehlis for (auto queryStatePair : cb_node->queryToStateMap) { 24159867daedbf52debc77d6568162ee21e071699b80Chris Forbes dev_data->queryToStateMap[queryStatePair.first] = queryStatePair.second; 24169867daedbf52debc77d6568162ee21e071699b80Chris Forbes } 24179a61300d900fe3e43e9a03c7fa6876934bc1264eTobin Ehlis for (auto eventStagePair : cb_node->eventToStageMap) { 24189867daedbf52debc77d6568162ee21e071699b80Chris Forbes dev_data->eventMap[eventStagePair.first].stageMask = eventStagePair.second; 2419da8f07baf262972eb3e719fa07b073c180dff157Chris Forbes } 24200a32ed7bdf03e7bda914e03c0bfa6ebf400cdf5bMichael Lentine 2421a7fef8833e0b4e1e4c7ea20ab56da451a6856c0cChris Forbes cb_node->in_use.fetch_sub(1); 24220a32ed7bdf03e7bda914e03c0bfa6ebf400cdf5bMichael Lentine } 24239867daedbf52debc77d6568162ee21e071699b80Chris Forbes 24249a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pFence = GetFenceNode(dev_data, submission.fence); 2425804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt if (pFence && pFence->scope == kSyncScopeInternal) { 24269867daedbf52debc77d6568162ee21e071699b80Chris Forbes pFence->state = FENCE_RETIRED; 24270a32ed7bdf03e7bda914e03c0bfa6ebf400cdf5bMichael Lentine } 24289867daedbf52debc77d6568162ee21e071699b80Chris Forbes 24299867daedbf52debc77d6568162ee21e071699b80Chris Forbes pQueue->submissions.pop_front(); 24309867daedbf52debc77d6568162ee21e071699b80Chris Forbes pQueue->seq++; 2431b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine } 24329867daedbf52debc77d6568162ee21e071699b80Chris Forbes 24339867daedbf52debc77d6568162ee21e071699b80Chris Forbes // Roll other queues forward to the highest seq we saw a wait for 24349867daedbf52debc77d6568162ee21e071699b80Chris Forbes for (auto qs : otherQueueSeqs) { 24359a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis RetireWorkOnQueue(dev_data, GetQueueState(dev_data, qs.first), qs.second); 2436d78749ee260a3ce7244cbfd97c11aacc2250f8d3Michael Lentine } 24379867daedbf52debc77d6568162ee21e071699b80Chris Forbes} 2438651d92815dfff917308137bb67aacccc4f60df86Chris Forbes 2439651d92815dfff917308137bb67aacccc4f60df86Chris Forbes// Submit a fence to a queue, delimiting previous fences and previous untracked 2440651d92815dfff917308137bb67aacccc4f60df86Chris Forbes// work by it. 244136c3a4fe8455762d2dc0b2b9ece44675a3ee8d97Tobin Ehlisstatic void SubmitFence(QUEUE_STATE *pQueue, FENCE_NODE *pFence, uint64_t submitCount) { 2442cdb1ea0ff0d966dda02543468377eae93b9e2f8fChris Forbes pFence->state = FENCE_INFLIGHT; 24439867daedbf52debc77d6568162ee21e071699b80Chris Forbes pFence->signaler.first = pQueue->queue; 24449867daedbf52debc77d6568162ee21e071699b80Chris Forbes pFence->signaler.second = pQueue->seq + pQueue->submissions.size() + submitCount; 2445b3d308d63ba34f40839f009ac83b33962d7f26b2Michael Lentine} 2446b3d308d63ba34f40839f009ac83b33962d7f26b2Michael Lentine 244751920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbourstatic bool validateCommandBufferSimultaneousUse(layer_data *dev_data, GLOBAL_CB_NODE *pCB, int current_submit_count) { 24483251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 2449a7fef8833e0b4e1e4c7ea20ab56da451a6856c0cChris Forbes if ((pCB->in_use.load() || current_submit_count > 1) && 24505b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis !(pCB->beginInfo.flags & VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT)) { 24513251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0, 2452315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis __LINE__, VALIDATION_ERROR_31a0008e, "DS", 24533251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Command Buffer 0x%p is already in use and is not marked for simultaneous use. %s", pCB->commandBuffer, 2454315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_31a0008e]); 24555b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 24563251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 24575b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 24585b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 2459946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinskistatic bool validateCommandBufferState(layer_data *dev_data, GLOBAL_CB_NODE *cb_state, const char *call_source, 24600de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski int current_submit_count, UNIQUE_VALIDATION_ERROR_CODE vu_id) { 2461c264142df95edb7eb96b5dc2d87562efce6ded43Tobin Ehlis bool skip = false; 2462cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.command_buffer_state) return skip; 24630a59acde4b40fde3bbfea5811d2abf2c85ca62f4Tobin Ehlis // Validate ONE_TIME_SUBMIT_BIT CB is not being submitted more than once 2464946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski if ((cb_state->beginInfo.flags & VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT) && 2465946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski (cb_state->submitCount + current_submit_count > 1)) { 2466c264142df95edb7eb96b5dc2d87562efce6ded43Tobin Ehlis skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0, 2467c264142df95edb7eb96b5dc2d87562efce6ded43Tobin Ehlis __LINE__, DRAWSTATE_COMMAND_BUFFER_SINGLE_SUBMIT_VIOLATION, "DS", 2468226a75bff897619b86cc227cf1196b5e245fb96dTobin Ehlis "Commandbuffer 0x%p was begun w/ VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT " 2469c264142df95edb7eb96b5dc2d87562efce6ded43Tobin Ehlis "set, but has been submitted 0x%" PRIxLEAST64 " times.", 2470946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski cb_state->commandBuffer, cb_state->submitCount + current_submit_count); 24710a59acde4b40fde3bbfea5811d2abf2c85ca62f4Tobin Ehlis } 247294307efee520ad91d5da2ff8f40609b31f05b2efChris Forbes 24735b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Validate that cmd buffers have been updated 247446daa701a01b92ae19e3ee9e661d677128fe7e6dChris Forbes switch (cb_state->state) { 247546daa701a01b92ae19e3ee9e661d677128fe7e6dChris Forbes case CB_INVALID_INCOMPLETE: 247646daa701a01b92ae19e3ee9e661d677128fe7e6dChris Forbes case CB_INVALID_COMPLETE: 2477946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski skip |= ReportInvalidCommandBuffer(dev_data, cb_state, call_source); 247846daa701a01b92ae19e3ee9e661d677128fe7e6dChris Forbes break; 247946daa701a01b92ae19e3ee9e661d677128fe7e6dChris Forbes 248046daa701a01b92ae19e3ee9e661d677128fe7e6dChris Forbes case CB_NEW: 24810de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 24820de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski (uint64_t)(cb_state->commandBuffer), __LINE__, vu_id, "DS", 24830de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski "Command buffer 0x%p used in the call to %s is unrecorded and contains no commands. %s", 24840de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski cb_state->commandBuffer, call_source, validation_error_map[vu_id]); 248546daa701a01b92ae19e3ee9e661d677128fe7e6dChris Forbes break; 248646daa701a01b92ae19e3ee9e661d677128fe7e6dChris Forbes 248746daa701a01b92ae19e3ee9e661d677128fe7e6dChris Forbes case CB_RECORDING: 2488c264142df95edb7eb96b5dc2d87562efce6ded43Tobin Ehlis skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 24899b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(cb_state->commandBuffer), __LINE__, DRAWSTATE_NO_END_COMMAND_BUFFER, "DS", 2490946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski "You must call vkEndCommandBuffer() on command buffer 0x%p before this call to %s!", 2491946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski cb_state->commandBuffer, call_source); 249246daa701a01b92ae19e3ee9e661d677128fe7e6dChris Forbes break; 249346daa701a01b92ae19e3ee9e661d677128fe7e6dChris Forbes 249446daa701a01b92ae19e3ee9e661d677128fe7e6dChris Forbes default: /* recorded */ 249546daa701a01b92ae19e3ee9e661d677128fe7e6dChris Forbes break; 24965b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 2497c264142df95edb7eb96b5dc2d87562efce6ded43Tobin Ehlis return skip; 24985b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 24995b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 250051920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbourstatic bool validateResources(layer_data *dev_data, GLOBAL_CB_NODE *cb_node) { 25013251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 250251920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour 250351920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour // TODO : We should be able to remove the NULL look-up checks from the code below as long as 250451920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour // all the corresponding cases are verified to cause CB_INVALID state and the CB_INVALID state 250551920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour // should then be flagged prior to calling this function 250651920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour for (auto drawDataElement : cb_node->drawData) { 250751920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour for (auto buffer : drawDataElement.buffers) { 250851920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour auto buffer_state = GetBufferState(dev_data, buffer); 250951920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour if (!buffer_state) { 25103251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, 25119b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(buffer), __LINE__, DRAWSTATE_INVALID_BUFFER, "DS", 25129b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "Cannot submit cmd buffer using deleted buffer 0x%" PRIx64 ".", HandleToUint64(buffer)); 251351920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour } 251451920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour } 251551920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour } 25163251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 251751920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour} 251851920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour 2519f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski// Check that the queue family index of 'queue' matches one of the entries in pQueueFamilyIndices 2520f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinskibool ValidImageBufferQueue(layer_data *dev_data, GLOBAL_CB_NODE *cb_node, const VK_OBJECT *object, VkQueue queue, uint32_t count, 2521f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski const uint32_t *indices) { 2522f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski bool found = false; 2523f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski bool skip = false; 2524f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski auto queue_state = GetQueueState(dev_data, queue); 2525f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski if (queue_state) { 2526f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski for (uint32_t i = 0; i < count; i++) { 2527f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski if (indices[i] == queue_state->queueFamilyIndex) { 2528f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski found = true; 2529f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski break; 2530f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski } 2531f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski } 2532f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski 2533f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski if (!found) { 25349b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip = log_msg( 25359b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, get_debug_report_enum[object->type], object->handle, __LINE__, 25369b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus DRAWSTATE_INVALID_QUEUE_FAMILY, "DS", "vkQueueSubmit: Command buffer 0x%" PRIxLEAST64 " contains %s 0x%" PRIxLEAST64 25379b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus " which was not created allowing concurrent access to this queue family %d.", 25389b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(cb_node->commandBuffer), object_string[object->type], object->handle, queue_state->queueFamilyIndex); 2539f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski } 2540f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski } 2541f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski return skip; 2542f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski} 2543f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski 25447bd96b29f4b8df99339ff1f7bc64f2f8940f8d25Mark Lobodzinski// Validate that queueFamilyIndices of primary command buffers match this queue 25457bd96b29f4b8df99339ff1f7bc64f2f8940f8d25Mark Lobodzinski// Secondary command buffers were previously validated in vkCmdExecuteCommands(). 25467bd96b29f4b8df99339ff1f7bc64f2f8940f8d25Mark Lobodzinskistatic bool validateQueueFamilyIndices(layer_data *dev_data, GLOBAL_CB_NODE *pCB, VkQueue queue) { 25473251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 25489a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pPool = GetCommandPoolNode(dev_data, pCB->createInfo.commandPool); 25499a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto queue_state = GetQueueState(dev_data, queue); 25507bd96b29f4b8df99339ff1f7bc64f2f8940f8d25Mark Lobodzinski 2551f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski if (pPool && queue_state) { 2552f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski if (pPool->queueFamilyIndex != queue_state->queueFamilyIndex) { 25533251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 2554315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pCB->commandBuffer), __LINE__, VALIDATION_ERROR_31a00094, "DS", 25553251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkQueueSubmit: Primary command buffer 0x%p created in queue family %d is being submitted on queue " 25563251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "0x%p from queue family %d. %s", 25573251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski pCB->commandBuffer, pPool->queueFamilyIndex, queue, queue_state->queueFamilyIndex, 2558315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_31a00094]); 2559f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski } 2560f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski 2561f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski // Ensure that any bound images or buffers created with SHARING_MODE_CONCURRENT have access to the current queue family 2562f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski for (auto object : pCB->object_bindings) { 25637a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski if (object.type == kVulkanObjectTypeImage) { 2564f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski auto image_state = GetImageState(dev_data, reinterpret_cast<VkImage &>(object.handle)); 2565f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski if (image_state && image_state->createInfo.sharingMode == VK_SHARING_MODE_CONCURRENT) { 25663251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidImageBufferQueue(dev_data, pCB, &object, queue, image_state->createInfo.queueFamilyIndexCount, 25673251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski image_state->createInfo.pQueueFamilyIndices); 2568f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski } 25697a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski } else if (object.type == kVulkanObjectTypeBuffer) { 2570f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski auto buffer_state = GetBufferState(dev_data, reinterpret_cast<VkBuffer &>(object.handle)); 2571f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski if (buffer_state && buffer_state->createInfo.sharingMode == VK_SHARING_MODE_CONCURRENT) { 25723251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidImageBufferQueue(dev_data, pCB, &object, queue, buffer_state->createInfo.queueFamilyIndexCount, 25733251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski buffer_state->createInfo.pQueueFamilyIndices); 2574f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski } 2575f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski } 2576f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski } 25777bd96b29f4b8df99339ff1f7bc64f2f8940f8d25Mark Lobodzinski } 25787bd96b29f4b8df99339ff1f7bc64f2f8940f8d25Mark Lobodzinski 25793251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 25807bd96b29f4b8df99339ff1f7bc64f2f8940f8d25Mark Lobodzinski} 25817bd96b29f4b8df99339ff1f7bc64f2f8940f8d25Mark Lobodzinski 258251920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbourstatic bool validatePrimaryCommandBufferState(layer_data *dev_data, GLOBAL_CB_NODE *pCB, int current_submit_count) { 25835b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Track in-use for resources off of primary and any secondary CBs 25843251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 2585a2d08a743ac1178e4d46da4d41c73fb73b5e79d7Chris Forbes 2586a2d08a743ac1178e4d46da4d41c73fb73b5e79d7Chris Forbes // If USAGE_SIMULTANEOUS_USE_BIT not set then CB cannot already be executing 2587a2d08a743ac1178e4d46da4d41c73fb73b5e79d7Chris Forbes // on device 25883251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= validateCommandBufferSimultaneousUse(dev_data, pCB, current_submit_count); 2589a2d08a743ac1178e4d46da4d41c73fb73b5e79d7Chris Forbes 25903251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= validateResources(dev_data, pCB); 2591a2d08a743ac1178e4d46da4d41c73fb73b5e79d7Chris Forbes 25921a3660584634742a3297915c94768d73f360e794Chris Forbes for (auto pSubCB : pCB->linkedCommandBuffers) { 259311decd82041d4b10aac41360fc76b6fda4f4bd27Chris Forbes skip |= validateResources(dev_data, pSubCB); 25941a3660584634742a3297915c94768d73f360e794Chris Forbes // TODO: replace with invalidateCommandBuffers() at recording. 259511decd82041d4b10aac41360fc76b6fda4f4bd27Chris Forbes if ((pSubCB->primaryCommandBuffer != pCB->commandBuffer) && 259611decd82041d4b10aac41360fc76b6fda4f4bd27Chris Forbes !(pSubCB->beginInfo.flags & VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT)) { 2597315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0, 2598315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis __LINE__, VALIDATION_ERROR_31a00092, "DS", 2599315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis "Commandbuffer 0x%p was submitted with secondary buffer 0x%p but that buffer has subsequently been bound to " 2600f634be57d858a71969b3183cd0e322fe1d0ad0fbMike Weiblen "primary cmd buffer 0x%p and it does not have VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT set. %s", 2601315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis pCB->commandBuffer, pSubCB->commandBuffer, pSubCB->primaryCommandBuffer, 2602315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_31a00092]); 26035b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 26045b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 2605a2d08a743ac1178e4d46da4d41c73fb73b5e79d7Chris Forbes 2606315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= validateCommandBufferState(dev_data, pCB, "vkQueueSubmit()", current_submit_count, VALIDATION_ERROR_31a00090); 2607a2d08a743ac1178e4d46da4d41c73fb73b5e79d7Chris Forbes 26083251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 26095b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 26105b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 2611bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinskistatic bool ValidateFenceForSubmit(layer_data *dev_data, FENCE_NODE *pFence) { 26123251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 261381c4a32a622486043c15e427fb0e85cc1cf7dd47Chris Forbes 2614804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt if (pFence && pFence->scope == kSyncScopeInternal) { 2615cdb1ea0ff0d966dda02543468377eae93b9e2f8fChris Forbes if (pFence->state == FENCE_INFLIGHT) { 2616315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis // TODO: opportunities for VALIDATION_ERROR_31a00080, VALIDATION_ERROR_316008b4, VALIDATION_ERROR_16400a0e 26173251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, 26189b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pFence->fence), __LINE__, DRAWSTATE_INVALID_FENCE, "DS", 26199b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "Fence 0x%" PRIx64 " is already in use by another submission.", HandleToUint64(pFence->fence)); 2620a265a8ed3bbb32ade305b1be3148d6001a870b76Tobin Ehlis } 262181c4a32a622486043c15e427fb0e85cc1cf7dd47Chris Forbes 2622cdb1ea0ff0d966dda02543468377eae93b9e2f8fChris Forbes else if (pFence->state == FENCE_RETIRED) { 2623315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis // TODO: opportunities for VALIDATION_ERROR_31a0007e, VALIDATION_ERROR_316008b2, VALIDATION_ERROR_16400a0e 26243251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, 26259b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pFence->fence), __LINE__, MEMTRACK_INVALID_FENCE_STATE, "MEM", 26263251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Fence 0x%" PRIxLEAST64 " submitted in SIGNALED state. Fences must be reset before being submitted", 26279b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pFence->fence)); 2628a265a8ed3bbb32ade305b1be3148d6001a870b76Tobin Ehlis } 26295b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 263081c4a32a622486043c15e427fb0e85cc1cf7dd47Chris Forbes 26313251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 263281c4a32a622486043c15e427fb0e85cc1cf7dd47Chris Forbes} 263381c4a32a622486043c15e427fb0e85cc1cf7dd47Chris Forbes 263451920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbourstatic void PostCallRecordQueueSubmit(layer_data *dev_data, VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, 263551920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour VkFence fence) { 263685926a33d427ee62f395a50886db980127063c72Mike Schuchardt uint64_t early_retire_seq = 0; 26379a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pQueue = GetQueueState(dev_data, queue); 26389a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pFence = GetFenceNode(dev_data, fence); 2639d7d60cccc862fee2d0b3ad410c5fdcc40ddc83aeChris Forbes 26406371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt if (pFence) { 26416371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt if (pFence->scope == kSyncScopeInternal) { 26426371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt // Mark fence in use 26436371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt SubmitFence(pQueue, pFence, std::max(1u, submitCount)); 26446371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt if (!submitCount) { 26456371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt // If no submissions, but just dropping a fence on the end of the queue, 26466371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt // record an empty submission with just the fence, so we can determine 26476371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt // its completion. 26486371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt pQueue->submissions.emplace_back(std::vector<VkCommandBuffer>(), std::vector<SEMAPHORE_WAIT>(), 26496371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt std::vector<VkSemaphore>(), std::vector<VkSemaphore>(), fence); 26506371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt } 26516371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt } else { 26526371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt // Retire work up until this fence early, we will not see the wait that corresponds to this signal 26536371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt early_retire_seq = pQueue->seq + pQueue->submissions.size(); 26546371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt if (!dev_data->external_sync_warning) { 26556371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt dev_data->external_sync_warning = true; 26566371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt log_msg(dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, 26576371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt HandleToUint64(fence), __LINE__, DRAWSTATE_QUEUE_FORWARD_PROGRESS, "DS", 26586371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt "vkQueueSubmit(): Signaling external fence 0x%" PRIx64 " on queue 0x%" PRIx64 26596371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt " will disable validation of preceding command buffer lifecycle states and the in-use status of " 26606371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt "associated objects.", 26616371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt HandleToUint64(fence), HandleToUint64(queue)); 26626371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt } 26636371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt } 2664651d92815dfff917308137bb67aacccc4f60df86Chris Forbes } 2665651d92815dfff917308137bb67aacccc4f60df86Chris Forbes 266651920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour // Now process each individual submit 26675b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) { 266851920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour std::vector<VkCommandBuffer> cbs; 26695b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis const VkSubmitInfo *submit = &pSubmits[submit_idx]; 26709867daedbf52debc77d6568162ee21e071699b80Chris Forbes vector<SEMAPHORE_WAIT> semaphore_waits; 26719867daedbf52debc77d6568162ee21e071699b80Chris Forbes vector<VkSemaphore> semaphore_signals; 267206d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt vector<VkSemaphore> semaphore_externals; 26735b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t i = 0; i < submit->waitSemaphoreCount; ++i) { 267451920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour VkSemaphore semaphore = submit->pWaitSemaphores[i]; 267551920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour auto pSemaphore = GetSemaphoreNode(dev_data, semaphore); 267651920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour if (pSemaphore) { 267706d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt if (pSemaphore->scope == kSyncScopeInternal) { 267806d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt if (pSemaphore->signaler.first != VK_NULL_HANDLE) { 267906d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt semaphore_waits.push_back({semaphore, pSemaphore->signaler.first, pSemaphore->signaler.second}); 268006d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt pSemaphore->in_use.fetch_add(1); 268106d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt } 268206d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt pSemaphore->signaler.first = VK_NULL_HANDLE; 268306d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt pSemaphore->signaled = false; 268406d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt } else { 268506d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt semaphore_externals.push_back(semaphore); 268651920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour pSemaphore->in_use.fetch_add(1); 268706d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt if (pSemaphore->scope == kSyncScopeExternalTemporary) { 268806d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt pSemaphore->scope = kSyncScopeInternal; 268906d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt } 269051920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour } 269151920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour } 269251920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour } 269351920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour for (uint32_t i = 0; i < submit->signalSemaphoreCount; ++i) { 269451920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour VkSemaphore semaphore = submit->pSignalSemaphores[i]; 269551920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour auto pSemaphore = GetSemaphoreNode(dev_data, semaphore); 269651920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour if (pSemaphore) { 269706d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt if (pSemaphore->scope == kSyncScopeInternal) { 269806d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt pSemaphore->signaler.first = queue; 269906d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt pSemaphore->signaler.second = pQueue->seq + pQueue->submissions.size() + 1; 270006d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt pSemaphore->signaled = true; 270106d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt pSemaphore->in_use.fetch_add(1); 270206d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt semaphore_signals.push_back(semaphore); 270306d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt } else { 270485926a33d427ee62f395a50886db980127063c72Mike Schuchardt // Retire work up until this submit early, we will not see the wait that corresponds to this signal 27056371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt early_retire_seq = std::max(early_retire_seq, pQueue->seq + pQueue->submissions.size() + 1); 270685926a33d427ee62f395a50886db980127063c72Mike Schuchardt if (!dev_data->external_sync_warning) { 270785926a33d427ee62f395a50886db980127063c72Mike Schuchardt dev_data->external_sync_warning = true; 270885926a33d427ee62f395a50886db980127063c72Mike Schuchardt log_msg(dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT, 270985926a33d427ee62f395a50886db980127063c72Mike Schuchardt HandleToUint64(semaphore), __LINE__, DRAWSTATE_QUEUE_FORWARD_PROGRESS, "DS", 271085926a33d427ee62f395a50886db980127063c72Mike Schuchardt "vkQueueSubmit(): Signaling external semaphore 0x%" PRIx64 " on queue 0x%" PRIx64 271185926a33d427ee62f395a50886db980127063c72Mike Schuchardt " will disable validation of preceding command buffer lifecycle states and the in-use status of " 271285926a33d427ee62f395a50886db980127063c72Mike Schuchardt "associated objects.", 271385926a33d427ee62f395a50886db980127063c72Mike Schuchardt HandleToUint64(semaphore), HandleToUint64(queue)); 271485926a33d427ee62f395a50886db980127063c72Mike Schuchardt } 271506d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt } 271651920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour } 271751920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour } 271851920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour for (uint32_t i = 0; i < submit->commandBufferCount; i++) { 271951920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour auto cb_node = GetCBNode(dev_data, submit->pCommandBuffers[i]); 272051920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour if (cb_node) { 272151920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour cbs.push_back(submit->pCommandBuffers[i]); 27221a3660584634742a3297915c94768d73f360e794Chris Forbes for (auto secondaryCmdBuffer : cb_node->linkedCommandBuffers) { 272311decd82041d4b10aac41360fc76b6fda4f4bd27Chris Forbes cbs.push_back(secondaryCmdBuffer->commandBuffer); 272451920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour } 272551920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour UpdateCmdBufImageLayouts(dev_data, cb_node); 272651920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour incrementResources(dev_data, cb_node); 27271a3660584634742a3297915c94768d73f360e794Chris Forbes for (auto secondaryCmdBuffer : cb_node->linkedCommandBuffers) { 272811decd82041d4b10aac41360fc76b6fda4f4bd27Chris Forbes incrementResources(dev_data, secondaryCmdBuffer); 272951920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour } 273051920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour } 273151920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour } 273206d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt pQueue->submissions.emplace_back(cbs, semaphore_waits, semaphore_signals, semaphore_externals, 273351920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour submit_idx == submitCount - 1 ? fence : VK_NULL_HANDLE); 273451920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour } 273551920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour 273685926a33d427ee62f395a50886db980127063c72Mike Schuchardt if (early_retire_seq) { 273785926a33d427ee62f395a50886db980127063c72Mike Schuchardt RetireWorkOnQueue(dev_data, pQueue, early_retire_seq); 273885926a33d427ee62f395a50886db980127063c72Mike Schuchardt } 273951920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour} 274051920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour 274151920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbourstatic bool PreCallValidateQueueSubmit(layer_data *dev_data, VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, 274251920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour VkFence fence) { 274351920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour auto pFence = GetFenceNode(dev_data, fence); 27443251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = ValidateFenceForSubmit(dev_data, pFence); 27453251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (skip) { 274651920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour return true; 274751920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour } 274851920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour 274951920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour unordered_set<VkSemaphore> signaled_semaphores; 275051920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour unordered_set<VkSemaphore> unsignaled_semaphores; 275106d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt unordered_set<VkSemaphore> internal_semaphores; 275251920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour vector<VkCommandBuffer> current_cmds; 2753c25ac48846c975d698243e53750c6bca28bba33eChris Forbes unordered_map<ImageSubresourcePair, IMAGE_LAYOUT_NODE> localImageLayoutMap; 275451920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour // Now verify each individual submit 275551920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) { 275651920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour const VkSubmitInfo *submit = &pSubmits[submit_idx]; 275751920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour for (uint32_t i = 0; i < submit->waitSemaphoreCount; ++i) { 2758315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateStageMaskGsTsEnables(dev_data, submit->pWaitDstStageMask[i], "vkQueueSubmit()", 2759315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_13c00098, VALIDATION_ERROR_13c0009a); 276001a48e41895b3951b297ff4245eff8f9c129ae20Chris Forbes VkSemaphore semaphore = submit->pWaitSemaphores[i]; 27619a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pSemaphore = GetSemaphoreNode(dev_data, semaphore); 276206d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt if (pSemaphore && (pSemaphore->scope == kSyncScopeInternal || internal_semaphores.count(semaphore))) { 276351920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour if (unsignaled_semaphores.count(semaphore) || 2764440bdd357701497c3442e3515f12ac1cfffc180aTony Barbour (!(signaled_semaphores.count(semaphore)) && !(pSemaphore->signaled))) { 27653251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT, 27669b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(semaphore), __LINE__, DRAWSTATE_QUEUE_FORWARD_PROGRESS, "DS", 27673251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Queue 0x%p is waiting on semaphore 0x%" PRIx64 " that has no way to be signaled.", queue, 27689b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(semaphore)); 276951920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour } else { 277051920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour signaled_semaphores.erase(semaphore); 277151920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour unsignaled_semaphores.insert(semaphore); 27721344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis } 27735b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 277406d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt if (pSemaphore && pSemaphore->scope == kSyncScopeExternalTemporary) { 277506d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt internal_semaphores.insert(semaphore); 277606d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt } 27775b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 27785b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t i = 0; i < submit->signalSemaphoreCount; ++i) { 277901a48e41895b3951b297ff4245eff8f9c129ae20Chris Forbes VkSemaphore semaphore = submit->pSignalSemaphores[i]; 27809a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pSemaphore = GetSemaphoreNode(dev_data, semaphore); 278106d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt if (pSemaphore && (pSemaphore->scope == kSyncScopeInternal || internal_semaphores.count(semaphore))) { 2782440bdd357701497c3442e3515f12ac1cfffc180aTony Barbour if (signaled_semaphores.count(semaphore) || (!(unsignaled_semaphores.count(semaphore)) && pSemaphore->signaled)) { 27833251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT, 27849b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(semaphore), __LINE__, DRAWSTATE_QUEUE_FORWARD_PROGRESS, "DS", 27853251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Queue 0x%p is signaling semaphore 0x%" PRIx64 27863251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski " that has already been signaled but not waited on by queue 0x%" PRIx64 ".", 27879b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus queue, HandleToUint64(semaphore), HandleToUint64(pSemaphore->signaler.first)); 27881344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis } else { 278951920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour unsignaled_semaphores.erase(semaphore); 279051920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour signaled_semaphores.insert(semaphore); 27911344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis } 27920a32ed7bdf03e7bda914e03c0bfa6ebf400cdf5bMichael Lentine } 27935b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 27945b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t i = 0; i < submit->commandBufferCount; i++) { 27959a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto cb_node = GetCBNode(dev_data, submit->pCommandBuffers[i]); 2796d74f8771414d9e80618cd7604ea4b1c459dfa42eTobin Ehlis if (cb_node) { 2797c25ac48846c975d698243e53750c6bca28bba33eChris Forbes skip |= ValidateCmdBufImageLayouts(dev_data, cb_node, dev_data->imageLayoutMap, localImageLayoutMap); 279851920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour current_cmds.push_back(submit->pCommandBuffers[i]); 27993251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= validatePrimaryCommandBufferState( 280051920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour dev_data, cb_node, (int)std::count(current_cmds.begin(), current_cmds.end(), submit->pCommandBuffers[i])); 28013251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= validateQueueFamilyIndices(dev_data, cb_node, queue); 280251920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour 2803ea371fa7c8c57edb4d1436e4570cf54f3fc0463fTobin Ehlis // Potential early exit here as bad object state may crash in delayed function calls 28043251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (skip) { 280551920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour return true; 280651920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour } 280751920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour 28081344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis // Call submit-time functions to validate/update state 2809d807198f24437c1b2478ff1d06a33ce4873a1451Tobin Ehlis for (auto &function : cb_node->queue_submit_functions) { 28103251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= function(); 28111344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis } 2812d74f8771414d9e80618cd7604ea4b1c459dfa42eTobin Ehlis for (auto &function : cb_node->eventUpdates) { 28133251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= function(queue); 28141344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis } 2815d74f8771414d9e80618cd7604ea4b1c459dfa42eTobin Ehlis for (auto &function : cb_node->queryUpdates) { 28163251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= function(queue); 2817d78749ee260a3ce7244cbfd97c11aacc2250f8d3Michael Lentine } 28181344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis } 28195b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 28209867daedbf52debc77d6568162ee21e071699b80Chris Forbes } 28213251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 282251920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour} 28239867daedbf52debc77d6568162ee21e071699b80Chris Forbes 282451920949f887ce8d3666c73c28ff19a5d8325a37Tony BarbourVKAPI_ATTR VkResult VKAPI_CALL QueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, VkFence fence) { 282551920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(queue), layer_data_map); 2826ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 282751920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour 282851920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour bool skip = PreCallValidateQueueSubmit(dev_data, queue, submitCount, pSubmits, fence); 2829b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 28305b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 2831440bdd357701497c3442e3515f12ac1cfffc180aTony Barbour if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 283251920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour 283351920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour VkResult result = dev_data->dispatch_table.QueueSubmit(queue, submitCount, pSubmits, fence); 283451920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour 283551920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour lock.lock(); 283651920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour PostCallRecordQueueSubmit(dev_data, queue, submitCount, pSubmits, fence); 283751920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour lock.unlock(); 28385b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 28395b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 28405b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 2841f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultzstatic bool PreCallValidateAllocateMemory(layer_data *dev_data) { 2842f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultz bool skip = false; 2843f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultz if (dev_data->memObjMap.size() >= dev_data->phys_dev_properties.properties.limits.maxMemoryAllocationCount) { 2844f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultz skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 2845315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(dev_data->device), __LINE__, VALIDATION_ERROR_16c004f8, "MEM", 2846f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultz "Number of currently valid memory objects is not less than the maximum allowed (%u). %s", 2847f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultz dev_data->phys_dev_properties.properties.limits.maxMemoryAllocationCount, 2848315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_16c004f8]); 2849f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultz } 2850f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultz return skip; 2851f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultz} 2852f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultz 2853f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultzstatic void PostCallRecordAllocateMemory(layer_data *dev_data, const VkMemoryAllocateInfo *pAllocateInfo, VkDeviceMemory *pMemory) { 2854f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultz add_mem_obj_info(dev_data, dev_data->device, *pMemory, pAllocateInfo); 2855f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultz return; 2856f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultz} 2857f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultz 285889d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR VkResult VKAPI_CALL AllocateMemory(VkDevice device, const VkMemoryAllocateInfo *pAllocateInfo, 285989d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I Wu const VkAllocationCallbacks *pAllocator, VkDeviceMemory *pMemory) { 2860f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultz VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 286156e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 2862ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 2863f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultz bool skip = PreCallValidateAllocateMemory(dev_data); 2864f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultz if (!skip) { 2865f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultz lock.unlock(); 2866f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultz result = dev_data->dispatch_table.AllocateMemory(device, pAllocateInfo, pAllocator, pMemory); 2867f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultz lock.lock(); 2868f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultz if (VK_SUCCESS == result) { 2869f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultz PostCallRecordAllocateMemory(dev_data, pAllocateInfo, pMemory); 2870f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultz } 2871e12739a56d02ca2fb5f0273862668e7475a21a6cMark Lobodzinski } 28725b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 28735b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 28745b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 2875177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis// For given obj node, if it is use, flag a validation error and return callback result, else return false 287669ea2c79d7b3f9c987671a10686afac066b275b9Mike Schuchardtbool ValidateObjectNotInUse(const layer_data *dev_data, BASE_NODE *obj_node, VK_OBJECT obj_struct, const char *caller_name, 2877177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis UNIQUE_VALIDATION_ERROR_CODE error_code) { 2878cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.object_in_use) return false; 2879177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis bool skip = false; 2880177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis if (obj_node->in_use.load()) { 288169ea2c79d7b3f9c987671a10686afac066b275b9Mike Schuchardt skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, get_debug_report_enum[obj_struct.type], 288269ea2c79d7b3f9c987671a10686afac066b275b9Mike Schuchardt obj_struct.handle, __LINE__, error_code, "DS", 288369ea2c79d7b3f9c987671a10686afac066b275b9Mike Schuchardt "Cannot call %s on %s 0x%" PRIx64 " that is currently in use by a command buffer. %s", caller_name, 288469ea2c79d7b3f9c987671a10686afac066b275b9Mike Schuchardt object_string[obj_struct.type], obj_struct.handle, validation_error_map[error_code]); 2885177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis } 2886177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis return skip; 2887177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis} 28885b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 2889177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlisstatic bool PreCallValidateFreeMemory(layer_data *dev_data, VkDeviceMemory mem, DEVICE_MEM_INFO **mem_info, VK_OBJECT *obj_struct) { 28909a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis *mem_info = GetMemObjInfo(dev_data, mem); 28919b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus *obj_struct = {HandleToUint64(mem), kVulkanObjectTypeDeviceMemory}; 2892cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.free_memory) return false; 2893177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis bool skip = false; 2894177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis if (*mem_info) { 289569ea2c79d7b3f9c987671a10686afac066b275b9Mike Schuchardt skip |= ValidateObjectNotInUse(dev_data, *mem_info, *obj_struct, "vkFreeMemory", VALIDATION_ERROR_2880054a); 2896177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis } 2897177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis return skip; 2898177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis} 28995b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 2900177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlisstatic void PostCallRecordFreeMemory(layer_data *dev_data, VkDeviceMemory mem, DEVICE_MEM_INFO *mem_info, VK_OBJECT obj_struct) { 2901177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis // Clear mem binding for any bound objects 290247705d01140c9f1492885e6efc5fa262e7e1c6a0Tobin Ehlis for (auto obj : mem_info->obj_bindings) { 290302a510945ff39f3d9e486e456aca5bfa6ea0c43aMark Lobodzinski log_msg(dev_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, get_debug_report_enum[obj.type], obj.handle, __LINE__, 29047a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski MEMTRACK_FREED_MEM_REF, "MEM", "VK Object 0x%" PRIxLEAST64 " still has a reference to mem obj 0x%" PRIxLEAST64, 29059b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus obj.handle, HandleToUint64(mem_info->mem)); 290647705d01140c9f1492885e6efc5fa262e7e1c6a0Tobin Ehlis switch (obj.type) { 29077a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski case kVulkanObjectTypeImage: { 29089a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto image_state = GetImageState(dev_data, reinterpret_cast<VkImage &>(obj.handle)); 2909cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski assert(image_state); // Any destroyed images should already be removed from bindings 2910cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski image_state->binding.mem = MEMORY_UNBOUND; 2911cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 2912cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } 29137a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski case kVulkanObjectTypeBuffer: { 29149a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto buffer_state = GetBufferState(dev_data, reinterpret_cast<VkBuffer &>(obj.handle)); 2915cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski assert(buffer_state); // Any destroyed buffers should already be removed from bindings 2916cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski buffer_state->binding.mem = MEMORY_UNBOUND; 2917cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 2918cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } 2919cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski default: 2920cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski // Should only have buffer or image objects bound to memory 2921cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski assert(0); 2922177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis } 2923177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis } 2924177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis // Any bound cmd buffers are now invalid 292539c845ed4c066740e9efaed0a00af51be07c67c1Tobin Ehlis invalidateCommandBuffers(dev_data, mem_info->cb_bindings, obj_struct); 2926177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis dev_data->memObjMap.erase(mem); 2927177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis} 2928177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis 2929177063aac84fac6f4e650c2629a08b48be643f96Tobin EhlisVKAPI_ATTR void VKAPI_CALL FreeMemory(VkDevice device, VkDeviceMemory mem, const VkAllocationCallbacks *pAllocator) { 293056e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 2931177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis DEVICE_MEM_INFO *mem_info = nullptr; 2932177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis VK_OBJECT obj_struct; 2933ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 2934177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis bool skip = PreCallValidateFreeMemory(dev_data, mem, &mem_info, &obj_struct); 2935177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis if (!skip) { 2936177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis lock.unlock(); 2937177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis dev_data->dispatch_table.FreeMemory(device, mem, pAllocator); 2938177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis lock.lock(); 2939405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour if (mem != VK_NULL_HANDLE) { 2940405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour PostCallRecordFreeMemory(dev_data, mem, mem_info, obj_struct); 2941405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour } 294274243a735fe102b370237ddf80d3e6f7ec5246dbMark Mueller } 29435b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 29445b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 2945f57fc64ac43691ad98e1713886b345465573070aTobin Ehlis// Validate that given Map memory range is valid. This means that the memory should not already be mapped, 2946f57fc64ac43691ad98e1713886b345465573070aTobin Ehlis// and that the size of the map range should be: 2947f57fc64ac43691ad98e1713886b345465573070aTobin Ehlis// 1. Not zero 2948f57fc64ac43691ad98e1713886b345465573070aTobin Ehlis// 2. Within the size of the memory allocation 294951ea774638f432bd8e700ec8291a980f405f429eTobin Ehlisstatic bool ValidateMapMemRange(layer_data *dev_data, VkDeviceMemory mem, VkDeviceSize offset, VkDeviceSize size) { 29503251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 29515b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 29525b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (size == 0) { 29533251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 29549b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(mem), __LINE__, MEMTRACK_INVALID_MAP, "MEM", 29553251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "VkMapMemory: Attempting to map memory range of size zero"); 29565b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 29575b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 295851ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis auto mem_element = dev_data->memObjMap.find(mem); 295951ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis if (mem_element != dev_data->memObjMap.end()) { 296057fc8e28c2e16118f9827e3ae1b107a27e0451a2Tobin Ehlis auto mem_info = mem_element->second.get(); 29615b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // It is an application error to call VkMapMemory on an object that is already mapped 2962de1d2592cdd497642de5b0e6f27ebc439018383bTobin Ehlis if (mem_info->mem_range.size != 0) { 29639b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip = 29649b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 29659b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(mem), __LINE__, MEMTRACK_INVALID_MAP, "MEM", 29669b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "VkMapMemory: Attempting to map memory on an already-mapped object 0x%" PRIxLEAST64, HandleToUint64(mem)); 29675b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 29685b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 29695b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Validate that offset + size is within object's allocationSize 29705b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (size == VK_WHOLE_SIZE) { 2971de1d2592cdd497642de5b0e6f27ebc439018383bTobin Ehlis if (offset >= mem_info->alloc_info.allocationSize) { 29723251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 29739b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(mem), __LINE__, MEMTRACK_INVALID_MAP, "MEM", 29743251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Mapping Memory from 0x%" PRIx64 " to 0x%" PRIx64 29753251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski " with size of VK_WHOLE_SIZE oversteps total array size 0x%" PRIx64, 29763251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski offset, mem_info->alloc_info.allocationSize, mem_info->alloc_info.allocationSize); 29775b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 29785b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } else { 2979de1d2592cdd497642de5b0e6f27ebc439018383bTobin Ehlis if ((offset + size) > mem_info->alloc_info.allocationSize) { 29803251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 2981315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(mem), __LINE__, VALIDATION_ERROR_31200552, "MEM", 29823251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Mapping Memory from 0x%" PRIx64 " to 0x%" PRIx64 " oversteps total array size 0x%" PRIx64 ". %s", 29833251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski offset, size + offset, mem_info->alloc_info.allocationSize, 2984315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_31200552]); 29855b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 29865b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 29875b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 29883251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 29895b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 29905b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 299151ea774638f432bd8e700ec8291a980f405f429eTobin Ehlisstatic void storeMemRanges(layer_data *dev_data, VkDeviceMemory mem, VkDeviceSize offset, VkDeviceSize size) { 29929a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto mem_info = GetMemObjInfo(dev_data, mem); 299357fc8e28c2e16118f9827e3ae1b107a27e0451a2Tobin Ehlis if (mem_info) { 2994de1d2592cdd497642de5b0e6f27ebc439018383bTobin Ehlis mem_info->mem_range.offset = offset; 2995de1d2592cdd497642de5b0e6f27ebc439018383bTobin Ehlis mem_info->mem_range.size = size; 29965b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 29975b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 29985b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 299951ea774638f432bd8e700ec8291a980f405f429eTobin Ehlisstatic bool deleteMemRanges(layer_data *dev_data, VkDeviceMemory mem) { 30003251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 30019a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto mem_info = GetMemObjInfo(dev_data, mem); 300257fc8e28c2e16118f9827e3ae1b107a27e0451a2Tobin Ehlis if (mem_info) { 3003de1d2592cdd497642de5b0e6f27ebc439018383bTobin Ehlis if (!mem_info->mem_range.size) { 30045b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Valid Usage: memory must currently be mapped 30053251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 3006315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(mem), __LINE__, VALIDATION_ERROR_33600562, "MEM", 30079b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "Unmapping Memory without memory being mapped: mem obj 0x%" PRIxLEAST64 ". %s", HandleToUint64(mem), 3008315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_33600562]); 30095b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 3010de1d2592cdd497642de5b0e6f27ebc439018383bTobin Ehlis mem_info->mem_range.size = 0; 30115f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski if (mem_info->shadow_copy) { 30125f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski free(mem_info->shadow_copy_base); 30135f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski mem_info->shadow_copy_base = 0; 30145f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski mem_info->shadow_copy = 0; 30155b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 30165b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 30173251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 30185b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 30195b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 30205f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski// Guard value for pad data 30215b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlisstatic char NoncoherentMemoryFillValue = 0xb; 30225b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 30235f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinskistatic void initializeAndTrackMemory(layer_data *dev_data, VkDeviceMemory mem, VkDeviceSize offset, VkDeviceSize size, 30245f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski void **ppData) { 30259a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto mem_info = GetMemObjInfo(dev_data, mem); 302657fc8e28c2e16118f9827e3ae1b107a27e0451a2Tobin Ehlis if (mem_info) { 3027de1d2592cdd497642de5b0e6f27ebc439018383bTobin Ehlis mem_info->p_driver_data = *ppData; 3028de1d2592cdd497642de5b0e6f27ebc439018383bTobin Ehlis uint32_t index = mem_info->alloc_info.memoryTypeIndex; 3029b1b606d27e8c4179534d7bbb48ce217429e37414Tobin Ehlis if (dev_data->phys_dev_mem_props.memoryTypes[index].propertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) { 30305f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski mem_info->shadow_copy = 0; 30315b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } else { 30325b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (size == VK_WHOLE_SIZE) { 30335f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski size = mem_info->alloc_info.allocationSize - offset; 30345b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 30355f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski mem_info->shadow_pad_size = dev_data->phys_dev_properties.properties.limits.minMemoryMapAlignment; 303616769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton assert(SafeModulo(mem_info->shadow_pad_size, 30375f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski dev_data->phys_dev_properties.properties.limits.minMemoryMapAlignment) == 0); 30385f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski // Ensure start of mapped region reflects hardware alignment constraints 30395f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski uint64_t map_alignment = dev_data->phys_dev_properties.properties.limits.minMemoryMapAlignment; 30405f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski 30415f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski // From spec: (ppData - offset) must be aligned to at least limits::minMemoryMapAlignment. 30425f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski uint64_t start_offset = offset % map_alignment; 30435f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski // Data passed to driver will be wrapped by a guardband of data to detect over- or under-writes. 3044bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski mem_info->shadow_copy_base = 3045bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski malloc(static_cast<size_t>(2 * mem_info->shadow_pad_size + size + map_alignment + start_offset)); 30465f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski 30475f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski mem_info->shadow_copy = 30485f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski reinterpret_cast<char *>((reinterpret_cast<uintptr_t>(mem_info->shadow_copy_base) + map_alignment) & 3049bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski ~(map_alignment - 1)) + 3050bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski start_offset; 305116769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton assert(SafeModulo(reinterpret_cast<uintptr_t>(mem_info->shadow_copy) + mem_info->shadow_pad_size - start_offset, 30525f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski map_alignment) == 0); 30535f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski 30546e17c244b21ce43ac57404a00a0d844039eed363Mark Lobodzinski memset(mem_info->shadow_copy, NoncoherentMemoryFillValue, static_cast<size_t>(2 * mem_info->shadow_pad_size + size)); 30555f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski *ppData = static_cast<char *>(mem_info->shadow_copy) + mem_info->shadow_pad_size; 30565b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 30575b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 30585b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 30595f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski 3060a265a8ed3bbb32ade305b1be3148d6001a870b76Tobin Ehlis// Verify that state for fence being waited on is appropriate. That is, 30619867daedbf52debc77d6568162ee21e071699b80Chris Forbes// a fence being waited on should not already be signaled and 3062a265a8ed3bbb32ade305b1be3148d6001a870b76Tobin Ehlis// it should have been submitted on a queue or during acquire next image 306349f6132af865afd5b7f413c91125971ac97c135aChris Forbesstatic inline bool verifyWaitFenceState(layer_data *dev_data, VkFence fence, const char *apiCall) { 30643251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 30659b48b44dd917f95b5f34dd629ec4076fc87eb3a2Chris Forbes 30669a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pFence = GetFenceNode(dev_data, fence); 3067804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt if (pFence && pFence->scope == kSyncScopeInternal) { 3068cdb1ea0ff0d966dda02543468377eae93b9e2f8fChris Forbes if (pFence->state == FENCE_UNSIGNALED) { 30693251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, 30709b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(fence), __LINE__, MEMTRACK_INVALID_FENCE_STATE, "MEM", 30713251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "%s called for fence 0x%" PRIxLEAST64 30723251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski " which has not been submitted on a Queue or during " 30733251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "acquire next image.", 30749b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus apiCall, HandleToUint64(fence)); 30755b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 30765b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 30773251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 30785b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 3079a265a8ed3bbb32ade305b1be3148d6001a870b76Tobin Ehlis 3080b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlisstatic void RetireFence(layer_data *dev_data, VkFence fence) { 30819a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pFence = GetFenceNode(dev_data, fence); 3082804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt if (pFence->scope == kSyncScopeInternal) { 3083804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt if (pFence->signaler.first != VK_NULL_HANDLE) { 3084804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt // Fence signaller is a queue -- use this as proof that prior operations on that queue have completed. 3085804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt RetireWorkOnQueue(dev_data, GetQueueState(dev_data, pFence->signaler.first), pFence->signaler.second); 3086804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt } else { 3087804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt // Fence signaller is the WSI. We're not tracking what the WSI op actually /was/ in CV yet, but we need to mark 3088804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt // the fence as retired. 3089804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt pFence->state = FENCE_RETIRED; 3090804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt } 3091d4513979120463171eb479cdded9336eb9944da1Chris Forbes } 3092b3ecd4c1fb44a2e65dfc13256afa9150aabde1d4Chris Forbes} 3093b3ecd4c1fb44a2e65dfc13256afa9150aabde1d4Chris Forbes 3094accdf1d467e269e05b89764faf204fb2ff600b57Tobin Ehlisstatic bool PreCallValidateWaitForFences(layer_data *dev_data, uint32_t fence_count, const VkFence *fences) { 3095cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.wait_for_fences) return false; 3096accdf1d467e269e05b89764faf204fb2ff600b57Tobin Ehlis bool skip = false; 3097accdf1d467e269e05b89764faf204fb2ff600b57Tobin Ehlis for (uint32_t i = 0; i < fence_count; i++) { 3098accdf1d467e269e05b89764faf204fb2ff600b57Tobin Ehlis skip |= verifyWaitFenceState(dev_data, fences[i], "vkWaitForFences"); 3099b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlis skip |= VerifyQueueStateToFence(dev_data, fences[i]); 3100accdf1d467e269e05b89764faf204fb2ff600b57Tobin Ehlis } 3101accdf1d467e269e05b89764faf204fb2ff600b57Tobin Ehlis return skip; 3102accdf1d467e269e05b89764faf204fb2ff600b57Tobin Ehlis} 3103accdf1d467e269e05b89764faf204fb2ff600b57Tobin Ehlis 3104b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlisstatic void PostCallRecordWaitForFences(layer_data *dev_data, uint32_t fence_count, const VkFence *fences, VkBool32 wait_all) { 3105b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlis // When we know that all fences are complete we can clean/remove their CBs 3106accdf1d467e269e05b89764faf204fb2ff600b57Tobin Ehlis if ((VK_TRUE == wait_all) || (1 == fence_count)) { 3107accdf1d467e269e05b89764faf204fb2ff600b57Tobin Ehlis for (uint32_t i = 0; i < fence_count; i++) { 3108b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlis RetireFence(dev_data, fences[i]); 3109accdf1d467e269e05b89764faf204fb2ff600b57Tobin Ehlis } 3110accdf1d467e269e05b89764faf204fb2ff600b57Tobin Ehlis } 3111accdf1d467e269e05b89764faf204fb2ff600b57Tobin Ehlis // NOTE : Alternate case not handled here is when some fences have completed. In 3112accdf1d467e269e05b89764faf204fb2ff600b57Tobin Ehlis // this case for app to guarantee which fences completed it will have to call 3113b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlis // vkGetFenceStatus() at which point we'll clean/remove their CBs if complete. 3114accdf1d467e269e05b89764faf204fb2ff600b57Tobin Ehlis} 3115accdf1d467e269e05b89764faf204fb2ff600b57Tobin Ehlis 3116bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL WaitForFences(VkDevice device, uint32_t fenceCount, const VkFence *pFences, VkBool32 waitAll, 3117bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski uint64_t timeout) { 311856e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 31195b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Verify fence status of submitted fences 3120ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 3121accdf1d467e269e05b89764faf204fb2ff600b57Tobin Ehlis bool skip = PreCallValidateWaitForFences(dev_data, fenceCount, pFences); 3122b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 3123cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 3124a265a8ed3bbb32ade305b1be3148d6001a870b76Tobin Ehlis 31254a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.WaitForFences(device, fenceCount, pFences, waitAll, timeout); 3126414e9a4117b500eac650d8b8f01a6e1b22d05aaeMark Mueller 31275b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (result == VK_SUCCESS) { 3128b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.lock(); 3129b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlis PostCallRecordWaitForFences(dev_data, fenceCount, pFences, waitAll); 3130b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 31315b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 31325b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 31335b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 31345b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 3135f073b96e7a0030b55a66b780bd3ed57262cf1fa2Tobin Ehlisstatic bool PreCallValidateGetFenceStatus(layer_data *dev_data, VkFence fence) { 3136cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.get_fence_state) return false; 3137f073b96e7a0030b55a66b780bd3ed57262cf1fa2Tobin Ehlis return verifyWaitFenceState(dev_data, fence, "vkGetFenceStatus"); 3138f073b96e7a0030b55a66b780bd3ed57262cf1fa2Tobin Ehlis} 3139f073b96e7a0030b55a66b780bd3ed57262cf1fa2Tobin Ehlis 3140b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlisstatic void PostCallRecordGetFenceStatus(layer_data *dev_data, VkFence fence) { RetireFence(dev_data, fence); } 3141f073b96e7a0030b55a66b780bd3ed57262cf1fa2Tobin Ehlis 314289d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR VkResult VKAPI_CALL GetFenceStatus(VkDevice device, VkFence fence) { 314356e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 3144ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 3145f073b96e7a0030b55a66b780bd3ed57262cf1fa2Tobin Ehlis bool skip = PreCallValidateGetFenceStatus(dev_data, fence); 3146b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 3147cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 3148a265a8ed3bbb32ade305b1be3148d6001a870b76Tobin Ehlis 31494a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.GetFenceStatus(device, fence); 31505b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (result == VK_SUCCESS) { 3151f073b96e7a0030b55a66b780bd3ed57262cf1fa2Tobin Ehlis lock.lock(); 3152b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlis PostCallRecordGetFenceStatus(dev_data, fence); 3153f073b96e7a0030b55a66b780bd3ed57262cf1fa2Tobin Ehlis lock.unlock(); 31545b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 31555b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 31565b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 31575b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 31583b3fccc991a6cbe649b96880f36d90318b3c7cc2Tobin Ehlisstatic void PostCallRecordGetDeviceQueue(layer_data *dev_data, uint32_t q_family_index, VkQueue queue) { 31593b3fccc991a6cbe649b96880f36d90318b3c7cc2Tobin Ehlis // Add queue to tracking set only if it is new 31603b3fccc991a6cbe649b96880f36d90318b3c7cc2Tobin Ehlis auto result = dev_data->queues.emplace(queue); 31613b3fccc991a6cbe649b96880f36d90318b3c7cc2Tobin Ehlis if (result.second == true) { 316236c3a4fe8455762d2dc0b2b9ece44675a3ee8d97Tobin Ehlis QUEUE_STATE *queue_state = &dev_data->queueMap[queue]; 31633b3fccc991a6cbe649b96880f36d90318b3c7cc2Tobin Ehlis queue_state->queue = queue; 31643b3fccc991a6cbe649b96880f36d90318b3c7cc2Tobin Ehlis queue_state->queueFamilyIndex = q_family_index; 31653b3fccc991a6cbe649b96880f36d90318b3c7cc2Tobin Ehlis queue_state->seq = 0; 31663b3fccc991a6cbe649b96880f36d90318b3c7cc2Tobin Ehlis } 31673b3fccc991a6cbe649b96880f36d90318b3c7cc2Tobin Ehlis} 31683b3fccc991a6cbe649b96880f36d90318b3c7cc2Tobin Ehlis 3169bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL GetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue *pQueue) { 317056e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 31714a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.GetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue); 3172ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 3173b376edacad6f7ab3fcc0a914e9b1673a9fcd5143Mark Lobodzinski 31743b3fccc991a6cbe649b96880f36d90318b3c7cc2Tobin Ehlis PostCallRecordGetDeviceQueue(dev_data, queueFamilyIndex, *pQueue); 31755b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 31765b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 317736c3a4fe8455762d2dc0b2b9ece44675a3ee8d97Tobin Ehlisstatic bool PreCallValidateQueueWaitIdle(layer_data *dev_data, VkQueue queue, QUEUE_STATE **queue_state) { 31789a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis *queue_state = GetQueueState(dev_data, queue); 3179cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.queue_wait_idle) return false; 3180e0cec9ec6dd3cfd83345cabba55ec021681801dbTobin Ehlis return VerifyQueueStateToSeq(dev_data, *queue_state, (*queue_state)->seq + (*queue_state)->submissions.size()); 31814273a1c157585a645dca4c960086032793899d05Tobin Ehlis} 31824273a1c157585a645dca4c960086032793899d05Tobin Ehlis 318336c3a4fe8455762d2dc0b2b9ece44675a3ee8d97Tobin Ehlisstatic void PostCallRecordQueueWaitIdle(layer_data *dev_data, QUEUE_STATE *queue_state) { 3184e0cec9ec6dd3cfd83345cabba55ec021681801dbTobin Ehlis RetireWorkOnQueue(dev_data, queue_state, queue_state->seq + queue_state->submissions.size()); 31854273a1c157585a645dca4c960086032793899d05Tobin Ehlis} 31864273a1c157585a645dca4c960086032793899d05Tobin Ehlis 318789d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR VkResult VKAPI_CALL QueueWaitIdle(VkQueue queue) { 318856e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(queue), layer_data_map); 318936c3a4fe8455762d2dc0b2b9ece44675a3ee8d97Tobin Ehlis QUEUE_STATE *queue_state = nullptr; 3190ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 31914273a1c157585a645dca4c960086032793899d05Tobin Ehlis bool skip = PreCallValidateQueueWaitIdle(dev_data, queue, &queue_state); 31929867daedbf52debc77d6568162ee21e071699b80Chris Forbes lock.unlock(); 3193cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 31944a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.QueueWaitIdle(queue); 31954273a1c157585a645dca4c960086032793899d05Tobin Ehlis if (VK_SUCCESS == result) { 3196e0cec9ec6dd3cfd83345cabba55ec021681801dbTobin Ehlis lock.lock(); 3197e0cec9ec6dd3cfd83345cabba55ec021681801dbTobin Ehlis PostCallRecordQueueWaitIdle(dev_data, queue_state); 3198e0cec9ec6dd3cfd83345cabba55ec021681801dbTobin Ehlis lock.unlock(); 31994273a1c157585a645dca4c960086032793899d05Tobin Ehlis } 32005b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 32015b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 32025b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 32038767ceaf6a7d5675c2fe0502df31a1339a5a6337Tobin Ehlisstatic bool PreCallValidateDeviceWaitIdle(layer_data *dev_data) { 3204cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.device_wait_idle) return false; 32058767ceaf6a7d5675c2fe0502df31a1339a5a6337Tobin Ehlis bool skip = false; 32068767ceaf6a7d5675c2fe0502df31a1339a5a6337Tobin Ehlis for (auto &queue : dev_data->queueMap) { 32078767ceaf6a7d5675c2fe0502df31a1339a5a6337Tobin Ehlis skip |= VerifyQueueStateToSeq(dev_data, &queue.second, queue.second.seq + queue.second.submissions.size()); 32088767ceaf6a7d5675c2fe0502df31a1339a5a6337Tobin Ehlis } 32098767ceaf6a7d5675c2fe0502df31a1339a5a6337Tobin Ehlis return skip; 32108767ceaf6a7d5675c2fe0502df31a1339a5a6337Tobin Ehlis} 32118767ceaf6a7d5675c2fe0502df31a1339a5a6337Tobin Ehlis 32128767ceaf6a7d5675c2fe0502df31a1339a5a6337Tobin Ehlisstatic void PostCallRecordDeviceWaitIdle(layer_data *dev_data) { 32138767ceaf6a7d5675c2fe0502df31a1339a5a6337Tobin Ehlis for (auto &queue : dev_data->queueMap) { 32148767ceaf6a7d5675c2fe0502df31a1339a5a6337Tobin Ehlis RetireWorkOnQueue(dev_data, &queue.second, queue.second.seq + queue.second.submissions.size()); 32158767ceaf6a7d5675c2fe0502df31a1339a5a6337Tobin Ehlis } 32168767ceaf6a7d5675c2fe0502df31a1339a5a6337Tobin Ehlis} 32178767ceaf6a7d5675c2fe0502df31a1339a5a6337Tobin Ehlis 321889d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR VkResult VKAPI_CALL DeviceWaitIdle(VkDevice device) { 321956e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 3220ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 32218767ceaf6a7d5675c2fe0502df31a1339a5a6337Tobin Ehlis bool skip = PreCallValidateDeviceWaitIdle(dev_data); 3222b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 3223cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 32244a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.DeviceWaitIdle(device); 32258767ceaf6a7d5675c2fe0502df31a1339a5a6337Tobin Ehlis if (VK_SUCCESS == result) { 32268767ceaf6a7d5675c2fe0502df31a1339a5a6337Tobin Ehlis lock.lock(); 32278767ceaf6a7d5675c2fe0502df31a1339a5a6337Tobin Ehlis PostCallRecordDeviceWaitIdle(dev_data); 32288767ceaf6a7d5675c2fe0502df31a1339a5a6337Tobin Ehlis lock.unlock(); 32298767ceaf6a7d5675c2fe0502df31a1339a5a6337Tobin Ehlis } 32305b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 32315b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 32325b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 32331d3dce01906e45faf7282cffc3334cbda1662656Tobin Ehlisstatic bool PreCallValidateDestroyFence(layer_data *dev_data, VkFence fence, FENCE_NODE **fence_node, VK_OBJECT *obj_struct) { 32349a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis *fence_node = GetFenceNode(dev_data, fence); 32359b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus *obj_struct = {HandleToUint64(fence), kVulkanObjectTypeFence}; 3236cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.destroy_fence) return false; 32371d3dce01906e45faf7282cffc3334cbda1662656Tobin Ehlis bool skip = false; 32381d3dce01906e45faf7282cffc3334cbda1662656Tobin Ehlis if (*fence_node) { 3239804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt if ((*fence_node)->scope == kSyncScopeInternal && (*fence_node)->state == FENCE_INFLIGHT) { 32401d3dce01906e45faf7282cffc3334cbda1662656Tobin Ehlis skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, 3241315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(fence), __LINE__, VALIDATION_ERROR_24e008c0, "DS", "Fence 0x%" PRIx64 " is in use. %s", 3242315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(fence), validation_error_map[VALIDATION_ERROR_24e008c0]); 32431d3dce01906e45faf7282cffc3334cbda1662656Tobin Ehlis } 32441d3dce01906e45faf7282cffc3334cbda1662656Tobin Ehlis } 32451d3dce01906e45faf7282cffc3334cbda1662656Tobin Ehlis return skip; 32461d3dce01906e45faf7282cffc3334cbda1662656Tobin Ehlis} 32471d3dce01906e45faf7282cffc3334cbda1662656Tobin Ehlis 32481d3dce01906e45faf7282cffc3334cbda1662656Tobin Ehlisstatic void PostCallRecordDestroyFence(layer_data *dev_data, VkFence fence) { dev_data->fenceMap.erase(fence); } 32491d3dce01906e45faf7282cffc3334cbda1662656Tobin Ehlis 325089d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR void VKAPI_CALL DestroyFence(VkDevice device, VkFence fence, const VkAllocationCallbacks *pAllocator) { 325156e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 32521d3dce01906e45faf7282cffc3334cbda1662656Tobin Ehlis // Common data objects used pre & post call 32531d3dce01906e45faf7282cffc3334cbda1662656Tobin Ehlis FENCE_NODE *fence_node = nullptr; 32541d3dce01906e45faf7282cffc3334cbda1662656Tobin Ehlis VK_OBJECT obj_struct; 3255ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 32561d3dce01906e45faf7282cffc3334cbda1662656Tobin Ehlis bool skip = PreCallValidateDestroyFence(dev_data, fence, &fence_node, &obj_struct); 32571344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis 32581d3dce01906e45faf7282cffc3334cbda1662656Tobin Ehlis if (!skip) { 32591d3dce01906e45faf7282cffc3334cbda1662656Tobin Ehlis lock.unlock(); 32604a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.DestroyFence(device, fence, pAllocator); 32611d3dce01906e45faf7282cffc3334cbda1662656Tobin Ehlis lock.lock(); 32621d3dce01906e45faf7282cffc3334cbda1662656Tobin Ehlis PostCallRecordDestroyFence(dev_data, fence); 32631d3dce01906e45faf7282cffc3334cbda1662656Tobin Ehlis } 32645b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 32655b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 3266c0f1f8368ec7be6f098e2599b31622f81ff00185Tobin Ehlisstatic bool PreCallValidateDestroySemaphore(layer_data *dev_data, VkSemaphore semaphore, SEMAPHORE_NODE **sema_node, 3267c0f1f8368ec7be6f098e2599b31622f81ff00185Tobin Ehlis VK_OBJECT *obj_struct) { 32689a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis *sema_node = GetSemaphoreNode(dev_data, semaphore); 32699b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus *obj_struct = {HandleToUint64(semaphore), kVulkanObjectTypeSemaphore}; 3270cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.destroy_semaphore) return false; 3271c0f1f8368ec7be6f098e2599b31622f81ff00185Tobin Ehlis bool skip = false; 3272c0f1f8368ec7be6f098e2599b31622f81ff00185Tobin Ehlis if (*sema_node) { 327369ea2c79d7b3f9c987671a10686afac066b275b9Mike Schuchardt skip |= ValidateObjectNotInUse(dev_data, *sema_node, *obj_struct, "vkDestroySemaphore", VALIDATION_ERROR_268008e2); 3274c0f1f8368ec7be6f098e2599b31622f81ff00185Tobin Ehlis } 3275c0f1f8368ec7be6f098e2599b31622f81ff00185Tobin Ehlis return skip; 3276c0f1f8368ec7be6f098e2599b31622f81ff00185Tobin Ehlis} 3277c0f1f8368ec7be6f098e2599b31622f81ff00185Tobin Ehlis 3278c0f1f8368ec7be6f098e2599b31622f81ff00185Tobin Ehlisstatic void PostCallRecordDestroySemaphore(layer_data *dev_data, VkSemaphore sema) { dev_data->semaphoreMap.erase(sema); } 3279c0f1f8368ec7be6f098e2599b31622f81ff00185Tobin Ehlis 3280bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL DestroySemaphore(VkDevice device, VkSemaphore semaphore, const VkAllocationCallbacks *pAllocator) { 328156e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 3282c0f1f8368ec7be6f098e2599b31622f81ff00185Tobin Ehlis SEMAPHORE_NODE *sema_node; 3283c0f1f8368ec7be6f098e2599b31622f81ff00185Tobin Ehlis VK_OBJECT obj_struct; 3284ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 3285c0f1f8368ec7be6f098e2599b31622f81ff00185Tobin Ehlis bool skip = PreCallValidateDestroySemaphore(dev_data, semaphore, &sema_node, &obj_struct); 3286eafbf0b68ee6ea6e0bf33f07e0058d00a96efd9aTobin Ehlis if (!skip) { 3287eafbf0b68ee6ea6e0bf33f07e0058d00a96efd9aTobin Ehlis lock.unlock(); 32884a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.DestroySemaphore(device, semaphore, pAllocator); 3289c0f1f8368ec7be6f098e2599b31622f81ff00185Tobin Ehlis lock.lock(); 3290c0f1f8368ec7be6f098e2599b31622f81ff00185Tobin Ehlis PostCallRecordDestroySemaphore(dev_data, semaphore); 329199d938c90c2f000ee73fb13513dacf84ffa5651fMark Mueller } 32925b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 32935b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 32944710dda89a1dd2e023334d4eda710a394b211cdcTobin Ehlisstatic bool PreCallValidateDestroyEvent(layer_data *dev_data, VkEvent event, EVENT_STATE **event_state, VK_OBJECT *obj_struct) { 32959a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis *event_state = GetEventNode(dev_data, event); 32969b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus *obj_struct = {HandleToUint64(event), kVulkanObjectTypeEvent}; 3297cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.destroy_event) return false; 3298d379c77e4254a740aa838a82e7af186525524617Tobin Ehlis bool skip = false; 3299d379c77e4254a740aa838a82e7af186525524617Tobin Ehlis if (*event_state) { 330069ea2c79d7b3f9c987671a10686afac066b275b9Mike Schuchardt skip |= ValidateObjectNotInUse(dev_data, *event_state, *obj_struct, "vkDestroyEvent", VALIDATION_ERROR_24c008f2); 3301d379c77e4254a740aa838a82e7af186525524617Tobin Ehlis } 3302d379c77e4254a740aa838a82e7af186525524617Tobin Ehlis return skip; 3303d379c77e4254a740aa838a82e7af186525524617Tobin Ehlis} 3304d379c77e4254a740aa838a82e7af186525524617Tobin Ehlis 33054710dda89a1dd2e023334d4eda710a394b211cdcTobin Ehlisstatic void PostCallRecordDestroyEvent(layer_data *dev_data, VkEvent event, EVENT_STATE *event_state, VK_OBJECT obj_struct) { 330639c845ed4c066740e9efaed0a00af51be07c67c1Tobin Ehlis invalidateCommandBuffers(dev_data, event_state->cb_bindings, obj_struct); 3307d379c77e4254a740aa838a82e7af186525524617Tobin Ehlis dev_data->eventMap.erase(event); 3308d379c77e4254a740aa838a82e7af186525524617Tobin Ehlis} 3309d379c77e4254a740aa838a82e7af186525524617Tobin Ehlis 331089d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR void VKAPI_CALL DestroyEvent(VkDevice device, VkEvent event, const VkAllocationCallbacks *pAllocator) { 331156e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 33124710dda89a1dd2e023334d4eda710a394b211cdcTobin Ehlis EVENT_STATE *event_state = nullptr; 3313d379c77e4254a740aa838a82e7af186525524617Tobin Ehlis VK_OBJECT obj_struct; 3314ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 3315d379c77e4254a740aa838a82e7af186525524617Tobin Ehlis bool skip = PreCallValidateDestroyEvent(dev_data, event, &event_state, &obj_struct); 3316f57cf525e45f3a65e25c2691464d65e29a79ba77Tobin Ehlis if (!skip) { 3317f57cf525e45f3a65e25c2691464d65e29a79ba77Tobin Ehlis lock.unlock(); 33184a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.DestroyEvent(device, event, pAllocator); 3319d379c77e4254a740aa838a82e7af186525524617Tobin Ehlis lock.lock(); 3320405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour if (event != VK_NULL_HANDLE) { 3321405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour PostCallRecordDestroyEvent(dev_data, event, event_state, obj_struct); 3322405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour } 3323f57cf525e45f3a65e25c2691464d65e29a79ba77Tobin Ehlis } 33245b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 33255b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 332683c1f2cdfb8eca95c7d450aca7863d5b269b7be6Tobin Ehlisstatic bool PreCallValidateDestroyQueryPool(layer_data *dev_data, VkQueryPool query_pool, QUERY_POOL_NODE **qp_state, 332783c1f2cdfb8eca95c7d450aca7863d5b269b7be6Tobin Ehlis VK_OBJECT *obj_struct) { 33289a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis *qp_state = GetQueryPoolNode(dev_data, query_pool); 33299b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus *obj_struct = {HandleToUint64(query_pool), kVulkanObjectTypeQueryPool}; 3330cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.destroy_query_pool) return false; 333183c1f2cdfb8eca95c7d450aca7863d5b269b7be6Tobin Ehlis bool skip = false; 333283c1f2cdfb8eca95c7d450aca7863d5b269b7be6Tobin Ehlis if (*qp_state) { 333369ea2c79d7b3f9c987671a10686afac066b275b9Mike Schuchardt skip |= ValidateObjectNotInUse(dev_data, *qp_state, *obj_struct, "vkDestroyQueryPool", VALIDATION_ERROR_26200632); 333483c1f2cdfb8eca95c7d450aca7863d5b269b7be6Tobin Ehlis } 333583c1f2cdfb8eca95c7d450aca7863d5b269b7be6Tobin Ehlis return skip; 333683c1f2cdfb8eca95c7d450aca7863d5b269b7be6Tobin Ehlis} 333783c1f2cdfb8eca95c7d450aca7863d5b269b7be6Tobin Ehlis 3338bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinskistatic void PostCallRecordDestroyQueryPool(layer_data *dev_data, VkQueryPool query_pool, QUERY_POOL_NODE *qp_state, 3339bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VK_OBJECT obj_struct) { 334083c1f2cdfb8eca95c7d450aca7863d5b269b7be6Tobin Ehlis invalidateCommandBuffers(dev_data, qp_state->cb_bindings, obj_struct); 334183c1f2cdfb8eca95c7d450aca7863d5b269b7be6Tobin Ehlis dev_data->queryPoolMap.erase(query_pool); 334283c1f2cdfb8eca95c7d450aca7863d5b269b7be6Tobin Ehlis} 334383c1f2cdfb8eca95c7d450aca7863d5b269b7be6Tobin Ehlis 3344bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL DestroyQueryPool(VkDevice device, VkQueryPool queryPool, const VkAllocationCallbacks *pAllocator) { 334556e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 334683c1f2cdfb8eca95c7d450aca7863d5b269b7be6Tobin Ehlis QUERY_POOL_NODE *qp_state = nullptr; 334783c1f2cdfb8eca95c7d450aca7863d5b269b7be6Tobin Ehlis VK_OBJECT obj_struct; 3348ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 334983c1f2cdfb8eca95c7d450aca7863d5b269b7be6Tobin Ehlis bool skip = PreCallValidateDestroyQueryPool(dev_data, queryPool, &qp_state, &obj_struct); 3350f57cf525e45f3a65e25c2691464d65e29a79ba77Tobin Ehlis if (!skip) { 3351f57cf525e45f3a65e25c2691464d65e29a79ba77Tobin Ehlis lock.unlock(); 33524a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.DestroyQueryPool(device, queryPool, pAllocator); 335383c1f2cdfb8eca95c7d450aca7863d5b269b7be6Tobin Ehlis lock.lock(); 3354405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour if (queryPool != VK_NULL_HANDLE) { 3355405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour PostCallRecordDestroyQueryPool(dev_data, queryPool, qp_state, obj_struct); 3356405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour } 3357f57cf525e45f3a65e25c2691464d65e29a79ba77Tobin Ehlis } 33585b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 33599fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlisstatic bool PreCallValidateGetQueryPoolResults(layer_data *dev_data, VkQueryPool query_pool, uint32_t first_query, 33609fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis uint32_t query_count, VkQueryResultFlags flags, 33619fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis unordered_map<QueryObject, vector<VkCommandBuffer>> *queries_in_flight) { 3362b36fb5ae8886f797de57fa6e14e8ccb079edef8eMark Lobodzinski bool skip = false; 3363b36fb5ae8886f797de57fa6e14e8ccb079edef8eMark Lobodzinski auto query_pool_state = dev_data->queryPoolMap.find(query_pool); 3364b36fb5ae8886f797de57fa6e14e8ccb079edef8eMark Lobodzinski if (query_pool_state != dev_data->queryPoolMap.end()) { 3365b36fb5ae8886f797de57fa6e14e8ccb079edef8eMark Lobodzinski if ((query_pool_state->second.createInfo.queryType == VK_QUERY_TYPE_TIMESTAMP) && (flags & VK_QUERY_RESULT_PARTIAL_BIT)) { 3366b36fb5ae8886f797de57fa6e14e8ccb079edef8eMark Lobodzinski skip |= log_msg( 3367b36fb5ae8886f797de57fa6e14e8ccb079edef8eMark Lobodzinski dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT, 0, __LINE__, 3368b36fb5ae8886f797de57fa6e14e8ccb079edef8eMark Lobodzinski VALIDATION_ERROR_2fa00664, "DS", 3369b36fb5ae8886f797de57fa6e14e8ccb079edef8eMark Lobodzinski "QueryPool 0x%" PRIx64 3370b36fb5ae8886f797de57fa6e14e8ccb079edef8eMark Lobodzinski " was created with a queryType of VK_QUERY_TYPE_TIMESTAMP but flags contains VK_QUERY_RESULT_PARTIAL_BIT. %s", 3371b36fb5ae8886f797de57fa6e14e8ccb079edef8eMark Lobodzinski HandleToUint64(query_pool), validation_error_map[VALIDATION_ERROR_2fa00664]); 3372b36fb5ae8886f797de57fa6e14e8ccb079edef8eMark Lobodzinski } 3373b36fb5ae8886f797de57fa6e14e8ccb079edef8eMark Lobodzinski } 3374b36fb5ae8886f797de57fa6e14e8ccb079edef8eMark Lobodzinski 3375a7fef8833e0b4e1e4c7ea20ab56da451a6856c0cChris Forbes // TODO: clean this up, it's insanely wasteful. 3376a7fef8833e0b4e1e4c7ea20ab56da451a6856c0cChris Forbes for (auto cmd_buffer : dev_data->commandBufferMap) { 3377a7fef8833e0b4e1e4c7ea20ab56da451a6856c0cChris Forbes if (cmd_buffer.second->in_use.load()) { 3378a7fef8833e0b4e1e4c7ea20ab56da451a6856c0cChris Forbes for (auto query_state_pair : cmd_buffer.second->queryToStateMap) { 3379b022d1937f5e9d9f87eef1097b4bf6f3b4043c9dMark Lobodzinski (*queries_in_flight)[query_state_pair.first].push_back(cmd_buffer.first); 3380a7fef8833e0b4e1e4c7ea20ab56da451a6856c0cChris Forbes } 33815b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 33825b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 3383b022d1937f5e9d9f87eef1097b4bf6f3b4043c9dMark Lobodzinski 3384cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.get_query_pool_results) return false; 33859fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis for (uint32_t i = 0; i < query_count; ++i) { 33869fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis QueryObject query = {query_pool, first_query + i}; 33879fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis auto qif_pair = queries_in_flight->find(query); 33889fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis auto query_state_pair = dev_data->queryToStateMap.find(query); 33899fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis if (query_state_pair != dev_data->queryToStateMap.end()) { 3390ec27ab7d1aa03fa187755b6720e1be995a994f5cMark Lobodzinski // Available and in flight 3391b022d1937f5e9d9f87eef1097b4bf6f3b4043c9dMark Lobodzinski if (qif_pair != queries_in_flight->end()) { 3392b022d1937f5e9d9f87eef1097b4bf6f3b4043c9dMark Lobodzinski if (query_state_pair->second) { 3393b022d1937f5e9d9f87eef1097b4bf6f3b4043c9dMark Lobodzinski for (auto cmd_buffer : qif_pair->second) { 3394b022d1937f5e9d9f87eef1097b4bf6f3b4043c9dMark Lobodzinski auto cb = GetCBNode(dev_data, cmd_buffer); 3395b022d1937f5e9d9f87eef1097b4bf6f3b4043c9dMark Lobodzinski auto query_event_pair = cb->waitedEventsBeforeQueryReset.find(query); 3396b022d1937f5e9d9f87eef1097b4bf6f3b4043c9dMark Lobodzinski if (query_event_pair == cb->waitedEventsBeforeQueryReset.end()) { 3397b022d1937f5e9d9f87eef1097b4bf6f3b4043c9dMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 3398b022d1937f5e9d9f87eef1097b4bf6f3b4043c9dMark Lobodzinski VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT, 0, __LINE__, DRAWSTATE_INVALID_QUERY, "DS", 3399b022d1937f5e9d9f87eef1097b4bf6f3b4043c9dMark Lobodzinski "Cannot get query results on queryPool 0x%" PRIx64 " with index %d which is in flight.", 3400b022d1937f5e9d9f87eef1097b4bf6f3b4043c9dMark Lobodzinski HandleToUint64(query_pool), first_query + i); 3401b022d1937f5e9d9f87eef1097b4bf6f3b4043c9dMark Lobodzinski } 3402b022d1937f5e9d9f87eef1097b4bf6f3b4043c9dMark Lobodzinski } 3403ec27ab7d1aa03fa187755b6720e1be995a994f5cMark Lobodzinski } 3404b022d1937f5e9d9f87eef1097b4bf6f3b4043c9dMark Lobodzinski } else if (!query_state_pair->second) { // Unavailable and Not in flight 34059fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT, 0, 34069fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis __LINE__, DRAWSTATE_INVALID_QUERY, "DS", 34079fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis "Cannot get query results on queryPool 0x%" PRIx64 " with index %d which is unavailable.", 34089b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(query_pool), first_query + i); 34095b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 3410b022d1937f5e9d9f87eef1097b4bf6f3b4043c9dMark Lobodzinski } else { // Uninitialized 3411b022d1937f5e9d9f87eef1097b4bf6f3b4043c9dMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT, 0, 3412b022d1937f5e9d9f87eef1097b4bf6f3b4043c9dMark Lobodzinski __LINE__, DRAWSTATE_INVALID_QUERY, "DS", 3413b022d1937f5e9d9f87eef1097b4bf6f3b4043c9dMark Lobodzinski "Cannot get query results on queryPool 0x%" PRIx64 3414b022d1937f5e9d9f87eef1097b4bf6f3b4043c9dMark Lobodzinski " with index %d as data has not been collected for this index.", 3415b022d1937f5e9d9f87eef1097b4bf6f3b4043c9dMark Lobodzinski HandleToUint64(query_pool), first_query + i); 34165b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 34175b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 34189fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis return skip; 34199fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis} 34209fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis 34219fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlisstatic void PostCallRecordGetQueryPoolResults(layer_data *dev_data, VkQueryPool query_pool, uint32_t first_query, 34229fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis uint32_t query_count, 34239fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis unordered_map<QueryObject, vector<VkCommandBuffer>> *queries_in_flight) { 34249fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis for (uint32_t i = 0; i < query_count; ++i) { 34259fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis QueryObject query = {query_pool, first_query + i}; 34269fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis auto qif_pair = queries_in_flight->find(query); 34279fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis auto query_state_pair = dev_data->queryToStateMap.find(query); 34289fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis if (query_state_pair != dev_data->queryToStateMap.end()) { 34299fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis // Available and in flight 34309fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis if (qif_pair != queries_in_flight->end() && query_state_pair != dev_data->queryToStateMap.end() && 34319fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis query_state_pair->second) { 34329fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis for (auto cmd_buffer : qif_pair->second) { 34339a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto cb = GetCBNode(dev_data, cmd_buffer); 34349fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis auto query_event_pair = cb->waitedEventsBeforeQueryReset.find(query); 34359fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis if (query_event_pair != cb->waitedEventsBeforeQueryReset.end()) { 34369fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis for (auto event : query_event_pair->second) { 34379fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis dev_data->eventMap[event].needsSignaled = true; 34389fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis } 34399fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis } 34409fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis } 34419fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis } 34429fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis } 34439fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis } 34449fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis} 34459fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis 34469fdee42cd357379efb9aa27f90beb75d1f824955Tobin EhlisVKAPI_ATTR VkResult VKAPI_CALL GetQueryPoolResults(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, 34479fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis size_t dataSize, void *pData, VkDeviceSize stride, VkQueryResultFlags flags) { 344856e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 34499fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis unordered_map<QueryObject, vector<VkCommandBuffer>> queries_in_flight; 3450ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 34519fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis bool skip = PreCallValidateGetQueryPoolResults(dev_data, queryPool, firstQuery, queryCount, flags, &queries_in_flight); 3452b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 3453cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 34549fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis VkResult result = 34559fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis dev_data->dispatch_table.GetQueryPoolResults(device, queryPool, firstQuery, queryCount, dataSize, pData, stride, flags); 34569fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis lock.lock(); 34579fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis PostCallRecordGetQueryPoolResults(dev_data, queryPool, firstQuery, queryCount, &queries_in_flight); 34589fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis lock.unlock(); 34599fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis return result; 34605b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 34615b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 3462825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis// Return true if given ranges intersect, else false 3463825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis// Prereq : For both ranges, range->end - range->start > 0. This case should have already resulted 3464825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis// in an error so not checking that here 3465825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis// pad_ranges bool indicates a linear and non-linear comparison which requires padding 34663251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski// In the case where padding is required, if an alias is encountered then a validation error is reported and skip 34673251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski// may be set by the callback function so caller should merge in skip value if padding case is possible. 34682ea938737c34152a86f5e453eaef7f77b45c0ea3Cort Stratton// This check can be skipped by passing skip_checks=true, for call sites outside the validation path. 34693251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinskistatic bool rangesIntersect(layer_data const *dev_data, MEMORY_RANGE const *range1, MEMORY_RANGE const *range2, bool *skip, 34702ea938737c34152a86f5e453eaef7f77b45c0ea3Cort Stratton bool skip_checks) { 34713251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski *skip = false; 3472825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis auto r1_start = range1->start; 3473825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis auto r1_end = range1->end; 3474825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis auto r2_start = range2->start; 3475825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis auto r2_end = range2->end; 3476825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis VkDeviceSize pad_align = 1; 3477825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis if (range1->linear != range2->linear) { 3478825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis pad_align = dev_data->phys_dev_properties.properties.limits.bufferImageGranularity; 3479825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis } 3480cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if ((r1_end & ~(pad_align - 1)) < (r2_start & ~(pad_align - 1))) return false; 3481cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if ((r1_start & ~(pad_align - 1)) > (r2_end & ~(pad_align - 1))) return false; 348247aaf733d7394bda75c6de24289efe6b281e3cffMark Lobodzinski 34832ea938737c34152a86f5e453eaef7f77b45c0ea3Cort Stratton if (!skip_checks && (range1->linear != range2->linear)) { 348453ecec26e80e4d18b57d24ed6eb91a3c9da4b95cTobin Ehlis // In linear vs. non-linear case, warn of aliasing 3485825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis const char *r1_linear_str = range1->linear ? "Linear" : "Non-linear"; 3486825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis const char *r1_type_str = range1->image ? "image" : "buffer"; 3487825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis const char *r2_linear_str = range2->linear ? "linear" : "non-linear"; 3488825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis const char *r2_type_str = range2->image ? "image" : "buffer"; 3489825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis auto obj_type = range1->image ? VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT : VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT; 34903251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski *skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, obj_type, range1->handle, 0, 34913251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski MEMTRACK_INVALID_ALIASING, "MEM", "%s %s 0x%" PRIx64 " is aliased with %s %s 0x%" PRIx64 34923251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski " which may indicate a bug. For further info refer to the " 34933251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Buffer-Image Granularity section of the Vulkan specification. " 34943251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "(https://www.khronos.org/registry/vulkan/specs/1.0-extensions/" 34953251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "xhtml/vkspec.html#resources-bufferimagegranularity)", 34963251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski r1_linear_str, r1_type_str, range1->handle, r2_linear_str, r2_type_str, range2->handle); 349747aaf733d7394bda75c6de24289efe6b281e3cffMark Lobodzinski } 3498825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis // Ranges intersect 3499825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis return true; 350047aaf733d7394bda75c6de24289efe6b281e3cffMark Lobodzinski} 3501623548a271287ae55415e45e3c654ee66d4e79ffTobin Ehlis// Simplified rangesIntersect that calls above function to check range1 for intersection with offset & end addresses 3502c3340a06ecac4d7b9540592cae339f8fc224d0b1Mark Lobodzinskibool rangesIntersect(layer_data const *dev_data, MEMORY_RANGE const *range1, VkDeviceSize offset, VkDeviceSize end) { 3503825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis // Create a local MEMORY_RANGE struct to wrap offset/size 3504825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis MEMORY_RANGE range_wrap; 3505825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis // Synch linear with range1 to avoid padding and potential validation error case 3506825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis range_wrap.linear = range1->linear; 3507825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis range_wrap.start = offset; 3508cf17f50f6489504c0d8151c46d6f77404ce2ffffTobin Ehlis range_wrap.end = end; 3509825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis bool tmp_bool; 35102ea938737c34152a86f5e453eaef7f77b45c0ea3Cort Stratton return rangesIntersect(dev_data, range1, &range_wrap, &tmp_bool, true); 3511825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis} 3512cf17f50f6489504c0d8151c46d6f77404ce2ffffTobin Ehlis// For given mem_info, set all ranges valid that intersect [offset-end] range 3513cf17f50f6489504c0d8151c46d6f77404ce2ffffTobin Ehlis// TODO : For ranges where there is no alias, we may want to create new buffer ranges that are valid 3514cf17f50f6489504c0d8151c46d6f77404ce2ffffTobin Ehlisstatic void SetMemRangesValid(layer_data const *dev_data, DEVICE_MEM_INFO *mem_info, VkDeviceSize offset, VkDeviceSize end) { 3515cf17f50f6489504c0d8151c46d6f77404ce2ffffTobin Ehlis bool tmp_bool = false; 3516f6e16b28b808a342cb92768001afa2cfeee08a11Tobin Ehlis MEMORY_RANGE map_range = {}; 3517cf17f50f6489504c0d8151c46d6f77404ce2ffffTobin Ehlis map_range.linear = true; 3518cf17f50f6489504c0d8151c46d6f77404ce2ffffTobin Ehlis map_range.start = offset; 3519cf17f50f6489504c0d8151c46d6f77404ce2ffffTobin Ehlis map_range.end = end; 3520cf17f50f6489504c0d8151c46d6f77404ce2ffffTobin Ehlis for (auto &handle_range_pair : mem_info->bound_ranges) { 35212ea938737c34152a86f5e453eaef7f77b45c0ea3Cort Stratton if (rangesIntersect(dev_data, &handle_range_pair.second, &map_range, &tmp_bool, false)) { 3522cf17f50f6489504c0d8151c46d6f77404ce2ffffTobin Ehlis // TODO : WARN here if tmp_bool true? 3523cf17f50f6489504c0d8151c46d6f77404ce2ffffTobin Ehlis handle_range_pair.second.valid = true; 3524cf17f50f6489504c0d8151c46d6f77404ce2ffffTobin Ehlis } 3525cf17f50f6489504c0d8151c46d6f77404ce2ffffTobin Ehlis } 3526cf17f50f6489504c0d8151c46d6f77404ce2ffffTobin Ehlis} 35270ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton 35280ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Strattonstatic bool ValidateInsertMemoryRange(layer_data const *dev_data, uint64_t handle, DEVICE_MEM_INFO *mem_info, 35290ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton VkDeviceSize memoryOffset, VkMemoryRequirements memRequirements, bool is_image, 35300ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton bool is_linear, const char *api_name) { 35310ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton bool skip = false; 35320ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton 35330ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton MEMORY_RANGE range; 35340ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton range.image = is_image; 35350ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton range.handle = handle; 35360ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton range.linear = is_linear; 35370ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton range.valid = mem_info->global_valid; 35380ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton range.memory = mem_info->mem; 35390ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton range.start = memoryOffset; 35400ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton range.size = memRequirements.size; 35410ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton range.end = memoryOffset + memRequirements.size - 1; 35420ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton range.aliases.clear(); 35430ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton 35440ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton // Check for aliasing problems. 35450ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton for (auto &obj_range_pair : mem_info->bound_ranges) { 35460ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton auto check_range = &obj_range_pair.second; 35470ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton bool intersection_error = false; 35482ea938737c34152a86f5e453eaef7f77b45c0ea3Cort Stratton if (rangesIntersect(dev_data, &range, check_range, &intersection_error, false)) { 35490ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton skip |= intersection_error; 35500ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton range.aliases.insert(check_range); 35510ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton } 35520ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton } 35530ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton 35540ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton if (memoryOffset >= mem_info->alloc_info.allocationSize) { 3555315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis UNIQUE_VALIDATION_ERROR_CODE error_code = is_image ? VALIDATION_ERROR_1740082c : VALIDATION_ERROR_1700080e; 35560ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton skip = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 35579b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(mem_info->mem), __LINE__, error_code, "MEM", 35580ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton "In %s, attempting to bind memory (0x%" PRIxLEAST64 ") to object (0x%" PRIxLEAST64 35590ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton "), memoryOffset=0x%" PRIxLEAST64 " must be less than the memory allocation size 0x%" PRIxLEAST64 ". %s", 35609b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus api_name, HandleToUint64(mem_info->mem), handle, memoryOffset, mem_info->alloc_info.allocationSize, 35619b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus validation_error_map[error_code]); 35620ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton } 35630ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton 35640ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton return skip; 35650ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton} 35660ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton 3567825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis// Object with given handle is being bound to memory w/ given mem_info struct. 3568825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis// Track the newly bound memory range with given memoryOffset 3569825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis// Also scan any previous ranges, track aliased ranges with new range, and flag an error if a linear 3570825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis// and non-linear range incorrectly overlap. 3571825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis// Return true if an error is flagged and the user callback returns "true", otherwise false 3572825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis// is_image indicates an image object, otherwise handle is for a buffer 3573825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis// is_linear indicates a buffer or linear image 35740ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Strattonstatic void InsertMemoryRange(layer_data const *dev_data, uint64_t handle, DEVICE_MEM_INFO *mem_info, VkDeviceSize memoryOffset, 35750ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton VkMemoryRequirements memRequirements, bool is_image, bool is_linear) { 35765360871dd546e8aa7c1a273e9036c201fe4e3ffbTobin Ehlis MEMORY_RANGE range; 3577825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis 3578825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis range.image = is_image; 357947aaf733d7394bda75c6de24289efe6b281e3cffMark Lobodzinski range.handle = handle; 3580825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis range.linear = is_linear; 3581f541bf53dee6daf82a4c8304354eac599a884d29Tobin Ehlis range.valid = mem_info->global_valid; 3582825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis range.memory = mem_info->mem; 358347aaf733d7394bda75c6de24289efe6b281e3cffMark Lobodzinski range.start = memoryOffset; 3584825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis range.size = memRequirements.size; 358547aaf733d7394bda75c6de24289efe6b281e3cffMark Lobodzinski range.end = memoryOffset + memRequirements.size - 1; 35865360871dd546e8aa7c1a273e9036c201fe4e3ffbTobin Ehlis range.aliases.clear(); 35875360871dd546e8aa7c1a273e9036c201fe4e3ffbTobin Ehlis // Update Memory aliasing 358875f4c8cec0996021a4258b9bf920a9e0fea4eac1Tobin 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 35895360871dd546e8aa7c1a273e9036c201fe4e3ffbTobin Ehlis // inserted into map before loop to get the final ptr, then we may enter loop when not needed & we check range against itself 35905360871dd546e8aa7c1a273e9036c201fe4e3ffbTobin Ehlis std::unordered_set<MEMORY_RANGE *> tmp_alias_ranges; 3591825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis for (auto &obj_range_pair : mem_info->bound_ranges) { 3592825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis auto check_range = &obj_range_pair.second; 35935360871dd546e8aa7c1a273e9036c201fe4e3ffbTobin Ehlis bool intersection_error = false; 35942ea938737c34152a86f5e453eaef7f77b45c0ea3Cort Stratton if (rangesIntersect(dev_data, &range, check_range, &intersection_error, true)) { 3595825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis range.aliases.insert(check_range); 35965360871dd546e8aa7c1a273e9036c201fe4e3ffbTobin Ehlis tmp_alias_ranges.insert(check_range); 3597825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis } 3598825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis } 35995360871dd546e8aa7c1a273e9036c201fe4e3ffbTobin Ehlis mem_info->bound_ranges[handle] = std::move(range); 36005360871dd546e8aa7c1a273e9036c201fe4e3ffbTobin Ehlis for (auto tmp_range : tmp_alias_ranges) { 36015360871dd546e8aa7c1a273e9036c201fe4e3ffbTobin Ehlis tmp_range->aliases.insert(&mem_info->bound_ranges[handle]); 36025360871dd546e8aa7c1a273e9036c201fe4e3ffbTobin Ehlis } 3603825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis if (is_image) 3604825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis mem_info->bound_images.insert(handle); 3605825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis else 3606825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis mem_info->bound_buffers.insert(handle); 360747aaf733d7394bda75c6de24289efe6b281e3cffMark Lobodzinski} 360847aaf733d7394bda75c6de24289efe6b281e3cffMark Lobodzinski 36090ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Strattonstatic bool ValidateInsertImageMemoryRange(layer_data const *dev_data, VkImage image, DEVICE_MEM_INFO *mem_info, 36100ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton VkDeviceSize mem_offset, VkMemoryRequirements mem_reqs, bool is_linear, 36110ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton const char *api_name) { 36129b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus return ValidateInsertMemoryRange(dev_data, HandleToUint64(image), mem_info, mem_offset, mem_reqs, true, is_linear, api_name); 36130ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton} 36140ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Strattonstatic void InsertImageMemoryRange(layer_data const *dev_data, VkImage image, DEVICE_MEM_INFO *mem_info, VkDeviceSize mem_offset, 36150ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton VkMemoryRequirements mem_reqs, bool is_linear) { 36169b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus InsertMemoryRange(dev_data, HandleToUint64(image), mem_info, mem_offset, mem_reqs, true, is_linear); 3617825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis} 3618825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis 36190ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Strattonstatic bool ValidateInsertBufferMemoryRange(layer_data const *dev_data, VkBuffer buffer, DEVICE_MEM_INFO *mem_info, 36200ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton VkDeviceSize mem_offset, VkMemoryRequirements mem_reqs, const char *api_name) { 36219b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus return ValidateInsertMemoryRange(dev_data, HandleToUint64(buffer), mem_info, mem_offset, mem_reqs, false, true, api_name); 36220ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton} 36230ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Strattonstatic void InsertBufferMemoryRange(layer_data const *dev_data, VkBuffer buffer, DEVICE_MEM_INFO *mem_info, VkDeviceSize mem_offset, 36240ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton VkMemoryRequirements mem_reqs) { 36259b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus InsertMemoryRange(dev_data, HandleToUint64(buffer), mem_info, mem_offset, mem_reqs, false, true); 3626825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis} 3627825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis 3628825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis// Remove MEMORY_RANGE struct for give handle from bound_ranges of mem_info 3629825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis// is_image indicates if handle is for image or buffer 3630825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis// This function will also remove the handle-to-index mapping from the appropriate 3631825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis// map and clean up any aliases for range being removed. 3632825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlisstatic void RemoveMemoryRange(uint64_t handle, DEVICE_MEM_INFO *mem_info, bool is_image) { 3633825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis auto erase_range = &mem_info->bound_ranges[handle]; 3634825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis for (auto alias_range : erase_range->aliases) { 3635825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis alias_range->aliases.erase(erase_range); 363647aaf733d7394bda75c6de24289efe6b281e3cffMark Lobodzinski } 36375360871dd546e8aa7c1a273e9036c201fe4e3ffbTobin Ehlis erase_range->aliases.clear(); 3638825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis mem_info->bound_ranges.erase(handle); 36391cba4e1b5940c6818572e05dcad5a3a47fafbc9eTobin Ehlis if (is_image) { 3640825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis mem_info->bound_images.erase(handle); 36411cba4e1b5940c6818572e05dcad5a3a47fafbc9eTobin Ehlis } else { 3642825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis mem_info->bound_buffers.erase(handle); 36431cba4e1b5940c6818572e05dcad5a3a47fafbc9eTobin Ehlis } 364447aaf733d7394bda75c6de24289efe6b281e3cffMark Lobodzinski} 364547aaf733d7394bda75c6de24289efe6b281e3cffMark Lobodzinski 3646842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinskivoid RemoveBufferMemoryRange(uint64_t handle, DEVICE_MEM_INFO *mem_info) { RemoveMemoryRange(handle, mem_info, false); } 3647825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis 36488c59133586421be878d393799b30044497f77727Mark Lobodzinskivoid RemoveImageMemoryRange(uint64_t handle, DEVICE_MEM_INFO *mem_info) { RemoveMemoryRange(handle, mem_info, true); } 3649825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis 3650bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL DestroyBuffer(VkDevice device, VkBuffer buffer, const VkAllocationCallbacks *pAllocator) { 365156e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 3652e1056daefb39e3a3fed0088874725c56a1359e54Tobin Ehlis BUFFER_STATE *buffer_state = nullptr; 3653e1056daefb39e3a3fed0088874725c56a1359e54Tobin Ehlis VK_OBJECT obj_struct; 3654ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 3655e1056daefb39e3a3fed0088874725c56a1359e54Tobin Ehlis bool skip = PreCallValidateDestroyBuffer(dev_data, buffer, &buffer_state, &obj_struct); 3656e1056daefb39e3a3fed0088874725c56a1359e54Tobin Ehlis if (!skip) { 3657b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 36584a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.DestroyBuffer(device, buffer, pAllocator); 3659e1056daefb39e3a3fed0088874725c56a1359e54Tobin Ehlis lock.lock(); 3660405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour if (buffer != VK_NULL_HANDLE) { 3661405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour PostCallRecordDestroyBuffer(dev_data, buffer, buffer_state, obj_struct); 3662405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour } 366347aaf733d7394bda75c6de24289efe6b281e3cffMark Lobodzinski } 36645b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 36655b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 3666bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL DestroyBufferView(VkDevice device, VkBufferView bufferView, const VkAllocationCallbacks *pAllocator) { 366756e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 3668f61017735c3291a2665487f2bac310578fc60a68Tobin Ehlis // Common data objects used pre & post call 36698e0ffae5b5c87fa062229b8c003be10c7e48aea1Tobin Ehlis BUFFER_VIEW_STATE *buffer_view_state = nullptr; 36708e0ffae5b5c87fa062229b8c003be10c7e48aea1Tobin Ehlis VK_OBJECT obj_struct; 3671ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 36728e0ffae5b5c87fa062229b8c003be10c7e48aea1Tobin Ehlis // Validate state before calling down chain, update common data if we'll be calling down chain 36738e0ffae5b5c87fa062229b8c003be10c7e48aea1Tobin Ehlis bool skip = PreCallValidateDestroyBufferView(dev_data, bufferView, &buffer_view_state, &obj_struct); 367438e26abbaa884eb48bfec4ddb4e0ae2c90634e06Tobin Ehlis if (!skip) { 367538e26abbaa884eb48bfec4ddb4e0ae2c90634e06Tobin Ehlis lock.unlock(); 36764a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.DestroyBufferView(device, bufferView, pAllocator); 36778e0ffae5b5c87fa062229b8c003be10c7e48aea1Tobin Ehlis lock.lock(); 3678405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour if (bufferView != VK_NULL_HANDLE) { 3679405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour PostCallRecordDestroyBufferView(dev_data, bufferView, buffer_view_state, obj_struct); 3680405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour } 36815b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 36825b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 36835b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 36842a0dd15a44bf665c97a3ff6adcbe7fe5853cdf60Tobin EhlisVKAPI_ATTR void VKAPI_CALL DestroyImage(VkDevice device, VkImage image, const VkAllocationCallbacks *pAllocator) { 368556e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 36861facd2c91911508b9fb61f54a56269841299f663Tobin Ehlis IMAGE_STATE *image_state = nullptr; 36872a0dd15a44bf665c97a3ff6adcbe7fe5853cdf60Tobin Ehlis VK_OBJECT obj_struct; 3688ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 36892a0dd15a44bf665c97a3ff6adcbe7fe5853cdf60Tobin Ehlis bool skip = PreCallValidateDestroyImage(dev_data, image, &image_state, &obj_struct); 36902a0dd15a44bf665c97a3ff6adcbe7fe5853cdf60Tobin Ehlis if (!skip) { 3691f940225c9e5e3e14b3f5a32d3ea360b585614600Tobin Ehlis lock.unlock(); 36924a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.DestroyImage(device, image, pAllocator); 36932a0dd15a44bf665c97a3ff6adcbe7fe5853cdf60Tobin Ehlis lock.lock(); 3694405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour if (image != VK_NULL_HANDLE) { 3695405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour PostCallRecordDestroyImage(dev_data, image, image_state, obj_struct); 3696405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour } 36975b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 36985b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 36995b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 37004261f1e2c91c90ce040ab36a13c9d92f6e988f10Mark Lobodzinskistatic bool ValidateMemoryTypes(const layer_data *dev_data, const DEVICE_MEM_INFO *mem_info, const uint32_t memory_type_bits, 3701f634be57d858a71969b3183cd0e322fe1d0ad0fbMike Weiblen const char *funcName, UNIQUE_VALIDATION_ERROR_CODE msgCode) { 37023251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 3703de1d2592cdd497642de5b0e6f27ebc439018383bTobin Ehlis if (((1 << mem_info->alloc_info.memoryTypeIndex) & memory_type_bits) == 0) { 37043251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 37059b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(mem_info->mem), __LINE__, msgCode, "MT", 37063251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "%s(): MemoryRequirements->memoryTypeBits (0x%X) for this object type are not compatible with the memory " 37073251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "type (0x%X) of this memory object 0x%" PRIx64 ". %s", 37089b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus funcName, memory_type_bits, mem_info->alloc_info.memoryTypeIndex, HandleToUint64(mem_info->mem), 37099b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus validation_error_map[msgCode]); 37104261f1e2c91c90ce040ab36a13c9d92f6e988f10Mark Lobodzinski } 37113251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 37124261f1e2c91c90ce040ab36a13c9d92f6e988f10Mark Lobodzinski} 37134261f1e2c91c90ce040ab36a13c9d92f6e988f10Mark Lobodzinski 3714160335c453ec51cc48bdef78e8befdb3c86ff292Cort Strattonstatic bool PreCallValidateBindBufferMemory(layer_data *dev_data, VkBuffer buffer, BUFFER_STATE *buffer_state, VkDeviceMemory mem, 3715160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton VkDeviceSize memoryOffset) { 37169207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton bool skip = false; 37175cca7b0a90e0b6fe1cc28ddbe9037c3ce3f3ee13Tobin Ehlis if (buffer_state) { 3718ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 37199207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton // Track objects tied to memory 37209b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus uint64_t buffer_handle = HandleToUint64(buffer); 37217a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski skip = ValidateSetMemBinding(dev_data, mem, buffer_handle, kVulkanObjectTypeBuffer, "vkBindBufferMemory()"); 37222eda842d84a02b9d5bfb03d6c26c5f7c00e6e8beTobin Ehlis if (!buffer_state->memory_requirements_checked) { 37232eda842d84a02b9d5bfb03d6c26c5f7c00e6e8beTobin Ehlis // There's not an explicit requirement in the spec to call vkGetBufferMemoryRequirements() prior to calling 37249207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton // BindBufferMemory, but it's implied in that memory being bound must conform with VkMemoryRequirements from 37259207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton // vkGetBufferMemoryRequirements() 37269207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, 37279207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton buffer_handle, __LINE__, DRAWSTATE_INVALID_BUFFER, "DS", 37289207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton "vkBindBufferMemory(): Binding memory to buffer 0x%" PRIxLEAST64 37299207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton " but vkGetBufferMemoryRequirements() has not been called on that buffer.", 37309207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton buffer_handle); 37312eda842d84a02b9d5bfb03d6c26c5f7c00e6e8beTobin Ehlis // Make the call for them so we can verify the state 37322eda842d84a02b9d5bfb03d6c26c5f7c00e6e8beTobin Ehlis lock.unlock(); 37339207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton dev_data->dispatch_table.GetBufferMemoryRequirements(dev_data->device, buffer, &buffer_state->requirements); 37342eda842d84a02b9d5bfb03d6c26c5f7c00e6e8beTobin Ehlis lock.lock(); 37352eda842d84a02b9d5bfb03d6c26c5f7c00e6e8beTobin Ehlis } 373647aaf733d7394bda75c6de24289efe6b281e3cffMark Lobodzinski 37370ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton // Validate bound memory range information 37389a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto mem_info = GetMemObjInfo(dev_data, mem); 373957fc8e28c2e16118f9827e3ae1b107a27e0451a2Tobin Ehlis if (mem_info) { 37400ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton skip |= ValidateInsertBufferMemoryRange(dev_data, buffer, mem_info, memoryOffset, buffer_state->requirements, 37410ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton "vkBindBufferMemory()"); 37429207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton skip |= ValidateMemoryTypes(dev_data, mem_info, buffer_state->requirements.memoryTypeBits, "vkBindBufferMemory()", 3743315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_17000816); 374447aaf733d7394bda75c6de24289efe6b281e3cffMark Lobodzinski } 374547aaf733d7394bda75c6de24289efe6b281e3cffMark Lobodzinski 37462c905c8b5aca814df6c680348145ca48885f9f69Dustin Graves // Validate memory requirements alignment 374716769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (SafeModulo(memoryOffset, buffer_state->requirements.alignment) != 0) { 3748f60e41965223825191505eebc96491bb52e494a2Cort Stratton skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, 3749315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis buffer_handle, __LINE__, VALIDATION_ERROR_17000818, "DS", 37509207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton "vkBindBufferMemory(): memoryOffset is 0x%" PRIxLEAST64 37519207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton " but must be an integer multiple of the " 37529207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton "VkMemoryRequirements::alignment value 0x%" PRIxLEAST64 37539207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton ", returned from a call to vkGetBufferMemoryRequirements with buffer. %s", 3754315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis memoryOffset, buffer_state->requirements.alignment, validation_error_map[VALIDATION_ERROR_17000818]); 37552c905c8b5aca814df6c680348145ca48885f9f69Dustin Graves } 3756ba4316045bf5f1054629bb7c2fced7bae98ed52aMark Mueller 3757160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton // Validate memory requirements size 3758160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton if (buffer_state->requirements.size > (mem_info->alloc_info.allocationSize - memoryOffset)) { 3759160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, 3760315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis buffer_handle, __LINE__, VALIDATION_ERROR_1700081a, "DS", 3761160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton "vkBindBufferMemory(): memory size minus memoryOffset is 0x%" PRIxLEAST64 3762160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton " but must be at least as large as " 3763160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton "VkMemoryRequirements::size value 0x%" PRIxLEAST64 3764160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton ", returned from a call to vkGetBufferMemoryRequirements with buffer. %s", 3765160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton mem_info->alloc_info.allocationSize - memoryOffset, buffer_state->requirements.size, 3766315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_1700081a]); 3767160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton } 3768160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton 37692c905c8b5aca814df6c680348145ca48885f9f69Dustin Graves // Validate device limits alignments 3770ba4316045bf5f1054629bb7c2fced7bae98ed52aMark Mueller static const VkBufferUsageFlagBits usage_list[3] = { 3771ba4316045bf5f1054629bb7c2fced7bae98ed52aMark Mueller static_cast<VkBufferUsageFlagBits>(VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT), 3772bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT}; 3773bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski static const char *memory_type[3] = {"texel", "uniform", "storage"}; 3774bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski static const char *offset_name[3] = {"minTexelBufferOffsetAlignment", "minUniformBufferOffsetAlignment", 3775bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski "minStorageBufferOffsetAlignment"}; 3776cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski 37779207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton // TODO: vk_validation_stats.py cannot abide braces immediately preceding or following a validation error enum 3778cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski // clang-format off 3779315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis static const UNIQUE_VALIDATION_ERROR_CODE msgCode[3] = { VALIDATION_ERROR_17000810, VALIDATION_ERROR_17000812, 3780315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_17000814 }; 3781cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski // clang-format on 3782ba4316045bf5f1054629bb7c2fced7bae98ed52aMark Mueller 3783ba4316045bf5f1054629bb7c2fced7bae98ed52aMark Mueller // Keep this one fresh! 3784ba4316045bf5f1054629bb7c2fced7bae98ed52aMark Mueller const VkDeviceSize offset_requirement[3] = { 3785ba4316045bf5f1054629bb7c2fced7bae98ed52aMark Mueller dev_data->phys_dev_properties.properties.limits.minTexelBufferOffsetAlignment, 3786ba4316045bf5f1054629bb7c2fced7bae98ed52aMark Mueller dev_data->phys_dev_properties.properties.limits.minUniformBufferOffsetAlignment, 3787bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski dev_data->phys_dev_properties.properties.limits.minStorageBufferOffsetAlignment}; 37888718070cf3e206488c168f1e6b9dd06d6880c9bcTobin Ehlis VkBufferUsageFlags usage = dev_data->bufferMap[buffer].get()->createInfo.usage; 3789ba4316045bf5f1054629bb7c2fced7bae98ed52aMark Mueller 3790ba4316045bf5f1054629bb7c2fced7bae98ed52aMark Mueller for (int i = 0; i < 3; i++) { 3791ba4316045bf5f1054629bb7c2fced7bae98ed52aMark Mueller if (usage & usage_list[i]) { 379216769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (SafeModulo(memoryOffset, offset_requirement[i]) != 0) { 37939207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton skip |= log_msg( 3794f60e41965223825191505eebc96491bb52e494a2Cort Stratton dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, buffer_handle, 3795cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski __LINE__, msgCode[i], "DS", "vkBindBufferMemory(): %s memoryOffset is 0x%" PRIxLEAST64 3796cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski " but must be a multiple of " 3797cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "device limit %s 0x%" PRIxLEAST64 ". %s", 3798cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski memory_type[i], memoryOffset, offset_name[i], offset_requirement[i], validation_error_map[msgCode[i]]); 3799ba4316045bf5f1054629bb7c2fced7bae98ed52aMark Mueller } 38002c905c8b5aca814df6c680348145ca48885f9f69Dustin Graves } 38012c905c8b5aca814df6c680348145ca48885f9f69Dustin Graves } 38025b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 38039207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton return skip; 38049207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton} 38059207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton 3806160335c453ec51cc48bdef78e8befdb3c86ff292Cort Strattonstatic void PostCallRecordBindBufferMemory(layer_data *dev_data, VkBuffer buffer, BUFFER_STATE *buffer_state, VkDeviceMemory mem, 3807160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton VkDeviceSize memoryOffset) { 38089207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton if (buffer_state) { 3809ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 38100ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton // Track bound memory range information 38110ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton auto mem_info = GetMemObjInfo(dev_data, mem); 38120ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton if (mem_info) { 38130ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton InsertBufferMemoryRange(dev_data, buffer, mem_info, memoryOffset, buffer_state->requirements); 38140ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton } 38150ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton 3816c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton // Track objects tied to memory 38179b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus uint64_t buffer_handle = HandleToUint64(buffer); 38187a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski SetMemBinding(dev_data, mem, buffer_handle, kVulkanObjectTypeBuffer, "vkBindBufferMemory()"); 3819c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton 38209207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton buffer_state->binding.mem = mem; 38219207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton buffer_state->binding.offset = memoryOffset; 38229207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton buffer_state->binding.size = buffer_state->requirements.size; 38239207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton } 38249207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton} 38259207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton 38269207132ef623d47fcbdfeb9ebc796eade35a2f4cCort StrattonVKAPI_ATTR VkResult VKAPI_CALL BindBufferMemory(VkDevice device, VkBuffer buffer, VkDeviceMemory mem, VkDeviceSize memoryOffset) { 38279207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 38289207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 3829160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton auto buffer_state = GetBufferState(dev_data, buffer); 3830160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton bool skip = PreCallValidateBindBufferMemory(dev_data, buffer, buffer_state, mem, memoryOffset); 38319207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton if (!skip) { 38324a0754042cf090e131e9e769d8a3633c228625beChris Forbes result = dev_data->dispatch_table.BindBufferMemory(device, buffer, mem, memoryOffset); 38339207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton if (result == VK_SUCCESS) { 3834160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton PostCallRecordBindBufferMemory(dev_data, buffer, buffer_state, mem, memoryOffset); 38359207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton } 38365b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 38375b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 38385b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 38395b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 3840bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL GetBufferMemoryRequirements(VkDevice device, VkBuffer buffer, 3841bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkMemoryRequirements *pMemoryRequirements) { 384256e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 384315caa3e8f88f57bdcc42a3eabb9375e57007e5aaTobin Ehlis dev_data->dispatch_table.GetBufferMemoryRequirements(device, buffer, pMemoryRequirements); 3844cd3fe6716d6c206368a0c404fcd25332860fd573Jean-François Marquis BUFFER_STATE* buffer_state; 3845cd3fe6716d6c206368a0c404fcd25332860fd573Jean-François Marquis { 3846cd3fe6716d6c206368a0c404fcd25332860fd573Jean-François Marquis unique_lock_t lock(global_lock); 3847cd3fe6716d6c206368a0c404fcd25332860fd573Jean-François Marquis buffer_state = GetBufferState(dev_data, buffer); 3848cd3fe6716d6c206368a0c404fcd25332860fd573Jean-François Marquis } 384915caa3e8f88f57bdcc42a3eabb9375e57007e5aaTobin Ehlis if (buffer_state) { 385015caa3e8f88f57bdcc42a3eabb9375e57007e5aaTobin Ehlis buffer_state->requirements = *pMemoryRequirements; 38512eda842d84a02b9d5bfb03d6c26c5f7c00e6e8beTobin Ehlis buffer_state->memory_requirements_checked = true; 385215caa3e8f88f57bdcc42a3eabb9375e57007e5aaTobin Ehlis } 38535b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 38545b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 3855bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL GetImageMemoryRequirements(VkDevice device, VkImage image, VkMemoryRequirements *pMemoryRequirements) { 385656e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 385715caa3e8f88f57bdcc42a3eabb9375e57007e5aaTobin Ehlis dev_data->dispatch_table.GetImageMemoryRequirements(device, image, pMemoryRequirements); 3858cd3fe6716d6c206368a0c404fcd25332860fd573Jean-François Marquis IMAGE_STATE* image_state; 3859cd3fe6716d6c206368a0c404fcd25332860fd573Jean-François Marquis { 3860cd3fe6716d6c206368a0c404fcd25332860fd573Jean-François Marquis unique_lock_t lock(global_lock); 3861cd3fe6716d6c206368a0c404fcd25332860fd573Jean-François Marquis image_state = GetImageState(dev_data, image); 3862cd3fe6716d6c206368a0c404fcd25332860fd573Jean-François Marquis } 386315caa3e8f88f57bdcc42a3eabb9375e57007e5aaTobin Ehlis if (image_state) { 386415caa3e8f88f57bdcc42a3eabb9375e57007e5aaTobin Ehlis image_state->requirements = *pMemoryRequirements; 38652eda842d84a02b9d5bfb03d6c26c5f7c00e6e8beTobin Ehlis image_state->memory_requirements_checked = true; 386615caa3e8f88f57bdcc42a3eabb9375e57007e5aaTobin Ehlis } 38675b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 3868593c857d8db57cf9ae2c590b75e22dadd51bd3d4Tobin Ehlis 3869bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL DestroyImageView(VkDevice device, VkImageView imageView, const VkAllocationCallbacks *pAllocator) { 387056e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 3871f61017735c3291a2665487f2bac310578fc60a68Tobin Ehlis // Common data objects used pre & post call 3872f61017735c3291a2665487f2bac310578fc60a68Tobin Ehlis IMAGE_VIEW_STATE *image_view_state = nullptr; 3873f61017735c3291a2665487f2bac310578fc60a68Tobin Ehlis VK_OBJECT obj_struct; 3874ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 3875f61017735c3291a2665487f2bac310578fc60a68Tobin Ehlis bool skip = PreCallValidateDestroyImageView(dev_data, imageView, &image_view_state, &obj_struct); 3876d85c42a6c1d6ad7a6f684c5bd793aab482b7705cTobin Ehlis if (!skip) { 3877d85c42a6c1d6ad7a6f684c5bd793aab482b7705cTobin Ehlis lock.unlock(); 38784a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.DestroyImageView(device, imageView, pAllocator); 3879f61017735c3291a2665487f2bac310578fc60a68Tobin Ehlis lock.lock(); 3880405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour if (imageView != VK_NULL_HANDLE) { 3881405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour PostCallRecordDestroyImageView(dev_data, imageView, image_view_state, obj_struct); 3882405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour } 3883d85c42a6c1d6ad7a6f684c5bd793aab482b7705cTobin Ehlis } 38845b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 38855b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 3886bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL DestroyShaderModule(VkDevice device, VkShaderModule shaderModule, 3887bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkAllocationCallbacks *pAllocator) { 388856e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 3889918c283ac4f8c604b79abd0c8b5706d2a7352a34Chris Forbes 3890ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 389151ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis dev_data->shaderModuleMap.erase(shaderModule); 3892b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 3893918c283ac4f8c604b79abd0c8b5706d2a7352a34Chris Forbes 389451ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis dev_data->dispatch_table.DestroyShaderModule(device, shaderModule, pAllocator); 38955b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 38965b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 38974c0df90de562aa248b524a28b355765d8e3eff25Tobin Ehlisstatic bool PreCallValidateDestroyPipeline(layer_data *dev_data, VkPipeline pipeline, PIPELINE_STATE **pipeline_state, 38988bd2ec9a26cca477de2de93304774cdba0af77bcTobin Ehlis VK_OBJECT *obj_struct) { 389994165f5005d1fa37801d49067fe7751789b89d27Tobin Ehlis *pipeline_state = getPipelineState(dev_data, pipeline); 39009b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus *obj_struct = {HandleToUint64(pipeline), kVulkanObjectTypePipeline}; 3901cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.destroy_pipeline) return false; 39028bd2ec9a26cca477de2de93304774cdba0af77bcTobin Ehlis bool skip = false; 39038bd2ec9a26cca477de2de93304774cdba0af77bcTobin Ehlis if (*pipeline_state) { 390469ea2c79d7b3f9c987671a10686afac066b275b9Mike Schuchardt skip |= ValidateObjectNotInUse(dev_data, *pipeline_state, *obj_struct, "vkDestroyPipeline", VALIDATION_ERROR_25c005fa); 39058bd2ec9a26cca477de2de93304774cdba0af77bcTobin Ehlis } 39068bd2ec9a26cca477de2de93304774cdba0af77bcTobin Ehlis return skip; 39078bd2ec9a26cca477de2de93304774cdba0af77bcTobin Ehlis} 39088bd2ec9a26cca477de2de93304774cdba0af77bcTobin Ehlis 39094c0df90de562aa248b524a28b355765d8e3eff25Tobin Ehlisstatic void PostCallRecordDestroyPipeline(layer_data *dev_data, VkPipeline pipeline, PIPELINE_STATE *pipeline_state, 39108bd2ec9a26cca477de2de93304774cdba0af77bcTobin Ehlis VK_OBJECT obj_struct) { 39118bd2ec9a26cca477de2de93304774cdba0af77bcTobin Ehlis // Any bound cmd buffers are now invalid 391239c845ed4c066740e9efaed0a00af51be07c67c1Tobin Ehlis invalidateCommandBuffers(dev_data, pipeline_state->cb_bindings, obj_struct); 39138bd2ec9a26cca477de2de93304774cdba0af77bcTobin Ehlis dev_data->pipelineMap.erase(pipeline); 39148bd2ec9a26cca477de2de93304774cdba0af77bcTobin Ehlis} 39158bd2ec9a26cca477de2de93304774cdba0af77bcTobin Ehlis 3916bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL DestroyPipeline(VkDevice device, VkPipeline pipeline, const VkAllocationCallbacks *pAllocator) { 391756e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 39184c0df90de562aa248b524a28b355765d8e3eff25Tobin Ehlis PIPELINE_STATE *pipeline_state = nullptr; 39198bd2ec9a26cca477de2de93304774cdba0af77bcTobin Ehlis VK_OBJECT obj_struct; 3920ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 39218bd2ec9a26cca477de2de93304774cdba0af77bcTobin Ehlis bool skip = PreCallValidateDestroyPipeline(dev_data, pipeline, &pipeline_state, &obj_struct); 3922f57cf525e45f3a65e25c2691464d65e29a79ba77Tobin Ehlis if (!skip) { 3923f57cf525e45f3a65e25c2691464d65e29a79ba77Tobin Ehlis lock.unlock(); 39244a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.DestroyPipeline(device, pipeline, pAllocator); 39258bd2ec9a26cca477de2de93304774cdba0af77bcTobin Ehlis lock.lock(); 3926405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour if (pipeline != VK_NULL_HANDLE) { 3927405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour PostCallRecordDestroyPipeline(dev_data, pipeline, pipeline_state, obj_struct); 3928405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour } 3929f57cf525e45f3a65e25c2691464d65e29a79ba77Tobin Ehlis } 39305b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 39315b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 3932bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL DestroyPipelineLayout(VkDevice device, VkPipelineLayout pipelineLayout, 3933bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkAllocationCallbacks *pAllocator) { 393456e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 3935ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 39366792ea7cc0ce5fa64b7bd6c946460608cbda91c7Tobin Ehlis dev_data->pipelineLayoutMap.erase(pipelineLayout); 3937e28cddb35c63274c13873b9a7060ad43b255c6f1Tobin Ehlis lock.unlock(); 3938e1a3be272f365a7d75f9cc1338d2eebafbf1e6cdTobin Ehlis 39394a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.DestroyPipelineLayout(device, pipelineLayout, pAllocator); 39405b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 39415b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 3942d31a44af6da568692a73201825459689c9431867Tobin Ehlisstatic bool PreCallValidateDestroySampler(layer_data *dev_data, VkSampler sampler, SAMPLER_STATE **sampler_state, 3943806095ea973371ad4c82bd0c2c58d53cc5557f0bTobin Ehlis VK_OBJECT *obj_struct) { 39449a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis *sampler_state = GetSamplerState(dev_data, sampler); 39459b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus *obj_struct = {HandleToUint64(sampler), kVulkanObjectTypeSampler}; 3946cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.destroy_sampler) return false; 3947806095ea973371ad4c82bd0c2c58d53cc5557f0bTobin Ehlis bool skip = false; 3948806095ea973371ad4c82bd0c2c58d53cc5557f0bTobin Ehlis if (*sampler_state) { 394969ea2c79d7b3f9c987671a10686afac066b275b9Mike Schuchardt skip |= ValidateObjectNotInUse(dev_data, *sampler_state, *obj_struct, "vkDestroySampler", VALIDATION_ERROR_26600874); 3950806095ea973371ad4c82bd0c2c58d53cc5557f0bTobin Ehlis } 3951806095ea973371ad4c82bd0c2c58d53cc5557f0bTobin Ehlis return skip; 3952806095ea973371ad4c82bd0c2c58d53cc5557f0bTobin Ehlis} 3953806095ea973371ad4c82bd0c2c58d53cc5557f0bTobin Ehlis 3954d31a44af6da568692a73201825459689c9431867Tobin Ehlisstatic void PostCallRecordDestroySampler(layer_data *dev_data, VkSampler sampler, SAMPLER_STATE *sampler_state, 3955806095ea973371ad4c82bd0c2c58d53cc5557f0bTobin Ehlis VK_OBJECT obj_struct) { 3956806095ea973371ad4c82bd0c2c58d53cc5557f0bTobin Ehlis // Any bound cmd buffers are now invalid 3957cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (sampler_state) invalidateCommandBuffers(dev_data, sampler_state->cb_bindings, obj_struct); 3958806095ea973371ad4c82bd0c2c58d53cc5557f0bTobin Ehlis dev_data->samplerMap.erase(sampler); 3959806095ea973371ad4c82bd0c2c58d53cc5557f0bTobin Ehlis} 3960806095ea973371ad4c82bd0c2c58d53cc5557f0bTobin Ehlis 3961bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL DestroySampler(VkDevice device, VkSampler sampler, const VkAllocationCallbacks *pAllocator) { 396256e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 3963d31a44af6da568692a73201825459689c9431867Tobin Ehlis SAMPLER_STATE *sampler_state = nullptr; 3964806095ea973371ad4c82bd0c2c58d53cc5557f0bTobin Ehlis VK_OBJECT obj_struct; 3965ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 3966806095ea973371ad4c82bd0c2c58d53cc5557f0bTobin Ehlis bool skip = PreCallValidateDestroySampler(dev_data, sampler, &sampler_state, &obj_struct); 3967f57cf525e45f3a65e25c2691464d65e29a79ba77Tobin Ehlis if (!skip) { 3968f57cf525e45f3a65e25c2691464d65e29a79ba77Tobin Ehlis lock.unlock(); 39694a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.DestroySampler(device, sampler, pAllocator); 3970806095ea973371ad4c82bd0c2c58d53cc5557f0bTobin Ehlis lock.lock(); 3971405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour if (sampler != VK_NULL_HANDLE) { 3972405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour PostCallRecordDestroySampler(dev_data, sampler, sampler_state, obj_struct); 3973405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour } 3974f57cf525e45f3a65e25c2691464d65e29a79ba77Tobin Ehlis } 39755b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 39765b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 397779c5b660cd51e93e279c1aa001a42801d3bf7a5dTobin Ehlisstatic void PostCallRecordDestroyDescriptorSetLayout(layer_data *dev_data, VkDescriptorSetLayout ds_layout) { 397879c5b660cd51e93e279c1aa001a42801d3bf7a5dTobin Ehlis dev_data->descriptorSetLayoutMap.erase(ds_layout); 397979c5b660cd51e93e279c1aa001a42801d3bf7a5dTobin Ehlis} 398079c5b660cd51e93e279c1aa001a42801d3bf7a5dTobin Ehlis 3981bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL DestroyDescriptorSetLayout(VkDevice device, VkDescriptorSetLayout descriptorSetLayout, 3982bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkAllocationCallbacks *pAllocator) { 398356e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 398479c5b660cd51e93e279c1aa001a42801d3bf7a5dTobin Ehlis dev_data->dispatch_table.DestroyDescriptorSetLayout(device, descriptorSetLayout, pAllocator); 3985ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 398679c5b660cd51e93e279c1aa001a42801d3bf7a5dTobin Ehlis PostCallRecordDestroyDescriptorSetLayout(dev_data, descriptorSetLayout); 39875b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 39885b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 3989c656e38f76da254b8b19e653d0945cabb43329bcTobin Ehlisstatic bool PreCallValidateDestroyDescriptorPool(layer_data *dev_data, VkDescriptorPool pool, 3990a21f0d8ac8389dc4e23749efc02d82a7ec1eaee3Tobin Ehlis DESCRIPTOR_POOL_STATE **desc_pool_state, VK_OBJECT *obj_struct) { 39919a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis *desc_pool_state = GetDescriptorPoolState(dev_data, pool); 39929b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus *obj_struct = {HandleToUint64(pool), kVulkanObjectTypeDescriptorPool}; 3993cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.destroy_descriptor_pool) return false; 3994c656e38f76da254b8b19e653d0945cabb43329bcTobin Ehlis bool skip = false; 3995c656e38f76da254b8b19e653d0945cabb43329bcTobin Ehlis if (*desc_pool_state) { 399669ea2c79d7b3f9c987671a10686afac066b275b9Mike Schuchardt skip |= 399769ea2c79d7b3f9c987671a10686afac066b275b9Mike Schuchardt ValidateObjectNotInUse(dev_data, *desc_pool_state, *obj_struct, "vkDestroyDescriptorPool", VALIDATION_ERROR_2440025e); 3998c656e38f76da254b8b19e653d0945cabb43329bcTobin Ehlis } 3999c656e38f76da254b8b19e653d0945cabb43329bcTobin Ehlis return skip; 4000c656e38f76da254b8b19e653d0945cabb43329bcTobin Ehlis} 4001c656e38f76da254b8b19e653d0945cabb43329bcTobin Ehlis 4002c656e38f76da254b8b19e653d0945cabb43329bcTobin Ehlisstatic void PostCallRecordDestroyDescriptorPool(layer_data *dev_data, VkDescriptorPool descriptorPool, 4003a21f0d8ac8389dc4e23749efc02d82a7ec1eaee3Tobin Ehlis DESCRIPTOR_POOL_STATE *desc_pool_state, VK_OBJECT obj_struct) { 4004c656e38f76da254b8b19e653d0945cabb43329bcTobin Ehlis // Any bound cmd buffers are now invalid 400539c845ed4c066740e9efaed0a00af51be07c67c1Tobin Ehlis invalidateCommandBuffers(dev_data, desc_pool_state->cb_bindings, obj_struct); 4006c656e38f76da254b8b19e653d0945cabb43329bcTobin Ehlis // Free sets that were in this pool 4007c656e38f76da254b8b19e653d0945cabb43329bcTobin Ehlis for (auto ds : desc_pool_state->sets) { 4008c656e38f76da254b8b19e653d0945cabb43329bcTobin Ehlis freeDescriptorSet(dev_data, ds); 4009c656e38f76da254b8b19e653d0945cabb43329bcTobin Ehlis } 4010c656e38f76da254b8b19e653d0945cabb43329bcTobin Ehlis dev_data->descriptorPoolMap.erase(descriptorPool); 4011ee7e96d032744c1db89cab21362ac8ecad6eec5aGabríel Arthúr Pétursson delete desc_pool_state; 4012c656e38f76da254b8b19e653d0945cabb43329bcTobin Ehlis} 4013c656e38f76da254b8b19e653d0945cabb43329bcTobin Ehlis 4014bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL DestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool, 4015bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkAllocationCallbacks *pAllocator) { 401656e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 4017a21f0d8ac8389dc4e23749efc02d82a7ec1eaee3Tobin Ehlis DESCRIPTOR_POOL_STATE *desc_pool_state = nullptr; 4018c656e38f76da254b8b19e653d0945cabb43329bcTobin Ehlis VK_OBJECT obj_struct; 4019ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 4020c656e38f76da254b8b19e653d0945cabb43329bcTobin Ehlis bool skip = PreCallValidateDestroyDescriptorPool(dev_data, descriptorPool, &desc_pool_state, &obj_struct); 4021c656e38f76da254b8b19e653d0945cabb43329bcTobin Ehlis if (!skip) { 4022c656e38f76da254b8b19e653d0945cabb43329bcTobin Ehlis lock.unlock(); 4023c656e38f76da254b8b19e653d0945cabb43329bcTobin Ehlis dev_data->dispatch_table.DestroyDescriptorPool(device, descriptorPool, pAllocator); 4024c656e38f76da254b8b19e653d0945cabb43329bcTobin Ehlis lock.lock(); 4025405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour if (descriptorPool != VK_NULL_HANDLE) { 4026405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour PostCallRecordDestroyDescriptorPool(dev_data, descriptorPool, desc_pool_state, obj_struct); 4027405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour } 4028c656e38f76da254b8b19e653d0945cabb43329bcTobin Ehlis } 40295b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 40303251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski// Verify cmdBuffer in given cb_node is not in global in-flight set, and return skip result 4031bc300ace5ad8d1935d42ee5dbbf36ce6ace4c0e8Tobin Ehlis// If this is a secondary command buffer, then make sure its primary is also in-flight 4032bc300ace5ad8d1935d42ee5dbbf36ce6ace4c0e8Tobin Ehlis// If primary is not in-flight, then remove secondary from global in-flight set 4033bc300ace5ad8d1935d42ee5dbbf36ce6ace4c0e8Tobin Ehlis// This function is only valid at a point when cmdBuffer is being reset or freed 4034cdc73d5b6b64942b377db7220cd16b4045f73c9aTobin Ehlisstatic bool checkCommandBufferInFlight(layer_data *dev_data, const GLOBAL_CB_NODE *cb_node, const char *action, 4035cdc73d5b6b64942b377db7220cd16b4045f73c9aTobin Ehlis UNIQUE_VALIDATION_ERROR_CODE error_code) { 40363251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 4037a7fef8833e0b4e1e4c7ea20ab56da451a6856c0cChris Forbes if (cb_node->in_use.load()) { 4038a7fef8833e0b4e1e4c7ea20ab56da451a6856c0cChris Forbes skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 4039a7fef8833e0b4e1e4c7ea20ab56da451a6856c0cChris Forbes HandleToUint64(cb_node->commandBuffer), __LINE__, error_code, "DS", 4040a7fef8833e0b4e1e4c7ea20ab56da451a6856c0cChris Forbes "Attempt to %s command buffer (0x%p) which is in use. %s", action, cb_node->commandBuffer, 4041a7fef8833e0b4e1e4c7ea20ab56da451a6856c0cChris Forbes validation_error_map[error_code]); 4042bc300ace5ad8d1935d42ee5dbbf36ce6ace4c0e8Tobin Ehlis } 40433251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 4044bc300ace5ad8d1935d42ee5dbbf36ce6ace4c0e8Tobin Ehlis} 4045a964cad279f9749cd9ebfc7555247ff3bff26d53Chris Forbes 4046bc300ace5ad8d1935d42ee5dbbf36ce6ace4c0e8Tobin Ehlis// Iterate over all cmdBuffers in given commandPool and verify that each is not in use 4047cdc73d5b6b64942b377db7220cd16b4045f73c9aTobin Ehlisstatic bool checkCommandBuffersInFlight(layer_data *dev_data, COMMAND_POOL_NODE *pPool, const char *action, 4048cdc73d5b6b64942b377db7220cd16b4045f73c9aTobin Ehlis UNIQUE_VALIDATION_ERROR_CODE error_code) { 40493251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 4050a01b5eb150981aad061238e64b173d0da8c11140Chris Forbes for (auto cmd_buffer : pPool->commandBuffers) { 4051a7fef8833e0b4e1e4c7ea20ab56da451a6856c0cChris Forbes skip |= checkCommandBufferInFlight(dev_data, GetCBNode(dev_data, cmd_buffer), action, error_code); 4052bc300ace5ad8d1935d42ee5dbbf36ce6ace4c0e8Tobin Ehlis } 40533251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 4054bc300ace5ad8d1935d42ee5dbbf36ce6ace4c0e8Tobin Ehlis} 40555b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 40567cb00fa300f2563ae3e8eb506bca912c11216953John Zulauf// Free all command buffers in given list, removing all references/links to them using ResetCommandBufferState 4057c8d1e7bb99c01ae0c2824fe7286fb0a1173de589John Zulaufstatic void FreeCommandBufferStates(layer_data *dev_data, COMMAND_POOL_NODE *pool_state, const uint32_t command_buffer_count, 4058c8d1e7bb99c01ae0c2824fe7286fb0a1173de589John Zulauf const VkCommandBuffer *command_buffers) { 4059c8d1e7bb99c01ae0c2824fe7286fb0a1173de589John Zulauf for (uint32_t i = 0; i < command_buffer_count; i++) { 4060c8d1e7bb99c01ae0c2824fe7286fb0a1173de589John Zulauf auto cb_state = GetCBNode(dev_data, command_buffers[i]); 4061c8d1e7bb99c01ae0c2824fe7286fb0a1173de589John Zulauf // Remove references to command buffer's state and delete 4062c8d1e7bb99c01ae0c2824fe7286fb0a1173de589John Zulauf if (cb_state) { 4063c8d1e7bb99c01ae0c2824fe7286fb0a1173de589John Zulauf // reset prior to delete, removing various references to it. 4064c8d1e7bb99c01ae0c2824fe7286fb0a1173de589John Zulauf // TODO: fix this, it's insane. 40657cb00fa300f2563ae3e8eb506bca912c11216953John Zulauf ResetCommandBufferState(dev_data, cb_state->commandBuffer); 4066c8d1e7bb99c01ae0c2824fe7286fb0a1173de589John Zulauf // Remove the cb_state's references from layer_data and COMMAND_POOL_NODE 4067c8d1e7bb99c01ae0c2824fe7286fb0a1173de589John Zulauf dev_data->commandBufferMap.erase(cb_state->commandBuffer); 4068c8d1e7bb99c01ae0c2824fe7286fb0a1173de589John Zulauf pool_state->commandBuffers.erase(command_buffers[i]); 4069c8d1e7bb99c01ae0c2824fe7286fb0a1173de589John Zulauf delete cb_state; 4070c8d1e7bb99c01ae0c2824fe7286fb0a1173de589John Zulauf } 4071c8d1e7bb99c01ae0c2824fe7286fb0a1173de589John Zulauf } 4072c8d1e7bb99c01ae0c2824fe7286fb0a1173de589John Zulauf} 4073c8d1e7bb99c01ae0c2824fe7286fb0a1173de589John Zulauf 4074bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL FreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount, 4075bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkCommandBuffer *pCommandBuffers) { 407656e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 40773251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 4078ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 4079c05d773a018aa47e89841533a6968d9e5b314038Chris Forbes 40805b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t i = 0; i < commandBufferCount; i++) { 40819a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto cb_node = GetCBNode(dev_data, pCommandBuffers[i]); 40825b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Delete CB information structure, and remove from commandBufferMap 40839f229695cf32913dab3fb75e5d52548ea57b3851Tobin Ehlis if (cb_node) { 4084315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= checkCommandBufferInFlight(dev_data, cb_node, "free", VALIDATION_ERROR_2840005e); 4085c05d773a018aa47e89841533a6968d9e5b314038Chris Forbes } 4086c05d773a018aa47e89841533a6968d9e5b314038Chris Forbes } 4087c05d773a018aa47e89841533a6968d9e5b314038Chris Forbes 40883251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (skip) return; 4089c05d773a018aa47e89841533a6968d9e5b314038Chris Forbes 40909a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pPool = GetCommandPoolNode(dev_data, commandPool); 4091c8d1e7bb99c01ae0c2824fe7286fb0a1173de589John Zulauf FreeCommandBufferStates(dev_data, pPool, commandBufferCount, pCommandBuffers); 4092b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 4093e1a3be272f365a7d75f9cc1338d2eebafbf1e6cdTobin Ehlis 40944a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.FreeCommandBuffers(device, commandPool, commandBufferCount, pCommandBuffers); 40955b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 40965b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 409789d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR VkResult VKAPI_CALL CreateCommandPool(VkDevice device, const VkCommandPoolCreateInfo *pCreateInfo, 4098bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkAllocationCallbacks *pAllocator, VkCommandPool *pCommandPool) { 409956e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 41005b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 41014a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.CreateCommandPool(device, pCreateInfo, pAllocator, pCommandPool); 41025b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 41035b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (VK_SUCCESS == result) { 4104ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 41055b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis dev_data->commandPoolMap[*pCommandPool].createFlags = pCreateInfo->flags; 41065b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis dev_data->commandPoolMap[*pCommandPool].queueFamilyIndex = pCreateInfo->queueFamilyIndex; 41075b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 41085b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 41095b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 41105b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 411189d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR VkResult VKAPI_CALL CreateQueryPool(VkDevice device, const VkQueryPoolCreateInfo *pCreateInfo, 411289d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I Wu const VkAllocationCallbacks *pAllocator, VkQueryPool *pQueryPool) { 411356e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 41140c45ab93ccfb9d39698ae47d6102d2e308ff476eTobin Ehlis bool skip = false; 41150c45ab93ccfb9d39698ae47d6102d2e308ff476eTobin Ehlis if (pCreateInfo && pCreateInfo->queryType == VK_QUERY_TYPE_PIPELINE_STATISTICS) { 41160c45ab93ccfb9d39698ae47d6102d2e308ff476eTobin Ehlis if (!dev_data->enabled_features.pipelineStatisticsQuery) { 41170c45ab93ccfb9d39698ae47d6102d2e308ff476eTobin Ehlis skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT, 0, 4118315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis __LINE__, VALIDATION_ERROR_11c0062e, "DS", 41190c45ab93ccfb9d39698ae47d6102d2e308ff476eTobin Ehlis "Query pool with type VK_QUERY_TYPE_PIPELINE_STATISTICS created on a device " 41200c45ab93ccfb9d39698ae47d6102d2e308ff476eTobin Ehlis "with VkDeviceCreateInfo.pEnabledFeatures.pipelineStatisticsQuery == VK_FALSE. %s", 4121315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_11c0062e]); 41220c45ab93ccfb9d39698ae47d6102d2e308ff476eTobin Ehlis } 41230c45ab93ccfb9d39698ae47d6102d2e308ff476eTobin Ehlis } 41240c45ab93ccfb9d39698ae47d6102d2e308ff476eTobin Ehlis 41250c45ab93ccfb9d39698ae47d6102d2e308ff476eTobin Ehlis VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 41260c45ab93ccfb9d39698ae47d6102d2e308ff476eTobin Ehlis if (!skip) { 41270c45ab93ccfb9d39698ae47d6102d2e308ff476eTobin Ehlis result = dev_data->dispatch_table.CreateQueryPool(device, pCreateInfo, pAllocator, pQueryPool); 41280c45ab93ccfb9d39698ae47d6102d2e308ff476eTobin Ehlis } 41295b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (result == VK_SUCCESS) { 4130ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 4131eafbf0b68ee6ea6e0bf33f07e0058d00a96efd9aTobin Ehlis QUERY_POOL_NODE *qp_node = &dev_data->queryPoolMap[*pQueryPool]; 4132eafbf0b68ee6ea6e0bf33f07e0058d00a96efd9aTobin Ehlis qp_node->createInfo = *pCreateInfo; 41335b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 41345b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 41355b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 41365b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 4137c8d1e7bb99c01ae0c2824fe7286fb0a1173de589John Zulaufstatic bool PreCallValidateDestroyCommandPool(layer_data *dev_data, VkCommandPool pool) { 4138c8d1e7bb99c01ae0c2824fe7286fb0a1173de589John Zulauf COMMAND_POOL_NODE *cp_state = GetCommandPoolNode(dev_data, pool); 4139cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.destroy_command_pool) return false; 41405f9c0dbd099bd351bc564e0f05170ceeadcc995dTobin Ehlis bool skip = false; 4141c8d1e7bb99c01ae0c2824fe7286fb0a1173de589John Zulauf if (cp_state) { 41425f9c0dbd099bd351bc564e0f05170ceeadcc995dTobin Ehlis // Verify that command buffers in pool are complete (not in-flight) 4143c8d1e7bb99c01ae0c2824fe7286fb0a1173de589John Zulauf skip |= checkCommandBuffersInFlight(dev_data, cp_state, "destroy command pool with", VALIDATION_ERROR_24000052); 41445f9c0dbd099bd351bc564e0f05170ceeadcc995dTobin Ehlis } 41455f9c0dbd099bd351bc564e0f05170ceeadcc995dTobin Ehlis return skip; 41465f9c0dbd099bd351bc564e0f05170ceeadcc995dTobin Ehlis} 41475b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 4148c8d1e7bb99c01ae0c2824fe7286fb0a1173de589John Zulaufstatic void PostCallRecordDestroyCommandPool(layer_data *dev_data, VkCommandPool pool) { 4149c8d1e7bb99c01ae0c2824fe7286fb0a1173de589John Zulauf COMMAND_POOL_NODE *cp_state = GetCommandPoolNode(dev_data, pool); 4150c8d1e7bb99c01ae0c2824fe7286fb0a1173de589John Zulauf // Remove cmdpool from cmdpoolmap, after freeing layer data for the command buffers 4151c8d1e7bb99c01ae0c2824fe7286fb0a1173de589John Zulauf // "When a pool is destroyed, all command buffers allocated from the pool are freed." 4152c8d1e7bb99c01ae0c2824fe7286fb0a1173de589John Zulauf if (cp_state) { 4153c8d1e7bb99c01ae0c2824fe7286fb0a1173de589John Zulauf // Create a vector, as FreeCommandBufferStates deletes from cp_state->commandBuffers during iteration. 4154c8d1e7bb99c01ae0c2824fe7286fb0a1173de589John Zulauf std::vector<VkCommandBuffer> cb_vec{cp_state->commandBuffers.begin(), cp_state->commandBuffers.end()}; 4155c8d1e7bb99c01ae0c2824fe7286fb0a1173de589John Zulauf FreeCommandBufferStates(dev_data, cp_state, static_cast<uint32_t>(cb_vec.size()), cb_vec.data()); 4156c8d1e7bb99c01ae0c2824fe7286fb0a1173de589John Zulauf dev_data->commandPoolMap.erase(pool); 4157a01b5eb150981aad061238e64b173d0da8c11140Chris Forbes } 41585f9c0dbd099bd351bc564e0f05170ceeadcc995dTobin Ehlis} 4159e1a3be272f365a7d75f9cc1338d2eebafbf1e6cdTobin Ehlis 41605f9c0dbd099bd351bc564e0f05170ceeadcc995dTobin Ehlis// Destroy commandPool along with all of the commandBuffers allocated from that pool 41615f9c0dbd099bd351bc564e0f05170ceeadcc995dTobin EhlisVKAPI_ATTR void VKAPI_CALL DestroyCommandPool(VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks *pAllocator) { 416256e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 4163ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 4164c8d1e7bb99c01ae0c2824fe7286fb0a1173de589John Zulauf bool skip = PreCallValidateDestroyCommandPool(dev_data, commandPool); 41655f9c0dbd099bd351bc564e0f05170ceeadcc995dTobin Ehlis if (!skip) { 41665f9c0dbd099bd351bc564e0f05170ceeadcc995dTobin Ehlis lock.unlock(); 41675f9c0dbd099bd351bc564e0f05170ceeadcc995dTobin Ehlis dev_data->dispatch_table.DestroyCommandPool(device, commandPool, pAllocator); 41685f9c0dbd099bd351bc564e0f05170ceeadcc995dTobin Ehlis lock.lock(); 4169405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour if (commandPool != VK_NULL_HANDLE) { 4170c8d1e7bb99c01ae0c2824fe7286fb0a1173de589John Zulauf PostCallRecordDestroyCommandPool(dev_data, commandPool); 4171405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour } 41725f9c0dbd099bd351bc564e0f05170ceeadcc995dTobin Ehlis } 41735b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 41745b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 4175bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL ResetCommandPool(VkDevice device, VkCommandPool commandPool, VkCommandPoolResetFlags flags) { 417656e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 41773251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 4178400cff9fad0e19c80f6c9ed1181795d411a4bec5Tobin Ehlis 4179ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 41809a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pPool = GetCommandPoolNode(dev_data, commandPool); 4181315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= checkCommandBuffersInFlight(dev_data, pPool, "reset command pool with", VALIDATION_ERROR_32800050); 41821ec6311a8537f4467db08eacbd762ebaa87e70b0Chris Forbes lock.unlock(); 4183a01b5eb150981aad061238e64b173d0da8c11140Chris Forbes 41843251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 41855b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 41864a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.ResetCommandPool(device, commandPool, flags); 41875b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 41885b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Reset all of the CBs allocated from this pool 41895b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (VK_SUCCESS == result) { 41901ec6311a8537f4467db08eacbd762ebaa87e70b0Chris Forbes lock.lock(); 4191a01b5eb150981aad061238e64b173d0da8c11140Chris Forbes for (auto cmdBuffer : pPool->commandBuffers) { 41927cb00fa300f2563ae3e8eb506bca912c11216953John Zulauf ResetCommandBufferState(dev_data, cmdBuffer); 41935b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 41941ec6311a8537f4467db08eacbd762ebaa87e70b0Chris Forbes lock.unlock(); 41955b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 41965b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 41975b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 41985b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 419989d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR VkResult VKAPI_CALL ResetFences(VkDevice device, uint32_t fenceCount, const VkFence *pFences) { 420056e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 42013251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 4202ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 42035b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t i = 0; i < fenceCount; ++i) { 42049a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pFence = GetFenceNode(dev_data, pFences[i]); 4205804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt if (pFence && pFence->scope == kSyncScopeInternal && pFence->state == FENCE_INFLIGHT) { 4206315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= 4207315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, 4208315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pFences[i]), __LINE__, VALIDATION_ERROR_32e008c6, "DS", "Fence 0x%" PRIx64 " is in use. %s", 4209315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pFences[i]), validation_error_map[VALIDATION_ERROR_32e008c6]); 42105b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 42115b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 4212b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 4213090da73358f71ba026e2474a822fecf55267d166Chris Forbes 42143251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 4215090da73358f71ba026e2474a822fecf55267d166Chris Forbes 42164a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.ResetFences(device, fenceCount, pFences); 4217090da73358f71ba026e2474a822fecf55267d166Chris Forbes 4218090da73358f71ba026e2474a822fecf55267d166Chris Forbes if (result == VK_SUCCESS) { 4219090da73358f71ba026e2474a822fecf55267d166Chris Forbes lock.lock(); 4220090da73358f71ba026e2474a822fecf55267d166Chris Forbes for (uint32_t i = 0; i < fenceCount; ++i) { 42219a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pFence = GetFenceNode(dev_data, pFences[i]); 4222090da73358f71ba026e2474a822fecf55267d166Chris Forbes if (pFence) { 4223804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt if (pFence->scope == kSyncScopeInternal) { 4224804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt pFence->state = FENCE_UNSIGNALED; 4225804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt } else if (pFence->scope == kSyncScopeExternalTemporary) { 4226804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt pFence->scope = kSyncScopeInternal; 4227804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt } 4228090da73358f71ba026e2474a822fecf55267d166Chris Forbes } 4229090da73358f71ba026e2474a822fecf55267d166Chris Forbes } 4230090da73358f71ba026e2474a822fecf55267d166Chris Forbes lock.unlock(); 4231090da73358f71ba026e2474a822fecf55267d166Chris Forbes } 4232090da73358f71ba026e2474a822fecf55267d166Chris Forbes 42335b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 42345b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 42355b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 4236e1cc7cf9e8a7808209ecc45df2421f3a494dacccTobin Ehlis// For given cb_nodes, invalidate them and track object causing invalidation 42370a4087f99558069e9f6a437ff2dbb5a9c1c22ccaTobin Ehlisvoid invalidateCommandBuffers(const layer_data *dev_data, std::unordered_set<GLOBAL_CB_NODE *> const &cb_nodes, VK_OBJECT obj) { 4238e1cc7cf9e8a7808209ecc45df2421f3a494dacccTobin Ehlis for (auto cb_node : cb_nodes) { 423939c845ed4c066740e9efaed0a00af51be07c67c1Tobin Ehlis if (cb_node->state == CB_RECORDING) { 424039c845ed4c066740e9efaed0a00af51be07c67c1Tobin Ehlis log_msg(dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 42419b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(cb_node->commandBuffer), __LINE__, DRAWSTATE_INVALID_COMMAND_BUFFER, "DS", 4242226a75bff897619b86cc227cf1196b5e245fb96dTobin Ehlis "Invalidating a command buffer that's currently being recorded: 0x%p.", cb_node->commandBuffer); 424346daa701a01b92ae19e3ee9e661d677128fe7e6dChris Forbes cb_node->state = CB_INVALID_INCOMPLETE; 424446daa701a01b92ae19e3ee9e661d677128fe7e6dChris Forbes } 4245ecf6f4952415c47ebb64999e1a962c4f688ca0f7Chris Forbes else if (cb_node->state == CB_RECORDED) { 424646daa701a01b92ae19e3ee9e661d677128fe7e6dChris Forbes cb_node->state = CB_INVALID_COMPLETE; 424739c845ed4c066740e9efaed0a00af51be07c67c1Tobin Ehlis } 4248e1cc7cf9e8a7808209ecc45df2421f3a494dacccTobin Ehlis cb_node->broken_bindings.push_back(obj); 4249db365f522319df6446b50584277a3bbfee1c1052Chris Forbes 4250db365f522319df6446b50584277a3bbfee1c1052Chris Forbes // if secondary, then propagate the invalidation to the primaries that will call us. 4251db365f522319df6446b50584277a3bbfee1c1052Chris Forbes if (cb_node->createInfo.level == VK_COMMAND_BUFFER_LEVEL_SECONDARY) { 4252db365f522319df6446b50584277a3bbfee1c1052Chris Forbes invalidateCommandBuffers(dev_data, cb_node->linkedCommandBuffers, obj); 4253db365f522319df6446b50584277a3bbfee1c1052Chris Forbes } 4254e1cc7cf9e8a7808209ecc45df2421f3a494dacccTobin Ehlis } 4255e1cc7cf9e8a7808209ecc45df2421f3a494dacccTobin Ehlis} 4256e1cc7cf9e8a7808209ecc45df2421f3a494dacccTobin Ehlis 4257c54e405a4ce05f4de10bb78bfc3a4769c41d2d59Tobin Ehlisstatic bool PreCallValidateDestroyFramebuffer(layer_data *dev_data, VkFramebuffer framebuffer, 4258c54e405a4ce05f4de10bb78bfc3a4769c41d2d59Tobin Ehlis FRAMEBUFFER_STATE **framebuffer_state, VK_OBJECT *obj_struct) { 42599a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis *framebuffer_state = GetFramebufferState(dev_data, framebuffer); 42609b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus *obj_struct = {HandleToUint64(framebuffer), kVulkanObjectTypeFramebuffer}; 4261cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.destroy_framebuffer) return false; 4262728a3e68af2277743cc59185dab7281e96480efeTobin Ehlis bool skip = false; 4263728a3e68af2277743cc59185dab7281e96480efeTobin Ehlis if (*framebuffer_state) { 426469ea2c79d7b3f9c987671a10686afac066b275b9Mike Schuchardt skip |= 426569ea2c79d7b3f9c987671a10686afac066b275b9Mike Schuchardt ValidateObjectNotInUse(dev_data, *framebuffer_state, *obj_struct, "vkDestroyFrameBuffer", VALIDATION_ERROR_250006f8); 4266728a3e68af2277743cc59185dab7281e96480efeTobin Ehlis } 4267728a3e68af2277743cc59185dab7281e96480efeTobin Ehlis return skip; 4268728a3e68af2277743cc59185dab7281e96480efeTobin Ehlis} 4269728a3e68af2277743cc59185dab7281e96480efeTobin Ehlis 4270c54e405a4ce05f4de10bb78bfc3a4769c41d2d59Tobin Ehlisstatic void PostCallRecordDestroyFramebuffer(layer_data *dev_data, VkFramebuffer framebuffer, FRAMEBUFFER_STATE *framebuffer_state, 4271728a3e68af2277743cc59185dab7281e96480efeTobin Ehlis VK_OBJECT obj_struct) { 427239c845ed4c066740e9efaed0a00af51be07c67c1Tobin Ehlis invalidateCommandBuffers(dev_data, framebuffer_state->cb_bindings, obj_struct); 4273728a3e68af2277743cc59185dab7281e96480efeTobin Ehlis dev_data->frameBufferMap.erase(framebuffer); 4274728a3e68af2277743cc59185dab7281e96480efeTobin Ehlis} 4275728a3e68af2277743cc59185dab7281e96480efeTobin Ehlis 4276bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL DestroyFramebuffer(VkDevice device, VkFramebuffer framebuffer, const VkAllocationCallbacks *pAllocator) { 427756e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 4278c54e405a4ce05f4de10bb78bfc3a4769c41d2d59Tobin Ehlis FRAMEBUFFER_STATE *framebuffer_state = nullptr; 4279728a3e68af2277743cc59185dab7281e96480efeTobin Ehlis VK_OBJECT obj_struct; 4280ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 4281728a3e68af2277743cc59185dab7281e96480efeTobin Ehlis bool skip = PreCallValidateDestroyFramebuffer(dev_data, framebuffer, &framebuffer_state, &obj_struct); 4282728a3e68af2277743cc59185dab7281e96480efeTobin Ehlis if (!skip) { 4283728a3e68af2277743cc59185dab7281e96480efeTobin Ehlis lock.unlock(); 4284728a3e68af2277743cc59185dab7281e96480efeTobin Ehlis dev_data->dispatch_table.DestroyFramebuffer(device, framebuffer, pAllocator); 4285728a3e68af2277743cc59185dab7281e96480efeTobin Ehlis lock.lock(); 4286405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour if (framebuffer != VK_NULL_HANDLE) { 4287405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour PostCallRecordDestroyFramebuffer(dev_data, framebuffer, framebuffer_state, obj_struct); 4288405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour } 42895b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 42905b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 42915b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 42920ffd03853dc28123fa113e6cd49264838559ee39Tobin Ehlisstatic bool PreCallValidateDestroyRenderPass(layer_data *dev_data, VkRenderPass render_pass, RENDER_PASS_STATE **rp_state, 42930ffd03853dc28123fa113e6cd49264838559ee39Tobin Ehlis VK_OBJECT *obj_struct) { 42949a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis *rp_state = GetRenderPassState(dev_data, render_pass); 42959b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus *obj_struct = {HandleToUint64(render_pass), kVulkanObjectTypeRenderPass}; 4296cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.destroy_renderpass) return false; 42970ffd03853dc28123fa113e6cd49264838559ee39Tobin Ehlis bool skip = false; 42980ffd03853dc28123fa113e6cd49264838559ee39Tobin Ehlis if (*rp_state) { 429969ea2c79d7b3f9c987671a10686afac066b275b9Mike Schuchardt skip |= ValidateObjectNotInUse(dev_data, *rp_state, *obj_struct, "vkDestroyRenderPass", VALIDATION_ERROR_264006d2); 43000ffd03853dc28123fa113e6cd49264838559ee39Tobin Ehlis } 43010ffd03853dc28123fa113e6cd49264838559ee39Tobin Ehlis return skip; 43020ffd03853dc28123fa113e6cd49264838559ee39Tobin Ehlis} 43030ffd03853dc28123fa113e6cd49264838559ee39Tobin Ehlis 43040ffd03853dc28123fa113e6cd49264838559ee39Tobin Ehlisstatic void PostCallRecordDestroyRenderPass(layer_data *dev_data, VkRenderPass render_pass, RENDER_PASS_STATE *rp_state, 43050ffd03853dc28123fa113e6cd49264838559ee39Tobin Ehlis VK_OBJECT obj_struct) { 430639c845ed4c066740e9efaed0a00af51be07c67c1Tobin Ehlis invalidateCommandBuffers(dev_data, rp_state->cb_bindings, obj_struct); 43070ffd03853dc28123fa113e6cd49264838559ee39Tobin Ehlis dev_data->renderPassMap.erase(render_pass); 43080ffd03853dc28123fa113e6cd49264838559ee39Tobin Ehlis} 43090ffd03853dc28123fa113e6cd49264838559ee39Tobin Ehlis 4310bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL DestroyRenderPass(VkDevice device, VkRenderPass renderPass, const VkAllocationCallbacks *pAllocator) { 431156e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 43120ffd03853dc28123fa113e6cd49264838559ee39Tobin Ehlis RENDER_PASS_STATE *rp_state = nullptr; 43130ffd03853dc28123fa113e6cd49264838559ee39Tobin Ehlis VK_OBJECT obj_struct; 4314ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 43150ffd03853dc28123fa113e6cd49264838559ee39Tobin Ehlis bool skip = PreCallValidateDestroyRenderPass(dev_data, renderPass, &rp_state, &obj_struct); 4316a9fbfe0c622e9fa4b56ddd015ed4c3c409020c2eTobin Ehlis if (!skip) { 4317a9fbfe0c622e9fa4b56ddd015ed4c3c409020c2eTobin Ehlis lock.unlock(); 43184a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.DestroyRenderPass(device, renderPass, pAllocator); 43190ffd03853dc28123fa113e6cd49264838559ee39Tobin Ehlis lock.lock(); 4320405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour if (renderPass != VK_NULL_HANDLE) { 4321405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour PostCallRecordDestroyRenderPass(dev_data, renderPass, rp_state, obj_struct); 4322405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour } 4323a9fbfe0c622e9fa4b56ddd015ed4c3c409020c2eTobin Ehlis } 43245b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 43255b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 432689d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR VkResult VKAPI_CALL CreateBuffer(VkDevice device, const VkBufferCreateInfo *pCreateInfo, 432789d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I Wu const VkAllocationCallbacks *pAllocator, VkBuffer *pBuffer) { 432856e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 4329ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 43303683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski bool skip = PreCallValidateCreateBuffer(dev_data, pCreateInfo); 43313683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski lock.unlock(); 43323683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski 43333683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 43344a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.CreateBuffer(device, pCreateInfo, pAllocator, pBuffer); 43355b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 43365b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (VK_SUCCESS == result) { 43373683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski lock.lock(); 43383683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski PostCallRecordCreateBuffer(dev_data, pCreateInfo, pBuffer); 43393683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski lock.unlock(); 43405b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 43415b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 43425b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 43435b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 434489d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR VkResult VKAPI_CALL CreateBufferView(VkDevice device, const VkBufferViewCreateInfo *pCreateInfo, 434589d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I Wu const VkAllocationCallbacks *pAllocator, VkBufferView *pView) { 434656e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 4347ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 43483251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = PreCallValidateCreateBufferView(dev_data, pCreateInfo); 43498c07a094dc9cc4afb6b62181f341c12b9e969041Mark Young lock.unlock(); 43503251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 43514a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.CreateBufferView(device, pCreateInfo, pAllocator, pView); 43525b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (VK_SUCCESS == result) { 43538c07a094dc9cc4afb6b62181f341c12b9e969041Mark Young lock.lock(); 43543683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski PostCallRecordCreateBufferView(dev_data, pCreateInfo, pView); 43558c07a094dc9cc4afb6b62181f341c12b9e969041Mark Young lock.unlock(); 43565b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 43575b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 43585b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 43595b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 43608dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski// Access helper functions for external modules 436157f0da98098689f3624c5503cfe1a4b5fede885aJeremy KniagerVkFormatProperties GetFormatProperties(core_validation::layer_data *device_data, VkFormat format) { 436257f0da98098689f3624c5503cfe1a4b5fede885aJeremy Kniager VkFormatProperties format_properties; 4363d0b59d0aabea9048c518840e762c7a510927c132Mark Lobodzinski instance_layer_data *instance_data = 4364d0b59d0aabea9048c518840e762c7a510927c132Mark Lobodzinski GetLayerDataPtr(get_dispatch_key(device_data->instance_data->instance), instance_layer_data_map); 436557f0da98098689f3624c5503cfe1a4b5fede885aJeremy Kniager instance_data->dispatch_table.GetPhysicalDeviceFormatProperties(device_data->physical_device, format, &format_properties); 4366d0b59d0aabea9048c518840e762c7a510927c132Mark Lobodzinski return format_properties; 43678dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski} 43688dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski 436957f0da98098689f3624c5503cfe1a4b5fede885aJeremy KniagerVkImageFormatProperties GetImageFormatProperties(core_validation::layer_data *device_data, VkFormat format, VkImageType image_type, 437057f0da98098689f3624c5503cfe1a4b5fede885aJeremy Kniager VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags) { 437157f0da98098689f3624c5503cfe1a4b5fede885aJeremy Kniager VkImageFormatProperties image_format_properties; 4372d0b59d0aabea9048c518840e762c7a510927c132Mark Lobodzinski instance_layer_data *instance_data = 4373d0b59d0aabea9048c518840e762c7a510927c132Mark Lobodzinski GetLayerDataPtr(get_dispatch_key(device_data->instance_data->instance), instance_layer_data_map); 4374d0b59d0aabea9048c518840e762c7a510927c132Mark Lobodzinski instance_data->dispatch_table.GetPhysicalDeviceImageFormatProperties(device_data->physical_device, format, image_type, tiling, 437557f0da98098689f3624c5503cfe1a4b5fede885aJeremy Kniager usage, flags, &image_format_properties); 4376d0b59d0aabea9048c518840e762c7a510927c132Mark Lobodzinski return image_format_properties; 43778dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski} 43788dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski 43797a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlisconst debug_report_data *GetReportData(const core_validation::layer_data *device_data) { return device_data->report_data; } 43808dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski 43818dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinskiconst VkPhysicalDeviceProperties *GetPhysicalDeviceProperties(core_validation::layer_data *device_data) { 43828dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski return &device_data->phys_dev_props; 43838dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski} 43848dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski 43858c59133586421be878d393799b30044497f77727Mark Lobodzinskiconst CHECK_DISABLED *GetDisables(core_validation::layer_data *device_data) { return &device_data->instance_data->disabled; } 43868c59133586421be878d393799b30044497f77727Mark Lobodzinski 43878c59133586421be878d393799b30044497f77727Mark Lobodzinskistd::unordered_map<VkImage, std::unique_ptr<IMAGE_STATE>> *GetImageMap(core_validation::layer_data *device_data) { 43888c59133586421be878d393799b30044497f77727Mark Lobodzinski return &device_data->imageMap; 43898c59133586421be878d393799b30044497f77727Mark Lobodzinski} 43908c59133586421be878d393799b30044497f77727Mark Lobodzinski 43918c59133586421be878d393799b30044497f77727Mark Lobodzinskistd::unordered_map<VkImage, std::vector<ImageSubresourcePair>> *GetImageSubresourceMap(core_validation::layer_data *device_data) { 43928c59133586421be878d393799b30044497f77727Mark Lobodzinski return &device_data->imageSubresourceMap; 43938c59133586421be878d393799b30044497f77727Mark Lobodzinski} 43948c59133586421be878d393799b30044497f77727Mark Lobodzinski 43958c59133586421be878d393799b30044497f77727Mark Lobodzinskistd::unordered_map<ImageSubresourcePair, IMAGE_LAYOUT_NODE> *GetImageLayoutMap(layer_data *device_data) { 43968c59133586421be878d393799b30044497f77727Mark Lobodzinski return &device_data->imageLayoutMap; 43978c59133586421be878d393799b30044497f77727Mark Lobodzinski} 43988c59133586421be878d393799b30044497f77727Mark Lobodzinski 43990db18ab1345f9e10907913b22ea5d57bd48077ebTobin Ehlisstd::unordered_map<ImageSubresourcePair, IMAGE_LAYOUT_NODE> const *GetImageLayoutMap(layer_data const *device_data) { 44000db18ab1345f9e10907913b22ea5d57bd48077ebTobin Ehlis return &device_data->imageLayoutMap; 44010db18ab1345f9e10907913b22ea5d57bd48077ebTobin Ehlis} 44020db18ab1345f9e10907913b22ea5d57bd48077ebTobin Ehlis 44033683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinskistd::unordered_map<VkBuffer, std::unique_ptr<BUFFER_STATE>> *GetBufferMap(layer_data *device_data) { 44043683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski return &device_data->bufferMap; 44053683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski} 44063683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski 44073683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinskistd::unordered_map<VkBufferView, std::unique_ptr<BUFFER_VIEW_STATE>> *GetBufferViewMap(layer_data *device_data) { 44083683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski return &device_data->bufferViewMap; 44093683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski} 44103683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski 44111c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinskistd::unordered_map<VkImageView, std::unique_ptr<IMAGE_VIEW_STATE>> *GetImageViewMap(layer_data *device_data) { 44121c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski return &device_data->imageViewMap; 44131c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski} 44141c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski 4415d0b59d0aabea9048c518840e762c7a510927c132Mark Lobodzinskiconst PHYS_DEV_PROPERTIES_NODE *GetPhysDevProperties(const layer_data *device_data) { 44166a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski return &device_data->phys_dev_properties; 44176a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski} 44186a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski 44195f3e7c34de87353f38bbcd79e12de8af4a9e7695Mark Lobodzinskiconst VkPhysicalDeviceFeatures *GetEnabledFeatures(const layer_data *device_data) { 44205f3e7c34de87353f38bbcd79e12de8af4a9e7695Mark Lobodzinski return &device_data->enabled_features; 44215f3e7c34de87353f38bbcd79e12de8af4a9e7695Mark Lobodzinski} 44225f3e7c34de87353f38bbcd79e12de8af4a9e7695Mark Lobodzinski 4423a149f1a0cb39b48b19822c8cf9ef2426cd2251dfMark Lobodzinskiconst DeviceExtensions *GetDeviceExtensions(const layer_data *device_data) { return &device_data->extensions; } 44240e2296e24065d02615ee87561bbb80af414a1ddfMike Schuchardt 442589d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR VkResult VKAPI_CALL CreateImage(VkDevice device, const VkImageCreateInfo *pCreateInfo, 442689d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I Wu const VkAllocationCallbacks *pAllocator, VkImage *pImage) { 44278dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 442856e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 44298dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski bool skip = PreCallValidateCreateImage(dev_data, pCreateInfo, pAllocator, pImage); 44308dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski if (!skip) { 44318dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski result = dev_data->dispatch_table.CreateImage(device, pCreateInfo, pAllocator, pImage); 44328dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski } 44335b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (VK_SUCCESS == result) { 4434ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 4435920311b6aa5614a545cad59521770d0898a75d65Mark Lobodzinski PostCallRecordCreateImage(dev_data, pCreateInfo, pImage); 44365b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 44375b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 44385b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 44395b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 44408c07a094dc9cc4afb6b62181f341c12b9e969041Mark YoungVKAPI_ATTR VkResult VKAPI_CALL CreateImageView(VkDevice device, const VkImageViewCreateInfo *pCreateInfo, 44418c07a094dc9cc4afb6b62181f341c12b9e969041Mark Young const VkAllocationCallbacks *pAllocator, VkImageView *pView) { 444256e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 4443ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 4444e3effabf8e97cae8e006477806ceaca62e4f2ce7Tobin Ehlis bool skip = PreCallValidateCreateImageView(dev_data, pCreateInfo); 44458c07a094dc9cc4afb6b62181f341c12b9e969041Mark Young lock.unlock(); 4446cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 44474a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.CreateImageView(device, pCreateInfo, pAllocator, pView); 44485b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (VK_SUCCESS == result) { 44498c07a094dc9cc4afb6b62181f341c12b9e969041Mark Young lock.lock(); 445079fde938178535f598e030a0e9d19a0cb61b72e0Tobin Ehlis PostCallRecordCreateImageView(dev_data, pCreateInfo, *pView); 44518c07a094dc9cc4afb6b62181f341c12b9e969041Mark Young lock.unlock(); 44525b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 4453bb6624cb996175d8945190886a200e720b3871efChris Forbes 44545b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 44555b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 44565b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 4457bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL CreateFence(VkDevice device, const VkFenceCreateInfo *pCreateInfo, 4458bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkAllocationCallbacks *pAllocator, VkFence *pFence) { 445956e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 44604a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.CreateFence(device, pCreateInfo, pAllocator, pFence); 44615b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (VK_SUCCESS == result) { 4462ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 4463a265a8ed3bbb32ade305b1be3148d6001a870b76Tobin Ehlis auto &fence_node = dev_data->fenceMap[*pFence]; 44648988ad37ea5a054ff2ae3cbe4b767ae6c13cf48bChris Forbes fence_node.fence = *pFence; 4465a265a8ed3bbb32ade305b1be3148d6001a870b76Tobin Ehlis fence_node.createInfo = *pCreateInfo; 4466cdb1ea0ff0d966dda02543468377eae93b9e2f8fChris Forbes fence_node.state = (pCreateInfo->flags & VK_FENCE_CREATE_SIGNALED_BIT) ? FENCE_RETIRED : FENCE_UNSIGNALED; 44675b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 44685b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 44695b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 44705b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 44715b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// TODO handle pipeline caches 447289d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR VkResult VKAPI_CALL CreatePipelineCache(VkDevice device, const VkPipelineCacheCreateInfo *pCreateInfo, 447389d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I Wu const VkAllocationCallbacks *pAllocator, VkPipelineCache *pPipelineCache) { 447456e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 44754a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.CreatePipelineCache(device, pCreateInfo, pAllocator, pPipelineCache); 44765b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 44775b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 44785b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 4479bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL DestroyPipelineCache(VkDevice device, VkPipelineCache pipelineCache, 4480bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkAllocationCallbacks *pAllocator) { 448156e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 44824a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.DestroyPipelineCache(device, pipelineCache, pAllocator); 44835b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 44845b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 4485bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL GetPipelineCacheData(VkDevice device, VkPipelineCache pipelineCache, size_t *pDataSize, 4486bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski void *pData) { 448756e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 44884a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.GetPipelineCacheData(device, pipelineCache, pDataSize, pData); 44895b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 44905b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 44915b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 4492bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL MergePipelineCaches(VkDevice device, VkPipelineCache dstCache, uint32_t srcCacheCount, 4493bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkPipelineCache *pSrcCaches) { 449456e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 44954a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.MergePipelineCaches(device, dstCache, srcCacheCount, pSrcCaches); 44965b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 44975b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 44985b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 4499fe772548f7a48b12772483e8faecc956fb76eb42Chris Forbes// Validation cache: 4500fe772548f7a48b12772483e8faecc956fb76eb42Chris Forbes// CV is the bottommost implementor of this extension. Don't pass calls down. 4501fe772548f7a48b12772483e8faecc956fb76eb42Chris ForbesVKAPI_ATTR VkResult VKAPI_CALL CreateValidationCacheEXT(VkDevice device, const VkValidationCacheCreateInfoEXT *pCreateInfo, 4502f85ac0ee54f3cfbac8bb9bf046de2f502e9b8bffCort Stratton const VkAllocationCallbacks *pAllocator, 4503f85ac0ee54f3cfbac8bb9bf046de2f502e9b8bffCort Stratton VkValidationCacheEXT *pValidationCache) { 4504fe772548f7a48b12772483e8faecc956fb76eb42Chris Forbes *pValidationCache = ValidationCache::Create(pCreateInfo); 4505fe772548f7a48b12772483e8faecc956fb76eb42Chris Forbes return *pValidationCache ? VK_SUCCESS : VK_ERROR_INITIALIZATION_FAILED; 4506fe772548f7a48b12772483e8faecc956fb76eb42Chris Forbes} 4507fe772548f7a48b12772483e8faecc956fb76eb42Chris Forbes 4508fe772548f7a48b12772483e8faecc956fb76eb42Chris ForbesVKAPI_ATTR void VKAPI_CALL DestroyValidationCacheEXT(VkDevice device, VkValidationCacheEXT validationCache, 4509f85ac0ee54f3cfbac8bb9bf046de2f502e9b8bffCort Stratton const VkAllocationCallbacks *pAllocator) { 4510fe772548f7a48b12772483e8faecc956fb76eb42Chris Forbes delete (ValidationCache *)validationCache; 4511fe772548f7a48b12772483e8faecc956fb76eb42Chris Forbes} 4512fe772548f7a48b12772483e8faecc956fb76eb42Chris Forbes 4513fe772548f7a48b12772483e8faecc956fb76eb42Chris ForbesVKAPI_ATTR VkResult VKAPI_CALL GetValidationCacheDataEXT(VkDevice device, VkValidationCacheEXT validationCache, size_t *pDataSize, 4514f85ac0ee54f3cfbac8bb9bf046de2f502e9b8bffCort Stratton void *pData) { 4515fe772548f7a48b12772483e8faecc956fb76eb42Chris Forbes size_t inSize = *pDataSize; 4516fe772548f7a48b12772483e8faecc956fb76eb42Chris Forbes ((ValidationCache *)validationCache)->Write(pDataSize, pData); 4517fe772548f7a48b12772483e8faecc956fb76eb42Chris Forbes return (pData && *pDataSize != inSize) ? VK_INCOMPLETE : VK_SUCCESS; 4518fe772548f7a48b12772483e8faecc956fb76eb42Chris Forbes} 4519fe772548f7a48b12772483e8faecc956fb76eb42Chris Forbes 4520fe772548f7a48b12772483e8faecc956fb76eb42Chris ForbesVKAPI_ATTR VkResult VKAPI_CALL MergeValidationCachesEXT(VkDevice device, VkValidationCacheEXT dstCache, uint32_t srcCacheCount, 4521b1260c070b19760942d5fddf0d7b1d8872311277Cort Stratton const VkValidationCacheEXT *pSrcCaches) { 4522b1260c070b19760942d5fddf0d7b1d8872311277Cort Stratton layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 4523b1260c070b19760942d5fddf0d7b1d8872311277Cort Stratton bool skip = false; 4524fe772548f7a48b12772483e8faecc956fb76eb42Chris Forbes auto dst = (ValidationCache *)dstCache; 4525b1260c070b19760942d5fddf0d7b1d8872311277Cort Stratton auto src = (ValidationCache const *const *)pSrcCaches; 4526b1260c070b19760942d5fddf0d7b1d8872311277Cort Stratton VkResult result = VK_SUCCESS; 4527b1260c070b19760942d5fddf0d7b1d8872311277Cort Stratton for (uint32_t i = 0; i < srcCacheCount; i++) { 4528b1260c070b19760942d5fddf0d7b1d8872311277Cort Stratton if (src[i] == dst) { 4529b1260c070b19760942d5fddf0d7b1d8872311277Cort Stratton skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT, 4530b1260c070b19760942d5fddf0d7b1d8872311277Cort Stratton 0, __LINE__, VALIDATION_ERROR_3e600c00, "DS", 4531b1260c070b19760942d5fddf0d7b1d8872311277Cort Stratton "vkMergeValidationCachesEXT: dstCache (0x%" PRIxLEAST64 ") must not appear in pSrcCaches array. %s", 4532b1260c070b19760942d5fddf0d7b1d8872311277Cort Stratton HandleToUint64(dstCache), validation_error_map[VALIDATION_ERROR_3e600c00]); 4533b1260c070b19760942d5fddf0d7b1d8872311277Cort Stratton result = VK_ERROR_VALIDATION_FAILED_EXT; 4534b1260c070b19760942d5fddf0d7b1d8872311277Cort Stratton } 4535b1260c070b19760942d5fddf0d7b1d8872311277Cort Stratton if (!skip) { 4536b1260c070b19760942d5fddf0d7b1d8872311277Cort Stratton dst->Merge(src[i]); 4537b1260c070b19760942d5fddf0d7b1d8872311277Cort Stratton } 4538b1260c070b19760942d5fddf0d7b1d8872311277Cort Stratton } 4539fe772548f7a48b12772483e8faecc956fb76eb42Chris Forbes 4540b1260c070b19760942d5fddf0d7b1d8872311277Cort Stratton return result; 4541fe772548f7a48b12772483e8faecc956fb76eb42Chris Forbes} 4542fe772548f7a48b12772483e8faecc956fb76eb42Chris Forbes 45433d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis// utility function to set collective state for pipeline 45444c0df90de562aa248b524a28b355765d8e3eff25Tobin Ehlisvoid set_pipeline_state(PIPELINE_STATE *pPipe) { 45453d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis // If any attachment used by this pipeline has blendEnable, set top-level blendEnable 45463d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis if (pPipe->graphicsPipelineCI.pColorBlendState) { 45473d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis for (size_t i = 0; i < pPipe->attachments.size(); ++i) { 45483d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis if (VK_TRUE == pPipe->attachments[i].blendEnable) { 45493d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis if (((pPipe->attachments[i].dstAlphaBlendFactor >= VK_BLEND_FACTOR_CONSTANT_COLOR) && 45503d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis (pPipe->attachments[i].dstAlphaBlendFactor <= VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA)) || 45513d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis ((pPipe->attachments[i].dstColorBlendFactor >= VK_BLEND_FACTOR_CONSTANT_COLOR) && 45523d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis (pPipe->attachments[i].dstColorBlendFactor <= VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA)) || 45533d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis ((pPipe->attachments[i].srcAlphaBlendFactor >= VK_BLEND_FACTOR_CONSTANT_COLOR) && 45543d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis (pPipe->attachments[i].srcAlphaBlendFactor <= VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA)) || 45553d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis ((pPipe->attachments[i].srcColorBlendFactor >= VK_BLEND_FACTOR_CONSTANT_COLOR) && 45563d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis (pPipe->attachments[i].srcColorBlendFactor <= VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA))) { 45573d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis pPipe->blendConstantsEnabled = true; 45583d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis } 45593d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis } 45603d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis } 45613d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis } 45623d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis} 45633d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis 4564daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinskibool validate_dual_src_blend_feature(layer_data *device_data, PIPELINE_STATE *pipe_state) { 4565daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski bool skip = false; 4566daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski if (pipe_state->graphicsPipelineCI.pColorBlendState) { 4567daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski for (size_t i = 0; i < pipe_state->attachments.size(); ++i) { 4568daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski if (!device_data->enabled_features.dualSrcBlend) { 4569daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski if ((pipe_state->attachments[i].dstAlphaBlendFactor == VK_BLEND_FACTOR_SRC1_COLOR) || 4570daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski (pipe_state->attachments[i].dstAlphaBlendFactor == VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR) || 4571daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski (pipe_state->attachments[i].dstAlphaBlendFactor == VK_BLEND_FACTOR_SRC1_ALPHA) || 4572daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski (pipe_state->attachments[i].dstAlphaBlendFactor == VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA) || 4573daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski (pipe_state->attachments[i].srcAlphaBlendFactor == VK_BLEND_FACTOR_SRC1_COLOR) || 4574daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski (pipe_state->attachments[i].srcAlphaBlendFactor == VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR) || 4575daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski (pipe_state->attachments[i].srcAlphaBlendFactor == VK_BLEND_FACTOR_SRC1_ALPHA) || 4576daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski (pipe_state->attachments[i].srcAlphaBlendFactor == VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA)) { 4577daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski skip |= 4578daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 45799b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pipe_state->pipeline), __LINE__, DRAWSTATE_INVALID_FEATURE, "DS", 4580daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski "CmdBindPipeline: vkPipeline (0x%" PRIxLEAST64 ") attachment[" PRINTF_SIZE_T_SPECIFIER 4581daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski "] has a dual-source blend factor but this device feature is not enabled.", 45829b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pipe_state->pipeline), i); 4583daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski } 4584daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski } 4585daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski } 4586daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski } 4587daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski return skip; 4588daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski} 4589daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski 4590bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL CreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count, 4591bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkGraphicsPipelineCreateInfo *pCreateInfos, 4592bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines) { 45935b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // The order of operations here is a little convoluted but gets the job done 45944c0df90de562aa248b524a28b355765d8e3eff25Tobin Ehlis // 1. Pipeline create state is first shadowed into PIPELINE_STATE struct 45955b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // 2. Create state is then validated (which uses flags setup during shadowing) 45965b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // 3. If everything looks good, we'll then create the pipeline and add NODE to pipelineMap 459742486a20f07b16f0c5361cdc00fd789b07b1989aMark Lobodzinski bool skip = false; 45983d67a6d0f5c42da03d838178741ef10928cd6397Chris Forbes vector<std::unique_ptr<PIPELINE_STATE>> pipe_state; 45993d67a6d0f5c42da03d838178741ef10928cd6397Chris Forbes pipe_state.reserve(count); 460056e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 46015b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 46025b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis uint32_t i = 0; 4603ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 46045b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 46055b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (i = 0; i < count; i++) { 46063d67a6d0f5c42da03d838178741ef10928cd6397Chris Forbes pipe_state.push_back(std::unique_ptr<PIPELINE_STATE>(new PIPELINE_STATE)); 4607cafebcdd40427a0713a3564dc8f39e47edbdb02fTobin Ehlis pipe_state[i]->initGraphicsPipeline(&pCreateInfos[i], GetRenderPassStateSharedPtr(dev_data, pCreateInfos[i].renderPass)); 46083800dc6928d2f26ad0da2a3b5796ee1042f70ec0Mark Lobodzinski pipe_state[i]->render_pass_ci.initialize(GetRenderPassState(dev_data, pCreateInfos[i].renderPass)->createInfo.ptr()); 460942486a20f07b16f0c5361cdc00fd789b07b1989aMark Lobodzinski pipe_state[i]->pipeline_layout = *getPipelineLayout(dev_data, pCreateInfos[i].layout); 46105b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 46114260fe87d0d168d6f4e7d65a648be05ebe1dedb3Chris Forbes 46124260fe87d0d168d6f4e7d65a648be05ebe1dedb3Chris Forbes for (i = 0; i < count; i++) { 46132f521eee4ccb1c84512ea767880df8f38751c0d4Chris Forbes skip |= ValidatePipelineLocked(dev_data, pipe_state, i); 46144260fe87d0d168d6f4e7d65a648be05ebe1dedb3Chris Forbes } 46155b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 461629243a95b358b0d96ab15064fb3f9b0c0f64b8e9Chris Forbes lock.unlock(); 461729243a95b358b0d96ab15064fb3f9b0c0f64b8e9Chris Forbes 4618c3e70f769bd4aa0988652050444d57cab4925c16Chris Forbes for (i = 0; i < count; i++) { 4619c3e70f769bd4aa0988652050444d57cab4925c16Chris Forbes skip |= ValidatePipelineUnlocked(dev_data, pipe_state, i); 4620c3e70f769bd4aa0988652050444d57cab4925c16Chris Forbes } 4621c3e70f769bd4aa0988652050444d57cab4925c16Chris Forbes 4622c70226063be6148056ceeccf835175a1fd59f24fChris Forbes if (skip) { 4623c70226063be6148056ceeccf835175a1fd59f24fChris Forbes for (i = 0; i < count; i++) { 46241ab616b32d4e5b7d62d4a8c41b0c03ea335ab845Chris Forbes pPipelines[i] = VK_NULL_HANDLE; 4625c70226063be6148056ceeccf835175a1fd59f24fChris Forbes } 46267a456d188475c23b566334be45dc0489b2789653Chris Forbes return VK_ERROR_VALIDATION_FAILED_EXT; 46277a456d188475c23b566334be45dc0489b2789653Chris Forbes } 46287a456d188475c23b566334be45dc0489b2789653Chris Forbes 4629bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski auto result = 4630bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski dev_data->dispatch_table.CreateGraphicsPipelines(device, pipelineCache, count, pCreateInfos, pAllocator, pPipelines); 46317a456d188475c23b566334be45dc0489b2789653Chris Forbes lock.lock(); 46327a456d188475c23b566334be45dc0489b2789653Chris Forbes for (i = 0; i < count; i++) { 46333d67a6d0f5c42da03d838178741ef10928cd6397Chris Forbes if (pPipelines[i] != VK_NULL_HANDLE) { 463461943a7503bc8594338f3364ef42f1d863486c04Chris Forbes pipe_state[i]->pipeline = pPipelines[i]; 463563cddeb5593a0ead9ecd5f74d05f506b37d7ac66Chris Forbes dev_data->pipelineMap[pPipelines[i]] = std::move(pipe_state[i]); 463661943a7503bc8594338f3364ef42f1d863486c04Chris Forbes } 46375b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 4638c70226063be6148056ceeccf835175a1fd59f24fChris Forbes 46395b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 46405b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 46415b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 4642bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL CreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count, 4643bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkComputePipelineCreateInfo *pCreateInfos, 4644bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines) { 46450108a1af0b7c6949846e9d71d00bbfb322b6f7caChris Forbes bool skip = false; 46465b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 4647e708f7e5c363576bfab5b39135d629ab2ce37167Chris Forbes vector<std::unique_ptr<PIPELINE_STATE>> pPipeState; 4648e708f7e5c363576bfab5b39135d629ab2ce37167Chris Forbes pPipeState.reserve(count); 464956e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 46505b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 46515b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis uint32_t i = 0; 4652ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 46535b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (i = 0; i < count; i++) { 46545b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Create and initialize internal tracking data structure 4655e708f7e5c363576bfab5b39135d629ab2ce37167Chris Forbes pPipeState.push_back(unique_ptr<PIPELINE_STATE>(new PIPELINE_STATE)); 46564c0df90de562aa248b524a28b355765d8e3eff25Tobin Ehlis pPipeState[i]->initComputePipeline(&pCreateInfos[i]); 4657c2a5a36d03bbe52f5854a5884346e4a84115e259Tobin Ehlis pPipeState[i]->pipeline_layout = *getPipelineLayout(dev_data, pCreateInfos[i].layout); 46585b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 46595b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // TODO: Add Compute Pipeline Verification 4660e708f7e5c363576bfab5b39135d629ab2ce37167Chris Forbes skip |= validate_compute_pipeline(dev_data, pPipeState[i].get()); 46615b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 46625b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 46637a456d188475c23b566334be45dc0489b2789653Chris Forbes if (skip) { 46645b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (i = 0; i < count; i++) { 4665fcf67c021fdfcbeb12fb04daa9a69ecd7d376c5cChris Forbes pPipelines[i] = VK_NULL_HANDLE; 46665b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 46675b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return VK_ERROR_VALIDATION_FAILED_EXT; 46685b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 46697a456d188475c23b566334be45dc0489b2789653Chris Forbes 46707a456d188475c23b566334be45dc0489b2789653Chris Forbes lock.unlock(); 4671bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski auto result = 4672bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski dev_data->dispatch_table.CreateComputePipelines(device, pipelineCache, count, pCreateInfos, pAllocator, pPipelines); 46737a456d188475c23b566334be45dc0489b2789653Chris Forbes lock.lock(); 46747a456d188475c23b566334be45dc0489b2789653Chris Forbes for (i = 0; i < count; i++) { 4675e708f7e5c363576bfab5b39135d629ab2ce37167Chris Forbes if (pPipelines[i] != VK_NULL_HANDLE) { 4676fcf67c021fdfcbeb12fb04daa9a69ecd7d376c5cChris Forbes pPipeState[i]->pipeline = pPipelines[i]; 467763cddeb5593a0ead9ecd5f74d05f506b37d7ac66Chris Forbes dev_data->pipelineMap[pPipelines[i]] = std::move(pPipeState[i]); 4678fcf67c021fdfcbeb12fb04daa9a69ecd7d376c5cChris Forbes } 46797a456d188475c23b566334be45dc0489b2789653Chris Forbes } 46807a456d188475c23b566334be45dc0489b2789653Chris Forbes 46815b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 46825b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 46835b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 468489d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR VkResult VKAPI_CALL CreateSampler(VkDevice device, const VkSamplerCreateInfo *pCreateInfo, 468589d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I Wu const VkAllocationCallbacks *pAllocator, VkSampler *pSampler) { 468656e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 46874a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.CreateSampler(device, pCreateInfo, pAllocator, pSampler); 46885b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (VK_SUCCESS == result) { 4689ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 4690d31a44af6da568692a73201825459689c9431867Tobin Ehlis dev_data->samplerMap[*pSampler] = unique_ptr<SAMPLER_STATE>(new SAMPLER_STATE(pSampler, pCreateInfo)); 46915b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 46925b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 46935b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 46945b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 46950c347fc6b08172b778c259e1a1219a2403495d48Tobin Ehlisstatic bool PreCallValidateCreateDescriptorSetLayout(layer_data *dev_data, const VkDescriptorSetLayoutCreateInfo *create_info) { 4696cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.create_descriptor_set_layout) return false; 46970c347fc6b08172b778c259e1a1219a2403495d48Tobin Ehlis return cvdescriptorset::DescriptorSetLayout::ValidateCreateInfo(dev_data->report_data, create_info); 46980c347fc6b08172b778c259e1a1219a2403495d48Tobin Ehlis} 46990c347fc6b08172b778c259e1a1219a2403495d48Tobin Ehlis 47000c347fc6b08172b778c259e1a1219a2403495d48Tobin Ehlisstatic void PostCallRecordCreateDescriptorSetLayout(layer_data *dev_data, const VkDescriptorSetLayoutCreateInfo *create_info, 47010c347fc6b08172b778c259e1a1219a2403495d48Tobin Ehlis VkDescriptorSetLayout set_layout) { 47027e180d382f501c7c04408bda1f5fe79317736a4fTobin Ehlis dev_data->descriptorSetLayoutMap[set_layout] = std::make_shared<cvdescriptorset::DescriptorSetLayout>(create_info, set_layout); 47030c347fc6b08172b778c259e1a1219a2403495d48Tobin Ehlis} 47040c347fc6b08172b778c259e1a1219a2403495d48Tobin Ehlis 4705bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL CreateDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo, 4706bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkAllocationCallbacks *pAllocator, 4707bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkDescriptorSetLayout *pSetLayout) { 470856e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 47090c347fc6b08172b778c259e1a1219a2403495d48Tobin Ehlis VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 4710ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 47110c347fc6b08172b778c259e1a1219a2403495d48Tobin Ehlis bool skip = PreCallValidateCreateDescriptorSetLayout(dev_data, pCreateInfo); 47120c347fc6b08172b778c259e1a1219a2403495d48Tobin Ehlis if (!skip) { 47130c347fc6b08172b778c259e1a1219a2403495d48Tobin Ehlis lock.unlock(); 47140c347fc6b08172b778c259e1a1219a2403495d48Tobin Ehlis result = dev_data->dispatch_table.CreateDescriptorSetLayout(device, pCreateInfo, pAllocator, pSetLayout); 47150c347fc6b08172b778c259e1a1219a2403495d48Tobin Ehlis if (VK_SUCCESS == result) { 47160c347fc6b08172b778c259e1a1219a2403495d48Tobin Ehlis lock.lock(); 47170c347fc6b08172b778c259e1a1219a2403495d48Tobin Ehlis PostCallRecordCreateDescriptorSetLayout(dev_data, pCreateInfo, *pSetLayout); 47180c347fc6b08172b778c259e1a1219a2403495d48Tobin Ehlis } 47195b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 47205b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 47215b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 47225b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 47239e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz// Used by CreatePipelineLayout and CmdPushConstants. 47249e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz// Note that the index argument is optional and only used by CreatePipelineLayout. 47259e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultzstatic bool validatePushConstantRange(const layer_data *dev_data, const uint32_t offset, const uint32_t size, 47269e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz const char *caller_name, uint32_t index = 0) { 4727cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.push_constant_range) return false; 47289e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz uint32_t const maxPushConstantsSize = dev_data->phys_dev_properties.properties.limits.maxPushConstantsSize; 47293251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 47309e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz // Check that offset + size don't exceed the max. 47319e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz // Prevent arithetic overflow here by avoiding addition and testing in this order. 47329e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz if ((offset >= maxPushConstantsSize) || (size > maxPushConstantsSize - offset)) { 47339e24d8153ab63bc3ac08b5a1517c203930b5de91Karl 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. 47349e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz if (0 == strcmp(caller_name, "vkCreatePipelineLayout()")) { 4735e420dd92dcfc04f279e98796a49ee26b2c3ddafeTobin Ehlis if (offset >= maxPushConstantsSize) { 47363251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 4737315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis __LINE__, VALIDATION_ERROR_11a0024c, "DS", 47383251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "%s call has push constants index %u with offset %u that " 47393251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "exceeds this device's maxPushConstantSize of %u. %s", 4740315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis caller_name, index, offset, maxPushConstantsSize, validation_error_map[VALIDATION_ERROR_11a0024c]); 4741e420dd92dcfc04f279e98796a49ee26b2c3ddafeTobin Ehlis } 4742e420dd92dcfc04f279e98796a49ee26b2c3ddafeTobin Ehlis if (size > maxPushConstantsSize - offset) { 4743315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 4744315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis __LINE__, VALIDATION_ERROR_11a00254, "DS", 4745315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis "%s call has push constants index %u with offset %u and size %u that " 4746315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis "exceeds this device's maxPushConstantSize of %u. %s", 4747315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis caller_name, index, offset, size, maxPushConstantsSize, 4748315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_11a00254]); 4749e420dd92dcfc04f279e98796a49ee26b2c3ddafeTobin Ehlis } 47509e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz } else if (0 == strcmp(caller_name, "vkCmdPushConstants()")) { 47514527dcafa951a1fa931b258bbcd2d48b283610a7Dave Houlton if (offset >= maxPushConstantsSize) { 47523251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 4753315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis __LINE__, VALIDATION_ERROR_1bc002e4, "DS", 47543251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "%s call has push constants index %u with offset %u that " 47553251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "exceeds this device's maxPushConstantSize of %u. %s", 4756315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis caller_name, index, offset, maxPushConstantsSize, validation_error_map[VALIDATION_ERROR_1bc002e4]); 47574527dcafa951a1fa931b258bbcd2d48b283610a7Dave Houlton } 47584527dcafa951a1fa931b258bbcd2d48b283610a7Dave Houlton if (size > maxPushConstantsSize - offset) { 4759315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 4760315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis __LINE__, VALIDATION_ERROR_1bc002e6, "DS", 4761315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis "%s call has push constants index %u with offset %u and size %u that " 4762315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis "exceeds this device's maxPushConstantSize of %u. %s", 4763315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis caller_name, index, offset, size, maxPushConstantsSize, 4764315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_1bc002e6]); 47654527dcafa951a1fa931b258bbcd2d48b283610a7Dave Houlton } 47669e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz } else { 47673251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 47683251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski __LINE__, DRAWSTATE_INTERNAL_ERROR, "DS", "%s caller not supported.", caller_name); 47699e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz } 47709e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz } 47719e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz // size needs to be non-zero and a multiple of 4. 47729e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz if ((size == 0) || ((size & 0x3) != 0)) { 47739e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz if (0 == strcmp(caller_name, "vkCreatePipelineLayout()")) { 4774891f13be101e95697e5af9503f06da38b0c48f79Tobin Ehlis if (size == 0) { 47753251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 4776315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis __LINE__, VALIDATION_ERROR_11a00250, "DS", 47773251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "%s call has push constants index %u with " 47783251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "size %u. Size must be greater than zero. %s", 4779315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis caller_name, index, size, validation_error_map[VALIDATION_ERROR_11a00250]); 4780891f13be101e95697e5af9503f06da38b0c48f79Tobin Ehlis } 4781891f13be101e95697e5af9503f06da38b0c48f79Tobin Ehlis if (size & 0x3) { 47823251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 4783315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis __LINE__, VALIDATION_ERROR_11a00252, "DS", 47843251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "%s call has push constants index %u with " 47853251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "size %u. Size must be a multiple of 4. %s", 4786315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis caller_name, index, size, validation_error_map[VALIDATION_ERROR_11a00252]); 4787891f13be101e95697e5af9503f06da38b0c48f79Tobin Ehlis } 47889e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz } else if (0 == strcmp(caller_name, "vkCmdPushConstants()")) { 47894527dcafa951a1fa931b258bbcd2d48b283610a7Dave Houlton if (size == 0) { 47903251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 4791315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis __LINE__, VALIDATION_ERROR_1bc2c21b, "DS", 47923251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "%s call has push constants index %u with " 47933251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "size %u. Size must be greater than zero. %s", 4794315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis caller_name, index, size, validation_error_map[VALIDATION_ERROR_1bc2c21b]); 47954527dcafa951a1fa931b258bbcd2d48b283610a7Dave Houlton } 47964527dcafa951a1fa931b258bbcd2d48b283610a7Dave Houlton if (size & 0x3) { 47973251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 4798315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis __LINE__, VALIDATION_ERROR_1bc002e2, "DS", 47993251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "%s call has push constants index %u with " 48003251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "size %u. Size must be a multiple of 4. %s", 4801315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis caller_name, index, size, validation_error_map[VALIDATION_ERROR_1bc002e2]); 48024527dcafa951a1fa931b258bbcd2d48b283610a7Dave Houlton } 48039e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz } else { 48043251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 48053251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski __LINE__, DRAWSTATE_INTERNAL_ERROR, "DS", "%s caller not supported.", caller_name); 48069e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz } 48079e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz } 48089e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz // offset needs to be a multiple of 4. 48099e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz if ((offset & 0x3) != 0) { 48109e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz if (0 == strcmp(caller_name, "vkCreatePipelineLayout()")) { 48113251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 4812315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis __LINE__, VALIDATION_ERROR_11a0024e, "DS", 48133251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "%s call has push constants index %u with " 48143251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "offset %u. Offset must be a multiple of 4. %s", 4815315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis caller_name, index, offset, validation_error_map[VALIDATION_ERROR_11a0024e]); 48169e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz } else if (0 == strcmp(caller_name, "vkCmdPushConstants()")) { 48173251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 4818315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis __LINE__, VALIDATION_ERROR_1bc002e0, "DS", 48193251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "%s call has push constants with " 48203251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "offset %u. Offset must be a multiple of 4. %s", 4821315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis caller_name, offset, validation_error_map[VALIDATION_ERROR_1bc002e0]); 48229e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz } else { 48233251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 48243251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski __LINE__, DRAWSTATE_INTERNAL_ERROR, "DS", "%s caller not supported.", caller_name); 48259e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz } 48265b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 48273251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 48285b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 48295b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 4830bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL CreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo *pCreateInfo, 483189d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I Wu const VkAllocationCallbacks *pAllocator, VkPipelineLayout *pPipelineLayout) { 48323251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 483356e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 4834bf0fa2ad7830118e59f0fb8ff88efae18a72e833Karl Schultz // TODO : Add checks for VALIDATION_ERRORS 865-870 48359e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz // Push Constant Range checks 483607a398f7c8da45c8286cba4ef33239646ee87dc9Karl Schultz uint32_t i, j; 48375b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (i = 0; i < pCreateInfo->pushConstantRangeCount; ++i) { 48383251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= validatePushConstantRange(dev_data, pCreateInfo->pPushConstantRanges[i].offset, 48393251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski pCreateInfo->pPushConstantRanges[i].size, "vkCreatePipelineLayout()", i); 48409e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz if (0 == pCreateInfo->pPushConstantRanges[i].stageFlags) { 48413251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 4842315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis __LINE__, VALIDATION_ERROR_11a2dc03, "DS", "vkCreatePipelineLayout() call has no stageFlags set. %s", 4843315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_11a2dc03]); 48449e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz } 48459e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz } 48463251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 484707a398f7c8da45c8286cba4ef33239646ee87dc9Karl Schultz 4848bf0fa2ad7830118e59f0fb8ff88efae18a72e833Karl 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. 484907a398f7c8da45c8286cba4ef33239646ee87dc9Karl Schultz for (i = 0; i < pCreateInfo->pushConstantRangeCount; ++i) { 485007a398f7c8da45c8286cba4ef33239646ee87dc9Karl Schultz for (j = i + 1; j < pCreateInfo->pushConstantRangeCount; ++j) { 4851bf0fa2ad7830118e59f0fb8ff88efae18a72e833Karl Schultz if (0 != (pCreateInfo->pPushConstantRanges[i].stageFlags & pCreateInfo->pPushConstantRanges[j].stageFlags)) { 48523251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 4853315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis __LINE__, VALIDATION_ERROR_0fe00248, "DS", 48543251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkCreatePipelineLayout() Duplicate stage flags found in ranges %d and %d. %s", i, j, 4855315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_0fe00248]); 48569e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz } 48575b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 48585b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 4859f73b2046273413ea1338dd714d67c39f8e0fa09eChris Forbes 486054aae8da345cdc9b9db8ac81e3e03075db79cf9fJózef Kucia std::vector<std::shared_ptr<cvdescriptorset::DescriptorSetLayout const>> set_layouts(pCreateInfo->setLayoutCount, nullptr); 486154aae8da345cdc9b9db8ac81e3e03075db79cf9fJózef Kucia unique_lock_t lock(global_lock); 486254aae8da345cdc9b9db8ac81e3e03075db79cf9fJózef Kucia unsigned int push_descriptor_set_count = 0; 486354aae8da345cdc9b9db8ac81e3e03075db79cf9fJózef Kucia for (i = 0; i < pCreateInfo->setLayoutCount; ++i) { 486454aae8da345cdc9b9db8ac81e3e03075db79cf9fJózef Kucia set_layouts[i] = GetDescriptorSetLayout(dev_data, pCreateInfo->pSetLayouts[i]); 486554aae8da345cdc9b9db8ac81e3e03075db79cf9fJózef Kucia if (set_layouts[i]->IsPushDescriptor()) ++push_descriptor_set_count; 486654aae8da345cdc9b9db8ac81e3e03075db79cf9fJózef Kucia } 486754aae8da345cdc9b9db8ac81e3e03075db79cf9fJózef Kucia lock.unlock(); 486854aae8da345cdc9b9db8ac81e3e03075db79cf9fJózef Kucia if (push_descriptor_set_count > 1) { 486954aae8da345cdc9b9db8ac81e3e03075db79cf9fJózef Kucia skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 487054aae8da345cdc9b9db8ac81e3e03075db79cf9fJózef Kucia __LINE__, VALIDATION_ERROR_0fe0024a, "DS", 487154aae8da345cdc9b9db8ac81e3e03075db79cf9fJózef Kucia "vkCreatePipelineLayout() Multiple push descriptor sets found. %s", 487254aae8da345cdc9b9db8ac81e3e03075db79cf9fJózef Kucia validation_error_map[VALIDATION_ERROR_0fe0024a]); 487354aae8da345cdc9b9db8ac81e3e03075db79cf9fJózef Kucia } 487454aae8da345cdc9b9db8ac81e3e03075db79cf9fJózef Kucia if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 487554aae8da345cdc9b9db8ac81e3e03075db79cf9fJózef Kucia 48764a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.CreatePipelineLayout(device, pCreateInfo, pAllocator, pPipelineLayout); 48775b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (VK_SUCCESS == result) { 487854aae8da345cdc9b9db8ac81e3e03075db79cf9fJózef Kucia lock.lock(); 48795b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis PIPELINE_LAYOUT_NODE &plNode = dev_data->pipelineLayoutMap[*pPipelineLayout]; 488069b71d9c89447ec87d823669ee9edbfc58af174aTobin Ehlis plNode.layout = *pPipelineLayout; 4881416bfef833408786b4a17f725b0ed6480bc65120Tobin Ehlis plNode.set_layouts.resize(pCreateInfo->setLayoutCount); 488254aae8da345cdc9b9db8ac81e3e03075db79cf9fJózef Kucia plNode.set_layouts.swap(set_layouts); 4883416bfef833408786b4a17f725b0ed6480bc65120Tobin Ehlis plNode.push_constant_ranges.resize(pCreateInfo->pushConstantRangeCount); 48845b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (i = 0; i < pCreateInfo->pushConstantRangeCount; ++i) { 4885416bfef833408786b4a17f725b0ed6480bc65120Tobin Ehlis plNode.push_constant_ranges[i] = pCreateInfo->pPushConstantRanges[i]; 48865b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 488754aae8da345cdc9b9db8ac81e3e03075db79cf9fJózef Kucia lock.unlock(); 48885b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 48895b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 48905b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 48915b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 4892bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL CreateDescriptorPool(VkDevice device, const VkDescriptorPoolCreateInfo *pCreateInfo, 4893bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkAllocationCallbacks *pAllocator, VkDescriptorPool *pDescriptorPool) { 489456e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 48954a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.CreateDescriptorPool(device, pCreateInfo, pAllocator, pDescriptorPool); 48965b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (VK_SUCCESS == result) { 4897a21f0d8ac8389dc4e23749efc02d82a7ec1eaee3Tobin Ehlis DESCRIPTOR_POOL_STATE *pNewNode = new DESCRIPTOR_POOL_STATE(*pDescriptorPool, pCreateInfo); 48985b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (NULL == pNewNode) { 48995b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT, 49009b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(*pDescriptorPool), __LINE__, DRAWSTATE_OUT_OF_MEMORY, "DS", 4901a21f0d8ac8389dc4e23749efc02d82a7ec1eaee3Tobin Ehlis "Out of memory while attempting to allocate DESCRIPTOR_POOL_STATE in vkCreateDescriptorPool()")) 49025b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return VK_ERROR_VALIDATION_FAILED_EXT; 49035b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } else { 4904ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 49055b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis dev_data->descriptorPoolMap[*pDescriptorPool] = pNewNode; 49065b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 49075b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } else { 49085b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Need to do anything if pool create fails? 49095b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 49105b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 49115b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 49125b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 4913bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL ResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool, 4914bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkDescriptorPoolResetFlags flags) { 4915315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis // TODO : Add checks for VALIDATION_ERROR_32a00272 491656e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 49174a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.ResetDescriptorPool(device, descriptorPool, flags); 49185b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (VK_SUCCESS == result) { 4919ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 49205b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis clearDescriptorPool(dev_data, device, descriptorPool, flags); 49215b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 49225b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 49235b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 49242c4e180a4442f968b44f3d5136f7ffda706f6428Chris Forbes// Ensure the pool contains enough descriptors and descriptor sets to satisfy 4925789832b514862c7a7b5b847eeb8e7cacb733b77bTobin Ehlis// an allocation request. Fills common_data with the total number of descriptors of each type required, 4926789832b514862c7a7b5b847eeb8e7cacb733b77bTobin Ehlis// as well as DescriptorSetLayout ptrs used for later update. 49277f61868b44f1da1dfa6a4ff726020411db92ce0dTobin Ehlisstatic bool PreCallValidateAllocateDescriptorSets(layer_data *dev_data, const VkDescriptorSetAllocateInfo *pAllocateInfo, 49287f61868b44f1da1dfa6a4ff726020411db92ce0dTobin Ehlis cvdescriptorset::AllocateDescriptorSetsData *common_data) { 49297a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlis // Always update common data 49307a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlis cvdescriptorset::UpdateAllocateDescriptorSetsData(dev_data, pAllocateInfo, common_data); 4931cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.allocate_descriptor_sets) return false; 49327e73e5c6b3020b96a821985f73012f2af0f1b992Tobin Ehlis // All state checks for AllocateDescriptorSets is done in single function 49337a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlis return cvdescriptorset::ValidateAllocateDescriptorSets(dev_data, pAllocateInfo, common_data); 49347e73e5c6b3020b96a821985f73012f2af0f1b992Tobin Ehlis} 49357e73e5c6b3020b96a821985f73012f2af0f1b992Tobin Ehlis// Allocation state was good and call down chain was made so update state based on allocating descriptor sets 49367e73e5c6b3020b96a821985f73012f2af0f1b992Tobin Ehlisstatic void PostCallRecordAllocateDescriptorSets(layer_data *dev_data, const VkDescriptorSetAllocateInfo *pAllocateInfo, 49377f61868b44f1da1dfa6a4ff726020411db92ce0dTobin Ehlis VkDescriptorSet *pDescriptorSets, 49387f61868b44f1da1dfa6a4ff726020411db92ce0dTobin Ehlis const cvdescriptorset::AllocateDescriptorSetsData *common_data) { 49397e73e5c6b3020b96a821985f73012f2af0f1b992Tobin Ehlis // All the updates are contained in a single cvdescriptorset function 49402c59c1d90b22aa759d785e4233e468616990ff92Tobin Ehlis cvdescriptorset::PerformAllocateDescriptorSets(pAllocateInfo, pDescriptorSets, common_data, &dev_data->descriptorPoolMap, 4941b110cb87b9478586719d7f7dc769b350857366baTobin Ehlis &dev_data->setMap, dev_data); 49422c4e180a4442f968b44f3d5136f7ffda706f6428Chris Forbes} 49432c4e180a4442f968b44f3d5136f7ffda706f6428Chris Forbes 4944827e8708bfc431aa792cba005ebf9f1fe35cc7e3Mark Lobodzinski// TODO: PostCallRecord routine is dependent on data generated in PreCallValidate -- needs to be moved out 4945bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL AllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo *pAllocateInfo, 4946bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkDescriptorSet *pDescriptorSets) { 494756e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 4948ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 49497f61868b44f1da1dfa6a4ff726020411db92ce0dTobin Ehlis cvdescriptorset::AllocateDescriptorSetsData common_data(pAllocateInfo->descriptorSetCount); 49503251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = PreCallValidateAllocateDescriptorSets(dev_data, pAllocateInfo, &common_data); 4951b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 4952d173e0daab123373ce75105f2a908f6ae7cef6abChris Forbes 49533251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 4954d173e0daab123373ce75105f2a908f6ae7cef6abChris Forbes 49554a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.AllocateDescriptorSets(device, pAllocateInfo, pDescriptorSets); 49566511ce241f7f210211e0c0e882f3c14889071f4dChris Forbes 49575b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (VK_SUCCESS == result) { 4958b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.lock(); 49597f61868b44f1da1dfa6a4ff726020411db92ce0dTobin Ehlis PostCallRecordAllocateDescriptorSets(dev_data, pAllocateInfo, pDescriptorSets, &common_data); 4960b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 49615b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 49625b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 49635b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 4964cd53549dd5a597894f308b4bb993c02ae30817d6Tobin Ehlis// Verify state before freeing DescriptorSets 4965cd53549dd5a597894f308b4bb993c02ae30817d6Tobin Ehlisstatic bool PreCallValidateFreeDescriptorSets(const layer_data *dev_data, VkDescriptorPool pool, uint32_t count, 4966cd53549dd5a597894f308b4bb993c02ae30817d6Tobin Ehlis const VkDescriptorSet *descriptor_sets) { 4967cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.free_descriptor_sets) return false; 49683251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 4969cd53549dd5a597894f308b4bb993c02ae30817d6Tobin Ehlis // First make sure sets being destroyed are not currently in-use 4970405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour for (uint32_t i = 0; i < count; ++i) { 4971405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour if (descriptor_sets[i] != VK_NULL_HANDLE) { 49723251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= validateIdleDescriptorSet(dev_data, descriptor_sets[i], "vkFreeDescriptorSets"); 4973405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour } 4974405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour } 4975cd53549dd5a597894f308b4bb993c02ae30817d6Tobin Ehlis 49769a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis DESCRIPTOR_POOL_STATE *pool_state = GetDescriptorPoolState(dev_data, pool); 4977a21f0d8ac8389dc4e23749efc02d82a7ec1eaee3Tobin Ehlis if (pool_state && !(VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT & pool_state->createInfo.flags)) { 4978cd53549dd5a597894f308b4bb993c02ae30817d6Tobin Ehlis // Can't Free from a NON_FREE pool 49793251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT, 4980315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pool), __LINE__, VALIDATION_ERROR_28600270, "DS", 49813251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "It is invalid to call vkFreeDescriptorSets() with a pool created without setting " 49823251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT. %s", 4983315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_28600270]); 4984cd53549dd5a597894f308b4bb993c02ae30817d6Tobin Ehlis } 49853251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 4986cd53549dd5a597894f308b4bb993c02ae30817d6Tobin Ehlis} 4987cd53549dd5a597894f308b4bb993c02ae30817d6Tobin Ehlis// Sets have been removed from the pool so update underlying state 4988cd53549dd5a597894f308b4bb993c02ae30817d6Tobin Ehlisstatic void PostCallRecordFreeDescriptorSets(layer_data *dev_data, VkDescriptorPool pool, uint32_t count, 4989cd53549dd5a597894f308b4bb993c02ae30817d6Tobin Ehlis const VkDescriptorSet *descriptor_sets) { 49909a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis DESCRIPTOR_POOL_STATE *pool_state = GetDescriptorPoolState(dev_data, pool); 4991cd53549dd5a597894f308b4bb993c02ae30817d6Tobin Ehlis // Update available descriptor sets in pool 4992cd53549dd5a597894f308b4bb993c02ae30817d6Tobin Ehlis pool_state->availableSets += count; 4993cd53549dd5a597894f308b4bb993c02ae30817d6Tobin Ehlis 4994cd53549dd5a597894f308b4bb993c02ae30817d6Tobin Ehlis // For each freed descriptor add its resources back into the pool as available and remove from pool and setMap 4995cd53549dd5a597894f308b4bb993c02ae30817d6Tobin Ehlis for (uint32_t i = 0; i < count; ++i) { 4996405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour if (descriptor_sets[i] != VK_NULL_HANDLE) { 4997405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour auto descriptor_set = dev_data->setMap[descriptor_sets[i]]; 4998405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour uint32_t type_index = 0, descriptor_count = 0; 4999405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour for (uint32_t j = 0; j < descriptor_set->GetBindingCount(); ++j) { 5000405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour type_index = static_cast<uint32_t>(descriptor_set->GetTypeFromIndex(j)); 5001405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour descriptor_count = descriptor_set->GetDescriptorCountFromIndex(j); 5002405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour pool_state->availableDescriptorTypeCount[type_index] += descriptor_count; 5003405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour } 5004405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour freeDescriptorSet(dev_data, descriptor_set); 5005405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour pool_state->sets.erase(descriptor_set); 5006405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour } 5007cd53549dd5a597894f308b4bb993c02ae30817d6Tobin Ehlis } 5008cd53549dd5a597894f308b4bb993c02ae30817d6Tobin Ehlis} 50095b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 5010bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL FreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t count, 5011bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkDescriptorSet *pDescriptorSets) { 501256e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 50135b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Make sure that no sets being destroyed are in-flight 5014ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 50153251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = PreCallValidateFreeDescriptorSets(dev_data, descriptorPool, count, pDescriptorSets); 5016b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 5017e1a3be272f365a7d75f9cc1338d2eebafbf1e6cdTobin Ehlis 50183251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 50194a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.FreeDescriptorSets(device, descriptorPool, count, pDescriptorSets); 50205b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (VK_SUCCESS == result) { 5021b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.lock(); 5022cd53549dd5a597894f308b4bb993c02ae30817d6Tobin Ehlis PostCallRecordFreeDescriptorSets(dev_data, descriptorPool, count, pDescriptorSets); 5023b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 50245b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 50255b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 50265b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 50276b67c2aac9862a21e0dd068966c8b0b3aaf0bafdTobin Ehlis// TODO : This is a Proof-of-concept for core validation architecture 50286b67c2aac9862a21e0dd068966c8b0b3aaf0bafdTobin Ehlis// Really we'll want to break out these functions to separate files but 50296b67c2aac9862a21e0dd068966c8b0b3aaf0bafdTobin Ehlis// keeping it all together here to prove out design 50306b67c2aac9862a21e0dd068966c8b0b3aaf0bafdTobin Ehlis// PreCallValidate* handles validating all of the state prior to calling down chain to UpdateDescriptorSets() 50316b67c2aac9862a21e0dd068966c8b0b3aaf0bafdTobin Ehlisstatic bool PreCallValidateUpdateDescriptorSets(layer_data *dev_data, uint32_t descriptorWriteCount, 50326b67c2aac9862a21e0dd068966c8b0b3aaf0bafdTobin Ehlis const VkWriteDescriptorSet *pDescriptorWrites, uint32_t descriptorCopyCount, 50336b67c2aac9862a21e0dd068966c8b0b3aaf0bafdTobin Ehlis const VkCopyDescriptorSet *pDescriptorCopies) { 5034cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.update_descriptor_sets) return false; 50356b67c2aac9862a21e0dd068966c8b0b3aaf0bafdTobin Ehlis // First thing to do is perform map look-ups. 50366b67c2aac9862a21e0dd068966c8b0b3aaf0bafdTobin Ehlis // NOTE : UpdateDescriptorSets is somewhat unique in that it's operating on a number of DescriptorSets 50376b67c2aac9862a21e0dd068966c8b0b3aaf0bafdTobin Ehlis // so we can't just do a single map look-up up-front, but do them individually in functions below 50386b67c2aac9862a21e0dd068966c8b0b3aaf0bafdTobin Ehlis 50396b67c2aac9862a21e0dd068966c8b0b3aaf0bafdTobin Ehlis // Now make call(s) that validate state, but don't perform state updates in this function 50406b67c2aac9862a21e0dd068966c8b0b3aaf0bafdTobin Ehlis // Note, here DescriptorSets is unique in that we don't yet have an instance. Using a helper function in the 50416b67c2aac9862a21e0dd068966c8b0b3aaf0bafdTobin Ehlis // namespace which will parse params and make calls into specific class instances 5042104ab082916e41467ef60baaab7a5a8b2e02c59cTobin Ehlis return cvdescriptorset::ValidateUpdateDescriptorSets(dev_data->report_data, dev_data, descriptorWriteCount, pDescriptorWrites, 5043104ab082916e41467ef60baaab7a5a8b2e02c59cTobin Ehlis descriptorCopyCount, pDescriptorCopies); 50446b67c2aac9862a21e0dd068966c8b0b3aaf0bafdTobin Ehlis} 50456b67c2aac9862a21e0dd068966c8b0b3aaf0bafdTobin Ehlis// PostCallRecord* handles recording state updates following call down chain to UpdateDescriptorSets() 50460c9526fb9fbc2d95ebda8902e1de9d9007ba4e9eTobin Ehlisstatic void PreCallRecordUpdateDescriptorSets(layer_data *dev_data, uint32_t descriptorWriteCount, 50470c9526fb9fbc2d95ebda8902e1de9d9007ba4e9eTobin Ehlis const VkWriteDescriptorSet *pDescriptorWrites, uint32_t descriptorCopyCount, 50480c9526fb9fbc2d95ebda8902e1de9d9007ba4e9eTobin Ehlis const VkCopyDescriptorSet *pDescriptorCopies) { 5049104ab082916e41467ef60baaab7a5a8b2e02c59cTobin Ehlis cvdescriptorset::PerformUpdateDescriptorSets(dev_data, descriptorWriteCount, pDescriptorWrites, descriptorCopyCount, 50506b67c2aac9862a21e0dd068966c8b0b3aaf0bafdTobin Ehlis pDescriptorCopies); 50516b67c2aac9862a21e0dd068966c8b0b3aaf0bafdTobin Ehlis} 50525b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 5053bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL UpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount, 5054bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkWriteDescriptorSet *pDescriptorWrites, uint32_t descriptorCopyCount, 5055bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkCopyDescriptorSet *pDescriptorCopies) { 50566b67c2aac9862a21e0dd068966c8b0b3aaf0bafdTobin Ehlis // Only map look-up at top level is for device-level layer_data 505756e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 5058ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 50593251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = PreCallValidateUpdateDescriptorSets(dev_data, descriptorWriteCount, pDescriptorWrites, descriptorCopyCount, 50603251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski pDescriptorCopies); 50613251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip) { 50620c9526fb9fbc2d95ebda8902e1de9d9007ba4e9eTobin Ehlis // Since UpdateDescriptorSets() is void, nothing to check prior to updating state & we can update before call down chain 50630c9526fb9fbc2d95ebda8902e1de9d9007ba4e9eTobin Ehlis PreCallRecordUpdateDescriptorSets(dev_data, descriptorWriteCount, pDescriptorWrites, descriptorCopyCount, 50640c9526fb9fbc2d95ebda8902e1de9d9007ba4e9eTobin Ehlis pDescriptorCopies); 50650c9526fb9fbc2d95ebda8902e1de9d9007ba4e9eTobin Ehlis lock.unlock(); 50664a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.UpdateDescriptorSets(device, descriptorWriteCount, pDescriptorWrites, descriptorCopyCount, 50674a0754042cf090e131e9e769d8a3633c228625beChris Forbes pDescriptorCopies); 50685b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 50695b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 50705b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 5071bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL AllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pCreateInfo, 5072bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkCommandBuffer *pCommandBuffer) { 507356e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 50744a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.AllocateCommandBuffers(device, pCreateInfo, pCommandBuffer); 50755b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (VK_SUCCESS == result) { 5076ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 50779a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pPool = GetCommandPoolNode(dev_data, pCreateInfo->commandPool); 5078cd9a648074f67a1d44c15a056b90fc66da8ead17Chris Forbes 5079cd9a648074f67a1d44c15a056b90fc66da8ead17Chris Forbes if (pPool) { 508072d66f0c1639cbaca92459498452d06db32d7aefTobin Ehlis for (uint32_t i = 0; i < pCreateInfo->commandBufferCount; i++) { 50815b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Add command buffer to its commandPool map 5082c8d1e7bb99c01ae0c2824fe7286fb0a1173de589John Zulauf pPool->commandBuffers.insert(pCommandBuffer[i]); 50835b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis GLOBAL_CB_NODE *pCB = new GLOBAL_CB_NODE; 50845b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Add command buffer to map 50855b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis dev_data->commandBufferMap[pCommandBuffer[i]] = pCB; 50867cb00fa300f2563ae3e8eb506bca912c11216953John Zulauf ResetCommandBufferState(dev_data, pCommandBuffer[i]); 50875b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->createInfo = *pCreateInfo; 50885b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->device = device; 50895b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 50905b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5091b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 50925b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 50935b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 50945b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 50955b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 5096883ee3f865f9dbd83134d148b26e96cb6a926b3dTobin Ehlis// Add bindings between the given cmd buffer & framebuffer and the framebuffer's children 5097c54e405a4ce05f4de10bb78bfc3a4769c41d2d59Tobin Ehlisstatic void AddFramebufferBinding(layer_data *dev_data, GLOBAL_CB_NODE *cb_state, FRAMEBUFFER_STATE *fb_state) { 50989b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus addCommandBufferBinding(&fb_state->cb_bindings, {HandleToUint64(fb_state->framebuffer), kVulkanObjectTypeFramebuffer}, 50990245b74a083d2cb3b083571deb0fe13b4ab428a4Tobin Ehlis cb_state); 5100883ee3f865f9dbd83134d148b26e96cb6a926b3dTobin Ehlis for (auto attachment : fb_state->attachments) { 5101883ee3f865f9dbd83134d148b26e96cb6a926b3dTobin Ehlis auto view_state = attachment.view_state; 5102883ee3f865f9dbd83134d148b26e96cb6a926b3dTobin Ehlis if (view_state) { 510303ea795b83fdf0099594808a1a57064dea7f02a1Tobin Ehlis AddCommandBufferBindingImageView(dev_data, cb_state, view_state); 5104883ee3f865f9dbd83134d148b26e96cb6a926b3dTobin Ehlis } 5105883ee3f865f9dbd83134d148b26e96cb6a926b3dTobin Ehlis } 5106883ee3f865f9dbd83134d148b26e96cb6a926b3dTobin Ehlis} 5107883ee3f865f9dbd83134d148b26e96cb6a926b3dTobin Ehlis 5108bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL BeginCommandBuffer(VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo *pBeginInfo) { 51093251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 511056e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 5111ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 51125b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Validate command buffer level 51139a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *cb_node = GetCBNode(dev_data, commandBuffer); 5114f909505280723ee24d2e74afc759d38dc09a37beTobin Ehlis if (cb_node) { 51155b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // This implicitly resets the Cmd Buffer so make sure any fence is done and then clear memory references 5116a7fef8833e0b4e1e4c7ea20ab56da451a6856c0cChris Forbes if (cb_node->in_use.load()) { 51173251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 5118315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(commandBuffer), __LINE__, VALIDATION_ERROR_16e00062, "MEM", 511959ae0ccadec962d9ca2cce7584fad6c57c1a4458Tobin Ehlis "Calling vkBeginCommandBuffer() on active command buffer %p before it has completed. " 51203251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "You must check command buffer fence before this call. %s", 5121315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis commandBuffer, validation_error_map[VALIDATION_ERROR_16e00062]); 51225b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5123f909505280723ee24d2e74afc759d38dc09a37beTobin Ehlis clear_cmd_buf_and_mem_references(dev_data, cb_node); 5124f909505280723ee24d2e74afc759d38dc09a37beTobin Ehlis if (cb_node->createInfo.level != VK_COMMAND_BUFFER_LEVEL_PRIMARY) { 51255b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Secondary Command Buffer 51265b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis const VkCommandBufferInheritanceInfo *pInfo = pBeginInfo->pInheritanceInfo; 51275b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (!pInfo) { 51283251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= 51295b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 5130315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(commandBuffer), __LINE__, VALIDATION_ERROR_16e00066, "DS", 5131bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski "vkBeginCommandBuffer(): Secondary Command Buffer (0x%p) must have inheritance info. %s", commandBuffer, 5132315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_16e00066]); 51335b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } else { 51345b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pBeginInfo->flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT) { 51352c09b45e970dcf95b0e03a2528662a93e0f5dc6fTobin Ehlis assert(pInfo->renderPass); 51362c09b45e970dcf95b0e03a2528662a93e0f5dc6fTobin Ehlis string errorString = ""; 51379a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto framebuffer = GetFramebufferState(dev_data, pInfo->framebuffer); 51382c09b45e970dcf95b0e03a2528662a93e0f5dc6fTobin Ehlis if (framebuffer) { 5139eacc703e5d08f497f9191991669e99d7330d5c3aTobin Ehlis if (framebuffer->createInfo.renderPass != pInfo->renderPass) { 51402c09b45e970dcf95b0e03a2528662a93e0f5dc6fTobin Ehlis // renderPass that framebuffer was created with must be compatible with local renderPass 5141eacc703e5d08f497f9191991669e99d7330d5c3aTobin Ehlis skip |= 5142ba9be0cec36d930fc0d5a0cbfbc00b0df49b08e4Tobin Ehlis validateRenderPassCompatibility(dev_data, "framebuffer", framebuffer->rp_state.get(), 5143ba9be0cec36d930fc0d5a0cbfbc00b0df49b08e4Tobin Ehlis "command buffer", GetRenderPassState(dev_data, pInfo->renderPass), 5144eacc703e5d08f497f9191991669e99d7330d5c3aTobin Ehlis "vkBeginCommandBuffer()", VALIDATION_ERROR_0280006e); 51455b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 51462c09b45e970dcf95b0e03a2528662a93e0f5dc6fTobin Ehlis // Connect this framebuffer and its children to this cmdBuffer 51472c09b45e970dcf95b0e03a2528662a93e0f5dc6fTobin Ehlis AddFramebufferBinding(dev_data, cb_node, framebuffer); 51485b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 51495b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 51504527dcafa951a1fa931b258bbcd2d48b283610a7Dave Houlton if ((pInfo->occlusionQueryEnable == VK_FALSE || dev_data->enabled_features.occlusionQueryPrecise == VK_FALSE) && 51515b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis (pInfo->queryFlags & VK_QUERY_CONTROL_PRECISE_BIT)) { 51523251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 51539b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, HandleToUint64(commandBuffer), __LINE__, 5154315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_16e00068, "DS", 51553251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkBeginCommandBuffer(): Secondary Command Buffer (0x%p) must not have " 51563251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "VK_QUERY_CONTROL_PRECISE_BIT if occulusionQuery is disabled or the device does not " 51573251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "support precise occlusion queries. %s", 5158315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis commandBuffer, validation_error_map[VALIDATION_ERROR_16e00068]); 51595b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 51605b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 51615b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pInfo && pInfo->renderPass != VK_NULL_HANDLE) { 51629a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto renderPass = GetRenderPassState(dev_data, pInfo->renderPass); 516316387282d11e414ae7cb9ddf3d0c1bebf8f2c74dChris Forbes if (renderPass) { 5164fb13c2c4174108223d9f8e43084020eb09115ed6Chris Forbes if (pInfo->subpass >= renderPass->createInfo.subpassCount) { 51653251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 51669b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, HandleToUint64(commandBuffer), __LINE__, 5167315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_0280006c, "DS", 51683251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkBeginCommandBuffer(): Secondary Command Buffers (0x%p) must have a subpass index (%d) " 51693251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "that is less than the number of subpasses (%d). %s", 51703251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski commandBuffer, pInfo->subpass, renderPass->createInfo.subpassCount, 5171315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_0280006c]); 51725b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 51735b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 51745b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 51755b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5176f909505280723ee24d2e74afc759d38dc09a37beTobin Ehlis if (CB_RECORDING == cb_node->state) { 51773251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 5178315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(commandBuffer), __LINE__, VALIDATION_ERROR_16e00062, "DS", 51793251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkBeginCommandBuffer(): Cannot call Begin on command buffer (0x%p" 51803251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski ") in the RECORDING state. Must first call vkEndCommandBuffer(). %s", 5181315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis commandBuffer, validation_error_map[VALIDATION_ERROR_16e00062]); 518246daa701a01b92ae19e3ee9e661d677128fe7e6dChris Forbes } else if (CB_RECORDED == cb_node->state || CB_INVALID_COMPLETE == cb_node->state) { 5183f909505280723ee24d2e74afc759d38dc09a37beTobin Ehlis VkCommandPool cmdPool = cb_node->createInfo.commandPool; 51849a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pPool = GetCommandPoolNode(dev_data, cmdPool); 5185cd9a648074f67a1d44c15a056b90fc66da8ead17Chris Forbes if (!(VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT & pPool->createFlags)) { 51863251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= 51875b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 5188315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(commandBuffer), __LINE__, VALIDATION_ERROR_16e00064, "DS", 5189226a75bff897619b86cc227cf1196b5e245fb96dTobin Ehlis "Call to vkBeginCommandBuffer() on command buffer (0x%p" 5190414e9a4117b500eac650d8b8f01a6e1b22d05aaeMark Mueller ") attempts to implicitly reset cmdBuffer created from command pool (0x%" PRIxLEAST64 51914527dcafa951a1fa931b258bbcd2d48b283610a7Dave Houlton ") that does NOT have the VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT bit set. %s", 5192315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis commandBuffer, HandleToUint64(cmdPool), validation_error_map[VALIDATION_ERROR_16e00064]); 51935b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 51947cb00fa300f2563ae3e8eb506bca912c11216953John Zulauf ResetCommandBufferState(dev_data, commandBuffer); 51955b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 51965b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Set updated state here in case implicit reset occurs above 5197f909505280723ee24d2e74afc759d38dc09a37beTobin Ehlis cb_node->state = CB_RECORDING; 5198f909505280723ee24d2e74afc759d38dc09a37beTobin Ehlis cb_node->beginInfo = *pBeginInfo; 5199f909505280723ee24d2e74afc759d38dc09a37beTobin Ehlis if (cb_node->beginInfo.pInheritanceInfo) { 5200f909505280723ee24d2e74afc759d38dc09a37beTobin Ehlis cb_node->inheritanceInfo = *(cb_node->beginInfo.pInheritanceInfo); 5201f909505280723ee24d2e74afc759d38dc09a37beTobin Ehlis cb_node->beginInfo.pInheritanceInfo = &cb_node->inheritanceInfo; 5202888e1d268098177fde4a2263e3d7b7cc415f1debMark Young // If we are a secondary command-buffer and inheriting. Update the items we should inherit. 5203f909505280723ee24d2e74afc759d38dc09a37beTobin Ehlis if ((cb_node->createInfo.level != VK_COMMAND_BUFFER_LEVEL_PRIMARY) && 5204f909505280723ee24d2e74afc759d38dc09a37beTobin Ehlis (cb_node->beginInfo.flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT)) { 52059a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis cb_node->activeRenderPass = GetRenderPassState(dev_data, cb_node->beginInfo.pInheritanceInfo->renderPass); 5206f909505280723ee24d2e74afc759d38dc09a37beTobin Ehlis cb_node->activeSubpass = cb_node->beginInfo.pInheritanceInfo->subpass; 5207350841afb70bf8dcfc3c6ec6b66f0aaa639553a3Tobin Ehlis cb_node->activeFramebuffer = cb_node->beginInfo.pInheritanceInfo->framebuffer; 5208f909505280723ee24d2e74afc759d38dc09a37beTobin Ehlis cb_node->framebuffers.insert(cb_node->beginInfo.pInheritanceInfo->framebuffer); 5209888e1d268098177fde4a2263e3d7b7cc415f1debMark Young } 52105b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 52115b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5212b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 52133251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (skip) { 52145b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return VK_ERROR_VALIDATION_FAILED_EXT; 52155b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 52164a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.BeginCommandBuffer(commandBuffer, pBeginInfo); 5217400cff9fad0e19c80f6c9ed1181795d411a4bec5Tobin Ehlis 52185b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 52195b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 52205b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 522189d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR VkResult VKAPI_CALL EndCommandBuffer(VkCommandBuffer commandBuffer) { 52223251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 522356e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 5224ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 52259a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); 52265b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pCB) { 52274527dcafa951a1fa931b258bbcd2d48b283610a7Dave Houlton if ((VK_COMMAND_BUFFER_LEVEL_PRIMARY == pCB->createInfo.level) || 52284527dcafa951a1fa931b258bbcd2d48b283610a7Dave Houlton !(pCB->beginInfo.flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT)) { 5229fd61966f8d41b5bce15620b70563b7864cbb28feCody Northrop // This needs spec clarification to update valid usage, see comments in PR: 5230fd61966f8d41b5bce15620b70563b7864cbb28feCody Northrop // https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/pull/516#discussion_r63013756 5231315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= insideRenderPass(dev_data, pCB, "vkEndCommandBuffer()", VALIDATION_ERROR_27400078); 5232fd61966f8d41b5bce15620b70563b7864cbb28feCody Northrop } 52333251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateCmd(dev_data, pCB, CMD_END, "vkEndCommandBuffer()"); 52345b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (auto query : pCB->activeQueries) { 52353251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 5236315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(commandBuffer), __LINE__, VALIDATION_ERROR_2740007a, "DS", 52373251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Ending command buffer with in progress query: queryPool 0x%" PRIx64 ", index %d. %s", 5238315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(query.pool), query.index, validation_error_map[VALIDATION_ERROR_2740007a]); 52395b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 52405b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 52413251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip) { 5242b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 52430d9453d85335963d6cabfbf400b058dc905ea238Chris Forbes auto result = dev_data->dispatch_table.EndCommandBuffer(commandBuffer); 5244b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.lock(); 52455b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (VK_SUCCESS == result) { 52465b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->state = CB_RECORDED; 52475b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 52480d9453d85335963d6cabfbf400b058dc905ea238Chris Forbes return result; 52495b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } else { 52500d9453d85335963d6cabfbf400b058dc905ea238Chris Forbes return VK_ERROR_VALIDATION_FAILED_EXT; 52515b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 52525b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 52535b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 5254bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL ResetCommandBuffer(VkCommandBuffer commandBuffer, VkCommandBufferResetFlags flags) { 52553251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 525656e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 5257ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 52589a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); 52595b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis VkCommandPool cmdPool = pCB->createInfo.commandPool; 52609a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pPool = GetCommandPoolNode(dev_data, cmdPool); 5261cd9a648074f67a1d44c15a056b90fc66da8ead17Chris Forbes if (!(VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT & pPool->createFlags)) { 52623251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 5263315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(commandBuffer), __LINE__, VALIDATION_ERROR_3260005c, "DS", 52643251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Attempt to reset command buffer (0x%p) created from command pool (0x%" PRIxLEAST64 52653251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski ") that does NOT have the VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT bit set. %s", 5266315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis commandBuffer, HandleToUint64(cmdPool), validation_error_map[VALIDATION_ERROR_3260005c]); 52675b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5268315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= checkCommandBufferInFlight(dev_data, pCB, "reset", VALIDATION_ERROR_3260005a); 5269b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 52703251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 52714a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.ResetCommandBuffer(commandBuffer, flags); 52725b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (VK_SUCCESS == result) { 5273b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.lock(); 52747cb00fa300f2563ae3e8eb506bca912c11216953John Zulauf ResetCommandBufferState(dev_data, commandBuffer); 5275b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 52765b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 52775b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 52785b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 527993c396d566d722dc5c6f438eae212da0e9337ba3Mark Lobodzinski 5280bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdBindPipeline(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, 5281bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkPipeline pipeline) { 5282e92495715edaa63453ce5775bf60f3795df72876Tobin Ehlis bool skip = false; 528356e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 5284ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 52859a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *cb_state = GetCBNode(dev_data, commandBuffer); 5286e92495715edaa63453ce5775bf60f3795df72876Tobin Ehlis if (cb_state) { 5287baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt skip |= ValidateCmdQueueFlags(dev_data, cb_state, "vkCmdBindPipeline()", VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, 5288315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_18002415); 528929f880e9c3c837307e7a19c0ef7275448d483e04Tobin Ehlis skip |= ValidateCmd(dev_data, cb_state, CMD_BINDPIPELINE, "vkCmdBindPipeline()"); 5290315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis // TODO: VALIDATION_ERROR_18000612 VALIDATION_ERROR_18000616 52915b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 5292374de4579f98cbbe8b616acb8e07a1a9c30402f8Chris Forbes auto pipe_state = getPipelineState(dev_data, pipeline); 5293374de4579f98cbbe8b616acb8e07a1a9c30402f8Chris Forbes if (VK_PIPELINE_BIND_POINT_GRAPHICS == pipelineBindPoint) { 529414494d322787d939bf6a9d3a03fc3938009592e0Chris Forbes cb_state->status &= ~cb_state->static_status; 52959563e5dea7a06a2b937f917e0983f6cce3759681Chris Forbes cb_state->static_status = MakeStaticStateMask(pipe_state->graphicsPipelineCI.ptr()->pDynamicState); 52969563e5dea7a06a2b937f917e0983f6cce3759681Chris Forbes cb_state->status |= cb_state->static_status; 5297e92495715edaa63453ce5775bf60f3795df72876Tobin Ehlis } 52989563e5dea7a06a2b937f917e0983f6cce3759681Chris Forbes cb_state->lastBound[pipelineBindPoint].pipeline_state = pipe_state; 52999563e5dea7a06a2b937f917e0983f6cce3759681Chris Forbes set_pipeline_state(pipe_state); 53009563e5dea7a06a2b937f917e0983f6cce3759681Chris Forbes skip |= validate_dual_src_blend_feature(dev_data, pipe_state); 53019b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus addCommandBufferBinding(&pipe_state->cb_bindings, {HandleToUint64(pipeline), kVulkanObjectTypePipeline}, cb_state); 53025b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5303b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 5304cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (!skip) dev_data->dispatch_table.CmdBindPipeline(commandBuffer, pipelineBindPoint, pipeline); 53055b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 53065b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 5307bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdSetViewport(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, 5308bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkViewport *pViewports) { 53093251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 531056e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 5311ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 53129a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); 53135b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pCB) { 5314315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateCmdQueueFlags(dev_data, pCB, "vkCmdSetViewport()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_1e002415); 53153251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateCmd(dev_data, pCB, CMD_SETVIEWPORTSTATE, "vkCmdSetViewport()"); 531676de58efdab4e3fb8911019e533bf80393bc5682Chris Forbes if (pCB->static_status & CBSTATUS_VIEWPORT_SET) { 531776de58efdab4e3fb8911019e533bf80393bc5682Chris Forbes skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 531876de58efdab4e3fb8911019e533bf80393bc5682Chris Forbes HandleToUint64(commandBuffer), __LINE__, VALIDATION_ERROR_1e00098a, "DS", 531976de58efdab4e3fb8911019e533bf80393bc5682Chris Forbes "vkCmdSetViewport(): pipeline was created without VK_DYNAMIC_STATE_VIEWPORT flag. %s.", 532076de58efdab4e3fb8911019e533bf80393bc5682Chris Forbes validation_error_map[VALIDATION_ERROR_1e00098a]); 532176de58efdab4e3fb8911019e533bf80393bc5682Chris Forbes } 53222843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes if (!skip) { 53232843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes pCB->viewportMask |= ((1u << viewportCount) - 1u) << firstViewport; 532476de58efdab4e3fb8911019e533bf80393bc5682Chris Forbes pCB->status |= CBSTATUS_VIEWPORT_SET; 53252843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes } 53265b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5327b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 53283251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip) dev_data->dispatch_table.CmdSetViewport(commandBuffer, firstViewport, viewportCount, pViewports); 53295b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 53305b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 5331bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdSetScissor(VkCommandBuffer commandBuffer, uint32_t firstScissor, uint32_t scissorCount, 5332bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkRect2D *pScissors) { 53333251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 533456e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 5335ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 53369a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); 53375b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pCB) { 5338315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateCmdQueueFlags(dev_data, pCB, "vkCmdSetScissor()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_1d802415); 53393251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateCmd(dev_data, pCB, CMD_SETSCISSORSTATE, "vkCmdSetScissor()"); 5340530cdb75eb81ef67b2093cea3c62737facfe91deChris Forbes if (pCB->static_status & CBSTATUS_SCISSOR_SET) { 5341530cdb75eb81ef67b2093cea3c62737facfe91deChris Forbes skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 5342530cdb75eb81ef67b2093cea3c62737facfe91deChris Forbes HandleToUint64(commandBuffer), __LINE__, VALIDATION_ERROR_1d80049c, "DS", 5343530cdb75eb81ef67b2093cea3c62737facfe91deChris Forbes "vkCmdSetScissor(): pipeline was created without VK_DYNAMIC_STATE_SCISSOR flag. %s.", 5344530cdb75eb81ef67b2093cea3c62737facfe91deChris Forbes validation_error_map[VALIDATION_ERROR_1d80049c]); 5345530cdb75eb81ef67b2093cea3c62737facfe91deChris Forbes } 53462843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes if (!skip) { 53472843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes pCB->scissorMask |= ((1u << scissorCount) - 1u) << firstScissor; 5348530cdb75eb81ef67b2093cea3c62737facfe91deChris Forbes pCB->status |= CBSTATUS_SCISSOR_SET; 53492843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes } 53505b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5351b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 53523251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip) dev_data->dispatch_table.CmdSetScissor(commandBuffer, firstScissor, scissorCount, pScissors); 53535b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 53545b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 535589d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR void VKAPI_CALL CmdSetLineWidth(VkCommandBuffer commandBuffer, float lineWidth) { 53563251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 535756e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 5358ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 53599a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); 53605b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pCB) { 5361315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateCmdQueueFlags(dev_data, pCB, "vkCmdSetLineWidth()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_1d602415); 53623251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateCmd(dev_data, pCB, CMD_SETLINEWIDTHSTATE, "vkCmdSetLineWidth()"); 5363a27508babf63d50aea75883a3702979193c23683Mark Young 53642843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes if (pCB->static_status & CBSTATUS_LINE_WIDTH_SET) { 53652843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 5366315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(commandBuffer), __LINE__, VALIDATION_ERROR_1d600626, "DS", 53673251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkCmdSetLineWidth called but pipeline was created without VK_DYNAMIC_STATE_LINE_WIDTH " 53682843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes "flag. %s", 5369315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_1d600626]); 5370a27508babf63d50aea75883a3702979193c23683Mark Young } 53712843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes if (!skip) { 53722843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes pCB->status |= CBSTATUS_LINE_WIDTH_SET; 53732843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes } 53745b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5375b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 53763251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip) dev_data->dispatch_table.CmdSetLineWidth(commandBuffer, lineWidth); 53775b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 53785b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 5379bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdSetDepthBias(VkCommandBuffer commandBuffer, float depthBiasConstantFactor, float depthBiasClamp, 5380bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski float depthBiasSlopeFactor) { 53813251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 538256e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 5383ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 53849a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); 53855b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pCB) { 5386315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateCmdQueueFlags(dev_data, pCB, "vkCmdSetDepthBias()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_1cc02415); 53873251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateCmd(dev_data, pCB, CMD_SETDEPTHBIASSTATE, "vkCmdSetDepthBias()"); 53882843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes if (pCB->static_status & CBSTATUS_DEPTH_BIAS_SET) { 53892843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 53902843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes HandleToUint64(commandBuffer), __LINE__, VALIDATION_ERROR_1cc0062a, "DS", 53912843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes "vkCmdSetDepthBias(): pipeline was created without VK_DYNAMIC_STATE_DEPTH_BIAS flag. %s.", 53922843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes validation_error_map[VALIDATION_ERROR_1cc0062a]); 53932843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes } 5394434c3e2a778a3ca5a0a5414cbedd7c0f20a883b7Mark Lobodzinski if ((depthBiasClamp != 0.0) && (!dev_data->enabled_features.depthBiasClamp)) { 53953251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 5396315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(commandBuffer), __LINE__, VALIDATION_ERROR_1cc0062c, "DS", 53973251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkCmdSetDepthBias(): the depthBiasClamp device feature is disabled: the depthBiasClamp " 53983251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "parameter must be set to 0.0. %s", 5399315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_1cc0062c]); 5400434c3e2a778a3ca5a0a5414cbedd7c0f20a883b7Mark Lobodzinski } 54013251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip) { 5402434c3e2a778a3ca5a0a5414cbedd7c0f20a883b7Mark Lobodzinski pCB->status |= CBSTATUS_DEPTH_BIAS_SET; 5403434c3e2a778a3ca5a0a5414cbedd7c0f20a883b7Mark Lobodzinski } 54045b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5405b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 54063251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip) 54074a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.CmdSetDepthBias(commandBuffer, depthBiasConstantFactor, depthBiasClamp, depthBiasSlopeFactor); 54085b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 54095b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 541089d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR void VKAPI_CALL CmdSetBlendConstants(VkCommandBuffer commandBuffer, const float blendConstants[4]) { 54113251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 541256e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 5413ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 54149a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); 54155b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pCB) { 5416315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateCmdQueueFlags(dev_data, pCB, "vkCmdSetBlendConstants()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_1ca02415); 54173251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateCmd(dev_data, pCB, CMD_SETBLENDSTATE, "vkCmdSetBlendConstants()"); 54182843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes if (pCB->static_status & CBSTATUS_BLEND_CONSTANTS_SET) { 54192843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 54202843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes HandleToUint64(commandBuffer), __LINE__, VALIDATION_ERROR_1ca004c8, "DS", 54212843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes "vkCmdSetBlendConstants(): pipeline was created without VK_DYNAMIC_STATE_BLEND_CONSTANTS flag. %s.", 54222843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes validation_error_map[VALIDATION_ERROR_1ca004c8]); 54232843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes } 54242843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes if (!skip) { 54252843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes pCB->status |= CBSTATUS_BLEND_CONSTANTS_SET; 54262843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes } 54275b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5428b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 54293251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip) dev_data->dispatch_table.CmdSetBlendConstants(commandBuffer, blendConstants); 54305b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 54315b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 5432bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdSetDepthBounds(VkCommandBuffer commandBuffer, float minDepthBounds, float maxDepthBounds) { 54333251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 543456e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 5435ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 54369a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); 54375b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pCB) { 5438315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateCmdQueueFlags(dev_data, pCB, "vkCmdSetDepthBounds()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_1ce02415); 54393251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateCmd(dev_data, pCB, CMD_SETDEPTHBOUNDSSTATE, "vkCmdSetDepthBounds()"); 54402843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes if (pCB->static_status & CBSTATUS_DEPTH_BOUNDS_SET) { 54412843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 54422843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes HandleToUint64(commandBuffer), __LINE__, VALIDATION_ERROR_1ce004ae, "DS", 54432843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes "vkCmdSetDepthBounds(): pipeline was created without VK_DYNAMIC_STATE_DEPTH_BOUNDS flag. %s.", 54442843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes validation_error_map[VALIDATION_ERROR_1ce004ae]); 54452843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes } 54462843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes if (!skip) { 54472843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes pCB->status |= CBSTATUS_DEPTH_BOUNDS_SET; 54482843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes } 54495b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5450b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 54513251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip) dev_data->dispatch_table.CmdSetDepthBounds(commandBuffer, minDepthBounds, maxDepthBounds); 54525b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 54535b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 5454bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdSetStencilCompareMask(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, 5455bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski uint32_t compareMask) { 54563251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 545756e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 5458ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 54599a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); 54605b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pCB) { 5461315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= 5462315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis ValidateCmdQueueFlags(dev_data, pCB, "vkCmdSetStencilCompareMask()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_1da02415); 54633251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateCmd(dev_data, pCB, CMD_SETSTENCILREADMASKSTATE, "vkCmdSetStencilCompareMask()"); 54642843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes if (pCB->static_status & CBSTATUS_STENCIL_READ_MASK_SET) { 54652843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 54662843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes HandleToUint64(commandBuffer), __LINE__, VALIDATION_ERROR_1da004b4, "DS", 54672843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes "vkCmdSetStencilCompareMask(): pipeline was created without VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK flag. %s.", 54682843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes validation_error_map[VALIDATION_ERROR_1da004b4]); 54692843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes } 54702843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes if (!skip) { 54712843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes pCB->status |= CBSTATUS_STENCIL_READ_MASK_SET; 54722843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes } 54735b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5474b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 54753251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip) dev_data->dispatch_table.CmdSetStencilCompareMask(commandBuffer, faceMask, compareMask); 54765b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 54775b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 5478bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdSetStencilWriteMask(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t writeMask) { 54793251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 548056e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 5481ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 54829a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); 54835b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pCB) { 5484315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= 5485315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis ValidateCmdQueueFlags(dev_data, pCB, "vkCmdSetStencilWriteMask()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_1de02415); 54863251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateCmd(dev_data, pCB, CMD_SETSTENCILWRITEMASKSTATE, "vkCmdSetStencilWriteMask()"); 54872843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes if (pCB->static_status & CBSTATUS_STENCIL_WRITE_MASK_SET) { 54882843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 54892843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes HandleToUint64(commandBuffer), __LINE__, VALIDATION_ERROR_1de004b6, "DS", 54902843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes "vkCmdSetStencilWriteMask(): pipeline was created without VK_DYNAMIC_STATE_STENCIL_WRITE_MASK flag. %s.", 54912843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes validation_error_map[VALIDATION_ERROR_1de004b6]); 54922843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes } 54932843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes if (!skip) { 54942843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes pCB->status |= CBSTATUS_STENCIL_WRITE_MASK_SET; 54952843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes } 54965b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5497b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 54983251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip) dev_data->dispatch_table.CmdSetStencilWriteMask(commandBuffer, faceMask, writeMask); 54995b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 55005b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 5501bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdSetStencilReference(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t reference) { 55023251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 550356e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 5504ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 55059a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); 55065b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pCB) { 5507315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= 5508315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis ValidateCmdQueueFlags(dev_data, pCB, "vkCmdSetStencilReference()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_1dc02415); 55093251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateCmd(dev_data, pCB, CMD_SETSTENCILREFERENCESTATE, "vkCmdSetStencilReference()"); 55102843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes if (pCB->static_status & CBSTATUS_STENCIL_REFERENCE_SET) { 55112843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 55122843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes HandleToUint64(commandBuffer), __LINE__, VALIDATION_ERROR_1dc004b8, "DS", 55132843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes "vkCmdSetStencilReference(): pipeline was created without VK_DYNAMIC_STATE_STENCIL_REFERENCE flag. %s.", 55142843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes validation_error_map[VALIDATION_ERROR_1dc004b8]); 55152843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes } 55162843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes if (!skip) { 55172843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes pCB->status |= CBSTATUS_STENCIL_REFERENCE_SET; 55182843b4615e7c0fa78b6a5f1656f53fef5e89c607Chris Forbes } 55195b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5520b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 55213251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip) dev_data->dispatch_table.CmdSetStencilReference(commandBuffer, faceMask, reference); 55225b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 55235b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 552476ff99fdcc54e35ab1f3c34c3b093ccecb99e4dbMark Lobodzinskistatic void PreCallRecordCmdBindDescriptorSets(layer_data *device_data, GLOBAL_CB_NODE *cb_state, 552576ff99fdcc54e35ab1f3c34c3b093ccecb99e4dbMark Lobodzinski VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, uint32_t firstSet, 552676ff99fdcc54e35ab1f3c34c3b093ccecb99e4dbMark Lobodzinski uint32_t setCount, const VkDescriptorSet *pDescriptorSets, 552776ff99fdcc54e35ab1f3c34c3b093ccecb99e4dbMark Lobodzinski uint32_t dynamicOffsetCount, const uint32_t *pDynamicOffsets) { 5528ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski uint32_t total_dynamic_descriptors = 0; 5529ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski string error_string = ""; 5530ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski uint32_t last_set_index = firstSet + setCount - 1; 55312d4a3c28bf95f00fa2aac7d07288f6faf22208abMark Lobodzinski auto last_bound = &cb_state->lastBound[pipelineBindPoint]; 55322d4a3c28bf95f00fa2aac7d07288f6faf22208abMark Lobodzinski 55332d4a3c28bf95f00fa2aac7d07288f6faf22208abMark Lobodzinski if (last_set_index >= last_bound->boundDescriptorSets.size()) { 55342d4a3c28bf95f00fa2aac7d07288f6faf22208abMark Lobodzinski last_bound->boundDescriptorSets.resize(last_set_index + 1); 55352d4a3c28bf95f00fa2aac7d07288f6faf22208abMark Lobodzinski last_bound->dynamicOffsets.resize(last_set_index + 1); 5536ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski } 55372d4a3c28bf95f00fa2aac7d07288f6faf22208abMark Lobodzinski auto old_final_bound_set = last_bound->boundDescriptorSets[last_set_index]; 5538ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski auto pipeline_layout = getPipelineLayout(device_data, layout); 5539ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski for (uint32_t set_idx = 0; set_idx < setCount; set_idx++) { 5540ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski cvdescriptorset::DescriptorSet *descriptor_set = GetSetNode(device_data, pDescriptorSets[set_idx]); 5541ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski if (descriptor_set) { 55422d4a3c28bf95f00fa2aac7d07288f6faf22208abMark Lobodzinski last_bound->pipeline_layout = *pipeline_layout; 55432d4a3c28bf95f00fa2aac7d07288f6faf22208abMark Lobodzinski 55442d4a3c28bf95f00fa2aac7d07288f6faf22208abMark Lobodzinski if ((last_bound->boundDescriptorSets[set_idx + firstSet] != nullptr) && 55452d4a3c28bf95f00fa2aac7d07288f6faf22208abMark Lobodzinski last_bound->boundDescriptorSets[set_idx + firstSet]->IsPushDescriptor()) { 554654aae8da345cdc9b9db8ac81e3e03075db79cf9fJózef Kucia last_bound->push_descriptor_set = nullptr; 55472d4a3c28bf95f00fa2aac7d07288f6faf22208abMark Lobodzinski last_bound->boundDescriptorSets[set_idx + firstSet] = nullptr; 55482d4a3c28bf95f00fa2aac7d07288f6faf22208abMark Lobodzinski } 55492d4a3c28bf95f00fa2aac7d07288f6faf22208abMark Lobodzinski 55502d4a3c28bf95f00fa2aac7d07288f6faf22208abMark Lobodzinski last_bound->boundDescriptorSets[set_idx + firstSet] = descriptor_set; 5551ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski 5552ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski auto set_dynamic_descriptor_count = descriptor_set->GetDynamicDescriptorCount(); 55532d4a3c28bf95f00fa2aac7d07288f6faf22208abMark Lobodzinski last_bound->dynamicOffsets[firstSet + set_idx].clear(); 5554ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski if (set_dynamic_descriptor_count) { 55552d4a3c28bf95f00fa2aac7d07288f6faf22208abMark Lobodzinski last_bound->dynamicOffsets[firstSet + set_idx] = 5556ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski std::vector<uint32_t>(pDynamicOffsets + total_dynamic_descriptors, 5557ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski pDynamicOffsets + total_dynamic_descriptors + set_dynamic_descriptor_count); 5558ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski total_dynamic_descriptors += set_dynamic_descriptor_count; 5559ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski } 5560ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski } 5561ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski // For any previously bound sets, need to set them to "invalid" if they were disturbed by this update 5562ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski if (firstSet > 0) { 5563ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski for (uint32_t i = 0; i < firstSet; ++i) { 55642d4a3c28bf95f00fa2aac7d07288f6faf22208abMark Lobodzinski if (last_bound->boundDescriptorSets[i] && 55652d4a3c28bf95f00fa2aac7d07288f6faf22208abMark Lobodzinski !verify_set_layout_compatibility(last_bound->boundDescriptorSets[i], pipeline_layout, i, error_string)) { 55662d4a3c28bf95f00fa2aac7d07288f6faf22208abMark Lobodzinski last_bound->boundDescriptorSets[i] = VK_NULL_HANDLE; 55675b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5568ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski } 5569ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski } 5570ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski // Check if newly last bound set invalidates any remaining bound sets 55712d4a3c28bf95f00fa2aac7d07288f6faf22208abMark Lobodzinski if ((last_bound->boundDescriptorSets.size() - 1) > (last_set_index)) { 5572ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski if (old_final_bound_set && 5573ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski !verify_set_layout_compatibility(old_final_bound_set, pipeline_layout, last_set_index, error_string)) { 55742d4a3c28bf95f00fa2aac7d07288f6faf22208abMark Lobodzinski last_bound->boundDescriptorSets.resize(last_set_index + 1); 5575ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski } 5576ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski } 5577ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski } 5578ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski} 5579ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski 5580ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinskistatic bool PreCallValidateCmdBindDescriptorSets(layer_data *device_data, GLOBAL_CB_NODE *cb_state, 5581ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, uint32_t firstSet, 5582ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski uint32_t setCount, const VkDescriptorSet *pDescriptorSets, 5583ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski uint32_t dynamicOffsetCount, const uint32_t *pDynamicOffsets) { 5584ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski bool skip = false; 5585ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski skip |= ValidateCmdQueueFlags(device_data, cb_state, "vkCmdBindDescriptorSets()", VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, 5586ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski VALIDATION_ERROR_17c02415); 5587ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski skip |= ValidateCmd(device_data, cb_state, CMD_BINDDESCRIPTORSETS, "vkCmdBindDescriptorSets()"); 5588ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski // Track total count of dynamic descriptor types to make sure we have an offset for each one 5589ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski uint32_t total_dynamic_descriptors = 0; 5590ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski string error_string = ""; 5591ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski uint32_t last_set_index = firstSet + setCount - 1; 5592ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski 5593ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski if (last_set_index >= cb_state->lastBound[pipelineBindPoint].boundDescriptorSets.size()) { 5594ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski cb_state->lastBound[pipelineBindPoint].boundDescriptorSets.resize(last_set_index + 1); 5595ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski cb_state->lastBound[pipelineBindPoint].dynamicOffsets.resize(last_set_index + 1); 5596ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski } 5597ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski auto pipeline_layout = getPipelineLayout(device_data, layout); 5598ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski for (uint32_t set_idx = 0; set_idx < setCount; set_idx++) { 5599ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski cvdescriptorset::DescriptorSet *descriptor_set = GetSetNode(device_data, pDescriptorSets[set_idx]); 5600ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski if (descriptor_set) { 5601ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski if (!descriptor_set->IsUpdated() && (descriptor_set->GetTotalDescriptorCount() != 0)) { 5602ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, 5603ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, HandleToUint64(pDescriptorSets[set_idx]), __LINE__, 5604ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski DRAWSTATE_DESCRIPTOR_SET_NOT_UPDATED, "DS", 5605ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski "Descriptor Set 0x%" PRIxLEAST64 5606ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski " bound but it was never updated. You may want to either update it or not bind it.", 5607ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski HandleToUint64(pDescriptorSets[set_idx])); 5608ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski } 5609ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski // Verify that set being bound is compatible with overlapping setLayout of pipelineLayout 5610ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski if (!verify_set_layout_compatibility(descriptor_set, pipeline_layout, set_idx + firstSet, error_string)) { 5611ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski skip |= 5612ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, 5613ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski HandleToUint64(pDescriptorSets[set_idx]), __LINE__, VALIDATION_ERROR_17c002cc, "DS", 5614ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski "descriptorSet #%u being bound is not compatible with overlapping descriptorSetLayout " 5615ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski "at index %u of pipelineLayout 0x%" PRIxLEAST64 " due to: %s. %s", 5616ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski set_idx, set_idx + firstSet, HandleToUint64(layout), error_string.c_str(), 5617ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski validation_error_map[VALIDATION_ERROR_17c002cc]); 5618ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski } 5619ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski 5620ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski auto set_dynamic_descriptor_count = descriptor_set->GetDynamicDescriptorCount(); 5621ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski 5622ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski if (set_dynamic_descriptor_count) { 5623ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski // First make sure we won't overstep bounds of pDynamicOffsets array 5624ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski if ((total_dynamic_descriptors + set_dynamic_descriptor_count) > dynamicOffsetCount) { 5625ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 5626ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, HandleToUint64(pDescriptorSets[set_idx]), 5627ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski __LINE__, DRAWSTATE_INVALID_DYNAMIC_OFFSET_COUNT, "DS", 5628ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski "descriptorSet #%u (0x%" PRIxLEAST64 5629ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski ") requires %u dynamicOffsets, but only %u dynamicOffsets are left in pDynamicOffsets " 5630ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski "array. There must be one dynamic offset for each dynamic descriptor being bound.", 5631ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski set_idx, HandleToUint64(pDescriptorSets[set_idx]), descriptor_set->GetDynamicDescriptorCount(), 5632ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski (dynamicOffsetCount - total_dynamic_descriptors)); 5633ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski } else { // Validate dynamic offsets and Dynamic Offset Minimums 5634ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski uint32_t cur_dyn_offset = total_dynamic_descriptors; 5635ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski for (uint32_t d = 0; d < descriptor_set->GetTotalDescriptorCount(); d++) { 5636ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski if (descriptor_set->GetTypeFromGlobalIndex(d) == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) { 5637ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski if (SafeModulo(pDynamicOffsets[cur_dyn_offset], 5638ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski device_data->phys_dev_properties.properties.limits.minUniformBufferOffsetAlignment) != 5639ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski 0) { 5640ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 5641315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, 5642315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_17c002d4, "DS", 5643315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis "vkCmdBindDescriptorSets(): pDynamicOffsets[%d] is %d but must be a multiple of " 5644315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis "device limit minUniformBufferOffsetAlignment 0x%" PRIxLEAST64 ". %s", 5645315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis cur_dyn_offset, pDynamicOffsets[cur_dyn_offset], 5646ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski device_data->phys_dev_properties.properties.limits.minUniformBufferOffsetAlignment, 5647315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_17c002d4]); 5648ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski } 5649ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski cur_dyn_offset++; 5650ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski } else if (descriptor_set->GetTypeFromGlobalIndex(d) == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) { 5651ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski if (SafeModulo(pDynamicOffsets[cur_dyn_offset], 5652ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski device_data->phys_dev_properties.properties.limits.minStorageBufferOffsetAlignment) != 5653ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski 0) { 5654ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 5655315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, 5656315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_17c002d4, "DS", 5657315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis "vkCmdBindDescriptorSets(): pDynamicOffsets[%d] is %d but must be a multiple of " 5658315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis "device limit minStorageBufferOffsetAlignment 0x%" PRIxLEAST64 ". %s", 5659315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis cur_dyn_offset, pDynamicOffsets[cur_dyn_offset], 5660ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski device_data->phys_dev_properties.properties.limits.minStorageBufferOffsetAlignment, 5661315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_17c002d4]); 5662ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski } 5663ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski cur_dyn_offset++; 566472d66f0c1639cbaca92459498452d06db32d7aefTobin Ehlis } 566572d66f0c1639cbaca92459498452d06db32d7aefTobin Ehlis } 5666ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski // Keep running total of dynamic descriptor count to verify at the end 5667ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski total_dynamic_descriptors += set_dynamic_descriptor_count; 566872d66f0c1639cbaca92459498452d06db32d7aefTobin Ehlis } 5669ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski } 5670ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski } else { 5671ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, 56729b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pDescriptorSets[set_idx]), __LINE__, DRAWSTATE_INVALID_SET, "DS", 56739b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "Attempt to bind descriptor set 0x%" PRIxLEAST64 " that doesn't exist!", 56749b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pDescriptorSets[set_idx])); 5675ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski } 5676ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski } 5677ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski // dynamicOffsetCount must equal the total number of dynamic descriptors in the sets being bound 5678ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski if (total_dynamic_descriptors != dynamicOffsetCount) { 5679ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 5680ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski HandleToUint64(cb_state->commandBuffer), __LINE__, VALIDATION_ERROR_17c002ce, "DS", 5681315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis "Attempting to bind %u descriptorSets with %u dynamic descriptors, but dynamicOffsetCount " 5682315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis "is %u. It should exactly match the number of dynamic descriptors. %s", 5683315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis setCount, total_dynamic_descriptors, dynamicOffsetCount, validation_error_map[VALIDATION_ERROR_17c002ce]); 56845b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5685ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski return skip; 5686ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski} 5687ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski 5688ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdBindDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, 5689ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski VkPipelineLayout layout, uint32_t firstSet, uint32_t setCount, 5690ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski const VkDescriptorSet *pDescriptorSets, uint32_t dynamicOffsetCount, 5691ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski const uint32_t *pDynamicOffsets) { 5692ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski bool skip = false; 5693ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski layer_data *device_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 5694ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski unique_lock_t lock(global_lock); 5695ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski GLOBAL_CB_NODE *cb_state = GetCBNode(device_data, commandBuffer); 5696ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski assert(cb_state); 5697ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski skip = PreCallValidateCmdBindDescriptorSets(device_data, cb_state, pipelineBindPoint, layout, firstSet, setCount, 5698ab727dc4a628d86d341d3cb9b915e8f82d2d8550Mark Lobodzinski pDescriptorSets, dynamicOffsetCount, pDynamicOffsets); 569943cc253608e6daccdfa8cb795a98cfea91ef1582Mark Lobodzinski if (!skip) { 570076ff99fdcc54e35ab1f3c34c3b093ccecb99e4dbMark Lobodzinski PreCallRecordCmdBindDescriptorSets(device_data, cb_state, pipelineBindPoint, layout, firstSet, setCount, pDescriptorSets, 570176ff99fdcc54e35ab1f3c34c3b093ccecb99e4dbMark Lobodzinski dynamicOffsetCount, pDynamicOffsets); 570276ff99fdcc54e35ab1f3c34c3b093ccecb99e4dbMark Lobodzinski lock.unlock(); 570343cc253608e6daccdfa8cb795a98cfea91ef1582Mark Lobodzinski device_data->dispatch_table.CmdBindDescriptorSets(commandBuffer, pipelineBindPoint, layout, firstSet, setCount, 570443cc253608e6daccdfa8cb795a98cfea91ef1582Mark Lobodzinski pDescriptorSets, dynamicOffsetCount, pDynamicOffsets); 570576ff99fdcc54e35ab1f3c34c3b093ccecb99e4dbMark Lobodzinski } else { 570676ff99fdcc54e35ab1f3c34c3b093ccecb99e4dbMark Lobodzinski lock.unlock(); 570776ff99fdcc54e35ab1f3c34c3b093ccecb99e4dbMark Lobodzinski 570843cc253608e6daccdfa8cb795a98cfea91ef1582Mark Lobodzinski } 570943cc253608e6daccdfa8cb795a98cfea91ef1582Mark Lobodzinski} 571043cc253608e6daccdfa8cb795a98cfea91ef1582Mark Lobodzinski 57112d4a3c28bf95f00fa2aac7d07288f6faf22208abMark Lobodzinskistatic void PreCallRecordCmdPushDescriptorSetKHR(layer_data *device_data, VkCommandBuffer commandBuffer, 57122d4a3c28bf95f00fa2aac7d07288f6faf22208abMark Lobodzinski VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, uint32_t set, 57132d4a3c28bf95f00fa2aac7d07288f6faf22208abMark Lobodzinski uint32_t descriptorWriteCount, const VkWriteDescriptorSet *pDescriptorWrites) { 571443cc253608e6daccdfa8cb795a98cfea91ef1582Mark Lobodzinski auto cb_state = GetCBNode(device_data, commandBuffer); 57152d4a3c28bf95f00fa2aac7d07288f6faf22208abMark Lobodzinski 57162d4a3c28bf95f00fa2aac7d07288f6faf22208abMark Lobodzinski if (set >= cb_state->lastBound[pipelineBindPoint].boundDescriptorSets.size()) { 57172d4a3c28bf95f00fa2aac7d07288f6faf22208abMark Lobodzinski cb_state->lastBound[pipelineBindPoint].boundDescriptorSets.resize(set + 1); 57182d4a3c28bf95f00fa2aac7d07288f6faf22208abMark Lobodzinski cb_state->lastBound[pipelineBindPoint].dynamicOffsets.resize(set + 1); 57192d4a3c28bf95f00fa2aac7d07288f6faf22208abMark Lobodzinski } 5720e959c76d9d1825a781896df22e891cfb52e2b9c2Tobin Ehlis const auto &layout_state = getPipelineLayout(device_data, layout); 5721e959c76d9d1825a781896df22e891cfb52e2b9c2Tobin Ehlis std::unique_ptr<cvdescriptorset::DescriptorSet> new_desc{ 5722e959c76d9d1825a781896df22e891cfb52e2b9c2Tobin Ehlis new cvdescriptorset::DescriptorSet(0, 0, layout_state->set_layouts[set], device_data)}; 57238938f7b0339a360aad99d6d33c7601465685dd64Chris Forbes cb_state->lastBound[pipelineBindPoint].boundDescriptorSets[set] = new_desc.get(); 572454aae8da345cdc9b9db8ac81e3e03075db79cf9fJózef Kucia cb_state->lastBound[pipelineBindPoint].push_descriptor_set = std::move(new_desc); 57255b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 57265b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 572743839a7f8cf2180734f7b8ed3514eda94a63107aMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdPushDescriptorSetKHR(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, 572843839a7f8cf2180734f7b8ed3514eda94a63107aMark Lobodzinski VkPipelineLayout layout, uint32_t set, uint32_t descriptorWriteCount, 572943839a7f8cf2180734f7b8ed3514eda94a63107aMark Lobodzinski const VkWriteDescriptorSet *pDescriptorWrites) { 573043839a7f8cf2180734f7b8ed3514eda94a63107aMark Lobodzinski layer_data *device_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 573143cc253608e6daccdfa8cb795a98cfea91ef1582Mark Lobodzinski unique_lock_t lock(global_lock); 57322d4a3c28bf95f00fa2aac7d07288f6faf22208abMark Lobodzinski PreCallRecordCmdPushDescriptorSetKHR(device_data, commandBuffer, pipelineBindPoint, layout, set, descriptorWriteCount, 573343cc253608e6daccdfa8cb795a98cfea91ef1582Mark Lobodzinski pDescriptorWrites); 573443cc253608e6daccdfa8cb795a98cfea91ef1582Mark Lobodzinski lock.unlock(); 573576ff99fdcc54e35ab1f3c34c3b093ccecb99e4dbMark Lobodzinski device_data->dispatch_table.CmdPushDescriptorSetKHR(commandBuffer, pipelineBindPoint, layout, set, descriptorWriteCount, 573676ff99fdcc54e35ab1f3c34c3b093ccecb99e4dbMark Lobodzinski pDescriptorWrites); 573743839a7f8cf2180734f7b8ed3514eda94a63107aMark Lobodzinski} 573843839a7f8cf2180734f7b8ed3514eda94a63107aMark Lobodzinski 5739c30d253d86241c51fbd96d13f1590db5d9424894Chris Forbesstatic VkDeviceSize GetIndexAlignment(VkIndexType indexType) { 5740c30d253d86241c51fbd96d13f1590db5d9424894Chris Forbes switch (indexType) { 5741c30d253d86241c51fbd96d13f1590db5d9424894Chris Forbes case VK_INDEX_TYPE_UINT16: 5742c30d253d86241c51fbd96d13f1590db5d9424894Chris Forbes return 2; 5743c30d253d86241c51fbd96d13f1590db5d9424894Chris Forbes case VK_INDEX_TYPE_UINT32: 5744c30d253d86241c51fbd96d13f1590db5d9424894Chris Forbes return 4; 5745c30d253d86241c51fbd96d13f1590db5d9424894Chris Forbes default: 5746c30d253d86241c51fbd96d13f1590db5d9424894Chris Forbes // Not a real index type. Express no alignment requirement here; we expect upper layer 5747c30d253d86241c51fbd96d13f1590db5d9424894Chris Forbes // to have already picked up on the enum being nonsense. 5748c30d253d86241c51fbd96d13f1590db5d9424894Chris Forbes return 1; 5749c30d253d86241c51fbd96d13f1590db5d9424894Chris Forbes } 5750c30d253d86241c51fbd96d13f1590db5d9424894Chris Forbes} 5751c30d253d86241c51fbd96d13f1590db5d9424894Chris Forbes 5752bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdBindIndexBuffer(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, 5753bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkIndexType indexType) { 5754946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski bool skip = false; 575556e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 5756ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 5757b3c2024e0ed61d7f68630d7eb7c8c03100689bb1Mark Lobodzinski 57589a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto buffer_state = GetBufferState(dev_data, buffer); 57599a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto cb_node = GetCBNode(dev_data, commandBuffer); 5760c30d253d86241c51fbd96d13f1590db5d9424894Chris Forbes assert(cb_node); 5761c30d253d86241c51fbd96d13f1590db5d9424894Chris Forbes assert(buffer_state); 5762c30d253d86241c51fbd96d13f1590db5d9424894Chris Forbes 5763c30d253d86241c51fbd96d13f1590db5d9424894Chris Forbes skip |= ValidateBufferUsageFlags(dev_data, buffer_state, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, true, 5764c30d253d86241c51fbd96d13f1590db5d9424894Chris Forbes VALIDATION_ERROR_17e00362, "vkCmdBindIndexBuffer()", "VK_BUFFER_USAGE_INDEX_BUFFER_BIT"); 5765c30d253d86241c51fbd96d13f1590db5d9424894Chris Forbes skip |= ValidateCmdQueueFlags(dev_data, cb_node, "vkCmdBindIndexBuffer()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_17e02415); 5766c30d253d86241c51fbd96d13f1590db5d9424894Chris Forbes skip |= ValidateCmd(dev_data, cb_node, CMD_BINDINDEXBUFFER, "vkCmdBindIndexBuffer()"); 5767c30d253d86241c51fbd96d13f1590db5d9424894Chris Forbes skip |= ValidateMemoryIsBoundToBuffer(dev_data, buffer_state, "vkCmdBindIndexBuffer()", VALIDATION_ERROR_17e00364); 5768c30d253d86241c51fbd96d13f1590db5d9424894Chris Forbes auto offset_align = GetIndexAlignment(indexType); 5769c30d253d86241c51fbd96d13f1590db5d9424894Chris Forbes if (offset % offset_align) { 5770c30d253d86241c51fbd96d13f1590db5d9424894Chris Forbes skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 57717209a72b558b1defb8dcddb2dbe7646d323c01a3Chris Forbes HandleToUint64(commandBuffer), __LINE__, VALIDATION_ERROR_17e00360, "DS", 57727209a72b558b1defb8dcddb2dbe7646d323c01a3Chris Forbes "vkCmdBindIndexBuffer() offset (0x%" PRIxLEAST64 ") does not fall on alignment (%s) boundary. %s", offset, 57737209a72b558b1defb8dcddb2dbe7646d323c01a3Chris Forbes string_VkIndexType(indexType), 57747209a72b558b1defb8dcddb2dbe7646d323c01a3Chris Forbes validation_error_map[VALIDATION_ERROR_17e00360]); 57755b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5776c30d253d86241c51fbd96d13f1590db5d9424894Chris Forbes 5777c30d253d86241c51fbd96d13f1590db5d9424894Chris Forbes if (skip) 5778c30d253d86241c51fbd96d13f1590db5d9424894Chris Forbes return; 5779c30d253d86241c51fbd96d13f1590db5d9424894Chris Forbes 5780c30d253d86241c51fbd96d13f1590db5d9424894Chris Forbes std::function<bool()> function = [=]() { 5781c30d253d86241c51fbd96d13f1590db5d9424894Chris Forbes return ValidateBufferMemoryIsValid(dev_data, buffer_state, "vkCmdBindIndexBuffer()"); 5782c30d253d86241c51fbd96d13f1590db5d9424894Chris Forbes }; 5783c30d253d86241c51fbd96d13f1590db5d9424894Chris Forbes cb_node->queue_submit_functions.push_back(function); 5784c30d253d86241c51fbd96d13f1590db5d9424894Chris Forbes cb_node->status |= CBSTATUS_INDEX_BUFFER_BOUND; 5785c30d253d86241c51fbd96d13f1590db5d9424894Chris Forbes 5786b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 5787c30d253d86241c51fbd96d13f1590db5d9424894Chris Forbes dev_data->dispatch_table.CmdBindIndexBuffer(commandBuffer, buffer, offset, indexType); 57885b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 57895b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 57905b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlisvoid updateResourceTracking(GLOBAL_CB_NODE *pCB, uint32_t firstBinding, uint32_t bindingCount, const VkBuffer *pBuffers) { 57915b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis uint32_t end = firstBinding + bindingCount; 57925b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pCB->currentDrawData.buffers.size() < end) { 57935b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->currentDrawData.buffers.resize(end); 57945b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 57955b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t i = 0; i < bindingCount; ++i) { 57965b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->currentDrawData.buffers[i + firstBinding] = pBuffers[i]; 57975b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 57985b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 57995b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 5800e3319189d6f8e3126522df7a5935d2c42f656291Dustin Gravesstatic inline void updateResourceTrackingOnDraw(GLOBAL_CB_NODE *pCB) { pCB->drawData.push_back(pCB->currentDrawData); } 58015b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 5802bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdBindVertexBuffers(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount, 5803bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkBuffer *pBuffers, const VkDeviceSize *pOffsets) { 5804946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski bool skip = false; 580556e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 5806ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 5807b3c2024e0ed61d7f68630d7eb7c8c03100689bb1Mark Lobodzinski 58089a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto cb_node = GetCBNode(dev_data, commandBuffer); 58097a31ef700e664f26961301bc5accadef33d86974Chris Forbes assert(cb_node); 58107a31ef700e664f26961301bc5accadef33d86974Chris Forbes 58117a31ef700e664f26961301bc5accadef33d86974Chris Forbes skip |= ValidateCmdQueueFlags(dev_data, cb_node, "vkCmdBindVertexBuffers()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_18202415); 58127a31ef700e664f26961301bc5accadef33d86974Chris Forbes skip |= ValidateCmd(dev_data, cb_node, CMD_BINDVERTEXBUFFER, "vkCmdBindVertexBuffers()"); 58137a31ef700e664f26961301bc5accadef33d86974Chris Forbes for (uint32_t i = 0; i < bindingCount; ++i) { 58147a31ef700e664f26961301bc5accadef33d86974Chris Forbes auto buffer_state = GetBufferState(dev_data, pBuffers[i]); 58157a31ef700e664f26961301bc5accadef33d86974Chris Forbes assert(buffer_state); 58167a31ef700e664f26961301bc5accadef33d86974Chris Forbes skip |= ValidateBufferUsageFlags(dev_data, buffer_state, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, true, 58177a31ef700e664f26961301bc5accadef33d86974Chris Forbes VALIDATION_ERROR_182004e6, "vkCmdBindVertexBuffers()", "VK_BUFFER_USAGE_VERTEX_BUFFER_BIT"); 58187a31ef700e664f26961301bc5accadef33d86974Chris Forbes skip |= ValidateMemoryIsBoundToBuffer(dev_data, buffer_state, "vkCmdBindVertexBuffers()", VALIDATION_ERROR_182004e8); 58197a31ef700e664f26961301bc5accadef33d86974Chris Forbes if (pOffsets[i] >= buffer_state->createInfo.size) { 58207a31ef700e664f26961301bc5accadef33d86974Chris Forbes skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, 58217a31ef700e664f26961301bc5accadef33d86974Chris Forbes HandleToUint64(buffer_state->buffer), __LINE__, VALIDATION_ERROR_182004e4, "DS", 58227a31ef700e664f26961301bc5accadef33d86974Chris Forbes "vkCmdBindVertexBuffers() offset (0x%" PRIxLEAST64 ") is beyond the end of the buffer. %s", 58237a31ef700e664f26961301bc5accadef33d86974Chris Forbes pOffsets[i], validation_error_map[VALIDATION_ERROR_182004e4]); 58245b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 58255b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 58267a31ef700e664f26961301bc5accadef33d86974Chris Forbes 58277a31ef700e664f26961301bc5accadef33d86974Chris Forbes if (skip) 58287a31ef700e664f26961301bc5accadef33d86974Chris Forbes return; 58297a31ef700e664f26961301bc5accadef33d86974Chris Forbes 58307a31ef700e664f26961301bc5accadef33d86974Chris Forbes for (uint32_t i = 0; i < bindingCount; ++i) { 58317a31ef700e664f26961301bc5accadef33d86974Chris Forbes auto buffer_state = GetBufferState(dev_data, pBuffers[i]); 58327a31ef700e664f26961301bc5accadef33d86974Chris Forbes assert(buffer_state); 58337a31ef700e664f26961301bc5accadef33d86974Chris Forbes std::function<bool()> function = [=]() { 58347a31ef700e664f26961301bc5accadef33d86974Chris Forbes return ValidateBufferMemoryIsValid(dev_data, buffer_state, "vkCmdBindVertexBuffers()"); 58357a31ef700e664f26961301bc5accadef33d86974Chris Forbes }; 58367a31ef700e664f26961301bc5accadef33d86974Chris Forbes cb_node->queue_submit_functions.push_back(function); 58377a31ef700e664f26961301bc5accadef33d86974Chris Forbes } 58387a31ef700e664f26961301bc5accadef33d86974Chris Forbes 58397a31ef700e664f26961301bc5accadef33d86974Chris Forbes updateResourceTracking(cb_node, firstBinding, bindingCount, pBuffers); 58407a31ef700e664f26961301bc5accadef33d86974Chris Forbes 5841b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 58427a31ef700e664f26961301bc5accadef33d86974Chris Forbes dev_data->dispatch_table.CmdBindVertexBuffers(commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets); 58435b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 58445b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 584525002b75574f762c62b1a00a595bab04ebb25452Mark Lobodzinski// Expects global_lock to be held by caller 58465569d6457ac22e7d245f3cdee045e71ffbc8b06eTobin Ehlisstatic void MarkStoreImagesAndBuffersAsWritten(layer_data *dev_data, GLOBAL_CB_NODE *pCB) { 58477a3985a8a9d255dcca9f5992ca2262c7e5df41c6Tobin Ehlis for (auto imageView : pCB->updateImages) { 58489a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto view_state = GetImageViewState(dev_data, imageView); 5849cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (!view_state) continue; 5850249eb117f85f5e0f3f3a83a2bf297893e0d054ceTobin Ehlis 58519a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto image_state = GetImageState(dev_data, view_state->create_info.image); 58521facd2c91911508b9fb61f54a56269841299f663Tobin Ehlis assert(image_state); 5853e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves std::function<bool()> function = [=]() { 58541facd2c91911508b9fb61f54a56269841299f663Tobin Ehlis SetImageMemoryValid(dev_data, image_state, true); 5855e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves return false; 58567a3985a8a9d255dcca9f5992ca2262c7e5df41c6Tobin Ehlis }; 5857d807198f24437c1b2478ff1d06a33ce4873a1451Tobin Ehlis pCB->queue_submit_functions.push_back(function); 58587a3985a8a9d255dcca9f5992ca2262c7e5df41c6Tobin Ehlis } 58597a3985a8a9d255dcca9f5992ca2262c7e5df41c6Tobin Ehlis for (auto buffer : pCB->updateBuffers) { 58609a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto buffer_state = GetBufferState(dev_data, buffer); 58615cca7b0a90e0b6fe1cc28ddbe9037c3ce3f3ee13Tobin Ehlis assert(buffer_state); 5862e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves std::function<bool()> function = [=]() { 58635cca7b0a90e0b6fe1cc28ddbe9037c3ce3f3ee13Tobin Ehlis SetBufferMemoryValid(dev_data, buffer_state, true); 5864e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves return false; 58657a3985a8a9d255dcca9f5992ca2262c7e5df41c6Tobin Ehlis }; 5866d807198f24437c1b2478ff1d06a33ce4873a1451Tobin Ehlis pCB->queue_submit_functions.push_back(function); 58675b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 58685b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 58695b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 5870ac4451d7e5da96a3a5d51e613c583c057aee9cf4Tobin Ehlis// Generic function to handle validation for all CmdDraw* type functions 5871ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlisstatic bool ValidateCmdDrawType(layer_data *dev_data, VkCommandBuffer cmd_buffer, bool indexed, VkPipelineBindPoint bind_point, 5872baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt CMD_TYPE cmd_type, GLOBAL_CB_NODE **cb_state, const char *caller, VkQueueFlags queue_flags, 5873baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt UNIQUE_VALIDATION_ERROR_CODE queue_flag_code, UNIQUE_VALIDATION_ERROR_CODE msg_code, 5874baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt UNIQUE_VALIDATION_ERROR_CODE const dynamic_state_msg_code) { 587558b923895f7f6be1b7d48bd4ee3e85e0b3dd0c4dTobin Ehlis bool skip = false; 58769a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis *cb_state = GetCBNode(dev_data, cmd_buffer); 587758b923895f7f6be1b7d48bd4ee3e85e0b3dd0c4dTobin Ehlis if (*cb_state) { 5878baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt skip |= ValidateCmdQueueFlags(dev_data, *cb_state, caller, queue_flags, queue_flag_code); 5879ac4451d7e5da96a3a5d51e613c583c057aee9cf4Tobin Ehlis skip |= ValidateCmd(dev_data, *cb_state, cmd_type, caller); 5880b4ab35582a070b18e22c0bd6cb8811c455f5b7ffTobin Ehlis skip |= ValidateDrawState(dev_data, *cb_state, cmd_type, indexed, bind_point, caller, dynamic_state_msg_code); 588125d3241067a529052f120867aa4c6161047cdb60Tobin Ehlis skip |= (VK_PIPELINE_BIND_POINT_GRAPHICS == bind_point) ? outsideRenderPass(dev_data, *cb_state, caller, msg_code) 588225d3241067a529052f120867aa4c6161047cdb60Tobin Ehlis : insideRenderPass(dev_data, *cb_state, caller, msg_code); 588358b923895f7f6be1b7d48bd4ee3e85e0b3dd0c4dTobin Ehlis } 588458b923895f7f6be1b7d48bd4ee3e85e0b3dd0c4dTobin Ehlis return skip; 588558b923895f7f6be1b7d48bd4ee3e85e0b3dd0c4dTobin Ehlis} 588658b923895f7f6be1b7d48bd4ee3e85e0b3dd0c4dTobin Ehlis 588725d3241067a529052f120867aa4c6161047cdb60Tobin Ehlis// Generic function to handle state update for all CmdDraw* and CmdDispatch* type functions 58886b33c4e6a6f232fca84e0a6229106717b0012488Chris Forbesstatic void UpdateStateCmdDrawDispatchType(layer_data *dev_data, GLOBAL_CB_NODE *cb_state, VkPipelineBindPoint bind_point) { 5889ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis UpdateDrawState(dev_data, cb_state, bind_point); 58902f921d33544c162dcb726fc3c7b915e89c02ff24Tobin Ehlis MarkStoreImagesAndBuffersAsWritten(dev_data, cb_state); 589125d3241067a529052f120867aa4c6161047cdb60Tobin Ehlis} 589225d3241067a529052f120867aa4c6161047cdb60Tobin Ehlis 5893ac4451d7e5da96a3a5d51e613c583c057aee9cf4Tobin Ehlis// Generic function to handle state update for all CmdDraw* type functions 58946b33c4e6a6f232fca84e0a6229106717b0012488Chris Forbesstatic void UpdateStateCmdDrawType(layer_data *dev_data, GLOBAL_CB_NODE *cb_state, VkPipelineBindPoint bind_point) { 58956b33c4e6a6f232fca84e0a6229106717b0012488Chris Forbes UpdateStateCmdDrawDispatchType(dev_data, cb_state, bind_point); 5896c0b225e42808ba8fada7a2f67ecd662e376ccf15Tobin Ehlis updateResourceTrackingOnDraw(cb_state); 5897b68b13ed4952bce61f6ebb0023542660c26b0562Chris Forbes cb_state->hasDrawCmd = true; 5898ac4451d7e5da96a3a5d51e613c583c057aee9cf4Tobin Ehlis} 5899ac4451d7e5da96a3a5d51e613c583c057aee9cf4Tobin Ehlis 5900ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlisstatic bool PreCallValidateCmdDraw(layer_data *dev_data, VkCommandBuffer cmd_buffer, bool indexed, VkPipelineBindPoint bind_point, 5901ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis GLOBAL_CB_NODE **cb_state, const char *caller) { 5902baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt return ValidateCmdDrawType(dev_data, cmd_buffer, indexed, bind_point, CMD_DRAW, cb_state, caller, VK_QUEUE_GRAPHICS_BIT, 5903315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1a202415, VALIDATION_ERROR_1a200017, VALIDATION_ERROR_1a200376); 5904ac4451d7e5da96a3a5d51e613c583c057aee9cf4Tobin Ehlis} 5905ac4451d7e5da96a3a5d51e613c583c057aee9cf4Tobin Ehlis 5906ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlisstatic void PostCallRecordCmdDraw(layer_data *dev_data, GLOBAL_CB_NODE *cb_state, VkPipelineBindPoint bind_point) { 59076b33c4e6a6f232fca84e0a6229106717b0012488Chris Forbes UpdateStateCmdDrawType(dev_data, cb_state, bind_point); 5908c0b225e42808ba8fada7a2f67ecd662e376ccf15Tobin Ehlis} 5909c0b225e42808ba8fada7a2f67ecd662e376ccf15Tobin Ehlis 591089d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR void VKAPI_CALL CmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount, 591189d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I Wu uint32_t firstVertex, uint32_t firstInstance) { 591256e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 591358b923895f7f6be1b7d48bd4ee3e85e0b3dd0c4dTobin Ehlis GLOBAL_CB_NODE *cb_state = nullptr; 5914ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 5915ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis bool skip = PreCallValidateCmdDraw(dev_data, commandBuffer, false, VK_PIPELINE_BIND_POINT_GRAPHICS, &cb_state, "vkCmdDraw()"); 5916b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 591758b923895f7f6be1b7d48bd4ee3e85e0b3dd0c4dTobin Ehlis if (!skip) { 59184a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.CmdDraw(commandBuffer, vertexCount, instanceCount, firstVertex, firstInstance); 5919c0b225e42808ba8fada7a2f67ecd662e376ccf15Tobin Ehlis lock.lock(); 5920ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis PostCallRecordCmdDraw(dev_data, cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS); 5921c0b225e42808ba8fada7a2f67ecd662e376ccf15Tobin Ehlis lock.unlock(); 5922c0b225e42808ba8fada7a2f67ecd662e376ccf15Tobin Ehlis } 59235b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 59245b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 5925ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlisstatic bool PreCallValidateCmdDrawIndexed(layer_data *dev_data, VkCommandBuffer cmd_buffer, bool indexed, 5926ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis VkPipelineBindPoint bind_point, GLOBAL_CB_NODE **cb_state, const char *caller) { 5927baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt return ValidateCmdDrawType(dev_data, cmd_buffer, indexed, bind_point, CMD_DRAWINDEXED, cb_state, caller, VK_QUEUE_GRAPHICS_BIT, 5928315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1a402415, VALIDATION_ERROR_1a400017, VALIDATION_ERROR_1a40039c); 5929ac4451d7e5da96a3a5d51e613c583c057aee9cf4Tobin Ehlis} 5930ac4451d7e5da96a3a5d51e613c583c057aee9cf4Tobin Ehlis 5931ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlisstatic void PostCallRecordCmdDrawIndexed(layer_data *dev_data, GLOBAL_CB_NODE *cb_state, VkPipelineBindPoint bind_point) { 59326b33c4e6a6f232fca84e0a6229106717b0012488Chris Forbes UpdateStateCmdDrawType(dev_data, cb_state, bind_point); 5933ac4451d7e5da96a3a5d51e613c583c057aee9cf4Tobin Ehlis} 5934ac4451d7e5da96a3a5d51e613c583c057aee9cf4Tobin Ehlis 5935bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount, 5936bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance) { 593756e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 5938ac4451d7e5da96a3a5d51e613c583c057aee9cf4Tobin Ehlis GLOBAL_CB_NODE *cb_state = nullptr; 5939ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 5940ac4451d7e5da96a3a5d51e613c583c057aee9cf4Tobin Ehlis bool skip = PreCallValidateCmdDrawIndexed(dev_data, commandBuffer, true, VK_PIPELINE_BIND_POINT_GRAPHICS, &cb_state, 5941ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis "vkCmdDrawIndexed()"); 5942b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 5943ac4451d7e5da96a3a5d51e613c583c057aee9cf4Tobin Ehlis if (!skip) { 59444a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.CmdDrawIndexed(commandBuffer, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance); 5945ac4451d7e5da96a3a5d51e613c583c057aee9cf4Tobin Ehlis lock.lock(); 5946ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis PostCallRecordCmdDrawIndexed(dev_data, cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS); 5947ac4451d7e5da96a3a5d51e613c583c057aee9cf4Tobin Ehlis lock.unlock(); 5948ac4451d7e5da96a3a5d51e613c583c057aee9cf4Tobin Ehlis } 59495b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 59505b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 5951ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlisstatic bool PreCallValidateCmdDrawIndirect(layer_data *dev_data, VkCommandBuffer cmd_buffer, VkBuffer buffer, bool indexed, 5952ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis VkPipelineBindPoint bind_point, GLOBAL_CB_NODE **cb_state, BUFFER_STATE **buffer_state, 5953ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis const char *caller) { 5954315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis bool skip = 5955315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis ValidateCmdDrawType(dev_data, cmd_buffer, indexed, bind_point, CMD_DRAWINDIRECT, cb_state, caller, VK_QUEUE_GRAPHICS_BIT, 5956315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1aa02415, VALIDATION_ERROR_1aa00017, VALIDATION_ERROR_1aa003cc); 59579a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis *buffer_state = GetBufferState(dev_data, buffer); 5958315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateMemoryIsBoundToBuffer(dev_data, *buffer_state, caller, VALIDATION_ERROR_1aa003b4); 595913c4316d0072cbc5bf3cd729abef4d114f3c96edMark Lobodzinski // TODO: If the drawIndirectFirstInstance feature is not enabled, all the firstInstance members of the 596013c4316d0072cbc5bf3cd729abef4d114f3c96edMark Lobodzinski // VkDrawIndirectCommand structures accessed by this command must be 0, which will require access to the contents of 'buffer'. 5961d6df438f6e5bf5142a66c857e5c84dd402451242Tobin Ehlis return skip; 5962d6df438f6e5bf5142a66c857e5c84dd402451242Tobin Ehlis} 5963d6df438f6e5bf5142a66c857e5c84dd402451242Tobin Ehlis 5964ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlisstatic void PostCallRecordCmdDrawIndirect(layer_data *dev_data, GLOBAL_CB_NODE *cb_state, VkPipelineBindPoint bind_point, 5965ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis BUFFER_STATE *buffer_state) { 59666b33c4e6a6f232fca84e0a6229106717b0012488Chris Forbes UpdateStateCmdDrawType(dev_data, cb_state, bind_point); 5967d6df438f6e5bf5142a66c857e5c84dd402451242Tobin Ehlis AddCommandBufferBindingBuffer(dev_data, cb_state, buffer_state); 5968d6df438f6e5bf5142a66c857e5c84dd402451242Tobin Ehlis} 5969d6df438f6e5bf5142a66c857e5c84dd402451242Tobin Ehlis 5970bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count, 5971bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski uint32_t stride) { 597256e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 5973d6df438f6e5bf5142a66c857e5c84dd402451242Tobin Ehlis GLOBAL_CB_NODE *cb_state = nullptr; 5974d6df438f6e5bf5142a66c857e5c84dd402451242Tobin Ehlis BUFFER_STATE *buffer_state = nullptr; 5975ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 5976872a2f0ca3ffdeddfa7483e777191fa64b853892Tony Barbour bool skip = PreCallValidateCmdDrawIndirect(dev_data, commandBuffer, buffer, false, VK_PIPELINE_BIND_POINT_GRAPHICS, &cb_state, 5977ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis &buffer_state, "vkCmdDrawIndirect()"); 5978b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 5979d6df438f6e5bf5142a66c857e5c84dd402451242Tobin Ehlis if (!skip) { 59804a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.CmdDrawIndirect(commandBuffer, buffer, offset, count, stride); 5981d6df438f6e5bf5142a66c857e5c84dd402451242Tobin Ehlis lock.lock(); 5982ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis PostCallRecordCmdDrawIndirect(dev_data, cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS, buffer_state); 5983d6df438f6e5bf5142a66c857e5c84dd402451242Tobin Ehlis lock.unlock(); 5984d6df438f6e5bf5142a66c857e5c84dd402451242Tobin Ehlis } 59855b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 59865b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 5987ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlisstatic bool PreCallValidateCmdDrawIndexedIndirect(layer_data *dev_data, VkCommandBuffer cmd_buffer, VkBuffer buffer, bool indexed, 5988ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis VkPipelineBindPoint bind_point, GLOBAL_CB_NODE **cb_state, 5989ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis BUFFER_STATE **buffer_state, const char *caller) { 5990315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis bool skip = 5991315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis ValidateCmdDrawType(dev_data, cmd_buffer, indexed, bind_point, CMD_DRAWINDEXEDINDIRECT, cb_state, caller, 5992315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_1a602415, VALIDATION_ERROR_1a600017, VALIDATION_ERROR_1a600434); 59939a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis *buffer_state = GetBufferState(dev_data, buffer); 5994315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateMemoryIsBoundToBuffer(dev_data, *buffer_state, caller, VALIDATION_ERROR_1a60041c); 599513c4316d0072cbc5bf3cd729abef4d114f3c96edMark Lobodzinski // TODO: If the drawIndirectFirstInstance feature is not enabled, all the firstInstance members of the 599613c4316d0072cbc5bf3cd729abef4d114f3c96edMark Lobodzinski // VkDrawIndexedIndirectCommand structures accessed by this command must be 0, which will require access to the contents of 599713c4316d0072cbc5bf3cd729abef4d114f3c96edMark Lobodzinski // 'buffer'. 59980c9ad626388bcde527db8d89829c45ebf0a94723Tobin Ehlis return skip; 59990c9ad626388bcde527db8d89829c45ebf0a94723Tobin Ehlis} 60000c9ad626388bcde527db8d89829c45ebf0a94723Tobin Ehlis 6001ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlisstatic void PostCallRecordCmdDrawIndexedIndirect(layer_data *dev_data, GLOBAL_CB_NODE *cb_state, VkPipelineBindPoint bind_point, 6002ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis BUFFER_STATE *buffer_state) { 60036b33c4e6a6f232fca84e0a6229106717b0012488Chris Forbes UpdateStateCmdDrawType(dev_data, cb_state, bind_point); 60040c9ad626388bcde527db8d89829c45ebf0a94723Tobin Ehlis AddCommandBufferBindingBuffer(dev_data, cb_state, buffer_state); 60050c9ad626388bcde527db8d89829c45ebf0a94723Tobin Ehlis} 60060c9ad626388bcde527db8d89829c45ebf0a94723Tobin Ehlis 6007bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, 6008bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski uint32_t count, uint32_t stride) { 600956e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 60100c9ad626388bcde527db8d89829c45ebf0a94723Tobin Ehlis GLOBAL_CB_NODE *cb_state = nullptr; 60110c9ad626388bcde527db8d89829c45ebf0a94723Tobin Ehlis BUFFER_STATE *buffer_state = nullptr; 6012ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 60130c9ad626388bcde527db8d89829c45ebf0a94723Tobin Ehlis bool skip = PreCallValidateCmdDrawIndexedIndirect(dev_data, commandBuffer, buffer, true, VK_PIPELINE_BIND_POINT_GRAPHICS, 6014ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis &cb_state, &buffer_state, "vkCmdDrawIndexedIndirect()"); 6015b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 60160c9ad626388bcde527db8d89829c45ebf0a94723Tobin Ehlis if (!skip) { 60174a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.CmdDrawIndexedIndirect(commandBuffer, buffer, offset, count, stride); 60180c9ad626388bcde527db8d89829c45ebf0a94723Tobin Ehlis lock.lock(); 6019ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis PostCallRecordCmdDrawIndexedIndirect(dev_data, cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS, buffer_state); 60200c9ad626388bcde527db8d89829c45ebf0a94723Tobin Ehlis lock.unlock(); 60210c9ad626388bcde527db8d89829c45ebf0a94723Tobin Ehlis } 60225b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 60235b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 6024ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlisstatic bool PreCallValidateCmdDispatch(layer_data *dev_data, VkCommandBuffer cmd_buffer, bool indexed, 6025ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis VkPipelineBindPoint bind_point, GLOBAL_CB_NODE **cb_state, const char *caller) { 6026baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt return ValidateCmdDrawType(dev_data, cmd_buffer, indexed, bind_point, CMD_DISPATCH, cb_state, caller, VK_QUEUE_COMPUTE_BIT, 6027315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_19c02415, VALIDATION_ERROR_19c00017, VALIDATION_ERROR_UNDEFINED); 602825d3241067a529052f120867aa4c6161047cdb60Tobin Ehlis} 602925d3241067a529052f120867aa4c6161047cdb60Tobin Ehlis 6030ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlisstatic void PostCallRecordCmdDispatch(layer_data *dev_data, GLOBAL_CB_NODE *cb_state, VkPipelineBindPoint bind_point) { 60316b33c4e6a6f232fca84e0a6229106717b0012488Chris Forbes UpdateStateCmdDrawDispatchType(dev_data, cb_state, bind_point); 603225d3241067a529052f120867aa4c6161047cdb60Tobin Ehlis} 603325d3241067a529052f120867aa4c6161047cdb60Tobin Ehlis 603489d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR void VKAPI_CALL CmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) { 603556e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 603625d3241067a529052f120867aa4c6161047cdb60Tobin Ehlis GLOBAL_CB_NODE *cb_state = nullptr; 6037ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 6038ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis bool skip = 6039ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis PreCallValidateCmdDispatch(dev_data, commandBuffer, false, VK_PIPELINE_BIND_POINT_COMPUTE, &cb_state, "vkCmdDispatch()"); 6040b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 604125d3241067a529052f120867aa4c6161047cdb60Tobin Ehlis if (!skip) { 60424a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.CmdDispatch(commandBuffer, x, y, z); 604325d3241067a529052f120867aa4c6161047cdb60Tobin Ehlis lock.lock(); 6044ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis PostCallRecordCmdDispatch(dev_data, cb_state, VK_PIPELINE_BIND_POINT_COMPUTE); 604525d3241067a529052f120867aa4c6161047cdb60Tobin Ehlis lock.unlock(); 604625d3241067a529052f120867aa4c6161047cdb60Tobin Ehlis } 60475b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 60485b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 6049ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlisstatic bool PreCallValidateCmdDispatchIndirect(layer_data *dev_data, VkCommandBuffer cmd_buffer, VkBuffer buffer, bool indexed, 6050ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis VkPipelineBindPoint bind_point, GLOBAL_CB_NODE **cb_state, 6051ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis BUFFER_STATE **buffer_state, const char *caller) { 6052baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt bool skip = 6053baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt ValidateCmdDrawType(dev_data, cmd_buffer, indexed, bind_point, CMD_DISPATCHINDIRECT, cb_state, caller, VK_QUEUE_COMPUTE_BIT, 6054315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1a002415, VALIDATION_ERROR_1a000017, VALIDATION_ERROR_UNDEFINED); 60559a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis *buffer_state = GetBufferState(dev_data, buffer); 6056315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateMemoryIsBoundToBuffer(dev_data, *buffer_state, caller, VALIDATION_ERROR_1a000322); 605779c66dcd1e0db7de8556bce6deb782a150c77b92Tobin Ehlis return skip; 605879c66dcd1e0db7de8556bce6deb782a150c77b92Tobin Ehlis} 605979c66dcd1e0db7de8556bce6deb782a150c77b92Tobin Ehlis 6060ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlisstatic void PostCallRecordCmdDispatchIndirect(layer_data *dev_data, GLOBAL_CB_NODE *cb_state, VkPipelineBindPoint bind_point, 6061ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis BUFFER_STATE *buffer_state) { 60626b33c4e6a6f232fca84e0a6229106717b0012488Chris Forbes UpdateStateCmdDrawDispatchType(dev_data, cb_state, bind_point); 606379c66dcd1e0db7de8556bce6deb782a150c77b92Tobin Ehlis AddCommandBufferBindingBuffer(dev_data, cb_state, buffer_state); 606479c66dcd1e0db7de8556bce6deb782a150c77b92Tobin Ehlis} 606579c66dcd1e0db7de8556bce6deb782a150c77b92Tobin Ehlis 6066bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) { 606756e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 606879c66dcd1e0db7de8556bce6deb782a150c77b92Tobin Ehlis GLOBAL_CB_NODE *cb_state = nullptr; 606979c66dcd1e0db7de8556bce6deb782a150c77b92Tobin Ehlis BUFFER_STATE *buffer_state = nullptr; 6070ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 60717433ab60c7ff16d37edb0f8b17b606ccd363e210Tobin Ehlis bool skip = PreCallValidateCmdDispatchIndirect(dev_data, commandBuffer, buffer, false, VK_PIPELINE_BIND_POINT_COMPUTE, 6072ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis &cb_state, &buffer_state, "vkCmdDispatchIndirect()"); 6073b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 607479c66dcd1e0db7de8556bce6deb782a150c77b92Tobin Ehlis if (!skip) { 60754a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.CmdDispatchIndirect(commandBuffer, buffer, offset); 607679c66dcd1e0db7de8556bce6deb782a150c77b92Tobin Ehlis lock.lock(); 6077ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis PostCallRecordCmdDispatchIndirect(dev_data, cb_state, VK_PIPELINE_BIND_POINT_COMPUTE, buffer_state); 607879c66dcd1e0db7de8556bce6deb782a150c77b92Tobin Ehlis lock.unlock(); 607979c66dcd1e0db7de8556bce6deb782a150c77b92Tobin Ehlis } 60805b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 60815b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 608289d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR void VKAPI_CALL CmdCopyBuffer(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkBuffer dstBuffer, 608389d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I Wu uint32_t regionCount, const VkBufferCopy *pRegions) { 6084c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski layer_data *device_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 6085ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 6086ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis 6087c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski auto cb_node = GetCBNode(device_data, commandBuffer); 6088c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski auto src_buffer_state = GetBufferState(device_data, srcBuffer); 6089c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski auto dst_buffer_state = GetBufferState(device_data, dstBuffer); 6090593c857d8db57cf9ae2c590b75e22dadd51bd3d4Tobin Ehlis 6091c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski if (cb_node && src_buffer_state && dst_buffer_state) { 6092c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski bool skip = PreCallValidateCmdCopyBuffer(device_data, cb_node, src_buffer_state, dst_buffer_state); 6093c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski if (!skip) { 6094c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski PreCallRecordCmdCopyBuffer(device_data, cb_node, src_buffer_state, dst_buffer_state); 6095c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski lock.unlock(); 6096c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski device_data->dispatch_table.CmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, regionCount, pRegions); 6097c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski } 6098ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis } else { 6099c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski lock.unlock(); 6100ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis assert(0); 61015b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 61025b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 61035b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 6104bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdCopyImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, 6105bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, 6106bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkImageCopy *pRegions) { 61076a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski bool skip = false; 61086a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski layer_data *device_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 6109ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 6110249eb117f85f5e0f3f3a83a2bf297893e0d054ceTobin Ehlis 61116a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski auto cb_node = GetCBNode(device_data, commandBuffer); 61126a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski auto src_image_state = GetImageState(device_data, srcImage); 61136a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski auto dst_image_state = GetImageState(device_data, dstImage); 61141facd2c91911508b9fb61f54a56269841299f663Tobin Ehlis if (cb_node && src_image_state && dst_image_state) { 61156a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip = PreCallValidateCmdCopyImage(device_data, cb_node, src_image_state, dst_image_state, regionCount, pRegions, 61166a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski srcImageLayout, dstImageLayout); 61176a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski if (!skip) { 6118a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis PreCallRecordCmdCopyImage(device_data, cb_node, src_image_state, dst_image_state, regionCount, pRegions, srcImageLayout, 6119a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis dstImageLayout); 61206a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski lock.unlock(); 61216a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski device_data->dispatch_table.CmdCopyImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, 61226a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski pRegions); 61235b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 6124249eb117f85f5e0f3f3a83a2bf297893e0d054ceTobin Ehlis } else { 61256a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski lock.unlock(); 6126249eb117f85f5e0f3f3a83a2bf297893e0d054ceTobin Ehlis assert(0); 61275b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 61285b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 61295b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 6130eebf670a2f04c402f2875f85aa4f889b06db48fcMark Lobodzinski// Validate that an image's sampleCount matches the requirement for a specific API call 613160568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinskibool ValidateImageSampleCount(layer_data *dev_data, IMAGE_STATE *image_state, VkSampleCountFlagBits sample_count, 613260568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski const char *location, UNIQUE_VALIDATION_ERROR_CODE msgCode) { 6133eebf670a2f04c402f2875f85aa4f889b06db48fcMark Lobodzinski bool skip = false; 61341facd2c91911508b9fb61f54a56269841299f663Tobin Ehlis if (image_state->createInfo.samples != sample_count) { 61359b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 61369b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(image_state->image), 0, msgCode, "DS", 61379b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "%s for image 0x%" PRIxLEAST64 " was created with a sample count of %s but must be %s. %s", location, 61389b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(image_state->image), string_VkSampleCountFlagBits(image_state->createInfo.samples), 61399b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus string_VkSampleCountFlagBits(sample_count), validation_error_map[msgCode]); 6140eebf670a2f04c402f2875f85aa4f889b06db48fcMark Lobodzinski } 6141eebf670a2f04c402f2875f85aa4f889b06db48fcMark Lobodzinski return skip; 6142eebf670a2f04c402f2875f85aa4f889b06db48fcMark Lobodzinski} 6143eebf670a2f04c402f2875f85aa4f889b06db48fcMark Lobodzinski 6144bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdBlitImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, 6145bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, 6146bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkImageBlit *pRegions, VkFilter filter) { 614756e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 6148ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 6149593c857d8db57cf9ae2c590b75e22dadd51bd3d4Tobin Ehlis 61509a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto cb_node = GetCBNode(dev_data, commandBuffer); 61519a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto src_image_state = GetImageState(dev_data, srcImage); 61529a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto dst_image_state = GetImageState(dev_data, dstImage); 61530dc51740dbd7b9f0ba7c071e0bf96f63d6d48c85Mark Lobodzinski 6154a99ceeafb2acc8ef0e18af2d1b24d5e1e68d5ee3Norbert Garnys bool skip = PreCallValidateCmdBlitImage(dev_data, cb_node, src_image_state, dst_image_state, regionCount, pRegions, 6155a99ceeafb2acc8ef0e18af2d1b24d5e1e68d5ee3Norbert Garnys srcImageLayout, dstImageLayout, filter); 61560dc51740dbd7b9f0ba7c071e0bf96f63d6d48c85Mark Lobodzinski 6157dca02371c9531e7a9a2a51decae1db4d297862c4Mark Lobodzinski if (!skip) { 6158a99ceeafb2acc8ef0e18af2d1b24d5e1e68d5ee3Norbert Garnys PreCallRecordCmdBlitImage(dev_data, cb_node, src_image_state, dst_image_state, regionCount, pRegions, srcImageLayout, 6159a99ceeafb2acc8ef0e18af2d1b24d5e1e68d5ee3Norbert Garnys dstImageLayout); 6160eebd811afd800663f15fda8fc71bc203a03fe294Mark Lobodzinski lock.unlock(); 61614a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.CmdBlitImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, 61624a0754042cf090e131e9e769d8a3633c228625beChris Forbes pRegions, filter); 61630dc51740dbd7b9f0ba7c071e0bf96f63d6d48c85Mark Lobodzinski } 61645b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 61655b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 6166bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdCopyBufferToImage(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkImage dstImage, 6167bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkImageLayout dstImageLayout, uint32_t regionCount, 6168bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkBufferImageCopy *pRegions) { 6169940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski layer_data *device_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 6170ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 6171940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski bool skip = false; 6172940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski auto cb_node = GetCBNode(device_data, commandBuffer); 6173940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski auto src_buffer_state = GetBufferState(device_data, srcBuffer); 6174940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski auto dst_image_state = GetImageState(device_data, dstImage); 6175940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski if (cb_node && src_buffer_state && dst_image_state) { 6176940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski skip = PreCallValidateCmdCopyBufferToImage(device_data, dstImageLayout, cb_node, src_buffer_state, dst_image_state, 617771c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski regionCount, pRegions, "vkCmdCopyBufferToImage()"); 6178ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis } else { 6179d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski lock.unlock(); 6180ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis assert(0); 6181e4d82c37d6c861b388dbc80297c18d6255858cb4Dave Houlton // TODO: report VU01244 here, or put in object tracker? 61825b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 6183940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski if (!skip) { 6184a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis PreCallRecordCmdCopyBufferToImage(device_data, cb_node, src_buffer_state, dst_image_state, regionCount, pRegions, 6185a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis dstImageLayout); 6186d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski lock.unlock(); 6187940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski device_data->dispatch_table.CmdCopyBufferToImage(commandBuffer, srcBuffer, dstImage, dstImageLayout, regionCount, pRegions); 6188d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski } 61895b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 61905b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 6191bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdCopyImageToBuffer(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, 6192bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkBuffer dstBuffer, uint32_t regionCount, const VkBufferImageCopy *pRegions) { 6193940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski bool skip = false; 6194940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski layer_data *device_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 6195ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 6196593c857d8db57cf9ae2c590b75e22dadd51bd3d4Tobin Ehlis 6197940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski auto cb_node = GetCBNode(device_data, commandBuffer); 6198940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski auto src_image_state = GetImageState(device_data, srcImage); 6199940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski auto dst_buffer_state = GetBufferState(device_data, dstBuffer); 6200940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski if (cb_node && src_image_state && dst_buffer_state) { 6201940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski skip = PreCallValidateCmdCopyImageToBuffer(device_data, srcImageLayout, cb_node, src_image_state, dst_buffer_state, 620271c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski regionCount, pRegions, "vkCmdCopyImageToBuffer()"); 6203ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis } else { 6204d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski lock.unlock(); 6205ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis assert(0); 6206e4d82c37d6c861b388dbc80297c18d6255858cb4Dave Houlton // TODO: report VU01262 here, or put in object tracker? 62075b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 6208940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski if (!skip) { 6209a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis PreCallRecordCmdCopyImageToBuffer(device_data, cb_node, src_image_state, dst_buffer_state, regionCount, pRegions, 6210a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis srcImageLayout); 6211d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski lock.unlock(); 6212940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski device_data->dispatch_table.CmdCopyImageToBuffer(commandBuffer, srcImage, srcImageLayout, dstBuffer, regionCount, pRegions); 6213d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski } 62145b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 62155b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 6216e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlisstatic bool PreCallCmdUpdateBuffer(layer_data *device_data, const GLOBAL_CB_NODE *cb_state, const BUFFER_STATE *dst_buffer_state) { 6217e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis bool skip = false; 6218e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis skip |= ValidateMemoryIsBoundToBuffer(device_data, dst_buffer_state, "vkCmdUpdateBuffer()", VALIDATION_ERROR_1e400046); 6219e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis // Validate that DST buffer has correct usage flags set 6220e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis skip |= ValidateBufferUsageFlags(device_data, dst_buffer_state, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true, 6221e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis VALIDATION_ERROR_1e400044, "vkCmdUpdateBuffer()", "VK_BUFFER_USAGE_TRANSFER_DST_BIT"); 6222e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis skip |= ValidateCmdQueueFlags(device_data, cb_state, "vkCmdUpdateBuffer()", 6223e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis VK_QUEUE_TRANSFER_BIT | VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, VALIDATION_ERROR_1e402415); 6224e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis skip |= ValidateCmd(device_data, cb_state, CMD_UPDATEBUFFER, "vkCmdUpdateBuffer()"); 6225e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis skip |= insideRenderPass(device_data, cb_state, "vkCmdUpdateBuffer()", VALIDATION_ERROR_1e400017); 6226e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis return skip; 6227e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis} 6228e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis 6229e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlisstatic void PostCallRecordCmdUpdateBuffer(layer_data *device_data, GLOBAL_CB_NODE *cb_state, BUFFER_STATE *dst_buffer_state) { 6230e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis // Update bindings between buffer and cmd buffer 6231e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis AddCommandBufferBindingBuffer(device_data, cb_state, dst_buffer_state); 6232e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis std::function<bool()> function = [=]() { 6233e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis SetBufferMemoryValid(device_data, dst_buffer_state, true); 6234e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis return false; 6235e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis }; 6236d807198f24437c1b2478ff1d06a33ce4873a1451Tobin Ehlis cb_state->queue_submit_functions.push_back(function); 6237e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis} 6238e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis 6239bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, 6240bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkDeviceSize dataSize, const uint32_t *pData) { 62413251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 624256e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 6243ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 6244593c857d8db57cf9ae2c590b75e22dadd51bd3d4Tobin Ehlis 6245e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis auto cb_state = GetCBNode(dev_data, commandBuffer); 6246e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis assert(cb_state); 62479a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto dst_buff_state = GetBufferState(dev_data, dstBuffer); 6248e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis assert(dst_buff_state); 6249e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis skip |= PreCallCmdUpdateBuffer(dev_data, cb_state, dst_buff_state); 6250b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 6251e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis if (!skip) { 6252e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis dev_data->dispatch_table.CmdUpdateBuffer(commandBuffer, dstBuffer, dstOffset, dataSize, pData); 6253e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis lock.lock(); 6254e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis PostCallRecordCmdUpdateBuffer(dev_data, cb_state, dst_buff_state); 6255e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis lock.unlock(); 6256e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis } 62575b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 62585b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 6259bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, 6260bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkDeviceSize size, uint32_t data) { 626123bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski layer_data *device_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 6262ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 626323bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski auto cb_node = GetCBNode(device_data, commandBuffer); 626423bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski auto buffer_state = GetBufferState(device_data, dstBuffer); 6265593c857d8db57cf9ae2c590b75e22dadd51bd3d4Tobin Ehlis 626623bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski if (cb_node && buffer_state) { 626723bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski bool skip = PreCallValidateCmdFillBuffer(device_data, cb_node, buffer_state); 626823bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski if (!skip) { 626923bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski PreCallRecordCmdFillBuffer(device_data, cb_node, buffer_state); 627023bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski lock.unlock(); 627123bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski device_data->dispatch_table.CmdFillBuffer(commandBuffer, dstBuffer, dstOffset, size, data); 627223bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski } 6273ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis } else { 627423bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski lock.unlock(); 6275ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis assert(0); 62765b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 62775b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 62785b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 62794028af23e688ab5730f48ab2244dd042e2eefaedMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdClearAttachments(VkCommandBuffer commandBuffer, uint32_t attachmentCount, 62804028af23e688ab5730f48ab2244dd042e2eefaedMark Lobodzinski const VkClearAttachment *pAttachments, uint32_t rectCount, 62814028af23e688ab5730f48ab2244dd042e2eefaedMark Lobodzinski const VkClearRect *pRects) { 62824028af23e688ab5730f48ab2244dd042e2eefaedMark Lobodzinski bool skip = false; 628356e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 62844028af23e688ab5730f48ab2244dd042e2eefaedMark Lobodzinski { 6285ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 62864028af23e688ab5730f48ab2244dd042e2eefaedMark Lobodzinski skip = PreCallValidateCmdClearAttachments(dev_data, commandBuffer, attachmentCount, pAttachments, rectCount, pRects); 62874028af23e688ab5730f48ab2244dd042e2eefaedMark Lobodzinski } 6288cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (!skip) dev_data->dispatch_table.CmdClearAttachments(commandBuffer, attachmentCount, pAttachments, rectCount, pRects); 62895b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 62905b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 62910482c55760707900fcd072f6895c121bcf055f6eMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdClearColorImage(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, 62920482c55760707900fcd072f6895c121bcf055f6eMark Lobodzinski const VkClearColorValue *pColor, uint32_t rangeCount, 62930482c55760707900fcd072f6895c121bcf055f6eMark Lobodzinski const VkImageSubresourceRange *pRanges) { 629456e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 6295ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 62960482c55760707900fcd072f6895c121bcf055f6eMark Lobodzinski 62970482c55760707900fcd072f6895c121bcf055f6eMark Lobodzinski bool skip = PreCallValidateCmdClearColorImage(dev_data, commandBuffer, image, imageLayout, rangeCount, pRanges); 62980482c55760707900fcd072f6895c121bcf055f6eMark Lobodzinski if (!skip) { 62990619dc1df076bfedcf0c999ceca3bdecd5ea5171Chris Forbes PreCallRecordCmdClearImage(dev_data, commandBuffer, image, imageLayout, rangeCount, pRanges); 63000482c55760707900fcd072f6895c121bcf055f6eMark Lobodzinski lock.unlock(); 63010482c55760707900fcd072f6895c121bcf055f6eMark Lobodzinski dev_data->dispatch_table.CmdClearColorImage(commandBuffer, image, imageLayout, pColor, rangeCount, pRanges); 63020482c55760707900fcd072f6895c121bcf055f6eMark Lobodzinski } 63030482c55760707900fcd072f6895c121bcf055f6eMark Lobodzinski} 63040482c55760707900fcd072f6895c121bcf055f6eMark Lobodzinski 63050482c55760707900fcd072f6895c121bcf055f6eMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdClearDepthStencilImage(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, 63060482c55760707900fcd072f6895c121bcf055f6eMark Lobodzinski const VkClearDepthStencilValue *pDepthStencil, uint32_t rangeCount, 63070482c55760707900fcd072f6895c121bcf055f6eMark Lobodzinski const VkImageSubresourceRange *pRanges) { 630856e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 6309ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 63100482c55760707900fcd072f6895c121bcf055f6eMark Lobodzinski 63110482c55760707900fcd072f6895c121bcf055f6eMark Lobodzinski bool skip = PreCallValidateCmdClearDepthStencilImage(dev_data, commandBuffer, image, imageLayout, rangeCount, pRanges); 63120482c55760707900fcd072f6895c121bcf055f6eMark Lobodzinski if (!skip) { 63130619dc1df076bfedcf0c999ceca3bdecd5ea5171Chris Forbes PreCallRecordCmdClearImage(dev_data, commandBuffer, image, imageLayout, rangeCount, pRanges); 63140482c55760707900fcd072f6895c121bcf055f6eMark Lobodzinski lock.unlock(); 63150482c55760707900fcd072f6895c121bcf055f6eMark Lobodzinski dev_data->dispatch_table.CmdClearDepthStencilImage(commandBuffer, image, imageLayout, pDepthStencil, rangeCount, pRanges); 63167f8aa8f5abceedbb599ef69af1dfbb38c0df2660Slawomir Cygan } 63175b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 63185b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 6319bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdResolveImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, 6320bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, 6321bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkImageResolve *pRegions) { 632256e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 6323ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 6324593c857d8db57cf9ae2c590b75e22dadd51bd3d4Tobin Ehlis 63259a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto cb_node = GetCBNode(dev_data, commandBuffer); 63269a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto src_image_state = GetImageState(dev_data, srcImage); 63279a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto dst_image_state = GetImageState(dev_data, dstImage); 632809fe5ac5edaec7f0dbcc9fd696e68194569aea89Mark Lobodzinski 632925f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski bool skip = PreCallValidateCmdResolveImage(dev_data, cb_node, src_image_state, dst_image_state, regionCount, pRegions); 633009fe5ac5edaec7f0dbcc9fd696e68194569aea89Mark Lobodzinski 633109fe5ac5edaec7f0dbcc9fd696e68194569aea89Mark Lobodzinski if (!skip) { 63326c0400e625554ce7fddb833eeace0de19cfcc965Mark Lobodzinski PreCallRecordCmdResolveImage(dev_data, cb_node, src_image_state, dst_image_state); 63336c0400e625554ce7fddb833eeace0de19cfcc965Mark Lobodzinski lock.unlock(); 63344a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.CmdResolveImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, 63354a0754042cf090e131e9e769d8a3633c228625beChris Forbes pRegions); 633609fe5ac5edaec7f0dbcc9fd696e68194569aea89Mark Lobodzinski } 63375b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 63385b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 6339a8d1e377bdeaf61a3209cb997502da4356a185bbMike WeiblenVKAPI_ATTR void VKAPI_CALL GetImageSubresourceLayout(VkDevice device, VkImage image, const VkImageSubresource *pSubresource, 6340a8d1e377bdeaf61a3209cb997502da4356a185bbMike Weiblen VkSubresourceLayout *pLayout) { 6341a8d1e377bdeaf61a3209cb997502da4356a185bbMike Weiblen layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 6342a8d1e377bdeaf61a3209cb997502da4356a185bbMike Weiblen 6343a8d1e377bdeaf61a3209cb997502da4356a185bbMike Weiblen bool skip = PreCallValidateGetImageSubresourceLayout(device_data, image, pSubresource); 6344a8d1e377bdeaf61a3209cb997502da4356a185bbMike Weiblen if (!skip) { 6345b06379a335598a3d8c53c694e875dda19eeab612Mark Lobodzinski device_data->dispatch_table.GetImageSubresourceLayout(device, image, pSubresource, pLayout); 6346b06379a335598a3d8c53c694e875dda19eeab612Mark Lobodzinski } 6347b06379a335598a3d8c53c694e875dda19eeab612Mark Lobodzinski} 6348b06379a335598a3d8c53c694e875dda19eeab612Mark Lobodzinski 6349b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentinebool setEventStageMask(VkQueue queue, VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask) { 635056e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 63519a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); 6352b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine if (pCB) { 6353b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine pCB->eventToStageMap[event] = stageMask; 6354b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine } 6355b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine auto queue_data = dev_data->queueMap.find(queue); 6356b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine if (queue_data != dev_data->queueMap.end()) { 6357b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine queue_data->second.eventToStageMap[event] = stageMask; 6358b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine } 6359b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine return false; 6360b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine} 6361b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine 6362bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdSetEvent(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask) { 63633251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 636456e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 6365ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 63669a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); 63675b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pCB) { 63683251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateCmdQueueFlags(dev_data, pCB, "vkCmdSetEvent()", VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, 6369315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1d402415); 63703251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateCmd(dev_data, pCB, CMD_SETEVENT, "vkCmdSetEvent()"); 6371315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= insideRenderPass(dev_data, pCB, "vkCmdSetEvent()", VALIDATION_ERROR_1d400017); 6372315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateStageMaskGsTsEnables(dev_data, stageMask, "vkCmdSetEvent()", VALIDATION_ERROR_1d4008fc, 6373315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1d4008fe); 63749a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto event_state = GetEventNode(dev_data, event); 63754710dda89a1dd2e023334d4eda710a394b211cdcTobin Ehlis if (event_state) { 63769b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus addCommandBufferBinding(&event_state->cb_bindings, {HandleToUint64(event), kVulkanObjectTypeEvent}, pCB); 63774710dda89a1dd2e023334d4eda710a394b211cdcTobin Ehlis event_state->cb_bindings.insert(pCB); 6378ad13b09db50a49347ea6a8c1408fcc5280042898Tobin Ehlis } 63795b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->events.push_back(event); 6380c1eb2a3736e03aaa15b849d217fd963021dc9780Michael Lentine if (!pCB->waitedEvents.count(event)) { 6381c1eb2a3736e03aaa15b849d217fd963021dc9780Michael Lentine pCB->writeEventsBeforeWait.push_back(event); 6382c1eb2a3736e03aaa15b849d217fd963021dc9780Michael Lentine } 6383f49bd2b5f4c968a3033b3e5099bbbcff51201575Chris Forbes pCB->eventUpdates.emplace_back([=](VkQueue q){return setEventStageMask(q, commandBuffer, event, stageMask);}); 63845b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 6385b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 63863251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip) dev_data->dispatch_table.CmdSetEvent(commandBuffer, event, stageMask); 63875b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 63885b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 6389bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdResetEvent(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask) { 63903251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 639156e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 6392ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 63939a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); 63945b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pCB) { 63953251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateCmdQueueFlags(dev_data, pCB, "vkCmdResetEvent()", VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, 6396315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1c402415); 63973251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateCmd(dev_data, pCB, CMD_RESETEVENT, "vkCmdResetEvent()"); 6398315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= insideRenderPass(dev_data, pCB, "vkCmdResetEvent()", VALIDATION_ERROR_1c400017); 6399315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateStageMaskGsTsEnables(dev_data, stageMask, "vkCmdResetEvent()", VALIDATION_ERROR_1c400904, 6400315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1c400906); 64019a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto event_state = GetEventNode(dev_data, event); 64024710dda89a1dd2e023334d4eda710a394b211cdcTobin Ehlis if (event_state) { 64039b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus addCommandBufferBinding(&event_state->cb_bindings, {HandleToUint64(event), kVulkanObjectTypeEvent}, pCB); 64044710dda89a1dd2e023334d4eda710a394b211cdcTobin Ehlis event_state->cb_bindings.insert(pCB); 6405ad13b09db50a49347ea6a8c1408fcc5280042898Tobin Ehlis } 64065b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->events.push_back(event); 6407c1eb2a3736e03aaa15b849d217fd963021dc9780Michael Lentine if (!pCB->waitedEvents.count(event)) { 6408c1eb2a3736e03aaa15b849d217fd963021dc9780Michael Lentine pCB->writeEventsBeforeWait.push_back(event); 6409c1eb2a3736e03aaa15b849d217fd963021dc9780Michael Lentine } 6410315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis // TODO : Add check for VALIDATION_ERROR_32c008f8 6411f49bd2b5f4c968a3033b3e5099bbbcff51201575Chris Forbes pCB->eventUpdates.emplace_back([=](VkQueue q){return setEventStageMask(q, commandBuffer, event, VkPipelineStageFlags(0));}); 64125b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 6413b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 64143251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip) dev_data->dispatch_table.CmdResetEvent(commandBuffer, event, stageMask); 64155b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 64165b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 6417a54aea2a72be3bd84371773cc79a678816615587Tobin Ehlis// Return input pipeline stage flags, expanded for individual bits if VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT 6418a54aea2a72be3bd84371773cc79a678816615587Tobin Ehlisstatic VkPipelineStageFlags ExpandPipelineStageFlags(VkPipelineStageFlags inflags) { 6419a54aea2a72be3bd84371773cc79a678816615587Tobin Ehlis return (inflags != VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT) 6420a54aea2a72be3bd84371773cc79a678816615587Tobin Ehlis ? inflags 6421a54aea2a72be3bd84371773cc79a678816615587Tobin Ehlis : (VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT | VK_PIPELINE_STAGE_VERTEX_INPUT_BIT | 6422a54aea2a72be3bd84371773cc79a678816615587Tobin Ehlis VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT | 6423a54aea2a72be3bd84371773cc79a678816615587Tobin Ehlis VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT | VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT | 6424a54aea2a72be3bd84371773cc79a678816615587Tobin Ehlis VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | 6425a54aea2a72be3bd84371773cc79a678816615587Tobin Ehlis VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | 6426a54aea2a72be3bd84371773cc79a678816615587Tobin Ehlis VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT); 6427a54aea2a72be3bd84371773cc79a678816615587Tobin Ehlis} 6428a54aea2a72be3bd84371773cc79a678816615587Tobin Ehlis 6429f384f33742c2b72888372332747298d08135ac92Tobin Ehlis// Verify image barrier image state and that the image is consistent with FB image 6430f384f33742c2b72888372332747298d08135ac92Tobin Ehlisstatic bool ValidateImageBarrierImage(layer_data *device_data, const char *funcName, GLOBAL_CB_NODE const *cb_state, 643179fc00370d55e7cbfd4052b579120e64b0a1a4beTobin Ehlis VkFramebuffer framebuffer, uint32_t active_subpass, const safe_VkSubpassDescription &sub_desc, 643279fc00370d55e7cbfd4052b579120e64b0a1a4beTobin Ehlis uint64_t rp_handle, uint32_t img_index, const VkImageMemoryBarrier &img_barrier) { 6433f384f33742c2b72888372332747298d08135ac92Tobin Ehlis bool skip = false; 643479fc00370d55e7cbfd4052b579120e64b0a1a4beTobin Ehlis const auto &fb_state = GetFramebufferState(device_data, framebuffer); 6435f384f33742c2b72888372332747298d08135ac92Tobin Ehlis assert(fb_state); 6436f384f33742c2b72888372332747298d08135ac92Tobin Ehlis const auto img_bar_image = img_barrier.image; 6437f384f33742c2b72888372332747298d08135ac92Tobin Ehlis bool image_match = false; 6438f384f33742c2b72888372332747298d08135ac92Tobin Ehlis bool sub_image_found = false; // Do we find a corresponding subpass description 6439f384f33742c2b72888372332747298d08135ac92Tobin Ehlis VkImageLayout sub_image_layout = VK_IMAGE_LAYOUT_UNDEFINED; 6440f384f33742c2b72888372332747298d08135ac92Tobin Ehlis uint32_t attach_index = 0; 6441f384f33742c2b72888372332747298d08135ac92Tobin Ehlis uint32_t index_count = 0; 6442f384f33742c2b72888372332747298d08135ac92Tobin Ehlis // Verify that a framebuffer image matches barrier image 6443f384f33742c2b72888372332747298d08135ac92Tobin Ehlis for (const auto &fb_attach : fb_state->attachments) { 6444f384f33742c2b72888372332747298d08135ac92Tobin Ehlis if (img_bar_image == fb_attach.image) { 6445f384f33742c2b72888372332747298d08135ac92Tobin Ehlis image_match = true; 6446f384f33742c2b72888372332747298d08135ac92Tobin Ehlis attach_index = index_count; 6447f384f33742c2b72888372332747298d08135ac92Tobin Ehlis break; 6448f384f33742c2b72888372332747298d08135ac92Tobin Ehlis } 6449f384f33742c2b72888372332747298d08135ac92Tobin Ehlis index_count++; 6450f384f33742c2b72888372332747298d08135ac92Tobin Ehlis } 6451f384f33742c2b72888372332747298d08135ac92Tobin Ehlis if (image_match) { // Make sure subpass is referring to matching attachment 6452f384f33742c2b72888372332747298d08135ac92Tobin Ehlis if (sub_desc.pDepthStencilAttachment && sub_desc.pDepthStencilAttachment->attachment == attach_index) { 6453f384f33742c2b72888372332747298d08135ac92Tobin Ehlis sub_image_layout = sub_desc.pDepthStencilAttachment->layout; 6454f384f33742c2b72888372332747298d08135ac92Tobin Ehlis sub_image_found = true; 6455f384f33742c2b72888372332747298d08135ac92Tobin Ehlis } else { 6456f384f33742c2b72888372332747298d08135ac92Tobin Ehlis for (uint32_t j = 0; j < sub_desc.colorAttachmentCount; ++j) { 6457f384f33742c2b72888372332747298d08135ac92Tobin Ehlis if (sub_desc.pColorAttachments && sub_desc.pColorAttachments[j].attachment == attach_index) { 6458f384f33742c2b72888372332747298d08135ac92Tobin Ehlis sub_image_layout = sub_desc.pColorAttachments[j].layout; 6459f384f33742c2b72888372332747298d08135ac92Tobin Ehlis sub_image_found = true; 6460f384f33742c2b72888372332747298d08135ac92Tobin Ehlis break; 6461f384f33742c2b72888372332747298d08135ac92Tobin Ehlis } else if (sub_desc.pResolveAttachments && sub_desc.pResolveAttachments[j].attachment == attach_index) { 6462f384f33742c2b72888372332747298d08135ac92Tobin Ehlis sub_image_layout = sub_desc.pResolveAttachments[j].layout; 6463f384f33742c2b72888372332747298d08135ac92Tobin Ehlis sub_image_found = true; 6464f384f33742c2b72888372332747298d08135ac92Tobin Ehlis break; 6465f384f33742c2b72888372332747298d08135ac92Tobin Ehlis } 6466f384f33742c2b72888372332747298d08135ac92Tobin Ehlis } 6467f384f33742c2b72888372332747298d08135ac92Tobin Ehlis } 6468f384f33742c2b72888372332747298d08135ac92Tobin Ehlis if (!sub_image_found) { 6469f384f33742c2b72888372332747298d08135ac92Tobin Ehlis skip |= log_msg( 6470f384f33742c2b72888372332747298d08135ac92Tobin Ehlis device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, rp_handle, 6471f384f33742c2b72888372332747298d08135ac92Tobin Ehlis __LINE__, VALIDATION_ERROR_1b800936, "CORE", 6472f384f33742c2b72888372332747298d08135ac92Tobin Ehlis "%s: Barrier pImageMemoryBarriers[%d].image (0x%" PRIx64 6473f384f33742c2b72888372332747298d08135ac92Tobin Ehlis ") is not referenced by the VkSubpassDescription for active subpass (%d) of current renderPass (0x%" PRIx64 "). %s", 6474f384f33742c2b72888372332747298d08135ac92Tobin Ehlis funcName, img_index, HandleToUint64(img_bar_image), active_subpass, rp_handle, 6475f384f33742c2b72888372332747298d08135ac92Tobin Ehlis validation_error_map[VALIDATION_ERROR_1b800936]); 6476f384f33742c2b72888372332747298d08135ac92Tobin Ehlis } 6477f384f33742c2b72888372332747298d08135ac92Tobin Ehlis } else { // !image_match 6478f384f33742c2b72888372332747298d08135ac92Tobin Ehlis auto const fb_handle = HandleToUint64(fb_state->framebuffer); 6479f384f33742c2b72888372332747298d08135ac92Tobin Ehlis skip |= 6480f384f33742c2b72888372332747298d08135ac92Tobin Ehlis log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT, fb_handle, 6481f384f33742c2b72888372332747298d08135ac92Tobin Ehlis __LINE__, VALIDATION_ERROR_1b800936, "CORE", 6482f384f33742c2b72888372332747298d08135ac92Tobin Ehlis "%s: Barrier pImageMemoryBarriers[%d].image (0x%" PRIx64 6483f384f33742c2b72888372332747298d08135ac92Tobin Ehlis ") does not match an image from the current framebuffer (0x%" PRIx64 "). %s", 6484f384f33742c2b72888372332747298d08135ac92Tobin Ehlis funcName, img_index, HandleToUint64(img_bar_image), fb_handle, validation_error_map[VALIDATION_ERROR_1b800936]); 6485f384f33742c2b72888372332747298d08135ac92Tobin Ehlis } 6486f384f33742c2b72888372332747298d08135ac92Tobin Ehlis if (img_barrier.oldLayout != img_barrier.newLayout) { 6487f384f33742c2b72888372332747298d08135ac92Tobin Ehlis skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 6488f384f33742c2b72888372332747298d08135ac92Tobin Ehlis HandleToUint64(cb_state->commandBuffer), __LINE__, VALIDATION_ERROR_1b80093a, "CORE", 6489f384f33742c2b72888372332747298d08135ac92Tobin Ehlis "%s: As the Image Barrier for image 0x%" PRIx64 6490f384f33742c2b72888372332747298d08135ac92Tobin Ehlis " is being executed within a render pass instance, oldLayout must equal newLayout yet they are " 6491f384f33742c2b72888372332747298d08135ac92Tobin Ehlis "%s and %s. %s", 6492f384f33742c2b72888372332747298d08135ac92Tobin Ehlis funcName, HandleToUint64(img_barrier.image), string_VkImageLayout(img_barrier.oldLayout), 6493f384f33742c2b72888372332747298d08135ac92Tobin Ehlis string_VkImageLayout(img_barrier.newLayout), validation_error_map[VALIDATION_ERROR_1b80093a]); 6494f384f33742c2b72888372332747298d08135ac92Tobin Ehlis } else { 6495f384f33742c2b72888372332747298d08135ac92Tobin Ehlis if (sub_image_found && sub_image_layout != img_barrier.oldLayout) { 6496f384f33742c2b72888372332747298d08135ac92Tobin Ehlis skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, 6497f384f33742c2b72888372332747298d08135ac92Tobin Ehlis rp_handle, __LINE__, VALIDATION_ERROR_1b800938, "CORE", 6498f384f33742c2b72888372332747298d08135ac92Tobin Ehlis "%s: Barrier pImageMemoryBarriers[%d].image (0x%" PRIx64 6499f384f33742c2b72888372332747298d08135ac92Tobin Ehlis ") is referenced by the VkSubpassDescription for active subpass (%d) of current renderPass (0x%" PRIx64 6500f384f33742c2b72888372332747298d08135ac92Tobin Ehlis ") as having layout %s, but image barrier has layout %s. %s", 6501f384f33742c2b72888372332747298d08135ac92Tobin Ehlis funcName, img_index, HandleToUint64(img_bar_image), active_subpass, rp_handle, 6502f384f33742c2b72888372332747298d08135ac92Tobin Ehlis string_VkImageLayout(img_barrier.oldLayout), string_VkImageLayout(sub_image_layout), 6503f384f33742c2b72888372332747298d08135ac92Tobin Ehlis validation_error_map[VALIDATION_ERROR_1b800938]); 6504f384f33742c2b72888372332747298d08135ac92Tobin Ehlis } 6505f384f33742c2b72888372332747298d08135ac92Tobin Ehlis } 6506f384f33742c2b72888372332747298d08135ac92Tobin Ehlis return skip; 6507f384f33742c2b72888372332747298d08135ac92Tobin Ehlis} 6508f384f33742c2b72888372332747298d08135ac92Tobin Ehlis 65094cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis// Validate image barriers within a renderPass 6510f384f33742c2b72888372332747298d08135ac92Tobin Ehlisstatic bool ValidateRenderPassImageBarriers(layer_data *device_data, const char *funcName, GLOBAL_CB_NODE *cb_state, 65114cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis uint32_t active_subpass, const safe_VkSubpassDescription &sub_desc, uint64_t rp_handle, 65124cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis VkAccessFlags sub_src_access_mask, VkAccessFlags sub_dst_access_mask, 65134cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis uint32_t image_mem_barrier_count, const VkImageMemoryBarrier *image_barriers) { 6514a4a1923d21087ded8e990190acd6752264712319Tobin Ehlis bool skip = false; 65154cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis for (uint32_t i = 0; i < image_mem_barrier_count; ++i) { 65164cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis const auto &img_barrier = image_barriers[i]; 65174cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis const auto &img_src_access_mask = img_barrier.srcAccessMask; 65184cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis if (img_src_access_mask != (sub_src_access_mask & img_src_access_mask)) { 6519c1c43cc01e333f3762c65ce4ad926c33235583d2Tobin Ehlis skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, 65204cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis rp_handle, __LINE__, VALIDATION_ERROR_1b80092e, "CORE", 65214cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis "%s: Barrier pImageMemoryBarriers[%d].srcAccessMask(0x%X) is not a subset of VkSubpassDependency " 65224cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis "srcAccessMask(0x%X) of " 6523e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis "subpass %d of renderPass 0x%" PRIx64 ". %s", 65244cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis funcName, i, img_src_access_mask, sub_src_access_mask, active_subpass, rp_handle, 65254cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis validation_error_map[VALIDATION_ERROR_1b80092e]); 6526e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis } 65274cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis const auto &img_dst_access_mask = img_barrier.dstAccessMask; 65284cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis if (img_dst_access_mask != (sub_dst_access_mask & img_dst_access_mask)) { 6529c1c43cc01e333f3762c65ce4ad926c33235583d2Tobin Ehlis skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, 65304cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis rp_handle, __LINE__, VALIDATION_ERROR_1b800930, "CORE", 65314cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis "%s: Barrier pImageMemoryBarriers[%d].dstAccessMask(0x%X) is not a subset of VkSubpassDependency " 65324cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis "dstAccessMask(0x%X) of " 6533e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis "subpass %d of renderPass 0x%" PRIx64 ". %s", 65344cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis funcName, i, img_dst_access_mask, sub_dst_access_mask, active_subpass, rp_handle, 65354cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis validation_error_map[VALIDATION_ERROR_1b800930]); 65365b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 65378f2467c1db3d48bcfd09dd91188dcb0318fa5c43Tobin Ehlis if (VK_QUEUE_FAMILY_IGNORED != img_barrier.srcQueueFamilyIndex || 65388f2467c1db3d48bcfd09dd91188dcb0318fa5c43Tobin Ehlis VK_QUEUE_FAMILY_IGNORED != img_barrier.dstQueueFamilyIndex) { 65398f2467c1db3d48bcfd09dd91188dcb0318fa5c43Tobin Ehlis skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, 65408f2467c1db3d48bcfd09dd91188dcb0318fa5c43Tobin Ehlis rp_handle, __LINE__, VALIDATION_ERROR_1b80093c, "CORE", 65418f2467c1db3d48bcfd09dd91188dcb0318fa5c43Tobin Ehlis "%s: Barrier pImageMemoryBarriers[%d].srcQueueFamilyIndex is %d and " 65428f2467c1db3d48bcfd09dd91188dcb0318fa5c43Tobin Ehlis "pImageMemoryBarriers[%d].dstQueueFamilyIndex is %d but both must be VK_QUEUE_FAMILY_IGNORED. %s", 65438f2467c1db3d48bcfd09dd91188dcb0318fa5c43Tobin Ehlis funcName, i, img_barrier.srcQueueFamilyIndex, i, img_barrier.dstQueueFamilyIndex, 65448f2467c1db3d48bcfd09dd91188dcb0318fa5c43Tobin Ehlis validation_error_map[VALIDATION_ERROR_1b80093c]); 65458f2467c1db3d48bcfd09dd91188dcb0318fa5c43Tobin Ehlis } 6546f384f33742c2b72888372332747298d08135ac92Tobin Ehlis // Secondary CBs can have null framebuffer so queue up validation in that case 'til FB is known 6547f384f33742c2b72888372332747298d08135ac92Tobin Ehlis if (VK_NULL_HANDLE == cb_state->activeFramebuffer) { 6548f384f33742c2b72888372332747298d08135ac92Tobin Ehlis assert(VK_COMMAND_BUFFER_LEVEL_SECONDARY == cb_state->createInfo.level); 6549f384f33742c2b72888372332747298d08135ac92Tobin Ehlis // Secondary CB case w/o FB specified delay validation 655079fc00370d55e7cbfd4052b579120e64b0a1a4beTobin Ehlis cb_state->cmd_execute_commands_functions.emplace_back([=](VkFramebuffer fb) { 655179fc00370d55e7cbfd4052b579120e64b0a1a4beTobin Ehlis return ValidateImageBarrierImage(device_data, funcName, cb_state, fb, active_subpass, sub_desc, rp_handle, i, 6552f384f33742c2b72888372332747298d08135ac92Tobin Ehlis img_barrier); 6553f384f33742c2b72888372332747298d08135ac92Tobin Ehlis }); 6554f384f33742c2b72888372332747298d08135ac92Tobin Ehlis } else { 655579fc00370d55e7cbfd4052b579120e64b0a1a4beTobin Ehlis skip |= ValidateImageBarrierImage(device_data, funcName, cb_state, cb_state->activeFramebuffer, active_subpass, 655679fc00370d55e7cbfd4052b579120e64b0a1a4beTobin Ehlis sub_desc, rp_handle, i, img_barrier); 65573025e72bc2b727622969d036966f50057392551aTobin Ehlis } 65584cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis } 65594cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis return skip; 65604cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis} 65614cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis 65624cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis// Validate VUs for Pipeline Barriers that are within a renderPass 65634cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis// Pre: cb_state->activeRenderPass must be a pointer to valid renderPass state 6564f384f33742c2b72888372332747298d08135ac92Tobin Ehlisstatic bool ValidateRenderPassPipelineBarriers(layer_data *device_data, const char *funcName, GLOBAL_CB_NODE *cb_state, 65654cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis VkPipelineStageFlags src_stage_mask, VkPipelineStageFlags dst_stage_mask, 65664cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis VkDependencyFlags dependency_flags, uint32_t mem_barrier_count, 65674cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis const VkMemoryBarrier *mem_barriers, uint32_t buffer_mem_barrier_count, 65684cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis const VkBufferMemoryBarrier *buffer_mem_barriers, uint32_t image_mem_barrier_count, 65694cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis const VkImageMemoryBarrier *image_barriers) { 65704cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis bool skip = false; 65714cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis auto rp_state = cb_state->activeRenderPass; 65724cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis const auto active_subpass = cb_state->activeSubpass; 65734cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis auto rp_handle = HandleToUint64(rp_state->renderPass); 65744cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis if (!rp_state->hasSelfDependency[active_subpass]) { 65754cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, 65764cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis rp_handle, __LINE__, VALIDATION_ERROR_1b800928, "CORE", 65774cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis "%s: Barriers cannot be set during subpass %d of renderPass 0x%" PRIx64 65784cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis " with no self-dependency specified. %s", 65794cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis funcName, active_subpass, rp_handle, validation_error_map[VALIDATION_ERROR_1b800928]); 65804cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis } else { 65814cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis assert(rp_state->subpass_to_dependency_index[cb_state->activeSubpass] != -1); 65824cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis // Grab ref to current subpassDescription up-front for use below 65834cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis const auto &sub_desc = rp_state->createInfo.pSubpasses[active_subpass]; 65844cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis const auto &sub_dep = rp_state->createInfo.pDependencies[rp_state->subpass_to_dependency_index[active_subpass]]; 65854cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis const auto &sub_src_stage_mask = ExpandPipelineStageFlags(sub_dep.srcStageMask); 65864cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis const auto &sub_dst_stage_mask = ExpandPipelineStageFlags(sub_dep.dstStageMask); 65874cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis if ((sub_src_stage_mask != VK_PIPELINE_STAGE_ALL_COMMANDS_BIT) && 65884cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis (src_stage_mask != (sub_src_stage_mask & src_stage_mask))) { 65894cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, 65904cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis rp_handle, __LINE__, VALIDATION_ERROR_1b80092a, "CORE", 65914cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis "%s: Barrier srcStageMask(0x%X) is not a subset of VkSubpassDependency srcStageMask(0x%X) of " 65924cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis "subpass %d of renderPass 0x%" PRIx64 ". %s", 65934cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis funcName, src_stage_mask, sub_src_stage_mask, active_subpass, rp_handle, 65944cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis validation_error_map[VALIDATION_ERROR_1b80092a]); 65954cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis } 65964cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis if ((sub_dst_stage_mask != VK_PIPELINE_STAGE_ALL_COMMANDS_BIT) && 65974cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis (dst_stage_mask != (sub_dst_stage_mask & dst_stage_mask))) { 65984cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, 65994cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis rp_handle, __LINE__, VALIDATION_ERROR_1b80092c, "CORE", 66004cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis "%s: Barrier dstStageMask(0x%X) is not a subset of VkSubpassDependency dstStageMask(0x%X) of " 66014cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis "subpass %d of renderPass 0x%" PRIx64 ". %s", 66024cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis funcName, dst_stage_mask, sub_dst_stage_mask, active_subpass, rp_handle, 66034cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis validation_error_map[VALIDATION_ERROR_1b80092c]); 66044cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis } 66054cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis if (0 != buffer_mem_barrier_count) { 66064cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, 66074cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis rp_handle, __LINE__, VALIDATION_ERROR_1b800934, "CORE", 66084cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis "%s: bufferMemoryBarrierCount is non-zero (%d) for " 66094cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis "subpass %d of renderPass 0x%" PRIx64 ". %s", 66104cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis funcName, buffer_mem_barrier_count, active_subpass, rp_handle, 66114cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis validation_error_map[VALIDATION_ERROR_1b800934]); 66124cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis } 66134cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis const auto &sub_src_access_mask = sub_dep.srcAccessMask; 66144cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis const auto &sub_dst_access_mask = sub_dep.dstAccessMask; 66154cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis for (uint32_t i = 0; i < mem_barrier_count; ++i) { 66164cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis const auto &mb_src_access_mask = mem_barriers[i].srcAccessMask; 66174cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis if (mb_src_access_mask != (sub_src_access_mask & mb_src_access_mask)) { 66184cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 66194cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, rp_handle, __LINE__, VALIDATION_ERROR_1b80092e, "CORE", 66204cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis "%s: Barrier pMemoryBarriers[%d].srcAccessMask(0x%X) is not a subset of VkSubpassDependency " 66214cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis "srcAccessMask(0x%X) of " 66224cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis "subpass %d of renderPass 0x%" PRIx64 ". %s", 66234cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis funcName, i, mb_src_access_mask, sub_src_access_mask, active_subpass, rp_handle, 66244cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis validation_error_map[VALIDATION_ERROR_1b80092e]); 66254cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis } 66264cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis const auto &mb_dst_access_mask = mem_barriers[i].dstAccessMask; 66274cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis if (mb_dst_access_mask != (sub_dst_access_mask & mb_dst_access_mask)) { 66284cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 66294cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, rp_handle, __LINE__, VALIDATION_ERROR_1b800930, "CORE", 66304cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis "%s: Barrier pMemoryBarriers[%d].dstAccessMask(0x%X) is not a subset of VkSubpassDependency " 66314cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis "dstAccessMask(0x%X) of " 66324cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis "subpass %d of renderPass 0x%" PRIx64 ". %s", 66334cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis funcName, i, mb_dst_access_mask, sub_dst_access_mask, active_subpass, rp_handle, 66344cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis validation_error_map[VALIDATION_ERROR_1b800930]); 66354cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis } 66364cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis } 66374cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis skip |= ValidateRenderPassImageBarriers(device_data, funcName, cb_state, active_subpass, sub_desc, rp_handle, 66384cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis sub_src_access_mask, sub_dst_access_mask, image_mem_barrier_count, image_barriers); 6639c1c43cc01e333f3762c65ce4ad926c33235583d2Tobin Ehlis if (sub_dep.dependencyFlags != dependency_flags) { 6640c1c43cc01e333f3762c65ce4ad926c33235583d2Tobin Ehlis skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, 6641c1c43cc01e333f3762c65ce4ad926c33235583d2Tobin Ehlis rp_handle, __LINE__, VALIDATION_ERROR_1b800932, "CORE", 6642c1c43cc01e333f3762c65ce4ad926c33235583d2Tobin Ehlis "%s: dependencyFlags param (0x%X) does not equal VkSubpassDependency " 6643c1c43cc01e333f3762c65ce4ad926c33235583d2Tobin Ehlis "dependencyFlags value (0x%X) for " 6644c1c43cc01e333f3762c65ce4ad926c33235583d2Tobin Ehlis "subpass %d of renderPass 0x%" PRIx64 ". %s", 6645c1c43cc01e333f3762c65ce4ad926c33235583d2Tobin Ehlis funcName, dependency_flags, sub_dep.dependencyFlags, cb_state->activeSubpass, rp_handle, 6646c1c43cc01e333f3762c65ce4ad926c33235583d2Tobin Ehlis validation_error_map[VALIDATION_ERROR_1b800932]); 6647c1c43cc01e333f3762c65ce4ad926c33235583d2Tobin Ehlis } 66485b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 6649e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis return skip; 6650e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis} 6651e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis 6652d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis// Array to mask individual accessMask to corresponding stageMask 6653d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis// accessMask active bit position (0-31) maps to index 6654d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlisconst static VkPipelineStageFlags AccessMaskToPipeStage[20] = { 6655d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis // VK_ACCESS_INDIRECT_COMMAND_READ_BIT = 0 6656d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, 6657d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis // VK_ACCESS_INDEX_READ_BIT = 1 6658d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 6659d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis // VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT = 2 6660d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 6661d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis // VK_ACCESS_UNIFORM_READ_BIT = 3 6662d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT | 6663d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT | VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT | 6664d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 6665d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis // VK_ACCESS_INPUT_ATTACHMENT_READ_BIT = 4 6666d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 6667d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis // VK_ACCESS_SHADER_READ_BIT = 5 6668d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT | 6669d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT | VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT | 6670d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 6671d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis // VK_ACCESS_SHADER_WRITE_BIT = 6 6672d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT | 6673d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT | VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT | 6674d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 6675d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis // VK_ACCESS_COLOR_ATTACHMENT_READ_BIT = 7 6676d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 6677d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis // VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT = 8 6678d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 6679d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis // VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT = 9 6680d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 6681d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis // VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT = 10 6682d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 6683d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis // VK_ACCESS_TRANSFER_READ_BIT = 11 6684d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_PIPELINE_STAGE_TRANSFER_BIT, 6685d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis // VK_ACCESS_TRANSFER_WRITE_BIT = 12 6686d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_PIPELINE_STAGE_TRANSFER_BIT, 6687d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis // VK_ACCESS_HOST_READ_BIT = 13 6688d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_PIPELINE_STAGE_HOST_BIT, 6689d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis // VK_ACCESS_HOST_WRITE_BIT = 14 6690d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_PIPELINE_STAGE_HOST_BIT, 6691d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis // VK_ACCESS_MEMORY_READ_BIT = 15 6692d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_ACCESS_FLAG_BITS_MAX_ENUM, // Always match 6693d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis // VK_ACCESS_MEMORY_WRITE_BIT = 16 6694d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_ACCESS_FLAG_BITS_MAX_ENUM, // Always match 6695d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis // VK_ACCESS_COMMAND_PROCESS_READ_BIT_NVX = 17 6696d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX, 6697d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis // VK_ACCESS_COMMAND_PROCESS_WRITE_BIT_NVX = 18 6698d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX, 6699d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis}; 6700d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis 6701d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis// Verify that all bits of access_mask are supported by the src_stage_mask 6702d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlisstatic bool ValidateAccessMaskPipelineStage(VkAccessFlags access_mask, VkPipelineStageFlags stage_mask) { 6703d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis // Early out if all commands set, or access_mask NULL 6704d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis if ((stage_mask & VK_PIPELINE_STAGE_ALL_COMMANDS_BIT) || (0 == access_mask)) return true; 6705d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis 6706d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis stage_mask = ExpandPipelineStageFlags(stage_mask); 6707d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis int index = 0; 6708d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis // for each of the set bits in access_mask, make sure that supporting stage mask bit(s) are set 6709d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis while (access_mask) { 6710d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis index = (u_ffs(access_mask) - 1); 6711d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis assert(index >= 0); 6712d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis // Must have "!= 0" compare to prevent warning from MSVC 6713d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis if ((AccessMaskToPipeStage[index] & stage_mask) == 0) return false; // early out 6714d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis access_mask &= ~(1 << index); // Mask off bit that's been checked 6715d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis } 6716d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis return true; 6717d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis} 6718d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis 6719e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlisstatic bool ValidateBarriers(layer_data *device_data, const char *funcName, GLOBAL_CB_NODE const *cb_state, 6720e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis VkPipelineStageFlags src_stage_mask, VkPipelineStageFlags dst_stage_mask, uint32_t memBarrierCount, 6721e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis const VkMemoryBarrier *pMemBarriers, uint32_t bufferBarrierCount, 6722e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis const VkBufferMemoryBarrier *pBufferMemBarriers, uint32_t imageMemBarrierCount, 6723e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis const VkImageMemoryBarrier *pImageMemBarriers) { 6724e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis bool skip = false; 6725d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis for (uint32_t i = 0; i < memBarrierCount; ++i) { 6726d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis const auto &mem_barrier = pMemBarriers[i]; 6727d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis if (!ValidateAccessMaskPipelineStage(mem_barrier.srcAccessMask, src_stage_mask)) { 6728d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 6729d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis HandleToUint64(cb_state->commandBuffer), __LINE__, VALIDATION_ERROR_1b800940, "DS", 6730d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis "%s: pMemBarriers[%d].srcAccessMask (0x%X) is not supported by srcStageMask (0x%X). %s", funcName, i, 6731d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis mem_barrier.srcAccessMask, src_stage_mask, validation_error_map[VALIDATION_ERROR_1b800940]); 6732d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis } 67331ce9b1e7d3dfd0841efede007022bdc960917008Tobin Ehlis if (!ValidateAccessMaskPipelineStage(mem_barrier.dstAccessMask, dst_stage_mask)) { 67341ce9b1e7d3dfd0841efede007022bdc960917008Tobin Ehlis skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 67351ce9b1e7d3dfd0841efede007022bdc960917008Tobin Ehlis HandleToUint64(cb_state->commandBuffer), __LINE__, VALIDATION_ERROR_1b800942, "DS", 67361ce9b1e7d3dfd0841efede007022bdc960917008Tobin Ehlis "%s: pMemBarriers[%d].dstAccessMask (0x%X) is not supported by dstStageMask (0x%X). %s", funcName, i, 67371ce9b1e7d3dfd0841efede007022bdc960917008Tobin Ehlis mem_barrier.dstAccessMask, dst_stage_mask, validation_error_map[VALIDATION_ERROR_1b800942]); 67381ce9b1e7d3dfd0841efede007022bdc960917008Tobin Ehlis } 6739d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis } 67405b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t i = 0; i < imageMemBarrierCount; ++i) { 67415b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis auto mem_barrier = &pImageMemBarriers[i]; 6742d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis if (!ValidateAccessMaskPipelineStage(mem_barrier->srcAccessMask, src_stage_mask)) { 6743d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 6744d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis HandleToUint64(cb_state->commandBuffer), __LINE__, VALIDATION_ERROR_1b800940, "DS", 6745d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis "%s: pImageMemBarriers[%d].srcAccessMask (0x%X) is not supported by srcStageMask (0x%X). %s", funcName, 6746d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis i, mem_barrier->srcAccessMask, src_stage_mask, validation_error_map[VALIDATION_ERROR_1b800940]); 6747d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis } 67481ce9b1e7d3dfd0841efede007022bdc960917008Tobin Ehlis if (!ValidateAccessMaskPipelineStage(mem_barrier->dstAccessMask, dst_stage_mask)) { 67491ce9b1e7d3dfd0841efede007022bdc960917008Tobin Ehlis skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 67501ce9b1e7d3dfd0841efede007022bdc960917008Tobin Ehlis HandleToUint64(cb_state->commandBuffer), __LINE__, VALIDATION_ERROR_1b800942, "DS", 67511ce9b1e7d3dfd0841efede007022bdc960917008Tobin Ehlis "%s: pImageMemBarriers[%d].dstAccessMask (0x%X) is not supported by dstStageMask (0x%X). %s", funcName, 67521ce9b1e7d3dfd0841efede007022bdc960917008Tobin Ehlis i, mem_barrier->dstAccessMask, dst_stage_mask, validation_error_map[VALIDATION_ERROR_1b800942]); 67531ce9b1e7d3dfd0841efede007022bdc960917008Tobin Ehlis } 6754e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis auto image_data = GetImageState(device_data, mem_barrier->image); 67558f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski if (image_data) { 67568f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski uint32_t src_q_f_index = mem_barrier->srcQueueFamilyIndex; 67578f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski uint32_t dst_q_f_index = mem_barrier->dstQueueFamilyIndex; 67588f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski if (image_data->createInfo.sharingMode == VK_SHARING_MODE_CONCURRENT) { 67598f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski // srcQueueFamilyIndex and dstQueueFamilyIndex must both 67608f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski // be VK_QUEUE_FAMILY_IGNORED 67618f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski if ((src_q_f_index != VK_QUEUE_FAMILY_IGNORED) || (dst_q_f_index != VK_QUEUE_FAMILY_IGNORED)) { 6762e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 6763e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, HandleToUint64(cb_state->commandBuffer), 6764e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis __LINE__, DRAWSTATE_INVALID_QUEUE_INDEX, "DS", 6765e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis "%s: Image Barrier for image 0x%" PRIx64 6766e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis " was created with sharingMode of " 6767e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis "VK_SHARING_MODE_CONCURRENT. Src and dst " 6768e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis "queueFamilyIndices must be VK_QUEUE_FAMILY_IGNORED.", 67699b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus funcName, HandleToUint64(mem_barrier->image)); 67708f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski } 67718f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski } else { 67728f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski // Sharing mode is VK_SHARING_MODE_EXCLUSIVE. srcQueueFamilyIndex and 67738f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski // dstQueueFamilyIndex must either both be VK_QUEUE_FAMILY_IGNORED, 67748f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski // or both be a valid queue family 67758f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski if (((src_q_f_index == VK_QUEUE_FAMILY_IGNORED) || (dst_q_f_index == VK_QUEUE_FAMILY_IGNORED)) && 67768f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski (src_q_f_index != dst_q_f_index)) { 6777e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 6778e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, HandleToUint64(cb_state->commandBuffer), 6779e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis __LINE__, DRAWSTATE_INVALID_QUEUE_INDEX, "DS", 6780e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis "%s: Image 0x%" PRIx64 6781e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis " was created with sharingMode " 6782e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis "of VK_SHARING_MODE_EXCLUSIVE. If one of src- or " 6783e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis "dstQueueFamilyIndex is VK_QUEUE_FAMILY_IGNORED, both " 6784e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis "must be.", 67859b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus funcName, HandleToUint64(mem_barrier->image)); 67868f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski } else if (((src_q_f_index != VK_QUEUE_FAMILY_IGNORED) && (dst_q_f_index != VK_QUEUE_FAMILY_IGNORED)) && 6787e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis ((src_q_f_index >= device_data->phys_dev_properties.queue_family_properties.size()) || 6788e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis (dst_q_f_index >= device_data->phys_dev_properties.queue_family_properties.size()))) { 6789e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 6790e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, HandleToUint64(cb_state->commandBuffer), 6791e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis __LINE__, DRAWSTATE_INVALID_QUEUE_INDEX, "DS", 67928f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski "%s: Image 0x%" PRIx64 67938f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski " was created with sharingMode " 67948f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski "of VK_SHARING_MODE_EXCLUSIVE, but srcQueueFamilyIndex %d" 67958f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski " or dstQueueFamilyIndex %d is greater than " PRINTF_SIZE_T_SPECIFIER 67968f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski "queueFamilies crated for this device.", 67979b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus funcName, HandleToUint64(mem_barrier->image), src_q_f_index, dst_q_f_index, 6798e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis device_data->phys_dev_properties.queue_family_properties.size()); 67995b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 68005b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 68018f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski } 68025b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 68038f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski if (mem_barrier->newLayout == VK_IMAGE_LAYOUT_UNDEFINED || mem_barrier->newLayout == VK_IMAGE_LAYOUT_PREINITIALIZED) { 6804e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 6805e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis HandleToUint64(cb_state->commandBuffer), __LINE__, DRAWSTATE_INVALID_BARRIER, "DS", 6806df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski "%s: Image Layout cannot be transitioned to UNDEFINED or " 6807df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski "PREINITIALIZED.", 6808df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski funcName); 68098f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski } 68108f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski if (image_data) { 68118f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski auto aspect_mask = mem_barrier->subresourceRange.aspectMask; 6812e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis skip |= ValidateImageAspectMask(device_data, image_data->image, image_data->createInfo.format, aspect_mask, funcName); 681395b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski 681423c5a2092f724fef497a5c87a489f32c8fa51e58Petr Kraus std::string param_name = "pImageMemoryBarriers[" + std::to_string(i) + "].subresourceRange"; 6815e25e057866af155bd456003120aa6155530a0e5fPetr Kraus skip |= ValidateImageBarrierSubresourceRange(device_data, image_data, mem_barrier->subresourceRange, funcName, 6816e25e057866af155bd456003120aa6155530a0e5fPetr Kraus param_name.c_str()); 68175b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 68185b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 68192044b110851e8f1b75d6d406a0c88612476c63dbChris Forbes 68205b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t i = 0; i < bufferBarrierCount; ++i) { 68215b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis auto mem_barrier = &pBufferMemBarriers[i]; 6822cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (!mem_barrier) continue; 68235b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 6824d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis if (!ValidateAccessMaskPipelineStage(mem_barrier->srcAccessMask, src_stage_mask)) { 6825d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 6826d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis HandleToUint64(cb_state->commandBuffer), __LINE__, VALIDATION_ERROR_1b800940, "DS", 6827d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis "%s: pBufferMemBarriers[%d].srcAccessMask (0x%X) is not supported by srcStageMask (0x%X). %s", funcName, 6828d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis i, mem_barrier->srcAccessMask, src_stage_mask, validation_error_map[VALIDATION_ERROR_1b800940]); 6829d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis } 68301ce9b1e7d3dfd0841efede007022bdc960917008Tobin Ehlis if (!ValidateAccessMaskPipelineStage(mem_barrier->dstAccessMask, dst_stage_mask)) { 68311ce9b1e7d3dfd0841efede007022bdc960917008Tobin Ehlis skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 68321ce9b1e7d3dfd0841efede007022bdc960917008Tobin Ehlis HandleToUint64(cb_state->commandBuffer), __LINE__, VALIDATION_ERROR_1b800942, "DS", 68331ce9b1e7d3dfd0841efede007022bdc960917008Tobin Ehlis "%s: pBufferMemBarriers[%d].dstAccessMask (0x%X) is not supported by dstStageMask (0x%X). %s", funcName, 68341ce9b1e7d3dfd0841efede007022bdc960917008Tobin Ehlis i, mem_barrier->dstAccessMask, dst_stage_mask, validation_error_map[VALIDATION_ERROR_1b800942]); 68351ce9b1e7d3dfd0841efede007022bdc960917008Tobin Ehlis } 68365b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Validate buffer barrier queue family indices 68375b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if ((mem_barrier->srcQueueFamilyIndex != VK_QUEUE_FAMILY_IGNORED && 6838e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis mem_barrier->srcQueueFamilyIndex >= device_data->phys_dev_properties.queue_family_properties.size()) || 68395b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis (mem_barrier->dstQueueFamilyIndex != VK_QUEUE_FAMILY_IGNORED && 6840e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis mem_barrier->dstQueueFamilyIndex >= device_data->phys_dev_properties.queue_family_properties.size())) { 6841e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 6842e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis HandleToUint64(cb_state->commandBuffer), __LINE__, DRAWSTATE_INVALID_QUEUE_INDEX, "DS", 6843cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "%s: Buffer Barrier 0x%" PRIx64 6844cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski " has QueueFamilyIndex greater " 6845a4a1923d21087ded8e990190acd6752264712319Tobin Ehlis "than the number of QueueFamilies (" PRINTF_SIZE_T_SPECIFIER ") for this device.", 68469b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus funcName, HandleToUint64(mem_barrier->buffer), 6847e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis device_data->phys_dev_properties.queue_family_properties.size()); 68485b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 68495b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 6850e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis auto buffer_state = GetBufferState(device_data, mem_barrier->buffer); 68515cca7b0a90e0b6fe1cc28ddbe9037c3ce3f3ee13Tobin Ehlis if (buffer_state) { 68525cca7b0a90e0b6fe1cc28ddbe9037c3ce3f3ee13Tobin Ehlis auto buffer_size = buffer_state->requirements.size; 68535b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (mem_barrier->offset >= buffer_size) { 6854e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis skip |= log_msg( 6855e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 6856e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis HandleToUint64(cb_state->commandBuffer), __LINE__, DRAWSTATE_INVALID_BARRIER, "DS", 6857e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis "%s: Buffer Barrier 0x%" PRIx64 " has offset 0x%" PRIx64 " which is not less than total size 0x%" PRIx64 ".", 6858e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis funcName, HandleToUint64(mem_barrier->buffer), HandleToUint64(mem_barrier->offset), 6859e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis HandleToUint64(buffer_size)); 6860df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski } else if (mem_barrier->size != VK_WHOLE_SIZE && (mem_barrier->offset + mem_barrier->size > buffer_size)) { 6861df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski skip |= 6862e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 6863e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis HandleToUint64(cb_state->commandBuffer), __LINE__, DRAWSTATE_INVALID_BARRIER, "DS", 6864df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski "%s: Buffer Barrier 0x%" PRIx64 " has offset 0x%" PRIx64 " and size 0x%" PRIx64 6865df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski " whose sum is greater than total size 0x%" PRIx64 ".", 68669b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus funcName, HandleToUint64(mem_barrier->buffer), HandleToUint64(mem_barrier->offset), 68679b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(mem_barrier->size), HandleToUint64(buffer_size)); 68685b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 68695b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 68705b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 6871a4a1923d21087ded8e990190acd6752264712319Tobin Ehlis return skip; 68725b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 68735b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 6874bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinskibool validateEventStageMask(VkQueue queue, GLOBAL_CB_NODE *pCB, uint32_t eventCount, size_t firstEventIndex, 6875bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkPipelineStageFlags sourceStageMask) { 68763251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 6877b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine VkPipelineStageFlags stageMask = 0; 687856e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(queue), layer_data_map); 6879b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine for (uint32_t i = 0; i < eventCount; ++i) { 68802ab14387df9b890fe4b13494ea249dd03cf898d2Chris Forbes auto event = pCB->events[firstEventIndex + i]; 6881b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine auto queue_data = dev_data->queueMap.find(queue); 6882cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (queue_data == dev_data->queueMap.end()) return false; 68832ab14387df9b890fe4b13494ea249dd03cf898d2Chris Forbes auto event_data = queue_data->second.eventToStageMap.find(event); 6884b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine if (event_data != queue_data->second.eventToStageMap.end()) { 6885b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine stageMask |= event_data->second; 6886b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine } else { 68879a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto global_event_data = GetEventNode(dev_data, event); 68889556936067fd0c4eb74c4a13631bc163b154faedTobin Ehlis if (!global_event_data) { 68893251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT, 68909b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(event), __LINE__, DRAWSTATE_INVALID_EVENT, "DS", 68919b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "Event 0x%" PRIx64 " cannot be waited on if it has never been set.", HandleToUint64(event)); 6892b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine } else { 68939556936067fd0c4eb74c4a13631bc163b154faedTobin Ehlis stageMask |= global_event_data->stageMask; 6894b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine } 6895b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine } 6896b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine } 6897c1eb2a3736e03aaa15b849d217fd963021dc9780Michael Lentine // TODO: Need to validate that host_bit is only set if set event is called 6898c1eb2a3736e03aaa15b849d217fd963021dc9780Michael Lentine // but set event can be called at any time. 6899c1eb2a3736e03aaa15b849d217fd963021dc9780Michael Lentine if (sourceStageMask != stageMask && sourceStageMask != (stageMask | VK_PIPELINE_STAGE_HOST_BIT)) { 69003251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 6901315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pCB->commandBuffer), __LINE__, VALIDATION_ERROR_1e62d401, "DS", 69023251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Submitting cmdbuffer with call to VkCmdWaitEvents " 69033251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "using srcStageMask 0x%X which must be the bitwise " 69043251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "OR of the stageMask parameters used in calls to " 69053251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkCmdSetEvent and VK_PIPELINE_STAGE_HOST_BIT if " 69063251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "used with vkSetEvent but instead is 0x%X. %s", 6907315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis sourceStageMask, stageMask, validation_error_map[VALIDATION_ERROR_1e62d401]); 6908b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine } 69093251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 6910b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine} 6911b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine 691207059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski// Note that we only check bits that HAVE required queueflags -- don't care entries are skipped 691307059341a6ab09b3bd64727d2689082828492191Mark Lobodzinskistatic std::unordered_map<VkPipelineStageFlags, VkQueueFlags> supported_pipeline_stages_table = { 691407059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski {VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX, VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT}, 691507059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski {VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT}, 691607059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski {VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, VK_QUEUE_GRAPHICS_BIT}, 691707059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski {VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, VK_QUEUE_GRAPHICS_BIT}, 691807059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski {VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT, VK_QUEUE_GRAPHICS_BIT}, 691907059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski {VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT, VK_QUEUE_GRAPHICS_BIT}, 692007059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski {VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT, VK_QUEUE_GRAPHICS_BIT}, 692107059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski {VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_QUEUE_GRAPHICS_BIT}, 692207059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski {VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, VK_QUEUE_GRAPHICS_BIT}, 692307059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski {VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_QUEUE_GRAPHICS_BIT}, 692407059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_QUEUE_GRAPHICS_BIT}, 692507059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski {VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_QUEUE_COMPUTE_BIT}, 692607059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski {VK_PIPELINE_STAGE_TRANSFER_BIT, VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT}, 692707059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski {VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_QUEUE_GRAPHICS_BIT}}; 692807059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski 692907059341a6ab09b3bd64727d2689082828492191Mark Lobodzinskistatic const VkPipelineStageFlags stage_flag_bit_array[] = {VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX, 693007059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, 693107059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 693207059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 693307059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT, 693407059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT, 693507059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT, 693607059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 693707059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, 693807059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 693907059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 694007059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 694107059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski VK_PIPELINE_STAGE_TRANSFER_BIT, 694207059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT}; 694307059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski 694407059341a6ab09b3bd64727d2689082828492191Mark Lobodzinskibool CheckStageMaskQueueCompatibility(layer_data *dev_data, VkCommandBuffer command_buffer, VkPipelineStageFlags stage_mask, 694507059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski VkQueueFlags queue_flags, const char *function, const char *src_or_dest, 694607059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski UNIQUE_VALIDATION_ERROR_CODE error_code) { 694707059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski bool skip = false; 694807059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski // Lookup each bit in the stagemask and check for overlap between its table bits and queue_flags 694907059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski for (const auto &item : stage_flag_bit_array) { 695007059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski if (stage_mask & item) { 695107059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski if ((supported_pipeline_stages_table[item] & queue_flags) == 0) { 695207059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski skip |= 695307059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 69549b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(command_buffer), __LINE__, error_code, "DL", 695507059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski "%s(): %s flag %s is not compatible with the queue family properties of this " 695607059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski "command buffer. %s", 695707059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski function, src_or_dest, string_VkPipelineStageFlagBits(static_cast<VkPipelineStageFlagBits>(item)), 695807059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski validation_error_map[error_code]); 695907059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski } 696007059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski } 696107059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski } 696207059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski return skip; 696307059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski} 696407059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski 6965e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlisbool ValidateStageMasksAgainstQueueCapabilities(layer_data *dev_data, GLOBAL_CB_NODE const *cb_state, 696607059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski VkPipelineStageFlags source_stage_mask, VkPipelineStageFlags dest_stage_mask, 696707059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski const char *function, UNIQUE_VALIDATION_ERROR_CODE error_code) { 696807059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski bool skip = false; 696907059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski uint32_t queue_family_index = dev_data->commandPoolMap[cb_state->createInfo.commandPool].queueFamilyIndex; 697056e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(dev_data->physical_device), instance_layer_data_map); 69719a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto physical_device_state = GetPhysicalDeviceState(instance_data, dev_data->physical_device); 697207059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski 697307059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski // Any pipeline stage included in srcStageMask or dstStageMask must be supported by the capabilities of the queue family 697407059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski // specified by the queueFamilyIndex member of the VkCommandPoolCreateInfo structure that was used to create the VkCommandPool 697507059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski // that commandBuffer was allocated from, as specified in the table of supported pipeline stages. 697607059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski 697707059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski if (queue_family_index < physical_device_state->queue_family_properties.size()) { 697807059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski VkQueueFlags specified_queue_flags = physical_device_state->queue_family_properties[queue_family_index].queueFlags; 697907059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski 698007059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski if ((source_stage_mask & VK_PIPELINE_STAGE_ALL_COMMANDS_BIT) == 0) { 698107059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski skip |= CheckStageMaskQueueCompatibility(dev_data, cb_state->commandBuffer, source_stage_mask, specified_queue_flags, 698207059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski function, "srcStageMask", error_code); 698307059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski } 698407059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski if ((dest_stage_mask & VK_PIPELINE_STAGE_ALL_COMMANDS_BIT) == 0) { 698507059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski skip |= CheckStageMaskQueueCompatibility(dev_data, cb_state->commandBuffer, dest_stage_mask, specified_queue_flags, 698607059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski function, "dstStageMask", error_code); 698707059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski } 698807059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski } 698907059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski return skip; 699007059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski} 699107059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski 6992d91b0b35cff4dc73d88fcf4ea567bd37997bbd98Mark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdWaitEvents(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents, 6993d91b0b35cff4dc73d88fcf4ea567bd37997bbd98Mark Lobodzinski VkPipelineStageFlags sourceStageMask, VkPipelineStageFlags dstStageMask, 6994d91b0b35cff4dc73d88fcf4ea567bd37997bbd98Mark Lobodzinski uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers, 6995d91b0b35cff4dc73d88fcf4ea567bd37997bbd98Mark Lobodzinski uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier *pBufferMemoryBarriers, 6996d91b0b35cff4dc73d88fcf4ea567bd37997bbd98Mark Lobodzinski uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier *pImageMemoryBarriers) { 6997d91b0b35cff4dc73d88fcf4ea567bd37997bbd98Mark Lobodzinski bool skip = false; 699856e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 6999ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 70009a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *cb_state = GetCBNode(dev_data, commandBuffer); 7001d91b0b35cff4dc73d88fcf4ea567bd37997bbd98Mark Lobodzinski if (cb_state) { 7002d91b0b35cff4dc73d88fcf4ea567bd37997bbd98Mark Lobodzinski skip |= ValidateStageMasksAgainstQueueCapabilities(dev_data, cb_state, sourceStageMask, dstStageMask, "vkCmdWaitEvents", 7003315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1e600918); 7004315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateStageMaskGsTsEnables(dev_data, sourceStageMask, "vkCmdWaitEvents()", VALIDATION_ERROR_1e60090e, 7005315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1e600912); 7006315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateStageMaskGsTsEnables(dev_data, dstStageMask, "vkCmdWaitEvents()", VALIDATION_ERROR_1e600910, 7007315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1e600914); 7008baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt skip |= ValidateCmdQueueFlags(dev_data, cb_state, "vkCmdWaitEvents()", VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, 7009315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1e602415); 7010ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski skip |= ValidateCmd(dev_data, cb_state, CMD_WAITEVENTS, "vkCmdWaitEvents()"); 7011e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis skip |= ValidateBarriersToImages(dev_data, cb_state, imageMemoryBarrierCount, pImageMemoryBarriers, "vkCmdWaitEvents()"); 7012e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis skip |= ValidateBarriers(dev_data, "vkCmdWaitEvents()", cb_state, sourceStageMask, dstStageMask, memoryBarrierCount, 7013e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, 7014e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis pImageMemoryBarriers); 701557cd2a36adb056c73dbea3ab898b092123c2a2c1Chris Forbes if (!skip) { 701657cd2a36adb056c73dbea3ab898b092123c2a2c1Chris Forbes auto first_event_index = cb_state->events.size(); 701757cd2a36adb056c73dbea3ab898b092123c2a2c1Chris Forbes for (uint32_t i = 0; i < eventCount; ++i) { 701857cd2a36adb056c73dbea3ab898b092123c2a2c1Chris Forbes auto event_state = GetEventNode(dev_data, pEvents[i]); 701957cd2a36adb056c73dbea3ab898b092123c2a2c1Chris Forbes if (event_state) { 702057cd2a36adb056c73dbea3ab898b092123c2a2c1Chris Forbes addCommandBufferBinding(&event_state->cb_bindings, {HandleToUint64(pEvents[i]), kVulkanObjectTypeEvent}, cb_state); 702157cd2a36adb056c73dbea3ab898b092123c2a2c1Chris Forbes event_state->cb_bindings.insert(cb_state); 702257cd2a36adb056c73dbea3ab898b092123c2a2c1Chris Forbes } 702357cd2a36adb056c73dbea3ab898b092123c2a2c1Chris Forbes cb_state->waitedEvents.insert(pEvents[i]); 702457cd2a36adb056c73dbea3ab898b092123c2a2c1Chris Forbes cb_state->events.push_back(pEvents[i]); 702557cd2a36adb056c73dbea3ab898b092123c2a2c1Chris Forbes } 702657cd2a36adb056c73dbea3ab898b092123c2a2c1Chris Forbes cb_state->eventUpdates.emplace_back([=](VkQueue q){ 702757cd2a36adb056c73dbea3ab898b092123c2a2c1Chris Forbes return validateEventStageMask(q, cb_state, eventCount, first_event_index, sourceStageMask); 702857cd2a36adb056c73dbea3ab898b092123c2a2c1Chris Forbes }); 702957cd2a36adb056c73dbea3ab898b092123c2a2c1Chris Forbes TransitionImageLayouts(dev_data, commandBuffer, imageMemoryBarrierCount, pImageMemoryBarriers); 703057cd2a36adb056c73dbea3ab898b092123c2a2c1Chris Forbes } 70315b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 7032b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 7033d91b0b35cff4dc73d88fcf4ea567bd37997bbd98Mark Lobodzinski if (!skip) 70344a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.CmdWaitEvents(commandBuffer, eventCount, pEvents, sourceStageMask, dstStageMask, 70354a0754042cf090e131e9e769d8a3633c228625beChris Forbes memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers, 70364a0754042cf090e131e9e769d8a3633c228625beChris Forbes imageMemoryBarrierCount, pImageMemoryBarriers); 70375b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 70385b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 7039f384f33742c2b72888372332747298d08135ac92Tobin Ehlisstatic bool PreCallValidateCmdPipelineBarrier(layer_data *device_data, GLOBAL_CB_NODE *cb_state, VkPipelineStageFlags srcStageMask, 7040f384f33742c2b72888372332747298d08135ac92Tobin Ehlis VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags, 7041f384f33742c2b72888372332747298d08135ac92Tobin Ehlis uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers, 7042f384f33742c2b72888372332747298d08135ac92Tobin Ehlis uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier *pBufferMemoryBarriers, 7043f384f33742c2b72888372332747298d08135ac92Tobin Ehlis uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier *pImageMemoryBarriers) { 704403122452370ba372b7fb62eaad6ef56a963b3fb0Mark Lobodzinski bool skip = false; 704503122452370ba372b7fb62eaad6ef56a963b3fb0Mark Lobodzinski skip |= ValidateStageMasksAgainstQueueCapabilities(device_data, cb_state, srcStageMask, dstStageMask, "vkCmdPipelineBarrier", 7046315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1b80093e); 7047baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt skip |= ValidateCmdQueueFlags(device_data, cb_state, "vkCmdPipelineBarrier()", 7048315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VK_QUEUE_TRANSFER_BIT | VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, VALIDATION_ERROR_1b802415); 704903122452370ba372b7fb62eaad6ef56a963b3fb0Mark Lobodzinski skip |= ValidateCmd(device_data, cb_state, CMD_PIPELINEBARRIER, "vkCmdPipelineBarrier()"); 7050315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateStageMaskGsTsEnables(device_data, srcStageMask, "vkCmdPipelineBarrier()", VALIDATION_ERROR_1b800920, 7051315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1b800924); 7052315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateStageMaskGsTsEnables(device_data, dstStageMask, "vkCmdPipelineBarrier()", VALIDATION_ERROR_1b800922, 7053315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1b800926); 7054e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis if (cb_state->activeRenderPass) { 7055e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis skip |= ValidateRenderPassPipelineBarriers(device_data, "vkCmdPipelineBarrier()", cb_state, srcStageMask, dstStageMask, 7056c1c43cc01e333f3762c65ce4ad926c33235583d2Tobin Ehlis dependencyFlags, memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, 7057e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers); 7058a287b10c55baa7d2d2ac891eb729666f988766eaTobin Ehlis if (skip) return true; // Early return to avoid redundant errors from below calls 7059e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis } 7060a287b10c55baa7d2d2ac891eb729666f988766eaTobin Ehlis skip |= 7061a287b10c55baa7d2d2ac891eb729666f988766eaTobin Ehlis ValidateBarriersToImages(device_data, cb_state, imageMemoryBarrierCount, pImageMemoryBarriers, "vkCmdPipelineBarrier()"); 7062e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis skip |= ValidateBarriers(device_data, "vkCmdPipelineBarrier()", cb_state, srcStageMask, dstStageMask, memoryBarrierCount, 7063e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, 7064e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis pImageMemoryBarriers); 706503122452370ba372b7fb62eaad6ef56a963b3fb0Mark Lobodzinski return skip; 706603122452370ba372b7fb62eaad6ef56a963b3fb0Mark Lobodzinski} 706703122452370ba372b7fb62eaad6ef56a963b3fb0Mark Lobodzinski 70686f88609b0b59259ed29581f1d824ee5e9d7c82ccMark Lobodzinskistatic void PreCallRecordCmdPipelineBarrier(layer_data *device_data, GLOBAL_CB_NODE *cb_state, VkCommandBuffer commandBuffer, 70696f88609b0b59259ed29581f1d824ee5e9d7c82ccMark Lobodzinski uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier *pImageMemoryBarriers) { 70706f88609b0b59259ed29581f1d824ee5e9d7c82ccMark Lobodzinski TransitionImageLayouts(device_data, commandBuffer, imageMemoryBarrierCount, pImageMemoryBarriers); 70716f88609b0b59259ed29581f1d824ee5e9d7c82ccMark Lobodzinski} 70726f88609b0b59259ed29581f1d824ee5e9d7c82ccMark Lobodzinski 7073d91b0b35cff4dc73d88fcf4ea567bd37997bbd98Mark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdPipelineBarrier(VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask, 7074d91b0b35cff4dc73d88fcf4ea567bd37997bbd98Mark Lobodzinski VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags, 7075d91b0b35cff4dc73d88fcf4ea567bd37997bbd98Mark Lobodzinski uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers, 7076d91b0b35cff4dc73d88fcf4ea567bd37997bbd98Mark Lobodzinski uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier *pBufferMemoryBarriers, 7077d91b0b35cff4dc73d88fcf4ea567bd37997bbd98Mark Lobodzinski uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier *pImageMemoryBarriers) { 7078d91b0b35cff4dc73d88fcf4ea567bd37997bbd98Mark Lobodzinski bool skip = false; 70796f88609b0b59259ed29581f1d824ee5e9d7c82ccMark Lobodzinski layer_data *device_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 7080ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 70816f88609b0b59259ed29581f1d824ee5e9d7c82ccMark Lobodzinski GLOBAL_CB_NODE *cb_state = GetCBNode(device_data, commandBuffer); 7082d91b0b35cff4dc73d88fcf4ea567bd37997bbd98Mark Lobodzinski if (cb_state) { 7083c1c43cc01e333f3762c65ce4ad926c33235583d2Tobin Ehlis skip |= PreCallValidateCmdPipelineBarrier(device_data, cb_state, srcStageMask, dstStageMask, dependencyFlags, 7084c1c43cc01e333f3762c65ce4ad926c33235583d2Tobin Ehlis memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, 7085c1c43cc01e333f3762c65ce4ad926c33235583d2Tobin Ehlis pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers); 70866f88609b0b59259ed29581f1d824ee5e9d7c82ccMark Lobodzinski if (!skip) { 70876f88609b0b59259ed29581f1d824ee5e9d7c82ccMark Lobodzinski PreCallRecordCmdPipelineBarrier(device_data, cb_state, commandBuffer, imageMemoryBarrierCount, pImageMemoryBarriers); 70886f88609b0b59259ed29581f1d824ee5e9d7c82ccMark Lobodzinski } 70896f88609b0b59259ed29581f1d824ee5e9d7c82ccMark Lobodzinski } else { 70906f88609b0b59259ed29581f1d824ee5e9d7c82ccMark Lobodzinski assert(0); 70915b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 7092b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 7093a79957f762f6fc6b74c25cb94d35a3fc36967471Tony Barbour if (!skip) { 7094a79957f762f6fc6b74c25cb94d35a3fc36967471Tony Barbour device_data->dispatch_table.CmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags, memoryBarrierCount, 7095a79957f762f6fc6b74c25cb94d35a3fc36967471Tony Barbour pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers, 7096a79957f762f6fc6b74c25cb94d35a3fc36967471Tony Barbour imageMemoryBarrierCount, pImageMemoryBarriers); 7097a79957f762f6fc6b74c25cb94d35a3fc36967471Tony Barbour } 70985b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 70995b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 710043ec3f090ca979777b306abe7c25662b9429e06dChris Forbesstatic bool setQueryState(VkQueue queue, VkCommandBuffer commandBuffer, QueryObject object, bool value) { 710156e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 71029a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); 7103d78749ee260a3ce7244cbfd97c11aacc2250f8d3Michael Lentine if (pCB) { 7104d78749ee260a3ce7244cbfd97c11aacc2250f8d3Michael Lentine pCB->queryToStateMap[object] = value; 7105d78749ee260a3ce7244cbfd97c11aacc2250f8d3Michael Lentine } 7106d78749ee260a3ce7244cbfd97c11aacc2250f8d3Michael Lentine auto queue_data = dev_data->queueMap.find(queue); 7107d78749ee260a3ce7244cbfd97c11aacc2250f8d3Michael Lentine if (queue_data != dev_data->queueMap.end()) { 7108d78749ee260a3ce7244cbfd97c11aacc2250f8d3Michael Lentine queue_data->second.queryToStateMap[object] = value; 7109d78749ee260a3ce7244cbfd97c11aacc2250f8d3Michael Lentine } 7110d78749ee260a3ce7244cbfd97c11aacc2250f8d3Michael Lentine return false; 7111d78749ee260a3ce7244cbfd97c11aacc2250f8d3Michael Lentine} 7112d78749ee260a3ce7244cbfd97c11aacc2250f8d3Michael Lentine 7113bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdBeginQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t slot, VkFlags flags) { 71143251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 711556e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 7116ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 71179a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); 71185b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pCB) { 71193251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateCmdQueueFlags(dev_data, pCB, "vkCmdBeginQuery()", VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, 7120315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_17802415); 71213251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateCmd(dev_data, pCB, CMD_BEGINQUERY, "vkCmdBeginQuery()"); 712243ec3f090ca979777b306abe7c25662b9429e06dChris Forbes } 712343ec3f090ca979777b306abe7c25662b9429e06dChris Forbes lock.unlock(); 712443ec3f090ca979777b306abe7c25662b9429e06dChris Forbes 712543ec3f090ca979777b306abe7c25662b9429e06dChris Forbes if (skip) return; 712643ec3f090ca979777b306abe7c25662b9429e06dChris Forbes 712743ec3f090ca979777b306abe7c25662b9429e06dChris Forbes dev_data->dispatch_table.CmdBeginQuery(commandBuffer, queryPool, slot, flags); 712843ec3f090ca979777b306abe7c25662b9429e06dChris Forbes 712943ec3f090ca979777b306abe7c25662b9429e06dChris Forbes lock.lock(); 713043ec3f090ca979777b306abe7c25662b9429e06dChris Forbes if (pCB) { 713143ec3f090ca979777b306abe7c25662b9429e06dChris Forbes QueryObject query = {queryPool, slot}; 713243ec3f090ca979777b306abe7c25662b9429e06dChris Forbes pCB->activeQueries.insert(query); 713343ec3f090ca979777b306abe7c25662b9429e06dChris Forbes pCB->startedQueries.insert(query); 71349a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis addCommandBufferBinding(&GetQueryPoolNode(dev_data, queryPool)->cb_bindings, 71359b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus {HandleToUint64(queryPool), kVulkanObjectTypeQueryPool}, pCB); 71365b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 71375b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 71385b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 713989d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR void VKAPI_CALL CmdEndQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t slot) { 7140946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski bool skip = false; 714156e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 7142ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 7143e17228238940d38a82570bc5b0ed4dd44e4cbd6dChris Forbes QueryObject query = {queryPool, slot}; 7144946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski GLOBAL_CB_NODE *cb_state = GetCBNode(dev_data, commandBuffer); 7145946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski if (cb_state) { 7146946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski if (!cb_state->activeQueries.count(query)) { 7147df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 7148315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(commandBuffer), __LINE__, VALIDATION_ERROR_1ae00652, "DS", 71499b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "Ending a query before it was started: queryPool 0x%" PRIx64 ", index %d. %s", 7150315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(queryPool), slot, validation_error_map[VALIDATION_ERROR_1ae00652]); 71515b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 7152baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt skip |= ValidateCmdQueueFlags(dev_data, cb_state, "VkCmdEndQuery()", VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, 7153315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1ae02415); 7154946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski skip |= ValidateCmd(dev_data, cb_state, CMD_ENDQUERY, "VkCmdEndQuery()"); 7155e17228238940d38a82570bc5b0ed4dd44e4cbd6dChris Forbes } 7156e17228238940d38a82570bc5b0ed4dd44e4cbd6dChris Forbes lock.unlock(); 7157e17228238940d38a82570bc5b0ed4dd44e4cbd6dChris Forbes 7158e17228238940d38a82570bc5b0ed4dd44e4cbd6dChris Forbes if (skip) return; 7159e17228238940d38a82570bc5b0ed4dd44e4cbd6dChris Forbes 7160e17228238940d38a82570bc5b0ed4dd44e4cbd6dChris Forbes dev_data->dispatch_table.CmdEndQuery(commandBuffer, queryPool, slot); 7161e17228238940d38a82570bc5b0ed4dd44e4cbd6dChris Forbes 7162e17228238940d38a82570bc5b0ed4dd44e4cbd6dChris Forbes lock.lock(); 7163e17228238940d38a82570bc5b0ed4dd44e4cbd6dChris Forbes if (cb_state) { 7164e17228238940d38a82570bc5b0ed4dd44e4cbd6dChris Forbes cb_state->activeQueries.erase(query); 7165e17228238940d38a82570bc5b0ed4dd44e4cbd6dChris Forbes cb_state->queryUpdates.emplace_back([=](VkQueue q){return setQueryState(q, commandBuffer, query, true);}); 71669a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis addCommandBufferBinding(&GetQueryPoolNode(dev_data, queryPool)->cb_bindings, 71679b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus {HandleToUint64(queryPool), kVulkanObjectTypeQueryPool}, cb_state); 71685b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 71695b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 71705b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 7171bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdResetQueryPool(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, 7172bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski uint32_t queryCount) { 7173946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski bool skip = false; 717456e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 7175ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 7176946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski GLOBAL_CB_NODE *cb_state = GetCBNode(dev_data, commandBuffer); 71773a4c679ed508b10fd119bb97c127c79b5d126d74Chris Forbes skip |= insideRenderPass(dev_data, cb_state, "vkCmdResetQueryPool()", VALIDATION_ERROR_1c600017); 71783a4c679ed508b10fd119bb97c127c79b5d126d74Chris Forbes skip |= ValidateCmd(dev_data, cb_state, CMD_RESETQUERYPOOL, "VkCmdResetQueryPool()"); 7179baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt skip |= ValidateCmdQueueFlags(dev_data, cb_state, "VkCmdResetQueryPool()", VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, 7180315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1c602415); 7181b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 71823a4c679ed508b10fd119bb97c127c79b5d126d74Chris Forbes 71833a4c679ed508b10fd119bb97c127c79b5d126d74Chris Forbes if (skip) return; 71843a4c679ed508b10fd119bb97c127c79b5d126d74Chris Forbes 71853a4c679ed508b10fd119bb97c127c79b5d126d74Chris Forbes dev_data->dispatch_table.CmdResetQueryPool(commandBuffer, queryPool, firstQuery, queryCount); 71863a4c679ed508b10fd119bb97c127c79b5d126d74Chris Forbes 71873a4c679ed508b10fd119bb97c127c79b5d126d74Chris Forbes lock.lock(); 71883a4c679ed508b10fd119bb97c127c79b5d126d74Chris Forbes for (uint32_t i = 0; i < queryCount; i++) { 71893a4c679ed508b10fd119bb97c127c79b5d126d74Chris Forbes QueryObject query = {queryPool, firstQuery + i}; 71903a4c679ed508b10fd119bb97c127c79b5d126d74Chris Forbes cb_state->waitedEventsBeforeQueryReset[query] = cb_state->waitedEvents; 7191f49bd2b5f4c968a3033b3e5099bbbcff51201575Chris Forbes cb_state->queryUpdates.emplace_back([=](VkQueue q){return setQueryState(q, commandBuffer, query, false);}); 71923a4c679ed508b10fd119bb97c127c79b5d126d74Chris Forbes } 71933a4c679ed508b10fd119bb97c127c79b5d126d74Chris Forbes addCommandBufferBinding(&GetQueryPoolNode(dev_data, queryPool)->cb_bindings, 71943a4c679ed508b10fd119bb97c127c79b5d126d74Chris Forbes {HandleToUint64(queryPool), kVulkanObjectTypeQueryPool}, cb_state); 71955b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 71965b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 71977ffbe89a37f5f822858a35646be0213fd2cd2b08Chris Forbesstatic bool IsQueryInvalid(layer_data *dev_data, QUEUE_STATE *queue_data, VkQueryPool queryPool, uint32_t queryIndex) { 71987ffbe89a37f5f822858a35646be0213fd2cd2b08Chris Forbes QueryObject query = {queryPool, queryIndex}; 71997ffbe89a37f5f822858a35646be0213fd2cd2b08Chris Forbes auto query_data = queue_data->queryToStateMap.find(query); 72007ffbe89a37f5f822858a35646be0213fd2cd2b08Chris Forbes if (query_data != queue_data->queryToStateMap.end()) { 72017ffbe89a37f5f822858a35646be0213fd2cd2b08Chris Forbes if (!query_data->second) return true; 72027ffbe89a37f5f822858a35646be0213fd2cd2b08Chris Forbes } else { 72037ffbe89a37f5f822858a35646be0213fd2cd2b08Chris Forbes auto it = dev_data->queryToStateMap.find(query); 72047ffbe89a37f5f822858a35646be0213fd2cd2b08Chris Forbes if (it == dev_data->queryToStateMap.end() || !it->second) 72057ffbe89a37f5f822858a35646be0213fd2cd2b08Chris Forbes return true; 72067ffbe89a37f5f822858a35646be0213fd2cd2b08Chris Forbes } 72077ffbe89a37f5f822858a35646be0213fd2cd2b08Chris Forbes 72087ffbe89a37f5f822858a35646be0213fd2cd2b08Chris Forbes return false; 72097ffbe89a37f5f822858a35646be0213fd2cd2b08Chris Forbes} 72107ffbe89a37f5f822858a35646be0213fd2cd2b08Chris Forbes 72117ffbe89a37f5f822858a35646be0213fd2cd2b08Chris Forbesstatic bool validateQuery(VkQueue queue, GLOBAL_CB_NODE *pCB, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount) { 72123251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 721356e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(pCB->commandBuffer), layer_data_map); 72147ffbe89a37f5f822858a35646be0213fd2cd2b08Chris Forbes auto queue_data = GetQueueState(dev_data, queue); 72157ffbe89a37f5f822858a35646be0213fd2cd2b08Chris Forbes if (!queue_data) return false; 7216d78749ee260a3ce7244cbfd97c11aacc2250f8d3Michael Lentine for (uint32_t i = 0; i < queryCount; i++) { 72177ffbe89a37f5f822858a35646be0213fd2cd2b08Chris Forbes if (IsQueryInvalid(dev_data, queue_data, queryPool, firstQuery + i)) { 72183251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 72199b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pCB->commandBuffer), __LINE__, DRAWSTATE_INVALID_QUERY, "DS", 72203251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Requesting a copy from query to buffer with invalid query: queryPool 0x%" PRIx64 ", index %d", 72219b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(queryPool), firstQuery + i); 7222d78749ee260a3ce7244cbfd97c11aacc2250f8d3Michael Lentine } 7223d78749ee260a3ce7244cbfd97c11aacc2250f8d3Michael Lentine } 72243251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 7225d78749ee260a3ce7244cbfd97c11aacc2250f8d3Michael Lentine} 7226d78749ee260a3ce7244cbfd97c11aacc2250f8d3Michael Lentine 7227bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdCopyQueryPoolResults(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, 7228bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski uint32_t queryCount, VkBuffer dstBuffer, VkDeviceSize dstOffset, 7229bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkDeviceSize stride, VkQueryResultFlags flags) { 7230946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski bool skip = false; 723156e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 7232ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 7233ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis 72349a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto cb_node = GetCBNode(dev_data, commandBuffer); 72359a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto dst_buff_state = GetBufferState(dev_data, dstBuffer); 72365cca7b0a90e0b6fe1cc28ddbe9037c3ce3f3ee13Tobin Ehlis if (cb_node && dst_buff_state) { 7237315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateMemoryIsBoundToBuffer(dev_data, dst_buff_state, "vkCmdCopyQueryPoolResults()", VALIDATION_ERROR_19400674); 7238ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis // Validate that DST buffer has correct usage flags set 7239315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= 7240315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis ValidateBufferUsageFlags(dev_data, dst_buff_state, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true, VALIDATION_ERROR_19400672, 7241315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis "vkCmdCopyQueryPoolResults()", "VK_BUFFER_USAGE_TRANSFER_DST_BIT"); 72424d285deca53ab503c0c9eb65ba1c4fb711138d7cChris Forbes skip |= ValidateCmdQueueFlags(dev_data, cb_node, "vkCmdCopyQueryPoolResults()", 72434d285deca53ab503c0c9eb65ba1c4fb711138d7cChris Forbes VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, VALIDATION_ERROR_19402415); 72444d285deca53ab503c0c9eb65ba1c4fb711138d7cChris Forbes skip |= ValidateCmd(dev_data, cb_node, CMD_COPYQUERYPOOLRESULTS, "vkCmdCopyQueryPoolResults()"); 72454d285deca53ab503c0c9eb65ba1c4fb711138d7cChris Forbes skip |= insideRenderPass(dev_data, cb_node, "vkCmdCopyQueryPoolResults()", VALIDATION_ERROR_19400017); 72464d285deca53ab503c0c9eb65ba1c4fb711138d7cChris Forbes } 72474d285deca53ab503c0c9eb65ba1c4fb711138d7cChris Forbes lock.unlock(); 72484d285deca53ab503c0c9eb65ba1c4fb711138d7cChris Forbes 72494d285deca53ab503c0c9eb65ba1c4fb711138d7cChris Forbes if (skip) return; 72504d285deca53ab503c0c9eb65ba1c4fb711138d7cChris Forbes 72514d285deca53ab503c0c9eb65ba1c4fb711138d7cChris Forbes dev_data->dispatch_table.CmdCopyQueryPoolResults(commandBuffer, queryPool, firstQuery, queryCount, dstBuffer, dstOffset, 72524d285deca53ab503c0c9eb65ba1c4fb711138d7cChris Forbes stride, flags); 72534d285deca53ab503c0c9eb65ba1c4fb711138d7cChris Forbes 72544d285deca53ab503c0c9eb65ba1c4fb711138d7cChris Forbes lock.lock(); 72554d285deca53ab503c0c9eb65ba1c4fb711138d7cChris Forbes if (cb_node && dst_buff_state) { 72564d285deca53ab503c0c9eb65ba1c4fb711138d7cChris Forbes AddCommandBufferBindingBuffer(dev_data, cb_node, dst_buff_state); 7257d807198f24437c1b2478ff1d06a33ce4873a1451Tobin Ehlis cb_node->queue_submit_functions.emplace_back([=]() { 72585cca7b0a90e0b6fe1cc28ddbe9037c3ce3f3ee13Tobin Ehlis SetBufferMemoryValid(dev_data, dst_buff_state, true); 7259e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves return false; 72604d285deca53ab503c0c9eb65ba1c4fb711138d7cChris Forbes }); 7261f49bd2b5f4c968a3033b3e5099bbbcff51201575Chris Forbes cb_node->queryUpdates.emplace_back([=](VkQueue q) { 7262f49bd2b5f4c968a3033b3e5099bbbcff51201575Chris Forbes return validateQuery(q, cb_node, queryPool, firstQuery, queryCount); 7263f49bd2b5f4c968a3033b3e5099bbbcff51201575Chris Forbes }); 72649a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis addCommandBufferBinding(&GetQueryPoolNode(dev_data, queryPool)->cb_bindings, 72659b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus {HandleToUint64(queryPool), kVulkanObjectTypeQueryPool}, cb_node); 72665b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 72675b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 72685b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 7269bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdPushConstants(VkCommandBuffer commandBuffer, VkPipelineLayout layout, VkShaderStageFlags stageFlags, 7270bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski uint32_t offset, uint32_t size, const void *pValues) { 7271946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski bool skip = false; 727256e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 7273ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 7274946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski GLOBAL_CB_NODE *cb_state = GetCBNode(dev_data, commandBuffer); 7275946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski if (cb_state) { 7276baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt skip |= ValidateCmdQueueFlags(dev_data, cb_state, "vkCmdPushConstants()", VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, 7277315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1bc02415); 7278946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski skip |= ValidateCmd(dev_data, cb_state, CMD_PUSHCONSTANTS, "vkCmdPushConstants()"); 72795b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 7280946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski skip |= validatePushConstantRange(dev_data, offset, size, "vkCmdPushConstants()"); 72819e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz if (0 == stageFlags) { 7282df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 7283315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(commandBuffer), __LINE__, VALIDATION_ERROR_1bc2dc03, "DS", 7284315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis "vkCmdPushConstants() call has no stageFlags set. %s", validation_error_map[VALIDATION_ERROR_1bc2dc03]); 72859e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz } 72869e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz 7287bf0fa2ad7830118e59f0fb8ff88efae18a72e833Karl Schultz // Check if specified push constant range falls within a pipeline-defined range which has matching stageFlags. 7288bf0fa2ad7830118e59f0fb8ff88efae18a72e833Karl Schultz // The spec doesn't seem to disallow having multiple push constant ranges with the 7289bf0fa2ad7830118e59f0fb8ff88efae18a72e833Karl Schultz // same offset and size, but different stageFlags. So we can't just check the 7290bf0fa2ad7830118e59f0fb8ff88efae18a72e833Karl Schultz // stageFlags in the first range with matching offset and size. 7291bf0fa2ad7830118e59f0fb8ff88efae18a72e833Karl Schultz if (!skip) { 7292bf0fa2ad7830118e59f0fb8ff88efae18a72e833Karl Schultz const auto &ranges = getPipelineLayout(dev_data, layout)->push_constant_ranges; 7293bf0fa2ad7830118e59f0fb8ff88efae18a72e833Karl Schultz bool found_matching_range = false; 7294bf0fa2ad7830118e59f0fb8ff88efae18a72e833Karl Schultz for (const auto &range : ranges) { 7295bf0fa2ad7830118e59f0fb8ff88efae18a72e833Karl Schultz if ((stageFlags == range.stageFlags) && (offset >= range.offset) && (offset + size <= range.offset + range.size)) { 7296bf0fa2ad7830118e59f0fb8ff88efae18a72e833Karl Schultz found_matching_range = true; 729715a574466ede280b595c451ad52f2b7b18f20b2dTobin Ehlis break; 7298a95cb74c9d0947ab3821b15e1289755286ea78eeKarl Schultz } 72999e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz } 7300bf0fa2ad7830118e59f0fb8ff88efae18a72e833Karl Schultz if (!found_matching_range) { 7301315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 7302315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(commandBuffer), __LINE__, VALIDATION_ERROR_1bc002de, "DS", 7303315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis "vkCmdPushConstants() stageFlags = 0x%" PRIx32 7304315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis " do not match the stageFlags in any of the ranges with" 7305315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis " offset = %d and size = %d in pipeline layout 0x%" PRIx64 ". %s", 7306315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis (uint32_t)stageFlags, offset, size, HandleToUint64(layout), 7307315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_1bc002de]); 730815a574466ede280b595c451ad52f2b7b18f20b2dTobin Ehlis } 73095b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 7310b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 7311946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski if (!skip) dev_data->dispatch_table.CmdPushConstants(commandBuffer, layout, stageFlags, offset, size, pValues); 73125b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 73135b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 7314bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdWriteTimestamp(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage, 7315bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkQueryPool queryPool, uint32_t slot) { 7316946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski bool skip = false; 731756e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 7318ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 7319946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski GLOBAL_CB_NODE *cb_state = GetCBNode(dev_data, commandBuffer); 7320946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski if (cb_state) { 7321baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt skip |= ValidateCmdQueueFlags(dev_data, cb_state, "vkCmdWriteTimestamp()", VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, 7322315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1e802415); 7323946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski skip |= ValidateCmd(dev_data, cb_state, CMD_WRITETIMESTAMP, "vkCmdWriteTimestamp()"); 73245b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 7325b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 73266eff586acc3c02decfb0c3af269693252efc8ef8Chris Forbes 73276eff586acc3c02decfb0c3af269693252efc8ef8Chris Forbes if (skip) return; 73286eff586acc3c02decfb0c3af269693252efc8ef8Chris Forbes 73296eff586acc3c02decfb0c3af269693252efc8ef8Chris Forbes dev_data->dispatch_table.CmdWriteTimestamp(commandBuffer, pipelineStage, queryPool, slot); 73306eff586acc3c02decfb0c3af269693252efc8ef8Chris Forbes 73316eff586acc3c02decfb0c3af269693252efc8ef8Chris Forbes lock.lock(); 73326eff586acc3c02decfb0c3af269693252efc8ef8Chris Forbes if (cb_state) { 73336eff586acc3c02decfb0c3af269693252efc8ef8Chris Forbes QueryObject query = {queryPool, slot}; 73346eff586acc3c02decfb0c3af269693252efc8ef8Chris Forbes cb_state->queryUpdates.emplace_back([=](VkQueue q) {return setQueryState(q, commandBuffer, query, true);}); 73356eff586acc3c02decfb0c3af269693252efc8ef8Chris Forbes } 73365b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 73375b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 73386600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinskistatic bool MatchUsage(layer_data *dev_data, uint32_t count, const VkAttachmentReference *attachments, 73399bd94c6fc216a1d67d5e98542519002fa56d19dbMike Schuchardt const VkFramebufferCreateInfo *fbci, VkImageUsageFlagBits usage_flag, 73409bd94c6fc216a1d67d5e98542519002fa56d19dbMike Schuchardt UNIQUE_VALIDATION_ERROR_CODE error_code) { 7341946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski bool skip = false; 73426600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski 73436600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski for (uint32_t attach = 0; attach < count; attach++) { 73446600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski if (attachments[attach].attachment != VK_ATTACHMENT_UNUSED) { 73456600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski // Attachment counts are verified elsewhere, but prevent an invalid access 73466600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski if (attachments[attach].attachment < fbci->attachmentCount) { 73476600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski const VkImageView *image_view = &fbci->pAttachments[attachments[attach].attachment]; 73489a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto view_state = GetImageViewState(dev_data, *image_view); 734979fde938178535f598e030a0e9d19a0cb61b72e0Tobin Ehlis if (view_state) { 73509a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis const VkImageCreateInfo *ici = &GetImageState(dev_data, view_state->create_info.image)->createInfo; 73516600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski if (ici != nullptr) { 73526600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski if ((ici->usage & usage_flag) == 0) { 7353df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 7354df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, error_code, "DS", 7355946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski "vkCreateFramebuffer: Framebuffer Attachment (%d) conflicts with the image's " 7356946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski "IMAGE_USAGE flags (%s). %s", 7357946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski attachments[attach].attachment, string_VkImageUsageFlagBits(usage_flag), 7358946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski validation_error_map[error_code]); 73596600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski } 73606600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski } 73616600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski } 73626600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski } 73636600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski } 73646600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski } 7365946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski return skip; 73666600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski} 73676600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski 7368d73d9c5ffd42f300d3ec49f64910a2b370694186Tobin Ehlis// Validate VkFramebufferCreateInfo which includes: 7369d73d9c5ffd42f300d3ec49f64910a2b370694186Tobin Ehlis// 1. attachmentCount equals renderPass attachmentCount 73705ef4ed03801d1456b7c30dd59ea014be126df771Tobin Ehlis// 2. corresponding framebuffer and renderpass attachments have matching formats 73715ef4ed03801d1456b7c30dd59ea014be126df771Tobin Ehlis// 3. corresponding framebuffer and renderpass attachments have matching sample counts 73725ef4ed03801d1456b7c30dd59ea014be126df771Tobin Ehlis// 4. fb attachments only have a single mip level 73735ef4ed03801d1456b7c30dd59ea014be126df771Tobin Ehlis// 5. fb attachment dimensions are each at least as large as the fb 73745ef4ed03801d1456b7c30dd59ea014be126df771Tobin Ehlis// 6. fb attachments use idenity swizzle 73755ef4ed03801d1456b7c30dd59ea014be126df771Tobin Ehlis// 7. fb attachments used by renderPass for color/input/ds have correct usage bit set 73766fb721e0f21c85d4457561d17c196280601cebc1Tobin Ehlis// 8. fb dimensions are within physical device limits 7377d73d9c5ffd42f300d3ec49f64910a2b370694186Tobin Ehlisstatic bool ValidateFramebufferCreateInfo(layer_data *dev_data, const VkFramebufferCreateInfo *pCreateInfo) { 73783251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 73796600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski 73809a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto rp_state = GetRenderPassState(dev_data, pCreateInfo->renderPass); 7381127937bcdb5817ee4568887c298ce36c88f3c58bTobin Ehlis if (rp_state) { 7382127937bcdb5817ee4568887c298ce36c88f3c58bTobin Ehlis const VkRenderPassCreateInfo *rpci = rp_state->createInfo.ptr(); 7383d73d9c5ffd42f300d3ec49f64910a2b370694186Tobin Ehlis if (rpci->attachmentCount != pCreateInfo->attachmentCount) { 73843251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg( 7385d73d9c5ffd42f300d3ec49f64910a2b370694186Tobin Ehlis dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, 7386315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pCreateInfo->renderPass), __LINE__, VALIDATION_ERROR_094006d8, "DS", 7387d73d9c5ffd42f300d3ec49f64910a2b370694186Tobin Ehlis "vkCreateFramebuffer(): VkFramebufferCreateInfo attachmentCount of %u does not match attachmentCount of %u of " 73889bd94c6fc216a1d67d5e98542519002fa56d19dbMike Schuchardt "renderPass (0x%" PRIxLEAST64 ") being used to create Framebuffer. %s", 73899b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus pCreateInfo->attachmentCount, rpci->attachmentCount, HandleToUint64(pCreateInfo->renderPass), 7390315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_094006d8]); 73915ef4ed03801d1456b7c30dd59ea014be126df771Tobin Ehlis } else { 739241ebcb6b517b1de5ae456d46d866f5e84a96a2c5Tobin Ehlis // attachmentCounts match, so make sure corresponding attachment details line up 73935ef4ed03801d1456b7c30dd59ea014be126df771Tobin Ehlis const VkImageView *image_views = pCreateInfo->pAttachments; 73945ef4ed03801d1456b7c30dd59ea014be126df771Tobin Ehlis for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i) { 73959a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto view_state = GetImageViewState(dev_data, image_views[i]); 739612d5600c2f9e32343016fd944432ba95df370797Tobin Ehlis auto &ivci = view_state->create_info; 739779fde938178535f598e030a0e9d19a0cb61b72e0Tobin Ehlis if (ivci.format != rpci->pAttachments[i].format) { 73983251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg( 73995ef4ed03801d1456b7c30dd59ea014be126df771Tobin Ehlis dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, 7400315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pCreateInfo->renderPass), __LINE__, VALIDATION_ERROR_094006e0, "DS", 74019bd94c6fc216a1d67d5e98542519002fa56d19dbMike Schuchardt "vkCreateFramebuffer(): VkFramebufferCreateInfo attachment #%u has format of %s that does not match " 74029bd94c6fc216a1d67d5e98542519002fa56d19dbMike Schuchardt "the format of " 74039bd94c6fc216a1d67d5e98542519002fa56d19dbMike Schuchardt "%s used by the corresponding attachment for renderPass (0x%" PRIxLEAST64 "). %s", 740479fde938178535f598e030a0e9d19a0cb61b72e0Tobin Ehlis i, string_VkFormat(ivci.format), string_VkFormat(rpci->pAttachments[i].format), 7405315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pCreateInfo->renderPass), validation_error_map[VALIDATION_ERROR_094006e0]); 74065ef4ed03801d1456b7c30dd59ea014be126df771Tobin Ehlis } 74079a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis const VkImageCreateInfo *ici = &GetImageState(dev_data, ivci.image)->createInfo; 74085ef4ed03801d1456b7c30dd59ea014be126df771Tobin Ehlis if (ici->samples != rpci->pAttachments[i].samples) { 74093251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg( 741041ebcb6b517b1de5ae456d46d866f5e84a96a2c5Tobin Ehlis dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, 7411315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pCreateInfo->renderPass), __LINE__, VALIDATION_ERROR_094006e2, "DS", 74129bd94c6fc216a1d67d5e98542519002fa56d19dbMike Schuchardt "vkCreateFramebuffer(): VkFramebufferCreateInfo attachment #%u has %s samples that do not match " 74139bd94c6fc216a1d67d5e98542519002fa56d19dbMike Schuchardt "the %s samples used by the corresponding attachment for renderPass (0x%" PRIxLEAST64 "). %s", 741441ebcb6b517b1de5ae456d46d866f5e84a96a2c5Tobin Ehlis i, string_VkSampleCountFlagBits(ici->samples), string_VkSampleCountFlagBits(rpci->pAttachments[i].samples), 7415315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pCreateInfo->renderPass), validation_error_map[VALIDATION_ERROR_094006e2]); 74165ef4ed03801d1456b7c30dd59ea014be126df771Tobin Ehlis } 74175ef4ed03801d1456b7c30dd59ea014be126df771Tobin Ehlis // Verify that view only has a single mip level 741879fde938178535f598e030a0e9d19a0cb61b72e0Tobin Ehlis if (ivci.subresourceRange.levelCount != 1) { 74193251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 7420315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis 0, __LINE__, VALIDATION_ERROR_094006e6, "DS", 74213251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkCreateFramebuffer(): VkFramebufferCreateInfo attachment #%u has mip levelCount of %u " 74223251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "but only a single mip level (levelCount == 1) is allowed when creating a Framebuffer. %s", 7423315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis i, ivci.subresourceRange.levelCount, validation_error_map[VALIDATION_ERROR_094006e6]); 74245ef4ed03801d1456b7c30dd59ea014be126df771Tobin Ehlis } 742579fde938178535f598e030a0e9d19a0cb61b72e0Tobin Ehlis const uint32_t mip_level = ivci.subresourceRange.baseMipLevel; 7426aac6fea2aeb81a0d354d80a9226bdc5de2aef5e2Tobin Ehlis uint32_t mip_width = max(1u, ici->extent.width >> mip_level); 7427aac6fea2aeb81a0d354d80a9226bdc5de2aef5e2Tobin Ehlis uint32_t mip_height = max(1u, ici->extent.height >> mip_level); 742879fde938178535f598e030a0e9d19a0cb61b72e0Tobin Ehlis if ((ivci.subresourceRange.layerCount < pCreateInfo->layers) || (mip_width < pCreateInfo->width) || 7429aac6fea2aeb81a0d354d80a9226bdc5de2aef5e2Tobin Ehlis (mip_height < pCreateInfo->height)) { 74302c911c34092d685a7fa4630028f6fcf4bf80e349Cort Stratton skip |= log_msg( 74312c911c34092d685a7fa4630028f6fcf4bf80e349Cort Stratton dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 7432315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_094006e4, "DS", 74332c911c34092d685a7fa4630028f6fcf4bf80e349Cort Stratton "vkCreateFramebuffer(): VkFramebufferCreateInfo attachment #%u mip level %u has dimensions smaller " 74342c911c34092d685a7fa4630028f6fcf4bf80e349Cort Stratton "than the corresponding framebuffer dimensions. Here are the respective dimensions for attachment #%u, " 74352c911c34092d685a7fa4630028f6fcf4bf80e349Cort Stratton "framebuffer:\n" 74362c911c34092d685a7fa4630028f6fcf4bf80e349Cort Stratton "width: %u, %u\n" 74372c911c34092d685a7fa4630028f6fcf4bf80e349Cort Stratton "height: %u, %u\n" 74382c911c34092d685a7fa4630028f6fcf4bf80e349Cort Stratton "layerCount: %u, %u\n%s", 74392c911c34092d685a7fa4630028f6fcf4bf80e349Cort Stratton i, ivci.subresourceRange.baseMipLevel, i, mip_width, pCreateInfo->width, mip_height, pCreateInfo->height, 7440315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis ivci.subresourceRange.layerCount, pCreateInfo->layers, validation_error_map[VALIDATION_ERROR_094006e4]); 74415ef4ed03801d1456b7c30dd59ea014be126df771Tobin Ehlis } 744279fde938178535f598e030a0e9d19a0cb61b72e0Tobin Ehlis if (((ivci.components.r != VK_COMPONENT_SWIZZLE_IDENTITY) && (ivci.components.r != VK_COMPONENT_SWIZZLE_R)) || 744379fde938178535f598e030a0e9d19a0cb61b72e0Tobin Ehlis ((ivci.components.g != VK_COMPONENT_SWIZZLE_IDENTITY) && (ivci.components.g != VK_COMPONENT_SWIZZLE_G)) || 744479fde938178535f598e030a0e9d19a0cb61b72e0Tobin Ehlis ((ivci.components.b != VK_COMPONENT_SWIZZLE_IDENTITY) && (ivci.components.b != VK_COMPONENT_SWIZZLE_B)) || 744579fde938178535f598e030a0e9d19a0cb61b72e0Tobin Ehlis ((ivci.components.a != VK_COMPONENT_SWIZZLE_IDENTITY) && (ivci.components.a != VK_COMPONENT_SWIZZLE_A))) { 74463251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg( 74475b9ab1fb8720c30edfbe8dd974e2364425471ad5Mark Lobodzinski dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 7448315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_094006e8, "DS", 7449da5b8b1df2368168be93e563eccdb500d62b97a5Tobin Ehlis "vkCreateFramebuffer(): VkFramebufferCreateInfo attachment #%u has non-identy swizzle. All framebuffer " 7450da5b8b1df2368168be93e563eccdb500d62b97a5Tobin Ehlis "attachments must have been created with the identity swizzle. Here are the actual swizzle values:\n" 7451da5b8b1df2368168be93e563eccdb500d62b97a5Tobin Ehlis "r swizzle = %s\n" 7452da5b8b1df2368168be93e563eccdb500d62b97a5Tobin Ehlis "g swizzle = %s\n" 7453da5b8b1df2368168be93e563eccdb500d62b97a5Tobin Ehlis "b swizzle = %s\n" 74549bd94c6fc216a1d67d5e98542519002fa56d19dbMike Schuchardt "a swizzle = %s\n" 74559bd94c6fc216a1d67d5e98542519002fa56d19dbMike Schuchardt "%s", 745679fde938178535f598e030a0e9d19a0cb61b72e0Tobin Ehlis i, string_VkComponentSwizzle(ivci.components.r), string_VkComponentSwizzle(ivci.components.g), 74579bd94c6fc216a1d67d5e98542519002fa56d19dbMike Schuchardt string_VkComponentSwizzle(ivci.components.b), string_VkComponentSwizzle(ivci.components.a), 7458315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_094006e8]); 74595ef4ed03801d1456b7c30dd59ea014be126df771Tobin Ehlis } 74605ef4ed03801d1456b7c30dd59ea014be126df771Tobin Ehlis } 7461d73d9c5ffd42f300d3ec49f64910a2b370694186Tobin Ehlis } 74625ef4ed03801d1456b7c30dd59ea014be126df771Tobin Ehlis // Verify correct attachment usage flags 74636600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski for (uint32_t subpass = 0; subpass < rpci->subpassCount; subpass++) { 74646600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski // Verify input attachments: 74653251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= 74669bd94c6fc216a1d67d5e98542519002fa56d19dbMike Schuchardt MatchUsage(dev_data, rpci->pSubpasses[subpass].inputAttachmentCount, rpci->pSubpasses[subpass].pInputAttachments, 7467315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis pCreateInfo, VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, VALIDATION_ERROR_094006de); 74686600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski // Verify color attachments: 74693251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= 74709bd94c6fc216a1d67d5e98542519002fa56d19dbMike Schuchardt MatchUsage(dev_data, rpci->pSubpasses[subpass].colorAttachmentCount, rpci->pSubpasses[subpass].pColorAttachments, 7471315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis pCreateInfo, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VALIDATION_ERROR_094006da); 74726600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski // Verify depth/stencil attachments: 74736600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski if (rpci->pSubpasses[subpass].pDepthStencilAttachment != nullptr) { 74743251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= MatchUsage(dev_data, 1, rpci->pSubpasses[subpass].pDepthStencilAttachment, pCreateInfo, 7475315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VALIDATION_ERROR_094006dc); 74766600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski } 74776600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski } 74786600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski } 74796fb721e0f21c85d4457561d17c196280601cebc1Tobin Ehlis // Verify FB dimensions are within physical device limits 74809bd94c6fc216a1d67d5e98542519002fa56d19dbMike Schuchardt if (pCreateInfo->width > dev_data->phys_dev_properties.properties.limits.maxFramebufferWidth) { 74813251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 7482315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_094006ec, "DS", 74833251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkCreateFramebuffer(): Requested VkFramebufferCreateInfo width exceeds physical device limits. " 74843251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Requested width: %u, device max: %u\n" 74853251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "%s", 74863251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski pCreateInfo->width, dev_data->phys_dev_properties.properties.limits.maxFramebufferWidth, 7487315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_094006ec]); 74889bd94c6fc216a1d67d5e98542519002fa56d19dbMike Schuchardt } 74899bd94c6fc216a1d67d5e98542519002fa56d19dbMike Schuchardt if (pCreateInfo->height > dev_data->phys_dev_properties.properties.limits.maxFramebufferHeight) { 74903251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 7491315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_094006f0, "DS", 74923251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkCreateFramebuffer(): Requested VkFramebufferCreateInfo height exceeds physical device limits. " 74933251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Requested height: %u, device max: %u\n" 74943251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "%s", 74953251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski pCreateInfo->height, dev_data->phys_dev_properties.properties.limits.maxFramebufferHeight, 7496315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_094006f0]); 74979bd94c6fc216a1d67d5e98542519002fa56d19dbMike Schuchardt } 74989bd94c6fc216a1d67d5e98542519002fa56d19dbMike Schuchardt if (pCreateInfo->layers > dev_data->phys_dev_properties.properties.limits.maxFramebufferLayers) { 74993251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 7500315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_094006f4, "DS", 75013251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkCreateFramebuffer(): Requested VkFramebufferCreateInfo layers exceeds physical device limits. " 75023251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Requested layers: %u, device max: %u\n" 75033251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "%s", 75043251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski pCreateInfo->layers, dev_data->phys_dev_properties.properties.limits.maxFramebufferLayers, 7505315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_094006f4]); 75066fb721e0f21c85d4457561d17c196280601cebc1Tobin Ehlis } 7507c70c914e514d6ee222af18505e6d4ce8387c3fa2Cort Stratton // Verify FB dimensions are greater than zero 7508c70c914e514d6ee222af18505e6d4ce8387c3fa2Cort Stratton if (pCreateInfo->width <= 0) { 7509c70c914e514d6ee222af18505e6d4ce8387c3fa2Cort Stratton skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 7510315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_094006ea, "DS", 7511c70c914e514d6ee222af18505e6d4ce8387c3fa2Cort Stratton "vkCreateFramebuffer(): Requested VkFramebufferCreateInfo width must be greater than zero. %s", 7512315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_094006ea]); 7513c70c914e514d6ee222af18505e6d4ce8387c3fa2Cort Stratton } 7514c70c914e514d6ee222af18505e6d4ce8387c3fa2Cort Stratton if (pCreateInfo->height <= 0) { 7515c70c914e514d6ee222af18505e6d4ce8387c3fa2Cort Stratton skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 7516315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_094006ee, "DS", 7517c70c914e514d6ee222af18505e6d4ce8387c3fa2Cort Stratton "vkCreateFramebuffer(): Requested VkFramebufferCreateInfo height must be greater than zero. %s", 7518315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_094006ee]); 7519c70c914e514d6ee222af18505e6d4ce8387c3fa2Cort Stratton } 7520c70c914e514d6ee222af18505e6d4ce8387c3fa2Cort Stratton if (pCreateInfo->layers <= 0) { 7521c70c914e514d6ee222af18505e6d4ce8387c3fa2Cort Stratton skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 7522315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_094006f2, "DS", 7523c70c914e514d6ee222af18505e6d4ce8387c3fa2Cort Stratton "vkCreateFramebuffer(): Requested VkFramebufferCreateInfo layers must be greater than zero. %s", 7524315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_094006f2]); 7525c70c914e514d6ee222af18505e6d4ce8387c3fa2Cort Stratton } 75263251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 75276600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski} 75286600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski 752964c259c2660d24b5b032f0cfa668de086dcd7eb4Tobin Ehlis// Validate VkFramebufferCreateInfo state prior to calling down chain to create Framebuffer object 753064c259c2660d24b5b032f0cfa668de086dcd7eb4Tobin Ehlis// Return true if an error is encountered and callback returns true to skip call down chain 753164c259c2660d24b5b032f0cfa668de086dcd7eb4Tobin Ehlis// false indicates that call down chain should proceed 753264c259c2660d24b5b032f0cfa668de086dcd7eb4Tobin Ehlisstatic bool PreCallValidateCreateFramebuffer(layer_data *dev_data, const VkFramebufferCreateInfo *pCreateInfo) { 753364c259c2660d24b5b032f0cfa668de086dcd7eb4Tobin Ehlis // TODO : Verify that renderPass FB is created with is compatible with FB 75343251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 75353251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateFramebufferCreateInfo(dev_data, pCreateInfo); 75363251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 753764c259c2660d24b5b032f0cfa668de086dcd7eb4Tobin Ehlis} 753864c259c2660d24b5b032f0cfa668de086dcd7eb4Tobin Ehlis 753954e0bb0ace13cc34255e0dc9ca6b0da2b4ac5be1Tobin Ehlis// CreateFramebuffer state has been validated and call down chain completed so record new framebuffer object 754054e0bb0ace13cc34255e0dc9ca6b0da2b4ac5be1Tobin Ehlisstatic void PostCallRecordCreateFramebuffer(layer_data *dev_data, const VkFramebufferCreateInfo *pCreateInfo, VkFramebuffer fb) { 754154e0bb0ace13cc34255e0dc9ca6b0da2b4ac5be1Tobin Ehlis // Shadow create info and store in map 7542c54e405a4ce05f4de10bb78bfc3a4769c41d2d59Tobin Ehlis std::unique_ptr<FRAMEBUFFER_STATE> fb_state( 7543ba9be0cec36d930fc0d5a0cbfbc00b0df49b08e4Tobin Ehlis new FRAMEBUFFER_STATE(fb, pCreateInfo, GetRenderPassStateSharedPtr(dev_data, pCreateInfo->renderPass))); 754476f04ca0e692f9f15d5ef7e0c658c24d11f34ebcTobin Ehlis 754554e0bb0ace13cc34255e0dc9ca6b0da2b4ac5be1Tobin Ehlis for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i) { 754654e0bb0ace13cc34255e0dc9ca6b0da2b4ac5be1Tobin Ehlis VkImageView view = pCreateInfo->pAttachments[i]; 75479a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto view_state = GetImageViewState(dev_data, view); 754879fde938178535f598e030a0e9d19a0cb61b72e0Tobin Ehlis if (!view_state) { 754954e0bb0ace13cc34255e0dc9ca6b0da2b4ac5be1Tobin Ehlis continue; 755054e0bb0ace13cc34255e0dc9ca6b0da2b4ac5be1Tobin Ehlis } 755154e0bb0ace13cc34255e0dc9ca6b0da2b4ac5be1Tobin Ehlis MT_FB_ATTACHMENT_INFO fb_info; 7552883ee3f865f9dbd83134d148b26e96cb6a926b3dTobin Ehlis fb_info.view_state = view_state; 755379fde938178535f598e030a0e9d19a0cb61b72e0Tobin Ehlis fb_info.image = view_state->create_info.image; 7554c54e405a4ce05f4de10bb78bfc3a4769c41d2d59Tobin Ehlis fb_state->attachments.push_back(fb_info); 755554e0bb0ace13cc34255e0dc9ca6b0da2b4ac5be1Tobin Ehlis } 7556c54e405a4ce05f4de10bb78bfc3a4769c41d2d59Tobin Ehlis dev_data->frameBufferMap[fb] = std::move(fb_state); 755754e0bb0ace13cc34255e0dc9ca6b0da2b4ac5be1Tobin Ehlis} 755854e0bb0ace13cc34255e0dc9ca6b0da2b4ac5be1Tobin Ehlis 755989d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR VkResult VKAPI_CALL CreateFramebuffer(VkDevice device, const VkFramebufferCreateInfo *pCreateInfo, 7560bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkAllocationCallbacks *pAllocator, VkFramebuffer *pFramebuffer) { 756156e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 7562ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 75633251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = PreCallValidateCreateFramebuffer(dev_data, pCreateInfo); 756464c259c2660d24b5b032f0cfa668de086dcd7eb4Tobin Ehlis lock.unlock(); 756564c259c2660d24b5b032f0cfa668de086dcd7eb4Tobin Ehlis 75663251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 756764c259c2660d24b5b032f0cfa668de086dcd7eb4Tobin Ehlis 75684a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.CreateFramebuffer(device, pCreateInfo, pAllocator, pFramebuffer); 75696600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski 75705b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (VK_SUCCESS == result) { 757164c259c2660d24b5b032f0cfa668de086dcd7eb4Tobin Ehlis lock.lock(); 757254e0bb0ace13cc34255e0dc9ca6b0da2b4ac5be1Tobin Ehlis PostCallRecordCreateFramebuffer(dev_data, pCreateInfo, *pFramebuffer); 757354e0bb0ace13cc34255e0dc9ca6b0da2b4ac5be1Tobin Ehlis lock.unlock(); 75745b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 75755b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 75765b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 75775b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 75784e11bb1277f55311686a42000520791e1db1dd7bbungemanstatic bool FindDependency(const uint32_t index, const uint32_t dependent, const std::vector<DAGNode> &subpass_to_node, 7579e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves std::unordered_set<uint32_t> &processed_nodes) { 75805b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // If we have already checked this node we have not found a dependency path so return false. 7581cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (processed_nodes.count(index)) return false; 75825b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis processed_nodes.insert(index); 75835b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis const DAGNode &node = subpass_to_node[index]; 75845b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Look for a dependency path. If one exists return true else recurse on the previous nodes. 75854e11bb1277f55311686a42000520791e1db1dd7bbungeman if (std::find(node.prev.begin(), node.prev.end(), dependent) == node.prev.end()) { 75865b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (auto elem : node.prev) { 7587cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (FindDependency(elem, dependent, subpass_to_node, processed_nodes)) return true; 75885b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 75895b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } else { 7590e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves return true; 75915b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 7592e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves return false; 75935b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 75945b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 75954e11bb1277f55311686a42000520791e1db1dd7bbungemanstatic bool CheckDependencyExists(const layer_data *dev_data, const uint32_t subpass, 75963251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski const std::vector<uint32_t> &dependent_subpasses, const std::vector<DAGNode> &subpass_to_node, 75973251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool &skip) { 7598e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves bool result = true; 75995b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Loop through all subpasses that share the same attachment and make sure a dependency exists 76005b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t k = 0; k < dependent_subpasses.size(); ++k) { 7601cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (static_cast<uint32_t>(subpass) == dependent_subpasses[k]) continue; 76025b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis const DAGNode &node = subpass_to_node[subpass]; 76035b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Check for a specified dependency between the two nodes. If one exists we are done. 76045b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis auto prev_elem = std::find(node.prev.begin(), node.prev.end(), dependent_subpasses[k]); 76055b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis auto next_elem = std::find(node.next.begin(), node.next.end(), dependent_subpasses[k]); 76065b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (prev_elem == node.prev.end() && next_elem == node.next.end()) { 76077655cb8b5eb52badee0b011729a05afa36316d69Jan-Harald Fredriksen // If no dependency exits an implicit dependency still might. If not, throw an error. 76085b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis std::unordered_set<uint32_t> processed_nodes; 76097655cb8b5eb52badee0b011729a05afa36316d69Jan-Harald Fredriksen if (!(FindDependency(subpass, dependent_subpasses[k], subpass_to_node, processed_nodes) || 7610bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski FindDependency(dependent_subpasses[k], subpass, subpass_to_node, processed_nodes))) { 76113251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 76123251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski __LINE__, DRAWSTATE_INVALID_RENDERPASS, "DS", 76133251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "A dependency between subpasses %d and %d must exist but one is not specified.", subpass, 76143251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski dependent_subpasses[k]); 7615e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves result = false; 76165b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 76175b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 76185b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 76195b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 76205b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 76215b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 76228860b85a52096f9f9b28616bc37feed505497a54Chris Forbesstatic bool CheckPreserved(const layer_data *dev_data, const VkRenderPassCreateInfo *pCreateInfo, const int index, 76233251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski const uint32_t attachment, const std::vector<DAGNode> &subpass_to_node, int depth, bool &skip) { 76245b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis const DAGNode &node = subpass_to_node[index]; 76255b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // If this node writes to the attachment return true as next nodes need to preserve the attachment. 76265b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis const VkSubpassDescription &subpass = pCreateInfo->pSubpasses[index]; 76275b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t j = 0; j < subpass.colorAttachmentCount; ++j) { 7628cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (attachment == subpass.pColorAttachments[j].attachment) return true; 76295b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 7630a4ea781e8fff70c9db0bedad7fcb6bba08e35da7Tony Barbour for (uint32_t j = 0; j < subpass.inputAttachmentCount; ++j) { 7631a4ea781e8fff70c9db0bedad7fcb6bba08e35da7Tony Barbour if (attachment == subpass.pInputAttachments[j].attachment) return true; 7632a4ea781e8fff70c9db0bedad7fcb6bba08e35da7Tony Barbour } 76335b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (subpass.pDepthStencilAttachment && subpass.pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) { 7634cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (attachment == subpass.pDepthStencilAttachment->attachment) return true; 76355b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 7636e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves bool result = false; 76375b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Loop through previous nodes and see if any of them write to the attachment. 76385b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (auto elem : node.prev) { 76393251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski result |= CheckPreserved(dev_data, pCreateInfo, elem, attachment, subpass_to_node, depth + 1, skip); 76405b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 76415b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // If the attachment was written to by a previous node than this node needs to preserve it. 76425b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (result && depth > 0) { 7643e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves bool has_preserved = false; 76445b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t j = 0; j < subpass.preserveAttachmentCount; ++j) { 76455b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (subpass.pPreserveAttachments[j] == attachment) { 7646e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves has_preserved = true; 76475b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis break; 76485b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 76495b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 7650e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves if (!has_preserved) { 76513251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 76523251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski __LINE__, DRAWSTATE_INVALID_RENDERPASS, "DS", 76533251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Attachment %d is used by a later subpass and must be preserved in subpass %d.", attachment, index); 76545b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 76555b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 76565b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 76575b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 76585b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 7659cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinskitemplate <class T> 7660cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinskibool isRangeOverlapping(T offset1, T size1, T offset2, T size2) { 76615b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return (((offset1 + size1) > offset2) && ((offset1 + size1) < (offset2 + size2))) || 76625b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis ((offset1 > offset2) && (offset1 < (offset2 + size2))); 76635b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 76645b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 76655b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlisbool isRegionOverlapping(VkImageSubresourceRange range1, VkImageSubresourceRange range2) { 76665b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return (isRangeOverlapping(range1.baseMipLevel, range1.levelCount, range2.baseMipLevel, range2.levelCount) && 76675b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis isRangeOverlapping(range1.baseArrayLayer, range1.layerCount, range2.baseArrayLayer, range2.layerCount)); 76685b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 76695b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 7670c54e405a4ce05f4de10bb78bfc3a4769c41d2d59Tobin Ehlisstatic bool ValidateDependencies(const layer_data *dev_data, FRAMEBUFFER_STATE const *framebuffer, 7671127937bcdb5817ee4568887c298ce36c88f3c58bTobin Ehlis RENDER_PASS_STATE const *renderPass) { 76723251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 7673fb13c2c4174108223d9f8e43084020eb09115ed6Chris Forbes auto const pFramebufferInfo = framebuffer->createInfo.ptr(); 7674fb13c2c4174108223d9f8e43084020eb09115ed6Chris Forbes auto const pCreateInfo = renderPass->createInfo.ptr(); 7675bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski auto const &subpass_to_node = renderPass->subpassToNode; 76765b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis std::vector<std::vector<uint32_t>> output_attachment_to_subpass(pCreateInfo->attachmentCount); 76775b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis std::vector<std::vector<uint32_t>> input_attachment_to_subpass(pCreateInfo->attachmentCount); 76785b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis std::vector<std::vector<uint32_t>> overlapping_attachments(pCreateInfo->attachmentCount); 76795b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Find overlapping attachments 76805b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i) { 76815b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t j = i + 1; j < pCreateInfo->attachmentCount; ++j) { 76825b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis VkImageView viewi = pFramebufferInfo->pAttachments[i]; 76835b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis VkImageView viewj = pFramebufferInfo->pAttachments[j]; 76845b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (viewi == viewj) { 76855b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis overlapping_attachments[i].push_back(j); 76865b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis overlapping_attachments[j].push_back(i); 76875b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis continue; 76885b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 76899a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto view_state_i = GetImageViewState(dev_data, viewi); 76909a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto view_state_j = GetImageViewState(dev_data, viewj); 769179fde938178535f598e030a0e9d19a0cb61b72e0Tobin Ehlis if (!view_state_i || !view_state_j) { 76925b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis continue; 76935b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 769479fde938178535f598e030a0e9d19a0cb61b72e0Tobin Ehlis auto view_ci_i = view_state_i->create_info; 769579fde938178535f598e030a0e9d19a0cb61b72e0Tobin Ehlis auto view_ci_j = view_state_j->create_info; 769679fde938178535f598e030a0e9d19a0cb61b72e0Tobin Ehlis if (view_ci_i.image == view_ci_j.image && isRegionOverlapping(view_ci_i.subresourceRange, view_ci_j.subresourceRange)) { 76975b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis overlapping_attachments[i].push_back(j); 76985b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis overlapping_attachments[j].push_back(i); 76995b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis continue; 77005b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 77019a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto image_data_i = GetImageState(dev_data, view_ci_i.image); 77029a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto image_data_j = GetImageState(dev_data, view_ci_j.image); 77036d1373829eded68f6e080ff2c33e03231360ed57Tobin Ehlis if (!image_data_i || !image_data_j) { 77045b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis continue; 77055b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 7706e46491ee6f16b9d29e68914fc6522aba2fde0ad4Tobin Ehlis if (image_data_i->binding.mem == image_data_j->binding.mem && 7707e46491ee6f16b9d29e68914fc6522aba2fde0ad4Tobin Ehlis isRangeOverlapping(image_data_i->binding.offset, image_data_i->binding.size, image_data_j->binding.offset, 7708e46491ee6f16b9d29e68914fc6522aba2fde0ad4Tobin Ehlis image_data_j->binding.size)) { 77095b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis overlapping_attachments[i].push_back(j); 77105b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis overlapping_attachments[j].push_back(i); 77115b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 77125b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 77135b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 77145b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t i = 0; i < overlapping_attachments.size(); ++i) { 77155b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis uint32_t attachment = i; 77165b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (auto other_attachment : overlapping_attachments[i]) { 77175b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (!(pCreateInfo->pAttachments[attachment].flags & VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT)) { 77189b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT, 7719315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(framebuffer->framebuffer), __LINE__, VALIDATION_ERROR_12200682, "DS", 77209b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "Attachment %d aliases attachment %d but doesn't " 77219b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "set VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT. %s", 7722315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis attachment, other_attachment, validation_error_map[VALIDATION_ERROR_12200682]); 77235b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 77245b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (!(pCreateInfo->pAttachments[other_attachment].flags & VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT)) { 77259b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT, 7726315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(framebuffer->framebuffer), __LINE__, VALIDATION_ERROR_12200682, "DS", 77279b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "Attachment %d aliases attachment %d but doesn't " 77289b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "set VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT. %s", 7729315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis other_attachment, attachment, validation_error_map[VALIDATION_ERROR_12200682]); 77305b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 77315b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 77325b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 77335b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Find for each attachment the subpasses that use them. 77341c1ee7bf64fb8cc2ba4b8661baa11dce24b3b23aMark Young unordered_set<uint32_t> attachmentIndices; 77355b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) { 77365b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis const VkSubpassDescription &subpass = pCreateInfo->pSubpasses[i]; 77371c1ee7bf64fb8cc2ba4b8661baa11dce24b3b23aMark Young attachmentIndices.clear(); 77385b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t j = 0; j < subpass.inputAttachmentCount; ++j) { 77395b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis uint32_t attachment = subpass.pInputAttachments[j].attachment; 7740cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (attachment == VK_ATTACHMENT_UNUSED) continue; 77415b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis input_attachment_to_subpass[attachment].push_back(i); 77425b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (auto overlapping_attachment : overlapping_attachments[attachment]) { 77435b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis input_attachment_to_subpass[overlapping_attachment].push_back(i); 77445b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 77455b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 77465b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t j = 0; j < subpass.colorAttachmentCount; ++j) { 77475b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis uint32_t attachment = subpass.pColorAttachments[j].attachment; 7748cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (attachment == VK_ATTACHMENT_UNUSED) continue; 77495b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis output_attachment_to_subpass[attachment].push_back(i); 77505b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (auto overlapping_attachment : overlapping_attachments[attachment]) { 77515b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis output_attachment_to_subpass[overlapping_attachment].push_back(i); 77525b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 77531c1ee7bf64fb8cc2ba4b8661baa11dce24b3b23aMark Young attachmentIndices.insert(attachment); 77545b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 77555b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (subpass.pDepthStencilAttachment && subpass.pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) { 77565b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis uint32_t attachment = subpass.pDepthStencilAttachment->attachment; 77575b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis output_attachment_to_subpass[attachment].push_back(i); 77585b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (auto overlapping_attachment : overlapping_attachments[attachment]) { 77595b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis output_attachment_to_subpass[overlapping_attachment].push_back(i); 77605b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 77611c1ee7bf64fb8cc2ba4b8661baa11dce24b3b23aMark Young 77621c1ee7bf64fb8cc2ba4b8661baa11dce24b3b23aMark Young if (attachmentIndices.count(attachment)) { 77633251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= 7764df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 7765df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski __LINE__, DRAWSTATE_INVALID_RENDERPASS, "DS", 77668860b85a52096f9f9b28616bc37feed505497a54Chris Forbes "Cannot use same attachment (%u) as both color and depth output in same subpass (%u).", attachment, i); 77671c1ee7bf64fb8cc2ba4b8661baa11dce24b3b23aMark Young } 77685b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 77695b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 77705b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // If there is a dependency needed make sure one exists 77715b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) { 77725b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis const VkSubpassDescription &subpass = pCreateInfo->pSubpasses[i]; 77735b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // If the attachment is an input then all subpasses that output must have a dependency relationship 77745b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t j = 0; j < subpass.inputAttachmentCount; ++j) { 777593fe72ec8460857bdb3c101095e6eb96d6171341Chris Forbes uint32_t attachment = subpass.pInputAttachments[j].attachment; 7776cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (attachment == VK_ATTACHMENT_UNUSED) continue; 77773251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski CheckDependencyExists(dev_data, i, output_attachment_to_subpass[attachment], subpass_to_node, skip); 77785b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 77795b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // If the attachment is an output then all subpasses that use the attachment must have a dependency relationship 77805b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t j = 0; j < subpass.colorAttachmentCount; ++j) { 778193fe72ec8460857bdb3c101095e6eb96d6171341Chris Forbes uint32_t attachment = subpass.pColorAttachments[j].attachment; 7782cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (attachment == VK_ATTACHMENT_UNUSED) continue; 77833251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski CheckDependencyExists(dev_data, i, output_attachment_to_subpass[attachment], subpass_to_node, skip); 77843251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski CheckDependencyExists(dev_data, i, input_attachment_to_subpass[attachment], subpass_to_node, skip); 77855b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 77865b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (subpass.pDepthStencilAttachment && subpass.pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) { 77875b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis const uint32_t &attachment = subpass.pDepthStencilAttachment->attachment; 77883251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski CheckDependencyExists(dev_data, i, output_attachment_to_subpass[attachment], subpass_to_node, skip); 77893251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski CheckDependencyExists(dev_data, i, input_attachment_to_subpass[attachment], subpass_to_node, skip); 77905b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 77915b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 77925b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Loop through implicit dependencies, if this pass reads make sure the attachment is preserved for all passes after it was 77935b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // written. 77945b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) { 77955b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis const VkSubpassDescription &subpass = pCreateInfo->pSubpasses[i]; 77965b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t j = 0; j < subpass.inputAttachmentCount; ++j) { 77973251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski CheckPreserved(dev_data, pCreateInfo, i, subpass.pInputAttachments[j].attachment, subpass_to_node, 0, skip); 77985b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 77995b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 78003251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 78015b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 78025b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 780332f68580aa01aab3e923cb52915a1d3dd4e993c5Chris Forbesstatic bool CreatePassDAG(const layer_data *dev_data, const VkRenderPassCreateInfo *pCreateInfo, 7804ea0a13226a513846fe5a7009783c5536b1255a56Tobin Ehlis std::vector<DAGNode> &subpass_to_node, std::vector<bool> &has_self_dependency, 7805ea0a13226a513846fe5a7009783c5536b1255a56Tobin Ehlis std::vector<int32_t> &subpass_to_dep_index) { 78063251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 78075b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) { 78085b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis DAGNode &subpass_node = subpass_to_node[i]; 78095b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis subpass_node.pass = i; 7810ea0a13226a513846fe5a7009783c5536b1255a56Tobin Ehlis subpass_to_dep_index[i] = -1; // Default to no dependency and overwrite below as needed 78115b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 78125b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t i = 0; i < pCreateInfo->dependencyCount; ++i) { 78135b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis const VkSubpassDependency &dependency = pCreateInfo->pDependencies[i]; 781466a7318a24c9dd8162a6ae49fd62867a263d4402Chris Forbes if (dependency.srcSubpass == VK_SUBPASS_EXTERNAL || dependency.dstSubpass == VK_SUBPASS_EXTERNAL) { 781566a7318a24c9dd8162a6ae49fd62867a263d4402Chris Forbes if (dependency.srcSubpass == dependency.dstSubpass) { 78163251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= 7817df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 7818df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski __LINE__, DRAWSTATE_INVALID_RENDERPASS, "DS", "The src and dest subpasses cannot both be external."); 781966a7318a24c9dd8162a6ae49fd62867a263d4402Chris Forbes } 782066a7318a24c9dd8162a6ae49fd62867a263d4402Chris Forbes } else if (dependency.srcSubpass > dependency.dstSubpass) { 78213251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 78223251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski __LINE__, DRAWSTATE_INVALID_RENDERPASS, "DS", 7823ea0a13226a513846fe5a7009783c5536b1255a56Tobin Ehlis "Dependency graph must be specified such that an earlier pass cannot depend on a later pass."); 78245b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } else if (dependency.srcSubpass == dependency.dstSubpass) { 78255b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis has_self_dependency[dependency.srcSubpass] = true; 7826b6820dcebf864c3e157647317ddd26180309fc2bChris Forbes subpass_to_dep_index[dependency.srcSubpass] = i; 78275c6aacf95832467d52b2fde1130b04bef559573aChris Forbes } else { 78285c6aacf95832467d52b2fde1130b04bef559573aChris Forbes subpass_to_node[dependency.dstSubpass].prev.push_back(dependency.srcSubpass); 78295c6aacf95832467d52b2fde1130b04bef559573aChris Forbes subpass_to_node[dependency.srcSubpass].next.push_back(dependency.dstSubpass); 78305b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 78315b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 78323251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 78335b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 7834918c283ac4f8c604b79abd0c8b5706d2a7352a34Chris Forbes 783589d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR VkResult VKAPI_CALL CreateShaderModule(VkDevice device, const VkShaderModuleCreateInfo *pCreateInfo, 7836bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkAllocationCallbacks *pAllocator, VkShaderModule *pShaderModule) { 783756e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 78387aec8a354c8de254cab09f6da7f24a794525d31eChris Forbes bool spirv_valid; 7839b1f65702539fd041337fccd493dc6d38dd2a603eChris Forbes 78407aec8a354c8de254cab09f6da7f24a794525d31eChris Forbes if (PreCallValidateCreateShaderModule(dev_data, pCreateInfo, &spirv_valid)) 78417aec8a354c8de254cab09f6da7f24a794525d31eChris Forbes return VK_ERROR_VALIDATION_FAILED_EXT; 78425b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 78434a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult res = dev_data->dispatch_table.CreateShaderModule(device, pCreateInfo, pAllocator, pShaderModule); 78445b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 784559ae0ccadec962d9ca2cce7584fad6c57c1a4458Tobin Ehlis if (res == VK_SUCCESS) { 7846ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 78477aec8a354c8de254cab09f6da7f24a794525d31eChris Forbes unique_ptr<shader_module> new_shader_module(spirv_valid ? new shader_module(pCreateInfo) : new shader_module()); 78487aec8a354c8de254cab09f6da7f24a794525d31eChris Forbes dev_data->shaderModuleMap[*pShaderModule] = std::move(new_shader_module); 78495b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 78505b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return res; 78515b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 78525b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 78534f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinskistatic bool ValidateAttachmentIndex(layer_data *dev_data, uint32_t attachment, uint32_t attachment_count, const char *type) { 78543251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 78554f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski if (attachment >= attachment_count && attachment != VK_ATTACHMENT_UNUSED) { 78563251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 7857315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_12200684, "DS", 78583251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "CreateRenderPass: %s attachment %d must be less than the total number of attachments %d. %s", type, 7859315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis attachment, attachment_count, validation_error_map[VALIDATION_ERROR_12200684]); 78604f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski } 78613251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 78624f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski} 78634f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski 7864bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinskistatic bool IsPowerOfTwo(unsigned x) { return x && !(x & (x - 1)); } 7865805ec497391f6bc513f7653ba6d535c509b54062Chris Forbes 78664f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinskistatic bool ValidateRenderpassAttachmentUsage(layer_data *dev_data, const VkRenderPassCreateInfo *pCreateInfo) { 78673251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 78684f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) { 78694f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski const VkSubpassDescription &subpass = pCreateInfo->pSubpasses[i]; 78704f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski if (subpass.pipelineBindPoint != VK_PIPELINE_BIND_POINT_GRAPHICS) { 78713251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 7872315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis __LINE__, VALIDATION_ERROR_14000698, "DS", 78733251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "CreateRenderPass: Pipeline bind point for subpass %d must be VK_PIPELINE_BIND_POINT_GRAPHICS. %s", i, 7874315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_14000698]); 78754f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski } 7876ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton 78774f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski for (uint32_t j = 0; j < subpass.preserveAttachmentCount; ++j) { 78784f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski uint32_t attachment = subpass.pPreserveAttachments[j]; 78794f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski if (attachment == VK_ATTACHMENT_UNUSED) { 78803251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 7881315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis __LINE__, VALIDATION_ERROR_140006aa, "DS", 78823251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "CreateRenderPass: Preserve attachment (%d) must not be VK_ATTACHMENT_UNUSED. %s", j, 7883315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_140006aa]); 78844f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski } else { 78853251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateAttachmentIndex(dev_data, attachment, pCreateInfo->attachmentCount, "Preserve"); 7886ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton 7887ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton bool found = (subpass.pDepthStencilAttachment != NULL && subpass.pDepthStencilAttachment->attachment == attachment); 7888ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton for (uint32_t r = 0; !found && r < subpass.inputAttachmentCount; ++r) { 7889ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton found = (subpass.pInputAttachments[r].attachment == attachment); 7890ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton } 7891ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton for (uint32_t r = 0; !found && r < subpass.colorAttachmentCount; ++r) { 7892ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton found = (subpass.pColorAttachments[r].attachment == attachment) || 7893ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton (subpass.pResolveAttachments != NULL && subpass.pResolveAttachments[r].attachment == attachment); 7894ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton } 7895ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton if (found) { 7896ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton skip |= log_msg( 7897ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 7898315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_140006ac, "DS", 7899ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton "CreateRenderPass: subpass %u pPreserveAttachments[%u] (%u) must not be used elsewhere in the subpass. %s", 7900315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis i, j, attachment, validation_error_map[VALIDATION_ERROR_140006ac]); 7901ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton } 79024f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski } 79034f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski } 79046a3bc5f071fe21799f0f7ae844716c333f11f39cChris Forbes 7905bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski auto subpass_performs_resolve = 7906bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski subpass.pResolveAttachments && 7907bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski std::any_of(subpass.pResolveAttachments, subpass.pResolveAttachments + subpass.colorAttachmentCount, 7908bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski [](VkAttachmentReference ref) { return ref.attachment != VK_ATTACHMENT_UNUSED; }); 79096a3bc5f071fe21799f0f7ae844716c333f11f39cChris Forbes 7910805ec497391f6bc513f7653ba6d535c509b54062Chris Forbes unsigned sample_count = 0; 7911805ec497391f6bc513f7653ba6d535c509b54062Chris Forbes 79124f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski for (uint32_t j = 0; j < subpass.colorAttachmentCount; ++j) { 79134f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski uint32_t attachment; 79144f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski if (subpass.pResolveAttachments) { 79154f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski attachment = subpass.pResolveAttachments[j].attachment; 79163251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateAttachmentIndex(dev_data, attachment, pCreateInfo->attachmentCount, "Resolve"); 79176a3bc5f071fe21799f0f7ae844716c333f11f39cChris Forbes 79183251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip && attachment != VK_ATTACHMENT_UNUSED && 79196a3bc5f071fe21799f0f7ae844716c333f11f39cChris Forbes pCreateInfo->pAttachments[attachment].samples != VK_SAMPLE_COUNT_1_BIT) { 79203251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 7921315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis 0, __LINE__, VALIDATION_ERROR_140006a2, "DS", 79223251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "CreateRenderPass: Subpass %u requests multisample resolve into attachment %u, " 79233251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "which must have VK_SAMPLE_COUNT_1_BIT but has %s. %s", 79243251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski i, attachment, string_VkSampleCountFlagBits(pCreateInfo->pAttachments[attachment].samples), 7925315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_140006a2]); 79266a3bc5f071fe21799f0f7ae844716c333f11f39cChris Forbes } 7927ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton 7928ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton if (!skip && subpass.pResolveAttachments[j].attachment != VK_ATTACHMENT_UNUSED && 7929ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton subpass.pColorAttachments[j].attachment == VK_ATTACHMENT_UNUSED) { 7930ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 7931315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis 0, __LINE__, VALIDATION_ERROR_1400069e, "DS", 7932ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton "CreateRenderPass: Subpass %u requests multisample resolve from attachment %u " 7933ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton "which has attachment=VK_ATTACHMENT_UNUSED. %s", 7934315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis i, attachment, validation_error_map[VALIDATION_ERROR_1400069e]); 7935ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton } 79364f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski } 79374f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski attachment = subpass.pColorAttachments[j].attachment; 79383251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateAttachmentIndex(dev_data, attachment, pCreateInfo->attachmentCount, "Color"); 79396a3bc5f071fe21799f0f7ae844716c333f11f39cChris Forbes 79403251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip && attachment != VK_ATTACHMENT_UNUSED) { 7941805ec497391f6bc513f7653ba6d535c509b54062Chris Forbes sample_count |= (unsigned)pCreateInfo->pAttachments[attachment].samples; 7942805ec497391f6bc513f7653ba6d535c509b54062Chris Forbes 7943bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski if (subpass_performs_resolve && pCreateInfo->pAttachments[attachment].samples == VK_SAMPLE_COUNT_1_BIT) { 79443251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 7945315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis 0, __LINE__, VALIDATION_ERROR_140006a0, "DS", 79463251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "CreateRenderPass: Subpass %u requests multisample resolve from attachment %u " 79473251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "which has VK_SAMPLE_COUNT_1_BIT. %s", 7948315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis i, attachment, validation_error_map[VALIDATION_ERROR_140006a0]); 7949dc7c45f01ae5690f7c969b4760463c1a6bac52d5Chris Forbes } 7950ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton 7951ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton if (subpass_performs_resolve && subpass.pResolveAttachments[j].attachment != VK_ATTACHMENT_UNUSED) { 7952ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton const auto &color_desc = pCreateInfo->pAttachments[attachment]; 7953ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton const auto &resolve_desc = pCreateInfo->pAttachments[subpass.pResolveAttachments[j].attachment]; 7954ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton if (color_desc.format != resolve_desc.format) { 7955315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= 7956315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 7957315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis 0, __LINE__, VALIDATION_ERROR_140006a4, "DS", 7958315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis "CreateRenderPass: Subpass %u pColorAttachments[%u] resolves to an attachment with a " 7959315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis "different format. " 7960315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis "color format: %u, resolve format: %u. %s", 7961315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis i, j, color_desc.format, resolve_desc.format, validation_error_map[VALIDATION_ERROR_140006a4]); 7962ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton } 7963ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton } 7964497e33d6b0547f5dccca245a5b6777831fbb0de0Maciej Jesionowski 7965497e33d6b0547f5dccca245a5b6777831fbb0de0Maciej Jesionowski if (dev_data->extensions.vk_amd_mixed_attachment_samples && 7966497e33d6b0547f5dccca245a5b6777831fbb0de0Maciej Jesionowski subpass.pDepthStencilAttachment && subpass.pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) { 7967497e33d6b0547f5dccca245a5b6777831fbb0de0Maciej Jesionowski const auto depth_stencil_sample_count = pCreateInfo->pAttachments[subpass.pDepthStencilAttachment->attachment].samples; 7968497e33d6b0547f5dccca245a5b6777831fbb0de0Maciej Jesionowski if (pCreateInfo->pAttachments[attachment].samples > depth_stencil_sample_count) { 7969497e33d6b0547f5dccca245a5b6777831fbb0de0Maciej Jesionowski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 7970497e33d6b0547f5dccca245a5b6777831fbb0de0Maciej Jesionowski __LINE__, VALIDATION_ERROR_14000bc4, "DS", 7971497e33d6b0547f5dccca245a5b6777831fbb0de0Maciej Jesionowski "CreateRenderPass: Subpass %u pColorAttachments[%u] has %s which is larger than " 7972497e33d6b0547f5dccca245a5b6777831fbb0de0Maciej Jesionowski "depth/stencil attachment %s. %s", 7973497e33d6b0547f5dccca245a5b6777831fbb0de0Maciej Jesionowski i, j, string_VkSampleCountFlagBits(pCreateInfo->pAttachments[attachment].samples), 7974497e33d6b0547f5dccca245a5b6777831fbb0de0Maciej Jesionowski string_VkSampleCountFlagBits(depth_stencil_sample_count), validation_error_map[VALIDATION_ERROR_14000bc4]); 7975497e33d6b0547f5dccca245a5b6777831fbb0de0Maciej Jesionowski } 7976497e33d6b0547f5dccca245a5b6777831fbb0de0Maciej Jesionowski } 79776a3bc5f071fe21799f0f7ae844716c333f11f39cChris Forbes } 79784f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski } 7979dc7c45f01ae5690f7c969b4760463c1a6bac52d5Chris Forbes 79804f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski if (subpass.pDepthStencilAttachment && subpass.pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) { 79814f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski uint32_t attachment = subpass.pDepthStencilAttachment->attachment; 79823251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateAttachmentIndex(dev_data, attachment, pCreateInfo->attachmentCount, "Depth stencil"); 7983805ec497391f6bc513f7653ba6d535c509b54062Chris Forbes 79843251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip && attachment != VK_ATTACHMENT_UNUSED) { 7985805ec497391f6bc513f7653ba6d535c509b54062Chris Forbes sample_count |= (unsigned)pCreateInfo->pAttachments[attachment].samples; 7986805ec497391f6bc513f7653ba6d535c509b54062Chris Forbes } 79874f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski } 7988dc7c45f01ae5690f7c969b4760463c1a6bac52d5Chris Forbes 79894f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski for (uint32_t j = 0; j < subpass.inputAttachmentCount; ++j) { 79904f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski uint32_t attachment = subpass.pInputAttachments[j].attachment; 79913251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateAttachmentIndex(dev_data, attachment, pCreateInfo->attachmentCount, "Input"); 79924f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski } 7993805ec497391f6bc513f7653ba6d535c509b54062Chris Forbes 7994497e33d6b0547f5dccca245a5b6777831fbb0de0Maciej Jesionowski if (!dev_data->extensions.vk_amd_mixed_attachment_samples && 7995497e33d6b0547f5dccca245a5b6777831fbb0de0Maciej Jesionowski sample_count && !IsPowerOfTwo(sample_count)) { 79963251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 7997315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis __LINE__, VALIDATION_ERROR_0082b401, "DS", 79983251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "CreateRenderPass: Subpass %u attempts to render to " 79993251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "attachments with inconsistent sample counts. %s", 8000315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis i, validation_error_map[VALIDATION_ERROR_0082b401]); 8001805ec497391f6bc513f7653ba6d535c509b54062Chris Forbes } 80024f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski } 80033251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 80044f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski} 80054f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski 80065245a74f239ad662d9ca3675789ad41f37424ce6Chris Forbesstatic void MarkAttachmentFirstUse(RENDER_PASS_STATE *render_pass, 80075245a74f239ad662d9ca3675789ad41f37424ce6Chris Forbes uint32_t index, 80085245a74f239ad662d9ca3675789ad41f37424ce6Chris Forbes bool is_read) { 80095245a74f239ad662d9ca3675789ad41f37424ce6Chris Forbes if (index == VK_ATTACHMENT_UNUSED) 80105245a74f239ad662d9ca3675789ad41f37424ce6Chris Forbes return; 80115245a74f239ad662d9ca3675789ad41f37424ce6Chris Forbes 80125245a74f239ad662d9ca3675789ad41f37424ce6Chris Forbes if (!render_pass->attachment_first_read.count(index)) 80135245a74f239ad662d9ca3675789ad41f37424ce6Chris Forbes render_pass->attachment_first_read[index] = is_read; 80145245a74f239ad662d9ca3675789ad41f37424ce6Chris Forbes} 80155245a74f239ad662d9ca3675789ad41f37424ce6Chris Forbes 801689d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR VkResult VKAPI_CALL CreateRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo, 80174f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass) { 80183251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 801956e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 80204f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski 8021ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 80224f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski // TODO: As part of wrapping up the mem_tracker/core_validation merge the following routine should be consolidated with 80234f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski // ValidateLayouts. 80243251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateRenderpassAttachmentUsage(dev_data, pCreateInfo); 8025208aecf4cb59762be429488d7d4484f138c2cd81Tobin Ehlis for (uint32_t i = 0; i < pCreateInfo->dependencyCount; ++i) { 80263251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateStageMaskGsTsEnables(dev_data, pCreateInfo->pDependencies[i].srcStageMask, "vkCreateRenderPass()", 8027315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_13e006b8, VALIDATION_ERROR_13e006bc); 80283251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateStageMaskGsTsEnables(dev_data, pCreateInfo->pDependencies[i].dstStageMask, "vkCreateRenderPass()", 8029315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_13e006ba, VALIDATION_ERROR_13e006be); 8030208aecf4cb59762be429488d7d4484f138c2cd81Tobin Ehlis } 80313251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip) { 80323251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateLayouts(dev_data, device, pCreateInfo); 8033ab38df28c5ae1816c5fa33c0c7840c6950e83f0dChris Forbes } 8034ff6101de02d1677fb54962e2ff57875e76898e26Chris Forbes lock.unlock(); 80354f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski 80363251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (skip) { 80374f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski return VK_ERROR_VALIDATION_FAILED_EXT; 80384f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski } 80394f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski 80404a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.CreateRenderPass(device, pCreateInfo, pAllocator, pRenderPass); 8041ff6101de02d1677fb54962e2ff57875e76898e26Chris Forbes 80425b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (VK_SUCCESS == result) { 80434f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski lock.lock(); 80444f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski 80454f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski std::vector<bool> has_self_dependency(pCreateInfo->subpassCount); 80464f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski std::vector<DAGNode> subpass_to_node(pCreateInfo->subpassCount); 8047ea0a13226a513846fe5a7009783c5536b1255a56Tobin Ehlis std::vector<int32_t> subpass_to_dep_index(pCreateInfo->subpassCount); 8048ea0a13226a513846fe5a7009783c5536b1255a56Tobin Ehlis skip |= CreatePassDAG(dev_data, pCreateInfo, subpass_to_node, has_self_dependency, subpass_to_dep_index); 80494f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski 8050e6852f66a1f1eb57097dbf98b8218104849fda0fTobin Ehlis auto render_pass = std::make_shared<RENDER_PASS_STATE>(pCreateInfo); 805198cddf7090b5d5dcc382045867753ef703d1c3d3Chris Forbes render_pass->renderPass = *pRenderPass; 8052cf2686cdbb12af8a29ca598c126b5e37215f0ef7Chris Forbes render_pass->hasSelfDependency = has_self_dependency; 8053cf2686cdbb12af8a29ca598c126b5e37215f0ef7Chris Forbes render_pass->subpassToNode = subpass_to_node; 8054ea0a13226a513846fe5a7009783c5536b1255a56Tobin Ehlis render_pass->subpass_to_dependency_index = subpass_to_dep_index; 8055db6ad16f7690669bb664b970a8e5c47abb8db9faChris Forbes 805687e0afcd98dcf3c1e5e2cbb3023fe89d9dd10cd2Tobin Ehlis for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) { 805787e0afcd98dcf3c1e5e2cbb3023fe89d9dd10cd2Tobin Ehlis const VkSubpassDescription &subpass = pCreateInfo->pSubpasses[i]; 805887e0afcd98dcf3c1e5e2cbb3023fe89d9dd10cd2Tobin Ehlis for (uint32_t j = 0; j < subpass.colorAttachmentCount; ++j) { 80595245a74f239ad662d9ca3675789ad41f37424ce6Chris Forbes MarkAttachmentFirstUse(render_pass.get(), subpass.pColorAttachments[j].attachment, false); 80609cde292b1c19c643b7c13018d9834cccfe6ef7eaChris Forbes 80615245a74f239ad662d9ca3675789ad41f37424ce6Chris Forbes // resolve attachments are considered to be written 80625245a74f239ad662d9ca3675789ad41f37424ce6Chris Forbes if (subpass.pResolveAttachments) { 80635245a74f239ad662d9ca3675789ad41f37424ce6Chris Forbes MarkAttachmentFirstUse(render_pass.get(), subpass.pResolveAttachments[j].attachment, false); 80649cde292b1c19c643b7c13018d9834cccfe6ef7eaChris Forbes } 806587e0afcd98dcf3c1e5e2cbb3023fe89d9dd10cd2Tobin Ehlis } 80665245a74f239ad662d9ca3675789ad41f37424ce6Chris Forbes if (subpass.pDepthStencilAttachment) { 80675245a74f239ad662d9ca3675789ad41f37424ce6Chris Forbes MarkAttachmentFirstUse(render_pass.get(), subpass.pDepthStencilAttachment->attachment, false); 806887e0afcd98dcf3c1e5e2cbb3023fe89d9dd10cd2Tobin Ehlis } 8069a5ce96d7c88653668a2b33a6b72bd3cb16d73f48Michael Lentine for (uint32_t j = 0; j < subpass.inputAttachmentCount; ++j) { 80705245a74f239ad662d9ca3675789ad41f37424ce6Chris Forbes MarkAttachmentFirstUse(render_pass.get(), subpass.pInputAttachments[j].attachment, true); 8071a5ce96d7c88653668a2b33a6b72bd3cb16d73f48Michael Lentine } 807287e0afcd98dcf3c1e5e2cbb3023fe89d9dd10cd2Tobin Ehlis } 8073db6ad16f7690669bb664b970a8e5c47abb8db9faChris Forbes 8074fb13c2c4174108223d9f8e43084020eb09115ed6Chris Forbes dev_data->renderPassMap[*pRenderPass] = std::move(render_pass); 80755b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 80765b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 80775b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 80784f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski 8079eb4c61477130f69f48fdf3ac31cb82104181cc73Chris Forbesstatic bool validatePrimaryCommandBuffer(const layer_data *dev_data, const GLOBAL_CB_NODE *pCB, char const *cmd_name, 80809bd94c6fc216a1d67d5e98542519002fa56d19dbMike Schuchardt UNIQUE_VALIDATION_ERROR_CODE error_code) { 80813251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 80825b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pCB->createInfo.level != VK_COMMAND_BUFFER_LEVEL_PRIMARY) { 80833251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 80849b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pCB->commandBuffer), __LINE__, error_code, "DS", 80859b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "Cannot execute command %s on a secondary command buffer. %s", cmd_name, validation_error_map[error_code]); 80865b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 80873251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 80885b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 80895b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 80908860b85a52096f9f9b28616bc37feed505497a54Chris Forbesstatic bool VerifyRenderAreaBounds(const layer_data *dev_data, const VkRenderPassBeginInfo *pRenderPassBegin) { 80913251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 8092c54e405a4ce05f4de10bb78bfc3a4769c41d2d59Tobin Ehlis const safe_VkFramebufferCreateInfo *pFramebufferInfo = 80939a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis &GetFramebufferState(dev_data, pRenderPassBegin->framebuffer)->createInfo; 8094885537d813d6fb3d199e76f6d63b6d3f78d0eeb0Michael Lentine if (pRenderPassBegin->renderArea.offset.x < 0 || 8095885537d813d6fb3d199e76f6d63b6d3f78d0eeb0Michael Lentine (pRenderPassBegin->renderArea.offset.x + pRenderPassBegin->renderArea.extent.width) > pFramebufferInfo->width || 8096885537d813d6fb3d199e76f6d63b6d3f78d0eeb0Michael Lentine pRenderPassBegin->renderArea.offset.y < 0 || 8097885537d813d6fb3d199e76f6d63b6d3f78d0eeb0Michael Lentine (pRenderPassBegin->renderArea.offset.y + pRenderPassBegin->renderArea.extent.height) > pFramebufferInfo->height) { 80983251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= static_cast<bool>(log_msg( 8099df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 8100885537d813d6fb3d199e76f6d63b6d3f78d0eeb0Michael Lentine DRAWSTATE_INVALID_RENDER_AREA, "CORE", 8101885537d813d6fb3d199e76f6d63b6d3f78d0eeb0Michael Lentine "Cannot execute a render pass with renderArea not within the bound of the " 8102885537d813d6fb3d199e76f6d63b6d3f78d0eeb0Michael Lentine "framebuffer. RenderArea: x %d, y %d, width %d, height %d. Framebuffer: width %d, " 8103885537d813d6fb3d199e76f6d63b6d3f78d0eeb0Michael Lentine "height %d.", 8104885537d813d6fb3d199e76f6d63b6d3f78d0eeb0Michael Lentine pRenderPassBegin->renderArea.offset.x, pRenderPassBegin->renderArea.offset.y, pRenderPassBegin->renderArea.extent.width, 8105885537d813d6fb3d199e76f6d63b6d3f78d0eeb0Michael Lentine pRenderPassBegin->renderArea.extent.height, pFramebufferInfo->width, pFramebufferInfo->height)); 8106885537d813d6fb3d199e76f6d63b6d3f78d0eeb0Michael Lentine } 81073251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 8108885537d813d6fb3d199e76f6d63b6d3f78d0eeb0Michael Lentine} 8109885537d813d6fb3d199e76f6d63b6d3f78d0eeb0Michael Lentine 81101a65650f856376768d7b03ea2d080aaff87cacfdMark 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 81111a65650f856376768d7b03ea2d080aaff87cacfdMark Lobodzinski// [load|store]Op flag must be checked 81121a65650f856376768d7b03ea2d080aaff87cacfdMark Lobodzinski// TODO: The memory valid flag in DEVICE_MEM_INFO should probably be split to track the validity of stencil memory separately. 8113cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinskitemplate <typename T> 8114cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinskistatic bool FormatSpecificLoadAndStoreOpSettings(VkFormat format, T color_depth_op, T stencil_op, T op) { 8115a49b8a211ce07e7fa2225d23f8cb11f1055b418aMark Lobodzinski if (color_depth_op != op && stencil_op != op) { 8116a49b8a211ce07e7fa2225d23f8cb11f1055b418aMark Lobodzinski return false; 8117a49b8a211ce07e7fa2225d23f8cb11f1055b418aMark Lobodzinski } 811816769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton bool check_color_depth_load_op = !FormatIsStencilOnly(format); 811916769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton bool check_stencil_load_op = FormatIsDepthAndStencil(format) || !check_color_depth_load_op; 8120a49b8a211ce07e7fa2225d23f8cb11f1055b418aMark Lobodzinski 81210d9453d85335963d6cabfbf400b058dc905ea238Chris Forbes return ((check_color_depth_load_op && (color_depth_op == op)) || 81220d9453d85335963d6cabfbf400b058dc905ea238Chris Forbes (check_stencil_load_op && (stencil_op == op))); 81231a65650f856376768d7b03ea2d080aaff87cacfdMark Lobodzinski} 81241a65650f856376768d7b03ea2d080aaff87cacfdMark Lobodzinski 8125bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdBeginRenderPass(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo *pRenderPassBegin, 8126bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkSubpassContents contents) { 81273251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 812856e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 8129ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 81309a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *cb_node = GetCBNode(dev_data, commandBuffer); 81319a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto render_pass_state = pRenderPassBegin ? GetRenderPassState(dev_data, pRenderPassBegin->renderPass) : nullptr; 81329a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto framebuffer = pRenderPassBegin ? GetFramebufferState(dev_data, pRenderPassBegin->framebuffer) : nullptr; 8133f909505280723ee24d2e74afc759d38dc09a37beTobin Ehlis if (cb_node) { 8134308153fd68fc050a302201fb5a7cca53de8dc866Mark Lobodzinski if (render_pass_state) { 8135cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski uint32_t clear_op_size = 0; // Make sure pClearValues is at least as large as last LOAD_OP_CLEAR 8136f909505280723ee24d2e74afc759d38dc09a37beTobin Ehlis cb_node->activeFramebuffer = pRenderPassBegin->framebuffer; 8137308153fd68fc050a302201fb5a7cca53de8dc866Mark Lobodzinski for (uint32_t i = 0; i < render_pass_state->createInfo.attachmentCount; ++i) { 8138f40ab6d10b8d755ce0e461c33916b0d4d5a5d437Chris Forbes MT_FB_ATTACHMENT_INFO &fb_info = framebuffer->attachments[i]; 8139308153fd68fc050a302201fb5a7cca53de8dc866Mark Lobodzinski auto pAttachment = &render_pass_state->createInfo.pAttachments[i]; 8140bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski if (FormatSpecificLoadAndStoreOpSettings(pAttachment->format, pAttachment->loadOp, pAttachment->stencilLoadOp, 81411a65650f856376768d7b03ea2d080aaff87cacfdMark Lobodzinski VK_ATTACHMENT_LOAD_OP_CLEAR)) { 814292bc0680357019834b7529148ab6d73353ce02c7Mark Lobodzinski clear_op_size = static_cast<uint32_t>(i) + 1; 814316387282d11e414ae7cb9ddf3d0c1bebf8f2c74dChris Forbes std::function<bool()> function = [=]() { 81449a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis SetImageMemoryValid(dev_data, GetImageState(dev_data, fb_info.image), true); 814516387282d11e414ae7cb9ddf3d0c1bebf8f2c74dChris Forbes return false; 814616387282d11e414ae7cb9ddf3d0c1bebf8f2c74dChris Forbes }; 8147d807198f24437c1b2478ff1d06a33ce4873a1451Tobin Ehlis cb_node->queue_submit_functions.push_back(function); 8148db6ad16f7690669bb664b970a8e5c47abb8db9faChris Forbes } else if (FormatSpecificLoadAndStoreOpSettings(pAttachment->format, pAttachment->loadOp, 8149bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski pAttachment->stencilLoadOp, VK_ATTACHMENT_LOAD_OP_DONT_CARE)) { 815016387282d11e414ae7cb9ddf3d0c1bebf8f2c74dChris Forbes std::function<bool()> function = [=]() { 81519a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis SetImageMemoryValid(dev_data, GetImageState(dev_data, fb_info.image), false); 815216387282d11e414ae7cb9ddf3d0c1bebf8f2c74dChris Forbes return false; 815316387282d11e414ae7cb9ddf3d0c1bebf8f2c74dChris Forbes }; 8154d807198f24437c1b2478ff1d06a33ce4873a1451Tobin Ehlis cb_node->queue_submit_functions.push_back(function); 8155db6ad16f7690669bb664b970a8e5c47abb8db9faChris Forbes } else if (FormatSpecificLoadAndStoreOpSettings(pAttachment->format, pAttachment->loadOp, 8156bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski pAttachment->stencilLoadOp, VK_ATTACHMENT_LOAD_OP_LOAD)) { 815716387282d11e414ae7cb9ddf3d0c1bebf8f2c74dChris Forbes std::function<bool()> function = [=]() { 81589a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis return ValidateImageMemoryIsValid(dev_data, GetImageState(dev_data, fb_info.image), 8159f989de4217bce0f293121d0da53dc8328276370fTobin Ehlis "vkCmdBeginRenderPass()"); 816016387282d11e414ae7cb9ddf3d0c1bebf8f2c74dChris Forbes }; 8161d807198f24437c1b2478ff1d06a33ce4873a1451Tobin Ehlis cb_node->queue_submit_functions.push_back(function); 816216387282d11e414ae7cb9ddf3d0c1bebf8f2c74dChris Forbes } 8163308153fd68fc050a302201fb5a7cca53de8dc866Mark Lobodzinski if (render_pass_state->attachment_first_read[i]) { 816416387282d11e414ae7cb9ddf3d0c1bebf8f2c74dChris Forbes std::function<bool()> function = [=]() { 81659a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis return ValidateImageMemoryIsValid(dev_data, GetImageState(dev_data, fb_info.image), 8166f989de4217bce0f293121d0da53dc8328276370fTobin Ehlis "vkCmdBeginRenderPass()"); 816716387282d11e414ae7cb9ddf3d0c1bebf8f2c74dChris Forbes }; 8168d807198f24437c1b2478ff1d06a33ce4873a1451Tobin Ehlis cb_node->queue_submit_functions.push_back(function); 81695b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 81705b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 81716de3c6ffa0819ee37cd5cecee918b062145e2ff1Tobin Ehlis if (clear_op_size > pRenderPassBegin->clearValueCount) { 81723251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg( 8173369cf6deef1fca74f9eb1f8ef6e96deba715b133Slawomir Cygan dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, 8174315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(render_pass_state->renderPass), __LINE__, VALIDATION_ERROR_1200070c, "DS", 8175bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski "In vkCmdBeginRenderPass() the VkRenderPassBeginInfo struct has a clearValueCount of %u but there must " 8176bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski "be at least %u entries in pClearValues array to account for the highest index attachment in renderPass " 8177cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "0x%" PRIx64 8178cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski " that uses VK_ATTACHMENT_LOAD_OP_CLEAR is %u. Note that the pClearValues array " 8179bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski "is indexed by attachment number so even if some pClearValues entries between 0 and %u correspond to " 8180bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski "attachments that aren't cleared they will be ignored. %s", 81819b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus pRenderPassBegin->clearValueCount, clear_op_size, HandleToUint64(render_pass_state->renderPass), clear_op_size, 8182315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis clear_op_size - 1, validation_error_map[VALIDATION_ERROR_1200070c]); 8183369cf6deef1fca74f9eb1f8ef6e96deba715b133Slawomir Cygan } 81843251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= VerifyRenderAreaBounds(dev_data, pRenderPassBegin); 81853251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= VerifyFramebufferAndRenderPassLayouts(dev_data, cb_node, pRenderPassBegin, 81863251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski GetFramebufferState(dev_data, pRenderPassBegin->framebuffer)); 81879d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis if (framebuffer->rp_state->renderPass != render_pass_state->renderPass) { 81889d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis skip |= validateRenderPassCompatibility(dev_data, "render pass", render_pass_state, "framebuffer", 8189ba9be0cec36d930fc0d5a0cbfbc00b0df49b08e4Tobin Ehlis framebuffer->rp_state.get(), "vkCmdBeginRenderPass()", 8190ba9be0cec36d930fc0d5a0cbfbc00b0df49b08e4Tobin Ehlis VALIDATION_ERROR_12000710); 81919d5a67a009fe27e9b5404ec035ab84ed34332e5eTobin Ehlis } 8192315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= insideRenderPass(dev_data, cb_node, "vkCmdBeginRenderPass()", VALIDATION_ERROR_17a00017); 81933251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateDependencies(dev_data, framebuffer, render_pass_state); 8194315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= validatePrimaryCommandBuffer(dev_data, cb_node, "vkCmdBeginRenderPass()", VALIDATION_ERROR_17a00019); 8195315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateCmdQueueFlags(dev_data, cb_node, "vkCmdBeginRenderPass()", VK_QUEUE_GRAPHICS_BIT, 8196315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_17a02415); 81973251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateCmd(dev_data, cb_node, CMD_BEGINRENDERPASS, "vkCmdBeginRenderPass()"); 8198308153fd68fc050a302201fb5a7cca53de8dc866Mark Lobodzinski cb_node->activeRenderPass = render_pass_state; 81995b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // This is a shallow copy as that is all that is needed for now 8200f909505280723ee24d2e74afc759d38dc09a37beTobin Ehlis cb_node->activeRenderPassBeginInfo = *pRenderPassBegin; 8201f909505280723ee24d2e74afc759d38dc09a37beTobin Ehlis cb_node->activeSubpass = 0; 8202f909505280723ee24d2e74afc759d38dc09a37beTobin Ehlis cb_node->activeSubpassContents = contents; 8203f909505280723ee24d2e74afc759d38dc09a37beTobin Ehlis cb_node->framebuffers.insert(pRenderPassBegin->framebuffer); 8204883ee3f865f9dbd83134d148b26e96cb6a926b3dTobin Ehlis // Connect this framebuffer and its children to this cmdBuffer 8205883ee3f865f9dbd83134d148b26e96cb6a926b3dTobin Ehlis AddFramebufferBinding(dev_data, cb_node, framebuffer); 8206e03f0c649de6e228761ae301b57494db4eabe4aeTobin Ehlis // Connect this RP to cmdBuffer 8207e03f0c649de6e228761ae301b57494db4eabe4aeTobin Ehlis addCommandBufferBinding(&render_pass_state->cb_bindings, 8208e03f0c649de6e228761ae301b57494db4eabe4aeTobin Ehlis {HandleToUint64(render_pass_state->renderPass), kVulkanObjectTypeRenderPass}, cb_node); 82095f025a7d647e3257e12a816fa1db078b5fc8ed49Tobin Ehlis // transition attachments to the correct layouts for beginning of renderPass and first subpass 82105f025a7d647e3257e12a816fa1db078b5fc8ed49Tobin Ehlis TransitionBeginRenderPassLayouts(dev_data, cb_node, render_pass_state, framebuffer); 82115b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 82125b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 8213b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 82143251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip) { 82154a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.CmdBeginRenderPass(commandBuffer, pRenderPassBegin, contents); 82165b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 82175b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 82185b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 821989d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR void VKAPI_CALL CmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents) { 82203251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 822156e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 8222ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 82239a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); 82245b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pCB) { 8225315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= validatePrimaryCommandBuffer(dev_data, pCB, "vkCmdNextSubpass()", VALIDATION_ERROR_1b600019); 8226315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateCmdQueueFlags(dev_data, pCB, "vkCmdNextSubpass()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_1b602415); 82273251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateCmd(dev_data, pCB, CMD_NEXTSUBPASS, "vkCmdNextSubpass()"); 8228315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= outsideRenderPass(dev_data, pCB, "vkCmdNextSubpass()", VALIDATION_ERROR_1b600017); 822980281691386b37385846f21b38e8c9d4b12cc74eChris Forbes 8230fb13c2c4174108223d9f8e43084020eb09115ed6Chris Forbes auto subpassCount = pCB->activeRenderPass->createInfo.subpassCount; 823180281691386b37385846f21b38e8c9d4b12cc74eChris Forbes if (pCB->activeSubpass == subpassCount - 1) { 82323251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 8233315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(commandBuffer), __LINE__, VALIDATION_ERROR_1b60071a, "DS", 82343251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkCmdNextSubpass(): Attempted to advance beyond final subpass. %s", 8235315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_1b60071a]); 823680281691386b37385846f21b38e8c9d4b12cc74eChris Forbes } 82375b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 8238b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 823996ebb1e373cc0993339e2ecc1dc47e9918406f87Chris Forbes 82403251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (skip) return; 824196ebb1e373cc0993339e2ecc1dc47e9918406f87Chris Forbes 82424a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.CmdNextSubpass(commandBuffer, contents); 824396ebb1e373cc0993339e2ecc1dc47e9918406f87Chris Forbes 824496ebb1e373cc0993339e2ecc1dc47e9918406f87Chris Forbes if (pCB) { 8245bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski lock.lock(); 8246bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski pCB->activeSubpass++; 8247bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski pCB->activeSubpassContents = contents; 82485f025a7d647e3257e12a816fa1db078b5fc8ed49Tobin Ehlis TransitionSubpassLayouts(dev_data, pCB, pCB->activeRenderPass, pCB->activeSubpass, 82499a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GetFramebufferState(dev_data, pCB->activeRenderPassBeginInfo.framebuffer)); 825096ebb1e373cc0993339e2ecc1dc47e9918406f87Chris Forbes } 82515b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 82525b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 825389d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR void VKAPI_CALL CmdEndRenderPass(VkCommandBuffer commandBuffer) { 82543251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 825556e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 8256ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 82579a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pCB = GetCBNode(dev_data, commandBuffer); 825855867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski FRAMEBUFFER_STATE *framebuffer = NULL; 825958c3d40b47b6b30c1e7c508ec14ee67fcd238c93Chris Forbes if (pCB) { 8260127937bcdb5817ee4568887c298ce36c88f3c58bTobin Ehlis RENDER_PASS_STATE *rp_state = pCB->activeRenderPass; 82619a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis framebuffer = GetFramebufferState(dev_data, pCB->activeFramebuffer); 8262127937bcdb5817ee4568887c298ce36c88f3c58bTobin Ehlis if (rp_state) { 8263127937bcdb5817ee4568887c298ce36c88f3c58bTobin Ehlis if (pCB->activeSubpass != rp_state->createInfo.subpassCount - 1) { 82643251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 82659b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, HandleToUint64(commandBuffer), __LINE__, 8266315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1b00071c, "DS", "vkCmdEndRenderPass(): Called before reaching final subpass. %s", 8267315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_1b00071c]); 826802a3382f28fc7c6ec6018165be88aa6fc4f05c9eChris Forbes } 826902a3382f28fc7c6ec6018165be88aa6fc4f05c9eChris Forbes 8270127937bcdb5817ee4568887c298ce36c88f3c58bTobin Ehlis for (size_t i = 0; i < rp_state->createInfo.attachmentCount; ++i) { 8271e3ad4b1284408353cc56a04951c1df1f35a636ceChris Forbes MT_FB_ATTACHMENT_INFO &fb_info = framebuffer->attachments[i]; 8272127937bcdb5817ee4568887c298ce36c88f3c58bTobin Ehlis auto pAttachment = &rp_state->createInfo.pAttachments[i]; 8273bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski if (FormatSpecificLoadAndStoreOpSettings(pAttachment->format, pAttachment->storeOp, pAttachment->stencilStoreOp, 8274bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VK_ATTACHMENT_STORE_OP_STORE)) { 827558c3d40b47b6b30c1e7c508ec14ee67fcd238c93Chris Forbes std::function<bool()> function = [=]() { 82769a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis SetImageMemoryValid(dev_data, GetImageState(dev_data, fb_info.image), true); 827758c3d40b47b6b30c1e7c508ec14ee67fcd238c93Chris Forbes return false; 827858c3d40b47b6b30c1e7c508ec14ee67fcd238c93Chris Forbes }; 8279d807198f24437c1b2478ff1d06a33ce4873a1451Tobin Ehlis pCB->queue_submit_functions.push_back(function); 8280db6ad16f7690669bb664b970a8e5c47abb8db9faChris Forbes } else if (FormatSpecificLoadAndStoreOpSettings(pAttachment->format, pAttachment->storeOp, 8281bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski pAttachment->stencilStoreOp, VK_ATTACHMENT_STORE_OP_DONT_CARE)) { 828258c3d40b47b6b30c1e7c508ec14ee67fcd238c93Chris Forbes std::function<bool()> function = [=]() { 82839a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis SetImageMemoryValid(dev_data, GetImageState(dev_data, fb_info.image), false); 828458c3d40b47b6b30c1e7c508ec14ee67fcd238c93Chris Forbes return false; 828558c3d40b47b6b30c1e7c508ec14ee67fcd238c93Chris Forbes }; 8286d807198f24437c1b2478ff1d06a33ce4873a1451Tobin Ehlis pCB->queue_submit_functions.push_back(function); 82875b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 82885b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 82895b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 8290315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= outsideRenderPass(dev_data, pCB, "vkCmdEndRenderpass()", VALIDATION_ERROR_1b000017); 8291315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= validatePrimaryCommandBuffer(dev_data, pCB, "vkCmdEndRenderPass()", VALIDATION_ERROR_1b000019); 8292315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateCmdQueueFlags(dev_data, pCB, "vkCmdEndRenderPass()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_1b002415); 82933251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateCmd(dev_data, pCB, CMD_ENDRENDERPASS, "vkCmdEndRenderPass()"); 82940e21dda98453b5ced1fe7a2ffd5ca4b21847fe09Chris Forbes } 82950e21dda98453b5ced1fe7a2ffd5ca4b21847fe09Chris Forbes lock.unlock(); 82960e21dda98453b5ced1fe7a2ffd5ca4b21847fe09Chris Forbes 82973251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (skip) return; 82980e21dda98453b5ced1fe7a2ffd5ca4b21847fe09Chris Forbes 82994a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.CmdEndRenderPass(commandBuffer); 83000e21dda98453b5ced1fe7a2ffd5ca4b21847fe09Chris Forbes 83010e21dda98453b5ced1fe7a2ffd5ca4b21847fe09Chris Forbes if (pCB) { 83020e21dda98453b5ced1fe7a2ffd5ca4b21847fe09Chris Forbes lock.lock(); 830355867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski TransitionFinalSubpassLayouts(dev_data, pCB, &pCB->activeRenderPassBeginInfo, framebuffer); 830458c3d40b47b6b30c1e7c508ec14ee67fcd238c93Chris Forbes pCB->activeRenderPass = nullptr; 830558c3d40b47b6b30c1e7c508ec14ee67fcd238c93Chris Forbes pCB->activeSubpass = 0; 830658c3d40b47b6b30c1e7c508ec14ee67fcd238c93Chris Forbes pCB->activeFramebuffer = VK_NULL_HANDLE; 83075b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 83085b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 83095b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 8310e3319189d6f8e3126522df7a5935d2c42f656291Dustin Gravesstatic bool validateFramebuffer(layer_data *dev_data, VkCommandBuffer primaryBuffer, const GLOBAL_CB_NODE *pCB, 831194983abdca3266bfd87e708f31fda2b56b1b547dTobin Ehlis VkCommandBuffer secondaryBuffer, const GLOBAL_CB_NODE *pSubCB, const char *caller) { 83123251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 83135b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (!pSubCB->beginInfo.pInheritanceInfo) { 83143251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 83155b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 8316c5b97dda856ff837638b3ebb7e231d5507c495a3Chris Forbes VkFramebuffer primary_fb = pCB->activeFramebuffer; 83175b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis VkFramebuffer secondary_fb = pSubCB->beginInfo.pInheritanceInfo->framebuffer; 83185b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (secondary_fb != VK_NULL_HANDLE) { 83195b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (primary_fb != secondary_fb) { 83203251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 8321315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(primaryBuffer), __LINE__, VALIDATION_ERROR_1b2000c6, "DS", 83223251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkCmdExecuteCommands() called w/ invalid secondary command buffer 0x%" PRIx64 83233251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski " which has a framebuffer 0x%" PRIx64 83243251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski " that is not the same as the primary command buffer's current active framebuffer 0x%" PRIx64 ". %s", 83259b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(secondaryBuffer), HandleToUint64(secondary_fb), HandleToUint64(primary_fb), 8326315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_1b2000c6]); 83275b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 83289a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto fb = GetFramebufferState(dev_data, secondary_fb); 8329e3ad4b1284408353cc56a04951c1df1f35a636ceChris Forbes if (!fb) { 83303251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 83319b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(primaryBuffer), __LINE__, DRAWSTATE_INVALID_SECONDARY_COMMAND_BUFFER, "DS", 83323251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkCmdExecuteCommands() called w/ invalid Cmd Buffer 0x%p " 83333251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "which has invalid framebuffer 0x%" PRIx64 ".", 83349b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus (void *)secondaryBuffer, HandleToUint64(secondary_fb)); 83353251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 83365b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 83375b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 83383251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 83395b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 83405b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 8341e3319189d6f8e3126522df7a5935d2c42f656291Dustin Gravesstatic bool validateSecondaryCommandBufferState(layer_data *dev_data, GLOBAL_CB_NODE *pCB, GLOBAL_CB_NODE *pSubCB) { 83423251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 83435b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis unordered_set<int> activeTypes; 83445b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (auto queryObject : pCB->activeQueries) { 83455b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis auto queryPoolData = dev_data->queryPoolMap.find(queryObject.pool); 83465b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (queryPoolData != dev_data->queryPoolMap.end()) { 83475b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (queryPoolData->second.createInfo.queryType == VK_QUERY_TYPE_PIPELINE_STATISTICS && 83485b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pSubCB->beginInfo.pInheritanceInfo) { 83495b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis VkQueryPipelineStatisticFlags cmdBufStatistics = pSubCB->beginInfo.pInheritanceInfo->pipelineStatistics; 83505b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if ((cmdBufStatistics & queryPoolData->second.createInfo.pipelineStatistics) != cmdBufStatistics) { 83519b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip |= log_msg( 83529b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 8353315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pCB->commandBuffer), __LINE__, VALIDATION_ERROR_1b2000d0, "DS", 83549b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "vkCmdExecuteCommands() called w/ invalid Cmd Buffer 0x%p " 83559b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "which has invalid active query pool 0x%" PRIx64 83569b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus ". Pipeline statistics is being queried so the command " 83579b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "buffer must have all bits set on the queryPool. %s", 8358315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis pCB->commandBuffer, HandleToUint64(queryPoolData->first), validation_error_map[VALIDATION_ERROR_1b2000d0]); 83595b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 83605b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 83615b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis activeTypes.insert(queryPoolData->second.createInfo.queryType); 83625b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 83635b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 83645b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (auto queryObject : pSubCB->startedQueries) { 83655b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis auto queryPoolData = dev_data->queryPoolMap.find(queryObject.pool); 83665b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (queryPoolData != dev_data->queryPoolMap.end() && activeTypes.count(queryPoolData->second.createInfo.queryType)) { 83679b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 83689b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pCB->commandBuffer), __LINE__, DRAWSTATE_INVALID_SECONDARY_COMMAND_BUFFER, "DS", 83699b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "vkCmdExecuteCommands() called w/ invalid Cmd Buffer 0x%p " 83709b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "which has invalid active query pool 0x%" PRIx64 83719b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "of type %d but a query of that type has been started on " 83729b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "secondary Cmd Buffer 0x%p.", 83739b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus pCB->commandBuffer, HandleToUint64(queryPoolData->first), queryPoolData->second.createInfo.queryType, 83749b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus pSubCB->commandBuffer); 83755b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 83765b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 83777bd96b29f4b8df99339ff1f7bc64f2f8940f8d25Mark Lobodzinski 83789a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto primary_pool = GetCommandPoolNode(dev_data, pCB->createInfo.commandPool); 83799a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto secondary_pool = GetCommandPoolNode(dev_data, pSubCB->createInfo.commandPool); 83807bd96b29f4b8df99339ff1f7bc64f2f8940f8d25Mark Lobodzinski if (primary_pool && secondary_pool && (primary_pool->queueFamilyIndex != secondary_pool->queueFamilyIndex)) { 83813251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= 8382226a75bff897619b86cc227cf1196b5e245fb96dTobin Ehlis log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 83839b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pSubCB->commandBuffer), __LINE__, DRAWSTATE_INVALID_QUEUE_FAMILY, "DS", 8384226a75bff897619b86cc227cf1196b5e245fb96dTobin Ehlis "vkCmdExecuteCommands(): Primary command buffer 0x%p" 8385226a75bff897619b86cc227cf1196b5e245fb96dTobin Ehlis " created in queue family %d has secondary command buffer 0x%p created in queue family %d.", 8386226a75bff897619b86cc227cf1196b5e245fb96dTobin Ehlis pCB->commandBuffer, primary_pool->queueFamilyIndex, pSubCB->commandBuffer, secondary_pool->queueFamilyIndex); 83877bd96b29f4b8df99339ff1f7bc64f2f8940f8d25Mark Lobodzinski } 83887bd96b29f4b8df99339ff1f7bc64f2f8940f8d25Mark Lobodzinski 83893251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 83905b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 83915b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 8392bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBuffersCount, 8393bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkCommandBuffer *pCommandBuffers) { 83943251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 839556e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 8396ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 83979a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); 83985b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pCB) { 83995b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis GLOBAL_CB_NODE *pSubCB = NULL; 84005b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t i = 0; i < commandBuffersCount; i++) { 84019a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis pSubCB = GetCBNode(dev_data, pCommandBuffers[i]); 84020a8b955c23012196339f3c10ffedc631ea0f7c58Tobin Ehlis assert(pSubCB); 84030a8b955c23012196339f3c10ffedc631ea0f7c58Tobin Ehlis if (VK_COMMAND_BUFFER_LEVEL_PRIMARY == pSubCB->createInfo.level) { 84043251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= 8405df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 8406315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pCommandBuffers[i]), __LINE__, VALIDATION_ERROR_1b2000b0, "DS", 8407df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski "vkCmdExecuteCommands() called w/ Primary Cmd Buffer 0x%p in element %u of pCommandBuffers " 8408df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski "array. All cmd buffers in pCommandBuffers array must be secondary. %s", 8409315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis pCommandBuffers[i], i, validation_error_map[VALIDATION_ERROR_1b2000b0]); 8410cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } else if (pCB->activeRenderPass) { // Secondary CB w/i RenderPass must have *CONTINUE_BIT set 84110de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski if (pSubCB->beginInfo.pInheritanceInfo != nullptr) { 84120de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski auto secondary_rp_state = GetRenderPassState(dev_data, pSubCB->beginInfo.pInheritanceInfo->renderPass); 84130de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski if (!(pSubCB->beginInfo.flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT)) { 84140de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski skip |= log_msg( 84150de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 8416315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pCommandBuffers[i]), __LINE__, VALIDATION_ERROR_1b2000c0, "DS", 84170de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski "vkCmdExecuteCommands(): Secondary Command Buffer (0x%p) executed within render pass (0x%" PRIxLEAST64 84180de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski ") must have had vkBeginCommandBuffer() called w/ VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT " 84190de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski "set. %s", 84200de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski pCommandBuffers[i], HandleToUint64(pCB->activeRenderPass->renderPass), 8421315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_1b2000c0]); 84220de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski } else { 84230de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski // Make sure render pass is compatible with parent command buffer pass if has continue 84240de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski if (pCB->activeRenderPass->renderPass != secondary_rp_state->renderPass) { 842594983abdca3266bfd87e708f31fda2b56b1b547dTobin Ehlis skip |= validateRenderPassCompatibility(dev_data, "primary command buffer", pCB->activeRenderPass, 842694983abdca3266bfd87e708f31fda2b56b1b547dTobin Ehlis "secondary command buffer", secondary_rp_state, 842794983abdca3266bfd87e708f31fda2b56b1b547dTobin Ehlis "vkCmdExecuteCommands()", VALIDATION_ERROR_1b2000c4); 84280de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski } 84290de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski // If framebuffer for secondary CB is not NULL, then it must match active FB from primaryCB 843094983abdca3266bfd87e708f31fda2b56b1b547dTobin Ehlis skip |= 843194983abdca3266bfd87e708f31fda2b56b1b547dTobin Ehlis validateFramebuffer(dev_data, commandBuffer, pCB, pCommandBuffers[i], pSubCB, "vkCmdExecuteCommands()"); 8432f384f33742c2b72888372332747298d08135ac92Tobin Ehlis if (VK_NULL_HANDLE == pSubCB->activeFramebuffer) { 843379fc00370d55e7cbfd4052b579120e64b0a1a4beTobin Ehlis // Inherit primary's activeFramebuffer and while running validate functions 843479fc00370d55e7cbfd4052b579120e64b0a1a4beTobin Ehlis for (auto &function : pSubCB->cmd_execute_commands_functions) { 843579fc00370d55e7cbfd4052b579120e64b0a1a4beTobin Ehlis skip |= function(pCB->activeFramebuffer); 8436f384f33742c2b72888372332747298d08135ac92Tobin Ehlis } 8437f384f33742c2b72888372332747298d08135ac92Tobin Ehlis } 84380de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski } 84395b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 84405b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 84415b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // TODO(mlentine): Move more logic into this method 84423251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= validateSecondaryCommandBufferState(dev_data, pCB, pSubCB); 8443315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= validateCommandBufferState(dev_data, pSubCB, "vkCmdExecuteCommands()", 0, VALIDATION_ERROR_1b2000b2); 84445b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (!(pSubCB->beginInfo.flags & VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT)) { 84459b2582dc67737351a72fbeb82e9e6e8cdff7a026Chris Forbes if (pSubCB->in_use.load() || pCB->linkedCommandBuffers.count(pSubCB)) { 84463251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 84479b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, HandleToUint64(pCB->commandBuffer), __LINE__, 8448315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1b2000b4, "DS", 84493251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Attempt to simultaneously execute command buffer 0x%p" 84503251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski " without VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT set! %s", 8451315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis pCB->commandBuffer, validation_error_map[VALIDATION_ERROR_1b2000b4]); 84525b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 84535b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pCB->beginInfo.flags & VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT) { 84545b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Warn that non-simultaneous secondary cmd buffer renders primary non-simultaneous 84553251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg( 84565b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 84579b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pCommandBuffers[i]), __LINE__, DRAWSTATE_INVALID_CB_SIMULTANEOUS_USE, "DS", 8458226a75bff897619b86cc227cf1196b5e245fb96dTobin Ehlis "vkCmdExecuteCommands(): Secondary Command Buffer (0x%p) " 8459226a75bff897619b86cc227cf1196b5e245fb96dTobin Ehlis "does not have VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT set and will cause primary command buffer " 8460226a75bff897619b86cc227cf1196b5e245fb96dTobin Ehlis "(0x%p) to be treated as if it does not have VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT " 846183b40cb743b7d87753e7503b148fef660ca45289Tobin Ehlis "set, even though it does.", 8462226a75bff897619b86cc227cf1196b5e245fb96dTobin Ehlis pCommandBuffers[i], pCB->commandBuffer); 84635b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->beginInfo.flags &= ~VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT; 84645b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 84655b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 8466f71dd305f197826a61f398bff725267a20ea1d90Chris Forbes if (!pCB->activeQueries.empty() && !dev_data->enabled_features.inheritedQueries) { 84673251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= 8468cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 8469315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pCommandBuffers[i]), __LINE__, VALIDATION_ERROR_1b2000ca, "DS", 8470cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "vkCmdExecuteCommands(): Secondary Command Buffer " 8471cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "(0x%p) cannot be submitted with a query in " 8472cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "flight and inherited queries not " 8473cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "supported on this device. %s", 8474315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis pCommandBuffers[i], validation_error_map[VALIDATION_ERROR_1b2000ca]); 84755b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 84769b2582dc67737351a72fbeb82e9e6e8cdff7a026Chris Forbes // TODO: separate validate from update! This is very tangled. 84778567fecbf563420f5900ade277ca68908aa87259Tobin Ehlis // Propagate layout transitions to the primary cmd buffer 84788567fecbf563420f5900ade277ca68908aa87259Tobin Ehlis for (auto ilm_entry : pSubCB->imageLayoutMap) { 84791fdcd3bc7fbd85f567a8270f6b7354c6f7b67661Alex Smith if (pCB->imageLayoutMap.find(ilm_entry.first) != pCB->imageLayoutMap.end()) { 84801fdcd3bc7fbd85f567a8270f6b7354c6f7b67661Alex Smith pCB->imageLayoutMap[ilm_entry.first].layout = ilm_entry.second.layout; 84811fdcd3bc7fbd85f567a8270f6b7354c6f7b67661Alex Smith } else { 84821fdcd3bc7fbd85f567a8270f6b7354c6f7b67661Alex Smith assert(ilm_entry.first.hasSubresource); 84831fdcd3bc7fbd85f567a8270f6b7354c6f7b67661Alex Smith IMAGE_CMD_BUF_LAYOUT_NODE node; 84841fdcd3bc7fbd85f567a8270f6b7354c6f7b67661Alex Smith if (!FindCmdBufLayout(dev_data, pCB, ilm_entry.first.image, ilm_entry.first.subresource, node)) { 84851fdcd3bc7fbd85f567a8270f6b7354c6f7b67661Alex Smith node.initialLayout = ilm_entry.second.initialLayout; 84861fdcd3bc7fbd85f567a8270f6b7354c6f7b67661Alex Smith } 84871fdcd3bc7fbd85f567a8270f6b7354c6f7b67661Alex Smith node.layout = ilm_entry.second.layout; 84881fdcd3bc7fbd85f567a8270f6b7354c6f7b67661Alex Smith SetLayout(dev_data, pCB, ilm_entry.first, node); 84891fdcd3bc7fbd85f567a8270f6b7354c6f7b67661Alex Smith } 84908567fecbf563420f5900ade277ca68908aa87259Tobin Ehlis } 84915b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pSubCB->primaryCommandBuffer = pCB->commandBuffer; 84921a3660584634742a3297915c94768d73f360e794Chris Forbes pCB->linkedCommandBuffers.insert(pSubCB); 84931a3660584634742a3297915c94768d73f360e794Chris Forbes pSubCB->linkedCommandBuffers.insert(pCB); 8494d4ee9fdb2def1e9dc70c5627c9103e264471b8ebMichael Lentine for (auto &function : pSubCB->queryUpdates) { 8495d4ee9fdb2def1e9dc70c5627c9103e264471b8ebMichael Lentine pCB->queryUpdates.push_back(function); 8496d4ee9fdb2def1e9dc70c5627c9103e264471b8ebMichael Lentine } 849775c6d3c8ccf58c2b4bb5eb14e8e6763b254bdc17Alex Smith for (auto &function : pSubCB->queue_submit_functions) { 849875c6d3c8ccf58c2b4bb5eb14e8e6763b254bdc17Alex Smith pCB->queue_submit_functions.push_back(function); 849975c6d3c8ccf58c2b4bb5eb14e8e6763b254bdc17Alex Smith } 85005b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 8501315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= validatePrimaryCommandBuffer(dev_data, pCB, "vkCmdExecuteCommands()", VALIDATION_ERROR_1b200019); 8502315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= 8503315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis ValidateCmdQueueFlags(dev_data, pCB, "vkCmdExecuteCommands()", 8504315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VK_QUEUE_TRANSFER_BIT | VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, VALIDATION_ERROR_1b202415); 8505f5a52627a6576d3d532cd1f2e1be6d9987aeda7fChris Forbes skip |= ValidateCmd(dev_data, pCB, CMD_EXECUTECOMMANDS, "vkCmdExecuteCommands()"); 85065b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 8507b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 85083251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip) dev_data->dispatch_table.CmdExecuteCommands(commandBuffer, commandBuffersCount, pCommandBuffers); 85095b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 85105b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 8511bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL MapMemory(VkDevice device, VkDeviceMemory mem, VkDeviceSize offset, VkDeviceSize size, VkFlags flags, 8512bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski void **ppData) { 851356e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 85145b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 85153251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 85165b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 8517ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 85189a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis DEVICE_MEM_INFO *mem_info = GetMemObjInfo(dev_data, mem); 8519cf17f50f6489504c0d8151c46d6f77404ce2ffffTobin Ehlis if (mem_info) { 8520f541bf53dee6daf82a4c8304354eac599a884d29Tobin Ehlis // TODO : This could me more fine-grained to track just region that is valid 8521f541bf53dee6daf82a4c8304354eac599a884d29Tobin Ehlis mem_info->global_valid = true; 8522623548a271287ae55415e45e3c654ee66d4e79ffTobin Ehlis auto end_offset = (VK_WHOLE_SIZE == size) ? mem_info->alloc_info.allocationSize - 1 : offset + size - 1; 85233251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateMapImageLayouts(dev_data, device, mem_info, offset, end_offset); 8524cf17f50f6489504c0d8151c46d6f77404ce2ffffTobin Ehlis // TODO : Do we need to create new "bound_range" for the mapped range? 8525623548a271287ae55415e45e3c654ee66d4e79ffTobin Ehlis SetMemRangesValid(dev_data, mem_info, offset, end_offset); 8526cf17f50f6489504c0d8151c46d6f77404ce2ffffTobin Ehlis if ((dev_data->phys_dev_mem_props.memoryTypes[mem_info->alloc_info.memoryTypeIndex].propertyFlags & 8527b1b606d27e8c4179534d7bbb48ce217429e37414Tobin Ehlis VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == 0) { 85283251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 8529315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(mem), __LINE__, VALIDATION_ERROR_31200554, "MEM", 85303251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Mapping Memory without VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT set: mem obj 0x%" PRIxLEAST64 ". %s", 8531315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(mem), validation_error_map[VALIDATION_ERROR_31200554]); 85325b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 85335b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 85343251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateMapMemRange(dev_data, mem, offset, size); 8535b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 85365b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 85373251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip) { 85384a0754042cf090e131e9e769d8a3633c228625beChris Forbes result = dev_data->dispatch_table.MapMemory(device, mem, offset, size, flags, ppData); 85397c0012acb5327961b0a5191434a08e5fa788786dTobin Ehlis if (VK_SUCCESS == result) { 85407c0012acb5327961b0a5191434a08e5fa788786dTobin Ehlis lock.lock(); 8541cf17f50f6489504c0d8151c46d6f77404ce2ffffTobin Ehlis // TODO : What's the point of this range? See comment on creating new "bound_range" above, which may replace this 85427c0012acb5327961b0a5191434a08e5fa788786dTobin Ehlis storeMemRanges(dev_data, mem, offset, size); 85435f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski initializeAndTrackMemory(dev_data, mem, offset, size, ppData); 85447c0012acb5327961b0a5191434a08e5fa788786dTobin Ehlis lock.unlock(); 85457c0012acb5327961b0a5191434a08e5fa788786dTobin Ehlis } 85465b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 85475b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 85485b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 85495b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 855089d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR void VKAPI_CALL UnmapMemory(VkDevice device, VkDeviceMemory mem) { 855156e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 85523251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 85535b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 8554ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 85553251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= deleteMemRanges(dev_data, mem); 8556b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 85573251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip) { 85584a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.UnmapMemory(device, mem); 85595b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 85605b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 85615b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 85628860b85a52096f9f9b28616bc37feed505497a54Chris Forbesstatic bool validateMemoryIsMapped(layer_data *dev_data, const char *funcName, uint32_t memRangeCount, 8563e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves const VkMappedMemoryRange *pMemRanges) { 8564c7ee6f2fe100c1aacfaa0872832717c906bb8a4aMark Lobodzinski bool skip = false; 85655b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t i = 0; i < memRangeCount; ++i) { 85669a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto mem_info = GetMemObjInfo(dev_data, pMemRanges[i].memory); 856757fc8e28c2e16118f9827e3ae1b107a27e0451a2Tobin Ehlis if (mem_info) { 8568f0b0053ba47c1fc2ee173cfef0eaf63356cd4b0cMark Lobodzinski if (pMemRanges[i].size == VK_WHOLE_SIZE) { 8569f0b0053ba47c1fc2ee173cfef0eaf63356cd4b0cMark Lobodzinski if (mem_info->mem_range.offset > pMemRanges[i].offset) { 8570315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= 8571315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 8572315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pMemRanges[i].memory), __LINE__, VALIDATION_ERROR_0c20055c, "MEM", 8573315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis "%s: Flush/Invalidate offset (" PRINTF_SIZE_T_SPECIFIER 8574315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis ") is less than Memory Object's offset " 8575315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis "(" PRINTF_SIZE_T_SPECIFIER "). %s", 8576315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis funcName, static_cast<size_t>(pMemRanges[i].offset), 8577315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis static_cast<size_t>(mem_info->mem_range.offset), validation_error_map[VALIDATION_ERROR_0c20055c]); 8578f0b0053ba47c1fc2ee173cfef0eaf63356cd4b0cMark Lobodzinski } 8579f0b0053ba47c1fc2ee173cfef0eaf63356cd4b0cMark Lobodzinski } else { 8580f0b0053ba47c1fc2ee173cfef0eaf63356cd4b0cMark Lobodzinski const uint64_t data_end = (mem_info->mem_range.size == VK_WHOLE_SIZE) 8581f0b0053ba47c1fc2ee173cfef0eaf63356cd4b0cMark Lobodzinski ? mem_info->alloc_info.allocationSize 8582f0b0053ba47c1fc2ee173cfef0eaf63356cd4b0cMark Lobodzinski : (mem_info->mem_range.offset + mem_info->mem_range.size); 8583f0b0053ba47c1fc2ee173cfef0eaf63356cd4b0cMark Lobodzinski if ((mem_info->mem_range.offset > pMemRanges[i].offset) || 8584f0b0053ba47c1fc2ee173cfef0eaf63356cd4b0cMark Lobodzinski (data_end < (pMemRanges[i].offset + pMemRanges[i].size))) { 8585c7ee6f2fe100c1aacfaa0872832717c906bb8a4aMark Lobodzinski skip |= 8586f0b0053ba47c1fc2ee173cfef0eaf63356cd4b0cMark Lobodzinski log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 8587315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pMemRanges[i].memory), __LINE__, VALIDATION_ERROR_0c20055a, "MEM", 8588f0b0053ba47c1fc2ee173cfef0eaf63356cd4b0cMark Lobodzinski "%s: Flush/Invalidate size or offset (" PRINTF_SIZE_T_SPECIFIER ", " PRINTF_SIZE_T_SPECIFIER 8589f0b0053ba47c1fc2ee173cfef0eaf63356cd4b0cMark Lobodzinski ") exceed the Memory Object's upper-bound " 8590f0b0053ba47c1fc2ee173cfef0eaf63356cd4b0cMark Lobodzinski "(" PRINTF_SIZE_T_SPECIFIER "). %s", 8591f0b0053ba47c1fc2ee173cfef0eaf63356cd4b0cMark Lobodzinski funcName, static_cast<size_t>(pMemRanges[i].offset + pMemRanges[i].size), 8592f0b0053ba47c1fc2ee173cfef0eaf63356cd4b0cMark Lobodzinski static_cast<size_t>(pMemRanges[i].offset), static_cast<size_t>(data_end), 8593315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_0c20055a]); 8594f0b0053ba47c1fc2ee173cfef0eaf63356cd4b0cMark Lobodzinski } 85955b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 85965b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 85975b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 8598c7ee6f2fe100c1aacfaa0872832717c906bb8a4aMark Lobodzinski return skip; 85995b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 86005b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 8601bba0de708d942e9a2187158915856995db1c5a4dMark Lobodzinskistatic bool ValidateAndCopyNoncoherentMemoryToDriver(layer_data *dev_data, uint32_t mem_range_count, 8602bba0de708d942e9a2187158915856995db1c5a4dMark Lobodzinski const VkMappedMemoryRange *mem_ranges) { 8603bba0de708d942e9a2187158915856995db1c5a4dMark Lobodzinski bool skip = false; 8604bba0de708d942e9a2187158915856995db1c5a4dMark Lobodzinski for (uint32_t i = 0; i < mem_range_count; ++i) { 86059a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto mem_info = GetMemObjInfo(dev_data, mem_ranges[i].memory); 860657fc8e28c2e16118f9827e3ae1b107a27e0451a2Tobin Ehlis if (mem_info) { 86075f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski if (mem_info->shadow_copy) { 86085f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski VkDeviceSize size = (mem_info->mem_range.size != VK_WHOLE_SIZE) 86095f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski ? mem_info->mem_range.size 8610d8a53ade6b5501256798a8b4ec0bc14f72adc1faTobin Ehlis : (mem_info->alloc_info.allocationSize - mem_info->mem_range.offset); 86115f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski char *data = static_cast<char *>(mem_info->shadow_copy); 86125f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski for (uint64_t j = 0; j < mem_info->shadow_pad_size; ++j) { 86135b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (data[j] != NoncoherentMemoryFillValue) { 86149b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip |= log_msg( 86159b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 86169b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(mem_ranges[i].memory), __LINE__, MEMTRACK_INVALID_MAP, "MEM", 86179b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "Memory underflow was detected on mem obj 0x%" PRIxLEAST64, HandleToUint64(mem_ranges[i].memory)); 86185b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 86195b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 86205f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski for (uint64_t j = (size + mem_info->shadow_pad_size); j < (2 * mem_info->shadow_pad_size + size); ++j) { 86215b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (data[j] != NoncoherentMemoryFillValue) { 86229b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip |= log_msg( 86239b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 86249b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(mem_ranges[i].memory), __LINE__, MEMTRACK_INVALID_MAP, "MEM", 86259b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "Memory overflow was detected on mem obj 0x%" PRIxLEAST64, HandleToUint64(mem_ranges[i].memory)); 86265b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 86275b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 86285f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski memcpy(mem_info->p_driver_data, static_cast<void *>(data + mem_info->shadow_pad_size), (size_t)(size)); 86295b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 86305b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 86315b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 8632bba0de708d942e9a2187158915856995db1c5a4dMark Lobodzinski return skip; 86335b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 86345b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 8635bba0de708d942e9a2187158915856995db1c5a4dMark Lobodzinskistatic void CopyNoncoherentMemoryFromDriver(layer_data *dev_data, uint32_t mem_range_count, const VkMappedMemoryRange *mem_ranges) { 8636bba0de708d942e9a2187158915856995db1c5a4dMark Lobodzinski for (uint32_t i = 0; i < mem_range_count; ++i) { 86379a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto mem_info = GetMemObjInfo(dev_data, mem_ranges[i].memory); 86385f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski if (mem_info && mem_info->shadow_copy) { 86395f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski VkDeviceSize size = (mem_info->mem_range.size != VK_WHOLE_SIZE) 86405f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski ? mem_info->mem_range.size 86415f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski : (mem_info->alloc_info.allocationSize - mem_ranges[i].offset); 86425f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski char *data = static_cast<char *>(mem_info->shadow_copy); 86435f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski memcpy(data + mem_info->shadow_pad_size, mem_info->p_driver_data, (size_t)(size)); 86449e21e56fc23ade48efd3752d2e2729895eb90349Mark Lobodzinski } 86459e21e56fc23ade48efd3752d2e2729895eb90349Mark Lobodzinski } 86469e21e56fc23ade48efd3752d2e2729895eb90349Mark Lobodzinski} 86479e21e56fc23ade48efd3752d2e2729895eb90349Mark Lobodzinski 8648ba16c7616eb49c78dc76eb7682d650287ad8614dMark Lobodzinskistatic bool ValidateMappedMemoryRangeDeviceLimits(layer_data *dev_data, const char *func_name, uint32_t mem_range_count, 8649ba16c7616eb49c78dc76eb7682d650287ad8614dMark Lobodzinski const VkMappedMemoryRange *mem_ranges) { 8650ba16c7616eb49c78dc76eb7682d650287ad8614dMark Lobodzinski bool skip = false; 8651ba16c7616eb49c78dc76eb7682d650287ad8614dMark Lobodzinski for (uint32_t i = 0; i < mem_range_count; ++i) { 8652ba16c7616eb49c78dc76eb7682d650287ad8614dMark Lobodzinski uint64_t atom_size = dev_data->phys_dev_properties.properties.limits.nonCoherentAtomSize; 865316769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (SafeModulo(mem_ranges[i].offset, atom_size) != 0) { 8654df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 8655315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(mem_ranges->memory), __LINE__, VALIDATION_ERROR_0c20055e, "MEM", 8656ba16c7616eb49c78dc76eb7682d650287ad8614dMark Lobodzinski "%s: Offset in pMemRanges[%d] is 0x%" PRIxLEAST64 8657ba16c7616eb49c78dc76eb7682d650287ad8614dMark Lobodzinski ", which is not a multiple of VkPhysicalDeviceLimits::nonCoherentAtomSize (0x%" PRIxLEAST64 "). %s", 8658315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis func_name, i, mem_ranges[i].offset, atom_size, validation_error_map[VALIDATION_ERROR_0c20055e]); 8659ba16c7616eb49c78dc76eb7682d650287ad8614dMark Lobodzinski } 866016769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if ((mem_ranges[i].size != VK_WHOLE_SIZE) && (SafeModulo(mem_ranges[i].size, atom_size) != 0)) { 8661df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 8662315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(mem_ranges->memory), __LINE__, VALIDATION_ERROR_0c200560, "MEM", 8663ba16c7616eb49c78dc76eb7682d650287ad8614dMark Lobodzinski "%s: Size in pMemRanges[%d] is 0x%" PRIxLEAST64 8664ba16c7616eb49c78dc76eb7682d650287ad8614dMark Lobodzinski ", which is not a multiple of VkPhysicalDeviceLimits::nonCoherentAtomSize (0x%" PRIxLEAST64 "). %s", 8665315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis func_name, i, mem_ranges[i].size, atom_size, validation_error_map[VALIDATION_ERROR_0c200560]); 8666ba16c7616eb49c78dc76eb7682d650287ad8614dMark Lobodzinski } 8667ba16c7616eb49c78dc76eb7682d650287ad8614dMark Lobodzinski } 8668ba16c7616eb49c78dc76eb7682d650287ad8614dMark Lobodzinski return skip; 8669ba16c7616eb49c78dc76eb7682d650287ad8614dMark Lobodzinski} 8670ba16c7616eb49c78dc76eb7682d650287ad8614dMark Lobodzinski 867180e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinskistatic bool PreCallValidateFlushMappedMemoryRanges(layer_data *dev_data, uint32_t mem_range_count, 867280e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinski const VkMappedMemoryRange *mem_ranges) { 867380e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinski bool skip = false; 8674ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 867580e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinski skip |= ValidateAndCopyNoncoherentMemoryToDriver(dev_data, mem_range_count, mem_ranges); 867680e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinski skip |= validateMemoryIsMapped(dev_data, "vkFlushMappedMemoryRanges", mem_range_count, mem_ranges); 867780e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinski return skip; 867880e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinski} 867980e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinski 8680bba0de708d942e9a2187158915856995db1c5a4dMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL FlushMappedMemoryRanges(VkDevice device, uint32_t memRangeCount, 8681bba0de708d942e9a2187158915856995db1c5a4dMark Lobodzinski const VkMappedMemoryRange *pMemRanges) { 86825b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 868356e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 86845b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 868580e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinski if (!PreCallValidateFlushMappedMemoryRanges(dev_data, memRangeCount, pMemRanges)) { 86864a0754042cf090e131e9e769d8a3633c228625beChris Forbes result = dev_data->dispatch_table.FlushMappedMemoryRanges(device, memRangeCount, pMemRanges); 86875b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 86885b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 86895b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 86905b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 869180e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinskistatic bool PreCallValidateInvalidateMappedMemoryRanges(layer_data *dev_data, uint32_t mem_range_count, 869280e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinski const VkMappedMemoryRange *mem_ranges) { 869380e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinski bool skip = false; 8694ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 869580e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinski skip |= validateMemoryIsMapped(dev_data, "vkInvalidateMappedMemoryRanges", mem_range_count, mem_ranges); 869680e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinski return skip; 869780e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinski} 869880e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinski 869980e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinskistatic void PostCallRecordInvalidateMappedMemoryRanges(layer_data *dev_data, uint32_t mem_range_count, 870080e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinski const VkMappedMemoryRange *mem_ranges) { 8701ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 870280e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinski // Update our shadow copy with modified driver data 870380e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinski CopyNoncoherentMemoryFromDriver(dev_data, mem_range_count, mem_ranges); 870480e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinski} 870580e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinski 8706bba0de708d942e9a2187158915856995db1c5a4dMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL InvalidateMappedMemoryRanges(VkDevice device, uint32_t memRangeCount, 8707bba0de708d942e9a2187158915856995db1c5a4dMark Lobodzinski const VkMappedMemoryRange *pMemRanges) { 87085b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 870956e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 87105b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 871180e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinski if (!PreCallValidateInvalidateMappedMemoryRanges(dev_data, memRangeCount, pMemRanges)) { 87124a0754042cf090e131e9e769d8a3633c228625beChris Forbes result = dev_data->dispatch_table.InvalidateMappedMemoryRanges(device, memRangeCount, pMemRanges); 871380e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinski if (result == VK_SUCCESS) { 871480e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinski PostCallRecordInvalidateMappedMemoryRanges(dev_data, memRangeCount, pMemRanges); 871580e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinski } 87165b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 87175b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 87185b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 87195b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 8720160335c453ec51cc48bdef78e8befdb3c86ff292Cort Strattonstatic bool PreCallValidateBindImageMemory(layer_data *dev_data, VkImage image, IMAGE_STATE *image_state, VkDeviceMemory mem, 8721160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton VkDeviceSize memoryOffset) { 87220109928beb33325a442d7e3e7f38e73edf9cc38bMark Lobodzinski bool skip = false; 87231facd2c91911508b9fb61f54a56269841299f663Tobin Ehlis if (image_state) { 8724ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 872594c53c062f0ccc70ef0ada8e98edc90eadc4cb45Tobin Ehlis // Track objects tied to memory 87269b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus uint64_t image_handle = HandleToUint64(image); 87277a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski skip = ValidateSetMemBinding(dev_data, mem, image_handle, kVulkanObjectTypeImage, "vkBindImageMemory()"); 8728ff3ef1181960319d2268e82dae075726f650c553Tobin Ehlis if (!image_state->memory_requirements_checked) { 8729ff3ef1181960319d2268e82dae075726f650c553Tobin Ehlis // There's not an explicit requirement in the spec to call vkGetImageMemoryRequirements() prior to calling 8730341d357dc354e888bfdc05b5dfd8c1cabe8417e0Cort Stratton // BindImageMemory but it's implied in that memory being bound must conform with VkMemoryRequirements from 8731341d357dc354e888bfdc05b5dfd8c1cabe8417e0Cort Stratton // vkGetImageMemoryRequirements() 87320109928beb33325a442d7e3e7f38e73edf9cc38bMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 87330109928beb33325a442d7e3e7f38e73edf9cc38bMark Lobodzinski image_handle, __LINE__, DRAWSTATE_INVALID_IMAGE, "DS", 87340109928beb33325a442d7e3e7f38e73edf9cc38bMark Lobodzinski "vkBindImageMemory(): Binding memory to image 0x%" PRIxLEAST64 87350109928beb33325a442d7e3e7f38e73edf9cc38bMark Lobodzinski " but vkGetImageMemoryRequirements() has not been called on that image.", 87360109928beb33325a442d7e3e7f38e73edf9cc38bMark Lobodzinski image_handle); 8737ff3ef1181960319d2268e82dae075726f650c553Tobin Ehlis // Make the call for them so we can verify the state 8738ff3ef1181960319d2268e82dae075726f650c553Tobin Ehlis lock.unlock(); 8739341d357dc354e888bfdc05b5dfd8c1cabe8417e0Cort Stratton dev_data->dispatch_table.GetImageMemoryRequirements(dev_data->device, image, &image_state->requirements); 8740ff3ef1181960319d2268e82dae075726f650c553Tobin Ehlis lock.lock(); 8741ff3ef1181960319d2268e82dae075726f650c553Tobin Ehlis } 874247aaf733d7394bda75c6de24289efe6b281e3cffMark Lobodzinski 87430ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton // Validate bound memory range information 87449a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto mem_info = GetMemObjInfo(dev_data, mem); 874557fc8e28c2e16118f9827e3ae1b107a27e0451a2Tobin Ehlis if (mem_info) { 87460ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton skip |= ValidateInsertImageMemoryRange(dev_data, image, mem_info, memoryOffset, image_state->requirements, 87470ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton image_state->createInfo.tiling == VK_IMAGE_TILING_LINEAR, "vkBindImageMemory()"); 874874300755ed9ec780d6073af71e47f201217008d6Cort Stratton skip |= ValidateMemoryTypes(dev_data, mem_info, image_state->requirements.memoryTypeBits, "vkBindImageMemory()", 8749315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1740082e); 875047aaf733d7394bda75c6de24289efe6b281e3cffMark Lobodzinski } 8751160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton 8752160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton // Validate memory requirements alignment 875316769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (SafeModulo(memoryOffset, image_state->requirements.alignment) != 0) { 8754160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 8755315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis image_handle, __LINE__, VALIDATION_ERROR_17400830, "DS", 8756160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton "vkBindImageMemory(): memoryOffset is 0x%" PRIxLEAST64 8757160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton " but must be an integer multiple of the " 8758160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton "VkMemoryRequirements::alignment value 0x%" PRIxLEAST64 8759160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton ", returned from a call to vkGetImageMemoryRequirements with image. %s", 8760315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis memoryOffset, image_state->requirements.alignment, validation_error_map[VALIDATION_ERROR_17400830]); 8761160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton } 8762160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton 8763160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton // Validate memory requirements size 8764160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton if (image_state->requirements.size > mem_info->alloc_info.allocationSize - memoryOffset) { 8765160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 8766315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis image_handle, __LINE__, VALIDATION_ERROR_17400832, "DS", 8767160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton "vkBindImageMemory(): memory size minus memoryOffset is 0x%" PRIxLEAST64 8768160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton " but must be at least as large as " 8769160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton "VkMemoryRequirements::size value 0x%" PRIxLEAST64 8770160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton ", returned from a call to vkGetImageMemoryRequirements with image. %s", 8771160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton mem_info->alloc_info.allocationSize - memoryOffset, image_state->requirements.size, 8772315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_17400832]); 8773160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton } 8774341d357dc354e888bfdc05b5dfd8c1cabe8417e0Cort Stratton } 8775341d357dc354e888bfdc05b5dfd8c1cabe8417e0Cort Stratton return skip; 8776341d357dc354e888bfdc05b5dfd8c1cabe8417e0Cort Stratton} 877747aaf733d7394bda75c6de24289efe6b281e3cffMark Lobodzinski 8778160335c453ec51cc48bdef78e8befdb3c86ff292Cort Strattonstatic void PostCallRecordBindImageMemory(layer_data *dev_data, VkImage image, IMAGE_STATE *image_state, VkDeviceMemory mem, 8779160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton VkDeviceSize memoryOffset) { 8780341d357dc354e888bfdc05b5dfd8c1cabe8417e0Cort Stratton if (image_state) { 8781ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 87820ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton // Track bound memory range information 87830ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton auto mem_info = GetMemObjInfo(dev_data, mem); 87840ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton if (mem_info) { 87850ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton InsertImageMemoryRange(dev_data, image, mem_info, memoryOffset, image_state->requirements, 87860ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton image_state->createInfo.tiling == VK_IMAGE_TILING_LINEAR); 87870ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton } 87880ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton 8789c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton // Track objects tied to memory 87909b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus uint64_t image_handle = HandleToUint64(image); 87917a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski SetMemBinding(dev_data, mem, image_handle, kVulkanObjectTypeImage, "vkBindImageMemory()"); 8792c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton 8793341d357dc354e888bfdc05b5dfd8c1cabe8417e0Cort Stratton image_state->binding.mem = mem; 8794341d357dc354e888bfdc05b5dfd8c1cabe8417e0Cort Stratton image_state->binding.offset = memoryOffset; 8795341d357dc354e888bfdc05b5dfd8c1cabe8417e0Cort Stratton image_state->binding.size = image_state->requirements.size; 8796341d357dc354e888bfdc05b5dfd8c1cabe8417e0Cort Stratton } 8797341d357dc354e888bfdc05b5dfd8c1cabe8417e0Cort Stratton} 8798341d357dc354e888bfdc05b5dfd8c1cabe8417e0Cort Stratton 8799341d357dc354e888bfdc05b5dfd8c1cabe8417e0Cort StrattonVKAPI_ATTR VkResult VKAPI_CALL BindImageMemory(VkDevice device, VkImage image, VkDeviceMemory mem, VkDeviceSize memoryOffset) { 8800341d357dc354e888bfdc05b5dfd8c1cabe8417e0Cort Stratton layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 8801341d357dc354e888bfdc05b5dfd8c1cabe8417e0Cort Stratton VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 8802160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton auto image_state = GetImageState(dev_data, image); 8803160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton bool skip = PreCallValidateBindImageMemory(dev_data, image, image_state, mem, memoryOffset); 8804341d357dc354e888bfdc05b5dfd8c1cabe8417e0Cort Stratton if (!skip) { 8805341d357dc354e888bfdc05b5dfd8c1cabe8417e0Cort Stratton result = dev_data->dispatch_table.BindImageMemory(device, image, mem, memoryOffset); 8806341d357dc354e888bfdc05b5dfd8c1cabe8417e0Cort Stratton if (result == VK_SUCCESS) { 8807160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton PostCallRecordBindImageMemory(dev_data, image, image_state, mem, memoryOffset); 880894c53c062f0ccc70ef0ada8e98edc90eadc4cb45Tobin Ehlis } 88095b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 88105b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 88115b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 88125b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 881389d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR VkResult VKAPI_CALL SetEvent(VkDevice device, VkEvent event) { 88143251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 88153ee1d6057ee6c49b9dbbeb067b7fd149bdba7b5cTobin Ehlis VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 881656e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 8817ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 88189a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto event_state = GetEventNode(dev_data, event); 88194710dda89a1dd2e023334d4eda710a394b211cdcTobin Ehlis if (event_state) { 88204710dda89a1dd2e023334d4eda710a394b211cdcTobin Ehlis event_state->needsSignaled = false; 88214710dda89a1dd2e023334d4eda710a394b211cdcTobin Ehlis event_state->stageMask = VK_PIPELINE_STAGE_HOST_BIT; 88224710dda89a1dd2e023334d4eda710a394b211cdcTobin Ehlis if (event_state->write_in_use) { 88233251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT, 88249b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(event), __LINE__, DRAWSTATE_QUEUE_FORWARD_PROGRESS, "DS", 88253251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Cannot call vkSetEvent() on event 0x%" PRIxLEAST64 " that is already in use by a command buffer.", 88269b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(event)); 88273ee1d6057ee6c49b9dbbeb067b7fd149bdba7b5cTobin Ehlis } 88283ee1d6057ee6c49b9dbbeb067b7fd149bdba7b5cTobin Ehlis } 8829b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 88306fcff21b8cce5159fdfa317e612f75f5ea6a189eTobin Ehlis // Host setting event is visible to all queues immediately so update stageMask for any queue that's seen this event 88316fcff21b8cce5159fdfa317e612f75f5ea6a189eTobin Ehlis // TODO : For correctness this needs separate fix to verify that app doesn't make incorrect assumptions about the 88326fcff21b8cce5159fdfa317e612f75f5ea6a189eTobin Ehlis // ordering of this command in relation to vkCmd[Set|Reset]Events (see GH297) 88336fcff21b8cce5159fdfa317e612f75f5ea6a189eTobin Ehlis for (auto queue_data : dev_data->queueMap) { 88346fcff21b8cce5159fdfa317e612f75f5ea6a189eTobin Ehlis auto event_entry = queue_data.second.eventToStageMap.find(event); 88356fcff21b8cce5159fdfa317e612f75f5ea6a189eTobin Ehlis if (event_entry != queue_data.second.eventToStageMap.end()) { 88366fcff21b8cce5159fdfa317e612f75f5ea6a189eTobin Ehlis event_entry->second |= VK_PIPELINE_STAGE_HOST_BIT; 88376fcff21b8cce5159fdfa317e612f75f5ea6a189eTobin Ehlis } 88386fcff21b8cce5159fdfa317e612f75f5ea6a189eTobin Ehlis } 88393251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip) result = dev_data->dispatch_table.SetEvent(device, event); 88405b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 88415b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 88425b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 8843baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardtstatic bool PreCallValidateQueueBindSparse(layer_data *dev_data, VkQueue queue, uint32_t bindInfoCount, 8844baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt const VkBindSparseInfo *pBindInfo, VkFence fence) { 88459a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pFence = GetFenceNode(dev_data, fence); 8846baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt bool skip = ValidateFenceForSubmit(dev_data, pFence); 8847baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt if (skip) { 8848baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt return true; 8849baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt } 8850baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt 8851baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt unordered_set<VkSemaphore> signaled_semaphores; 8852baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt unordered_set<VkSemaphore> unsignaled_semaphores; 885306d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt unordered_set<VkSemaphore> internal_semaphores; 8854baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt for (uint32_t bindIdx = 0; bindIdx < bindInfoCount; ++bindIdx) { 8855baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt const VkBindSparseInfo &bindInfo = pBindInfo[bindIdx]; 8856baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt 8857baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt std::vector<SEMAPHORE_WAIT> semaphore_waits; 8858baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt std::vector<VkSemaphore> semaphore_signals; 8859baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt for (uint32_t i = 0; i < bindInfo.waitSemaphoreCount; ++i) { 8860baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt VkSemaphore semaphore = bindInfo.pWaitSemaphores[i]; 8861baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt auto pSemaphore = GetSemaphoreNode(dev_data, semaphore); 886206d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt if (pSemaphore && (pSemaphore->scope == kSyncScopeInternal || internal_semaphores.count(semaphore))) { 8863baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt if (unsignaled_semaphores.count(semaphore) || 8864baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt (!(signaled_semaphores.count(semaphore)) && !(pSemaphore->signaled))) { 8865baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT, 8866baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt HandleToUint64(semaphore), __LINE__, DRAWSTATE_QUEUE_FORWARD_PROGRESS, "DS", 8867baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt "Queue 0x%p is waiting on semaphore 0x%" PRIx64 " that has no way to be signaled.", queue, 8868baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt HandleToUint64(semaphore)); 8869baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt } else { 8870baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt signaled_semaphores.erase(semaphore); 8871baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt unsignaled_semaphores.insert(semaphore); 8872baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt } 8873baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt } 887406d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt if (pSemaphore && pSemaphore->scope == kSyncScopeExternalTemporary) { 887506d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt internal_semaphores.insert(semaphore); 887606d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt } 8877baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt } 8878baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt for (uint32_t i = 0; i < bindInfo.signalSemaphoreCount; ++i) { 8879baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt VkSemaphore semaphore = bindInfo.pSignalSemaphores[i]; 8880baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt auto pSemaphore = GetSemaphoreNode(dev_data, semaphore); 888106d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt if (pSemaphore && pSemaphore->scope == kSyncScopeInternal) { 8882baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt if (signaled_semaphores.count(semaphore) || (!(unsignaled_semaphores.count(semaphore)) && pSemaphore->signaled)) { 8883baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT, 8884baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt HandleToUint64(semaphore), __LINE__, DRAWSTATE_QUEUE_FORWARD_PROGRESS, "DS", 8885baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt "Queue 0x%p is signaling semaphore 0x%" PRIx64 8886baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt " that has already been signaled but not waited on by queue 0x%" PRIx64 ".", 8887baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt queue, HandleToUint64(semaphore), HandleToUint64(pSemaphore->signaler.first)); 8888baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt } else { 8889baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt unsignaled_semaphores.erase(semaphore); 8890baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt signaled_semaphores.insert(semaphore); 8891baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt } 8892baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt } 8893baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt } 8894baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt } 8895651d92815dfff917308137bb67aacccc4f60df86Chris Forbes 8896baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt return skip; 8897baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt} 8898baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardtstatic void PostCallRecordQueueBindSparse(layer_data *dev_data, VkQueue queue, uint32_t bindInfoCount, 8899baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt const VkBindSparseInfo *pBindInfo, VkFence fence) { 890085926a33d427ee62f395a50886db980127063c72Mike Schuchardt uint64_t early_retire_seq = 0; 8901baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt auto pFence = GetFenceNode(dev_data, fence); 8902baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt auto pQueue = GetQueueState(dev_data, queue); 8903651d92815dfff917308137bb67aacccc4f60df86Chris Forbes 89046371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt if (pFence) { 89056371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt if (pFence->scope == kSyncScopeInternal) { 89066371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt SubmitFence(pQueue, pFence, std::max(1u, bindInfoCount)); 89076371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt if (!bindInfoCount) { 89086371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt // No work to do, just dropping a fence in the queue by itself. 89096371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt pQueue->submissions.emplace_back(std::vector<VkCommandBuffer>(), std::vector<SEMAPHORE_WAIT>(), 89106371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt std::vector<VkSemaphore>(), std::vector<VkSemaphore>(), fence); 89116371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt } 89126371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt } else { 89136371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt // Retire work up until this fence early, we will not see the wait that corresponds to this signal 89146371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt early_retire_seq = pQueue->seq + pQueue->submissions.size(); 89156371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt if (!dev_data->external_sync_warning) { 89166371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt dev_data->external_sync_warning = true; 89176371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt log_msg(dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, 89186371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt HandleToUint64(fence), __LINE__, DRAWSTATE_QUEUE_FORWARD_PROGRESS, "DS", 89196371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt "vkQueueBindSparse(): Signaling external fence 0x%" PRIx64 " on queue 0x%" PRIx64 89206371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt " will disable validation of preceding command buffer lifecycle states and the in-use status of " 89216371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt "associated objects.", 89226371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt HandleToUint64(fence), HandleToUint64(queue)); 89236371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt } 89246371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt } 89254b38d3aa8b6be6a7f5bebb472ab439da0562824fTobin Ehlis } 8926651d92815dfff917308137bb67aacccc4f60df86Chris Forbes 89271344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis for (uint32_t bindIdx = 0; bindIdx < bindInfoCount; ++bindIdx) { 89281344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis const VkBindSparseInfo &bindInfo = pBindInfo[bindIdx]; 89295b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Track objects tied to memory 89301344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis for (uint32_t j = 0; j < bindInfo.bufferBindCount; j++) { 89311344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis for (uint32_t k = 0; k < bindInfo.pBufferBinds[j].bindCount; k++) { 8932f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis auto sparse_binding = bindInfo.pBufferBinds[j].pBinds[k]; 8933baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt SetSparseMemBinding(dev_data, {sparse_binding.memory, sparse_binding.memoryOffset, sparse_binding.size}, 8934baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt HandleToUint64(bindInfo.pBufferBinds[j].buffer), kVulkanObjectTypeBuffer); 89355b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 89365b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 89371344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis for (uint32_t j = 0; j < bindInfo.imageOpaqueBindCount; j++) { 89381344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis for (uint32_t k = 0; k < bindInfo.pImageOpaqueBinds[j].bindCount; k++) { 8939f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis auto sparse_binding = bindInfo.pImageOpaqueBinds[j].pBinds[k]; 8940baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt SetSparseMemBinding(dev_data, {sparse_binding.memory, sparse_binding.memoryOffset, sparse_binding.size}, 8941baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt HandleToUint64(bindInfo.pImageOpaqueBinds[j].image), kVulkanObjectTypeImage); 89425b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 89435b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 89441344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis for (uint32_t j = 0; j < bindInfo.imageBindCount; j++) { 89451344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis for (uint32_t k = 0; k < bindInfo.pImageBinds[j].bindCount; k++) { 8946f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis auto sparse_binding = bindInfo.pImageBinds[j].pBinds[k]; 8947f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis // TODO: This size is broken for non-opaque bindings, need to update to comprehend full sparse binding data 8948f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis VkDeviceSize size = sparse_binding.extent.depth * sparse_binding.extent.height * sparse_binding.extent.width * 4; 8949baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt SetSparseMemBinding(dev_data, {sparse_binding.memory, sparse_binding.memoryOffset, size}, 8950baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt HandleToUint64(bindInfo.pImageBinds[j].image), kVulkanObjectTypeImage); 89515b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 89525b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 89539867daedbf52debc77d6568162ee21e071699b80Chris Forbes 89549867daedbf52debc77d6568162ee21e071699b80Chris Forbes std::vector<SEMAPHORE_WAIT> semaphore_waits; 89559867daedbf52debc77d6568162ee21e071699b80Chris Forbes std::vector<VkSemaphore> semaphore_signals; 895606d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt std::vector<VkSemaphore> semaphore_externals; 89571344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis for (uint32_t i = 0; i < bindInfo.waitSemaphoreCount; ++i) { 895801a48e41895b3951b297ff4245eff8f9c129ae20Chris Forbes VkSemaphore semaphore = bindInfo.pWaitSemaphores[i]; 89599a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pSemaphore = GetSemaphoreNode(dev_data, semaphore); 896001a48e41895b3951b297ff4245eff8f9c129ae20Chris Forbes if (pSemaphore) { 896106d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt if (pSemaphore->scope == kSyncScopeInternal) { 896206d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt if (pSemaphore->signaler.first != VK_NULL_HANDLE) { 896306d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt semaphore_waits.push_back({semaphore, pSemaphore->signaler.first, pSemaphore->signaler.second}); 896406d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt pSemaphore->in_use.fetch_add(1); 896506d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt } 896606d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt pSemaphore->signaler.first = VK_NULL_HANDLE; 896706d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt pSemaphore->signaled = false; 896806d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt } else { 896906d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt semaphore_externals.push_back(semaphore); 8970baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt pSemaphore->in_use.fetch_add(1); 897106d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt if (pSemaphore->scope == kSyncScopeExternalTemporary) { 897206d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt pSemaphore->scope = kSyncScopeInternal; 897306d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt } 89745b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 89755b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 89765b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 89771344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis for (uint32_t i = 0; i < bindInfo.signalSemaphoreCount; ++i) { 897801a48e41895b3951b297ff4245eff8f9c129ae20Chris Forbes VkSemaphore semaphore = bindInfo.pSignalSemaphores[i]; 89799a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pSemaphore = GetSemaphoreNode(dev_data, semaphore); 898001a48e41895b3951b297ff4245eff8f9c129ae20Chris Forbes if (pSemaphore) { 898106d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt if (pSemaphore->scope == kSyncScopeInternal) { 898206d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt pSemaphore->signaler.first = queue; 898306d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt pSemaphore->signaler.second = pQueue->seq + pQueue->submissions.size() + 1; 898406d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt pSemaphore->signaled = true; 898506d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt pSemaphore->in_use.fetch_add(1); 898606d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt semaphore_signals.push_back(semaphore); 898706d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt } else { 898885926a33d427ee62f395a50886db980127063c72Mike Schuchardt // Retire work up until this submit early, we will not see the wait that corresponds to this signal 89896371247236bc48772bb4b0ea109fdc400723d84fMike Schuchardt early_retire_seq = std::max(early_retire_seq, pQueue->seq + pQueue->submissions.size() + 1); 899085926a33d427ee62f395a50886db980127063c72Mike Schuchardt if (!dev_data->external_sync_warning) { 899185926a33d427ee62f395a50886db980127063c72Mike Schuchardt dev_data->external_sync_warning = true; 899285926a33d427ee62f395a50886db980127063c72Mike Schuchardt log_msg(dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT, 899385926a33d427ee62f395a50886db980127063c72Mike Schuchardt HandleToUint64(semaphore), __LINE__, DRAWSTATE_QUEUE_FORWARD_PROGRESS, "DS", 899485926a33d427ee62f395a50886db980127063c72Mike Schuchardt "vkQueueBindSparse(): Signaling external semaphore 0x%" PRIx64 " on queue 0x%" PRIx64 899585926a33d427ee62f395a50886db980127063c72Mike Schuchardt " will disable validation of preceding command buffer lifecycle states and the in-use status of " 899685926a33d427ee62f395a50886db980127063c72Mike Schuchardt "associated objects.", 899785926a33d427ee62f395a50886db980127063c72Mike Schuchardt HandleToUint64(semaphore), HandleToUint64(queue)); 899885926a33d427ee62f395a50886db980127063c72Mike Schuchardt } 899906d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt } 90005b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 90015b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 90029867daedbf52debc77d6568162ee21e071699b80Chris Forbes 900306d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt pQueue->submissions.emplace_back(std::vector<VkCommandBuffer>(), semaphore_waits, semaphore_signals, semaphore_externals, 90049867daedbf52debc77d6568162ee21e071699b80Chris Forbes bindIdx == bindInfoCount - 1 ? fence : VK_NULL_HANDLE); 90055b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 90069867daedbf52debc77d6568162ee21e071699b80Chris Forbes 900785926a33d427ee62f395a50886db980127063c72Mike Schuchardt if (early_retire_seq) { 900885926a33d427ee62f395a50886db980127063c72Mike Schuchardt RetireWorkOnQueue(dev_data, pQueue, early_retire_seq); 900985926a33d427ee62f395a50886db980127063c72Mike Schuchardt } 9010baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt} 90119867daedbf52debc77d6568162ee21e071699b80Chris Forbes 9012baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike SchuchardtVKAPI_ATTR VkResult VKAPI_CALL QueueBindSparse(VkQueue queue, uint32_t bindInfoCount, const VkBindSparseInfo *pBindInfo, 9013baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt VkFence fence) { 9014baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(queue), layer_data_map); 9015baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt unique_lock_t lock(global_lock); 9016baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt bool skip = PreCallValidateQueueBindSparse(dev_data, queue, bindInfoCount, pBindInfo, fence); 9017b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 90185b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 9019baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 9020baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt 9021baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt VkResult result = dev_data->dispatch_table.QueueBindSparse(queue, bindInfoCount, pBindInfo, fence); 90225b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 9023baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt lock.lock(); 9024baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt PostCallRecordQueueBindSparse(dev_data, queue, bindInfoCount, pBindInfo, fence); 9025baf4a700b1d8e70ac34d8f8069f5eb496efae0dfMike Schuchardt lock.unlock(); 90265b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 90275b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 90285b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 902989d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR VkResult VKAPI_CALL CreateSemaphore(VkDevice device, const VkSemaphoreCreateInfo *pCreateInfo, 903089d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I Wu const VkAllocationCallbacks *pAllocator, VkSemaphore *pSemaphore) { 903156e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 90324a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.CreateSemaphore(device, pCreateInfo, pAllocator, pSemaphore); 90335b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (result == VK_SUCCESS) { 9034ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 9035bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski SEMAPHORE_NODE *sNode = &dev_data->semaphoreMap[*pSemaphore]; 90369867daedbf52debc77d6568162ee21e071699b80Chris Forbes sNode->signaler.first = VK_NULL_HANDLE; 90379867daedbf52debc77d6568162ee21e071699b80Chris Forbes sNode->signaler.second = 0; 90381344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis sNode->signaled = false; 903906d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt sNode->scope = kSyncScopeInternal; 90405b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 90415b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 90425b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 90435b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 904406d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardtstatic bool PreCallValidateImportSemaphore(layer_data *dev_data, VkSemaphore semaphore, const char *caller_name) { 904506d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt SEMAPHORE_NODE *sema_node = GetSemaphoreNode(dev_data, semaphore); 904606d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt VK_OBJECT obj_struct = {HandleToUint64(semaphore), kVulkanObjectTypeSemaphore}; 904706d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt bool skip = false; 904806d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt if (sema_node) { 904906d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt skip |= ValidateObjectNotInUse(dev_data, sema_node, obj_struct, caller_name, VALIDATION_ERROR_UNDEFINED); 905006d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt } 905106d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt return skip; 905206d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt} 905306d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt 905406d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardtstatic void PostCallRecordImportSemaphore(layer_data *dev_data, VkSemaphore semaphore, 905506d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt VkExternalSemaphoreHandleTypeFlagBitsKHR handle_type, VkSemaphoreImportFlagsKHR flags) { 905606d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt SEMAPHORE_NODE *sema_node = GetSemaphoreNode(dev_data, semaphore); 905706d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt if (sema_node && sema_node->scope != kSyncScopeExternalPermanent) { 905806d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt if ((handle_type == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT_KHR || flags & VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR) && 905906d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt sema_node->scope == kSyncScopeInternal) { 906006d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt sema_node->scope = kSyncScopeExternalTemporary; 906106d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt } else { 906206d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt sema_node->scope = kSyncScopeExternalPermanent; 906306d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt } 906406d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt } 906506d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt} 906606d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt 906706d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt#ifdef VK_USE_PLATFORM_WIN32_KHR 906806d5c171f0bb0acbed8120af6bac43f13a869e3fMike SchuchardtVKAPI_ATTR VkResult VKAPI_CALL 906906d5c171f0bb0acbed8120af6bac43f13a869e3fMike SchuchardtImportSemaphoreWin32HandleKHR(VkDevice device, const VkImportSemaphoreWin32HandleInfoKHR *pImportSemaphoreWin32HandleInfo) { 907006d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 907106d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 907206d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt bool skip = 907306d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt PreCallValidateImportSemaphore(dev_data, pImportSemaphoreWin32HandleInfo->semaphore, "vkImportSemaphoreWin32HandleKHR"); 907406d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt 907506d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt if (!skip) { 907606d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt result = dev_data->dispatch_table.ImportSemaphoreWin32HandleKHR(device, pImportSemaphoreWin32HandleInfo); 907706d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt } 907806d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt 907906d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt if (result == VK_SUCCESS) { 908006d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt PostCallRecordImportSemaphore(dev_data, pImportSemaphoreWin32HandleInfo->semaphore, 908106d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt pImportSemaphoreWin32HandleInfo->handleType, pImportSemaphoreWin32HandleInfo->flags); 908206d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt } 908306d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt return result; 908406d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt} 908506d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt#endif 908606d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt 908716f39f23c20176b9ff809d10d76b62663e1adabdMike SchuchardtVKAPI_ATTR VkResult VKAPI_CALL ImportSemaphoreFdKHR(VkDevice device, const VkImportSemaphoreFdInfoKHR *pImportSemaphoreFdInfo) { 908816f39f23c20176b9ff809d10d76b62663e1adabdMike Schuchardt VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 908916f39f23c20176b9ff809d10d76b62663e1adabdMike Schuchardt layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 909016f39f23c20176b9ff809d10d76b62663e1adabdMike Schuchardt bool skip = PreCallValidateImportSemaphore(dev_data, pImportSemaphoreFdInfo->semaphore, "vkImportSemaphoreFdKHR"); 909116f39f23c20176b9ff809d10d76b62663e1adabdMike Schuchardt 909216f39f23c20176b9ff809d10d76b62663e1adabdMike Schuchardt if (!skip) { 909316f39f23c20176b9ff809d10d76b62663e1adabdMike Schuchardt result = dev_data->dispatch_table.ImportSemaphoreFdKHR(device, pImportSemaphoreFdInfo); 909416f39f23c20176b9ff809d10d76b62663e1adabdMike Schuchardt } 909516f39f23c20176b9ff809d10d76b62663e1adabdMike Schuchardt 909616f39f23c20176b9ff809d10d76b62663e1adabdMike Schuchardt if (result == VK_SUCCESS) { 909716f39f23c20176b9ff809d10d76b62663e1adabdMike Schuchardt PostCallRecordImportSemaphore(dev_data, pImportSemaphoreFdInfo->semaphore, pImportSemaphoreFdInfo->handleType, 909816f39f23c20176b9ff809d10d76b62663e1adabdMike Schuchardt pImportSemaphoreFdInfo->flags); 909916f39f23c20176b9ff809d10d76b62663e1adabdMike Schuchardt } 910016f39f23c20176b9ff809d10d76b62663e1adabdMike Schuchardt return result; 910116f39f23c20176b9ff809d10d76b62663e1adabdMike Schuchardt} 910216f39f23c20176b9ff809d10d76b62663e1adabdMike Schuchardt 910306d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardtstatic void PostCallRecordGetSemaphore(layer_data *dev_data, VkSemaphore semaphore, 910406d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt VkExternalSemaphoreHandleTypeFlagBitsKHR handle_type) { 910506d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt SEMAPHORE_NODE *sema_node = GetSemaphoreNode(dev_data, semaphore); 910606d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt if (sema_node && handle_type != VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT_KHR) { 910706d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt // Cannot track semaphore state once it is exported, except for Sync FD handle types which have copy transference 910806d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt sema_node->scope = kSyncScopeExternalPermanent; 910906d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt } 911006d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt} 911106d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt 911206d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt#ifdef VK_USE_PLATFORM_WIN32_KHR 911306d5c171f0bb0acbed8120af6bac43f13a869e3fMike SchuchardtVKAPI_ATTR VkResult VKAPI_CALL GetSemaphoreWin32HandleKHR(VkDevice device, 911406d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt const VkSemaphoreGetWin32HandleInfoKHR *pGetWin32HandleInfo, 911506d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt HANDLE *pHandle) { 911606d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 911706d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt VkResult result = dev_data->dispatch_table.GetSemaphoreWin32HandleKHR(device, pGetWin32HandleInfo, pHandle); 911806d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt 911906d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt if (result == VK_SUCCESS) { 912006d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt PostCallRecordGetSemaphore(dev_data, pGetWin32HandleInfo->semaphore, pGetWin32HandleInfo->handleType); 912106d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt } 912206d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt return result; 912306d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt} 912406d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt#endif 912506d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt 912616f39f23c20176b9ff809d10d76b62663e1adabdMike SchuchardtVKAPI_ATTR VkResult VKAPI_CALL GetSemaphoreFdKHR(VkDevice device, const VkSemaphoreGetFdInfoKHR *pGetFdInfo, int *pFd) { 912716f39f23c20176b9ff809d10d76b62663e1adabdMike Schuchardt layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 912816f39f23c20176b9ff809d10d76b62663e1adabdMike Schuchardt VkResult result = dev_data->dispatch_table.GetSemaphoreFdKHR(device, pGetFdInfo, pFd); 912916f39f23c20176b9ff809d10d76b62663e1adabdMike Schuchardt 913016f39f23c20176b9ff809d10d76b62663e1adabdMike Schuchardt if (result == VK_SUCCESS) { 913116f39f23c20176b9ff809d10d76b62663e1adabdMike Schuchardt PostCallRecordGetSemaphore(dev_data, pGetFdInfo->semaphore, pGetFdInfo->handleType); 913216f39f23c20176b9ff809d10d76b62663e1adabdMike Schuchardt } 913316f39f23c20176b9ff809d10d76b62663e1adabdMike Schuchardt return result; 913416f39f23c20176b9ff809d10d76b62663e1adabdMike Schuchardt} 913516f39f23c20176b9ff809d10d76b62663e1adabdMike Schuchardt 9136804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardtstatic bool PreCallValidateImportFence(layer_data *dev_data, VkFence fence, const char *caller_name) { 9137804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt FENCE_NODE *fence_node = GetFenceNode(dev_data, fence); 9138804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt bool skip = false; 9139804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt if (fence_node && fence_node->scope == kSyncScopeInternal && fence_node->state == FENCE_INFLIGHT) { 9140804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, 9141804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt HandleToUint64(fence), __LINE__, VALIDATION_ERROR_UNDEFINED, "DS", 9142804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt "Cannot call %s on fence 0x%" PRIx64 " that is currently in use.", caller_name, HandleToUint64(fence)); 9143804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt } 9144804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt return skip; 9145804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt} 9146804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt 9147804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardtstatic void PostCallRecordImportFence(layer_data *dev_data, VkFence fence, VkExternalFenceHandleTypeFlagBitsKHR handle_type, 9148804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt VkFenceImportFlagsKHR flags) { 9149804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt FENCE_NODE *fence_node = GetFenceNode(dev_data, fence); 9150804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt if (fence_node && fence_node->scope != kSyncScopeExternalPermanent) { 9151804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt if ((handle_type == VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR || flags & VK_FENCE_IMPORT_TEMPORARY_BIT_KHR) && 9152804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt fence_node->scope == kSyncScopeInternal) { 9153804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt fence_node->scope = kSyncScopeExternalTemporary; 9154804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt } else { 9155804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt fence_node->scope = kSyncScopeExternalPermanent; 9156804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt } 9157804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt } 9158804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt} 9159804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt 9160804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt#ifdef VK_USE_PLATFORM_WIN32_KHR 9161804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike SchuchardtVKAPI_ATTR VkResult VKAPI_CALL ImportFenceWin32HandleKHR(VkDevice device, 9162804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt const VkImportFenceWin32HandleInfoKHR *pImportFenceWin32HandleInfo) { 9163804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 9164804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 9165804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt bool skip = PreCallValidateImportFence(dev_data, pImportFenceWin32HandleInfo->fence, "vkImportFenceWin32HandleKHR"); 9166804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt 9167804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt if (!skip) { 9168804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt result = dev_data->dispatch_table.ImportFenceWin32HandleKHR(device, pImportFenceWin32HandleInfo); 9169804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt } 9170804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt 9171804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt if (result == VK_SUCCESS) { 9172804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt PostCallRecordImportFence(dev_data, pImportFenceWin32HandleInfo->fence, pImportFenceWin32HandleInfo->handleType, 9173804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt pImportFenceWin32HandleInfo->flags); 9174804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt } 9175804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt return result; 9176804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt} 9177804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt#endif 9178804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt 9179804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike SchuchardtVKAPI_ATTR VkResult VKAPI_CALL ImportFenceFdKHR(VkDevice device, const VkImportFenceFdInfoKHR *pImportFenceFdInfo) { 9180804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 9181804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 9182804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt bool skip = PreCallValidateImportFence(dev_data, pImportFenceFdInfo->fence, "vkImportFenceFdKHR"); 9183804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt 9184804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt if (!skip) { 9185804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt result = dev_data->dispatch_table.ImportFenceFdKHR(device, pImportFenceFdInfo); 9186804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt } 9187804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt 9188804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt if (result == VK_SUCCESS) { 9189804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt PostCallRecordImportFence(dev_data, pImportFenceFdInfo->fence, pImportFenceFdInfo->handleType, pImportFenceFdInfo->flags); 9190804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt } 9191804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt return result; 9192804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt} 9193804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt 9194804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardtstatic void PostCallRecordGetFence(layer_data *dev_data, VkFence fence, VkExternalFenceHandleTypeFlagBitsKHR handle_type) { 9195804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt FENCE_NODE *fence_node = GetFenceNode(dev_data, fence); 9196804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt if (fence_node) { 9197804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt if (handle_type != VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR) { 9198804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt // Export with reference transference becomes external 9199804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt fence_node->scope = kSyncScopeExternalPermanent; 9200804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt } else if (fence_node->scope == kSyncScopeInternal) { 9201804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt // Export with copy transference has a side effect of resetting the fence 9202804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt fence_node->state = FENCE_UNSIGNALED; 9203804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt } 9204804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt } 9205804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt} 9206804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt 9207804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt#ifdef VK_USE_PLATFORM_WIN32_KHR 9208804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike SchuchardtVKAPI_ATTR VkResult VKAPI_CALL GetFenceWin32HandleKHR(VkDevice device, const VkFenceGetWin32HandleInfoKHR *pGetWin32HandleInfo, 9209804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt HANDLE *pHandle) { 9210804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 9211804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt VkResult result = dev_data->dispatch_table.GetFenceWin32HandleKHR(device, pGetWin32HandleInfo, pHandle); 9212804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt 9213804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt if (result == VK_SUCCESS) { 9214804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt PostCallRecordGetFence(dev_data, pGetWin32HandleInfo->fence, pGetWin32HandleInfo->handleType); 9215804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt } 9216804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt return result; 9217804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt} 9218804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt#endif 9219804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt 9220804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike SchuchardtVKAPI_ATTR VkResult VKAPI_CALL GetFenceFdKHR(VkDevice device, const VkFenceGetFdInfoKHR *pGetFdInfo, int *pFd) { 9221804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 9222804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt VkResult result = dev_data->dispatch_table.GetFenceFdKHR(device, pGetFdInfo, pFd); 9223804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt 9224804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt if (result == VK_SUCCESS) { 9225804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt PostCallRecordGetFence(dev_data, pGetFdInfo->fence, pGetFdInfo->handleType); 9226804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt } 9227804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt return result; 9228804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt} 9229804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt 9230bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL CreateEvent(VkDevice device, const VkEventCreateInfo *pCreateInfo, 9231bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkAllocationCallbacks *pAllocator, VkEvent *pEvent) { 923256e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 92334a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.CreateEvent(device, pCreateInfo, pAllocator, pEvent); 92345b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (result == VK_SUCCESS) { 9235ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 92365b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis dev_data->eventMap[*pEvent].needsSignaled = false; 9237293ecfc5e69ed3978a8c04518166d828294870a4Tony Barbour dev_data->eventMap[*pEvent].write_in_use = 0; 92385b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis dev_data->eventMap[*pEvent].stageMask = VkPipelineStageFlags(0); 92395b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 92405b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 92415b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 92425b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 92439ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinskistatic bool PreCallValidateCreateSwapchainKHR(layer_data *dev_data, const char *func_name, 92449ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski VkSwapchainCreateInfoKHR const *pCreateInfo, SURFACE_STATE *surface_state, 92459ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski SWAPCHAIN_NODE *old_swapchain_state) { 9246d3b3114fb37a32af2ba563f784da54a877492b23Chris Forbes auto most_recent_swapchain = surface_state->swapchain ? surface_state->swapchain : surface_state->old_swapchain; 9247d3b3114fb37a32af2ba563f784da54a877492b23Chris Forbes 92484bd5f453535de3d3423ff1f9995b4acb15f791d2Chris Forbes // TODO: revisit this. some of these rules are being relaxed. 92490bbc015828bdb99e85e6731ce92428557902701fPetr Kraus 92500bbc015828bdb99e85e6731ce92428557902701fPetr Kraus // All physical devices and queue families are required to be able 92510bbc015828bdb99e85e6731ce92428557902701fPetr Kraus // to present to any native window on Android; require the 92520bbc015828bdb99e85e6731ce92428557902701fPetr Kraus // application to have established support on any other platform. 9253d4eaca34eca7f4b4e34190c441a579347bb2016aMark Lobodzinski if (!dev_data->instance_data->extensions.vk_khr_android_surface) { 92540bbc015828bdb99e85e6731ce92428557902701fPetr Kraus auto support_predicate = [dev_data](decltype(surface_state->gpu_queue_support)::const_reference qs) -> bool { 92550bbc015828bdb99e85e6731ce92428557902701fPetr Kraus // TODO: should restrict search only to queue families of VkDeviceQueueCreateInfos, not whole phys. device 92560bbc015828bdb99e85e6731ce92428557902701fPetr Kraus return (qs.first.gpu == dev_data->physical_device) && qs.second; 92570bbc015828bdb99e85e6731ce92428557902701fPetr Kraus }; 92580bbc015828bdb99e85e6731ce92428557902701fPetr Kraus const auto& support = surface_state->gpu_queue_support; 92590bbc015828bdb99e85e6731ce92428557902701fPetr Kraus bool is_supported = std::any_of(support.begin(), support.end(), support_predicate); 92600bbc015828bdb99e85e6731ce92428557902701fPetr Kraus 92610bbc015828bdb99e85e6731ce92428557902701fPetr Kraus if (!is_supported) { 92620bbc015828bdb99e85e6731ce92428557902701fPetr Kraus if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 9263315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(dev_data->device), __LINE__, VALIDATION_ERROR_146009ec, "DS", 92640bbc015828bdb99e85e6731ce92428557902701fPetr Kraus "%s: pCreateInfo->surface is not known at this time to be supported for presentation by this device. " 92650bbc015828bdb99e85e6731ce92428557902701fPetr Kraus "The vkGetPhysicalDeviceSurfaceSupportKHR() must be called beforehand, and it must return VK_TRUE support " 92660bbc015828bdb99e85e6731ce92428557902701fPetr Kraus "with this surface for at least one queue family of this device. %s", 9267315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis func_name, validation_error_map[VALIDATION_ERROR_146009ec])) 92680bbc015828bdb99e85e6731ce92428557902701fPetr Kraus return true; 92690bbc015828bdb99e85e6731ce92428557902701fPetr Kraus } 92700bbc015828bdb99e85e6731ce92428557902701fPetr Kraus } 92710bbc015828bdb99e85e6731ce92428557902701fPetr Kraus 9272d3b3114fb37a32af2ba563f784da54a877492b23Chris Forbes if (most_recent_swapchain != old_swapchain_state || (surface_state->old_swapchain && surface_state->swapchain)) { 9273d3b3114fb37a32af2ba563f784da54a877492b23Chris Forbes if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 92749b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(dev_data->device), __LINE__, DRAWSTATE_SWAPCHAIN_ALREADY_EXISTS, "DS", 92759ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski "%s: surface has an existing swapchain other than oldSwapchain", func_name)) 9276d3b3114fb37a32af2ba563f784da54a877492b23Chris Forbes return true; 9277d3b3114fb37a32af2ba563f784da54a877492b23Chris Forbes } 9278d3b3114fb37a32af2ba563f784da54a877492b23Chris Forbes if (old_swapchain_state && old_swapchain_state->createInfo.surface != pCreateInfo->surface) { 9279d3b3114fb37a32af2ba563f784da54a877492b23Chris Forbes if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, 92809b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pCreateInfo->oldSwapchain), __LINE__, DRAWSTATE_SWAPCHAIN_WRONG_SURFACE, "DS", 92819b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "%s: pCreateInfo->oldSwapchain's surface is not pCreateInfo->surface", func_name)) 9282d3b3114fb37a32af2ba563f784da54a877492b23Chris Forbes return true; 9283d3b3114fb37a32af2ba563f784da54a877492b23Chris Forbes } 92849a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto physical_device_state = GetPhysicalDeviceState(dev_data->instance_data, dev_data->physical_device); 92857de258f87ca1192db116a66b209253793d276ebcChris Forbes if (physical_device_state->vkGetPhysicalDeviceSurfaceCapabilitiesKHRState == UNCALLED) { 92867de258f87ca1192db116a66b209253793d276ebcChris Forbes if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 92879b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(dev_data->physical_device), __LINE__, DRAWSTATE_SWAPCHAIN_CREATE_BEFORE_QUERY, "DS", 92889ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski "%s: surface capabilities not retrieved for this physical device", func_name)) 92897de258f87ca1192db116a66b209253793d276ebcChris Forbes return true; 9290cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } else { // have valid capabilities 92915c99b4daed164798f307244c9bde17b4f66014fbChris Forbes auto &capabilities = physical_device_state->surfaceCapabilities; 92929ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski // Validate pCreateInfo->minImageCount against VkSurfaceCapabilitiesKHR::{min|max}ImageCount: 92932fbc1a61dff1781368a0c592c25985abb46e4891Mike Weiblen if (pCreateInfo->minImageCount < capabilities.minImageCount) { 92942fbc1a61dff1781368a0c592c25985abb46e4891Mike Weiblen if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 9295315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(dev_data->device), __LINE__, VALIDATION_ERROR_146009ee, "DS", 92969ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski "%s called with minImageCount = %d, which is outside the bounds returned " 92972fbc1a61dff1781368a0c592c25985abb46e4891Mike Weiblen "by vkGetPhysicalDeviceSurfaceCapabilitiesKHR() (i.e. minImageCount = %d, maxImageCount = %d). %s", 92989ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski func_name, pCreateInfo->minImageCount, capabilities.minImageCount, capabilities.maxImageCount, 9299315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_146009ee])) 93002fbc1a61dff1781368a0c592c25985abb46e4891Mike Weiblen return true; 93012fbc1a61dff1781368a0c592c25985abb46e4891Mike Weiblen } 93022fbc1a61dff1781368a0c592c25985abb46e4891Mike Weiblen 93032fbc1a61dff1781368a0c592c25985abb46e4891Mike Weiblen if ((capabilities.maxImageCount > 0) && (pCreateInfo->minImageCount > capabilities.maxImageCount)) { 93045c99b4daed164798f307244c9bde17b4f66014fbChris Forbes if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 9305315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(dev_data->device), __LINE__, VALIDATION_ERROR_146009f0, "DS", 93069ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski "%s called with minImageCount = %d, which is outside the bounds returned " 93072fbc1a61dff1781368a0c592c25985abb46e4891Mike Weiblen "by vkGetPhysicalDeviceSurfaceCapabilitiesKHR() (i.e. minImageCount = %d, maxImageCount = %d). %s", 93089ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski func_name, pCreateInfo->minImageCount, capabilities.minImageCount, capabilities.maxImageCount, 9309315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_146009f0])) 93105c99b4daed164798f307244c9bde17b4f66014fbChris Forbes return true; 93115c99b4daed164798f307244c9bde17b4f66014fbChris Forbes } 93122fbc1a61dff1781368a0c592c25985abb46e4891Mike Weiblen 93139ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski // Validate pCreateInfo->imageExtent against VkSurfaceCapabilitiesKHR::{current|min|max}ImageExtent: 9314b42b2f0f35df5143dcc982217434cf0d42a45afeCort if ((pCreateInfo->imageExtent.width < capabilities.minImageExtent.width) || 9315b42b2f0f35df5143dcc982217434cf0d42a45afeCort (pCreateInfo->imageExtent.width > capabilities.maxImageExtent.width) || 9316b42b2f0f35df5143dcc982217434cf0d42a45afeCort (pCreateInfo->imageExtent.height < capabilities.minImageExtent.height) || 9317b42b2f0f35df5143dcc982217434cf0d42a45afeCort (pCreateInfo->imageExtent.height > capabilities.maxImageExtent.height)) { 93185c99b4daed164798f307244c9bde17b4f66014fbChris Forbes if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 9319315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(dev_data->device), __LINE__, VALIDATION_ERROR_146009f4, "DS", 93209ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski "%s called with imageExtent = (%d,%d), which is outside the bounds returned by " 93219ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski "vkGetPhysicalDeviceSurfaceCapabilitiesKHR(): currentExtent = (%d,%d), minImageExtent = (%d,%d), " 93229ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski "maxImageExtent = (%d,%d). %s", 93239ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski func_name, pCreateInfo->imageExtent.width, pCreateInfo->imageExtent.height, 93249ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski capabilities.currentExtent.width, capabilities.currentExtent.height, capabilities.minImageExtent.width, 93259ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski capabilities.minImageExtent.height, capabilities.maxImageExtent.width, capabilities.maxImageExtent.height, 9326315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_146009f4])) 93275c99b4daed164798f307244c9bde17b4f66014fbChris Forbes return true; 93285c99b4daed164798f307244c9bde17b4f66014fbChris Forbes } 93299ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski // pCreateInfo->preTransform should have exactly one bit set, and that bit must also be set in 93309ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski // VkSurfaceCapabilitiesKHR::supportedTransforms. 93315c99b4daed164798f307244c9bde17b4f66014fbChris Forbes if (!pCreateInfo->preTransform || (pCreateInfo->preTransform & (pCreateInfo->preTransform - 1)) || 93325c99b4daed164798f307244c9bde17b4f66014fbChris Forbes !(pCreateInfo->preTransform & capabilities.supportedTransforms)) { 93339ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski // This is an error situation; one for which we'd like to give the developer a helpful, multi-line error message. Build 93349ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski // it up a little at a time, and then log it: 93355c99b4daed164798f307244c9bde17b4f66014fbChris Forbes std::string errorString = ""; 93365c99b4daed164798f307244c9bde17b4f66014fbChris Forbes char str[1024]; 93375c99b4daed164798f307244c9bde17b4f66014fbChris Forbes // Here's the first part of the message: 93389ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski sprintf(str, "%s called with a non-supported pCreateInfo->preTransform (i.e. %s). Supported values are:\n", func_name, 93395c99b4daed164798f307244c9bde17b4f66014fbChris Forbes string_VkSurfaceTransformFlagBitsKHR(pCreateInfo->preTransform)); 93405c99b4daed164798f307244c9bde17b4f66014fbChris Forbes errorString += str; 93415c99b4daed164798f307244c9bde17b4f66014fbChris Forbes for (int i = 0; i < 32; i++) { 93425c99b4daed164798f307244c9bde17b4f66014fbChris Forbes // Build up the rest of the message: 93435c99b4daed164798f307244c9bde17b4f66014fbChris Forbes if ((1 << i) & capabilities.supportedTransforms) { 93445c99b4daed164798f307244c9bde17b4f66014fbChris Forbes const char *newStr = string_VkSurfaceTransformFlagBitsKHR((VkSurfaceTransformFlagBitsKHR)(1 << i)); 93455c99b4daed164798f307244c9bde17b4f66014fbChris Forbes sprintf(str, " %s\n", newStr); 93465c99b4daed164798f307244c9bde17b4f66014fbChris Forbes errorString += str; 93475c99b4daed164798f307244c9bde17b4f66014fbChris Forbes } 93485c99b4daed164798f307244c9bde17b4f66014fbChris Forbes } 93495c99b4daed164798f307244c9bde17b4f66014fbChris Forbes // Log the message that we've built up: 93505c99b4daed164798f307244c9bde17b4f66014fbChris Forbes if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 9351315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(dev_data->device), __LINE__, VALIDATION_ERROR_146009fe, "DS", "%s. %s", errorString.c_str(), 9352315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_146009fe])) 93535c99b4daed164798f307244c9bde17b4f66014fbChris Forbes return true; 93545c99b4daed164798f307244c9bde17b4f66014fbChris Forbes } 93557b0d28d116977b91892f354e002edd760bdb86cbChris Forbes 93569ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski // pCreateInfo->compositeAlpha should have exactly one bit set, and that bit must also be set in 93579ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski // VkSurfaceCapabilitiesKHR::supportedCompositeAlpha 93585c99b4daed164798f307244c9bde17b4f66014fbChris Forbes if (!pCreateInfo->compositeAlpha || (pCreateInfo->compositeAlpha & (pCreateInfo->compositeAlpha - 1)) || 93595c99b4daed164798f307244c9bde17b4f66014fbChris Forbes !((pCreateInfo->compositeAlpha) & capabilities.supportedCompositeAlpha)) { 93609ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski // This is an error situation; one for which we'd like to give the developer a helpful, multi-line error message. Build 93619ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski // it up a little at a time, and then log it: 93625c99b4daed164798f307244c9bde17b4f66014fbChris Forbes std::string errorString = ""; 93635c99b4daed164798f307244c9bde17b4f66014fbChris Forbes char str[1024]; 93645c99b4daed164798f307244c9bde17b4f66014fbChris Forbes // Here's the first part of the message: 93659ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski sprintf(str, "%s called with a non-supported pCreateInfo->compositeAlpha (i.e. %s). Supported values are:\n", 93669ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski func_name, string_VkCompositeAlphaFlagBitsKHR(pCreateInfo->compositeAlpha)); 93675c99b4daed164798f307244c9bde17b4f66014fbChris Forbes errorString += str; 93685c99b4daed164798f307244c9bde17b4f66014fbChris Forbes for (int i = 0; i < 32; i++) { 93695c99b4daed164798f307244c9bde17b4f66014fbChris Forbes // Build up the rest of the message: 93705c99b4daed164798f307244c9bde17b4f66014fbChris Forbes if ((1 << i) & capabilities.supportedCompositeAlpha) { 93715c99b4daed164798f307244c9bde17b4f66014fbChris Forbes const char *newStr = string_VkCompositeAlphaFlagBitsKHR((VkCompositeAlphaFlagBitsKHR)(1 << i)); 93725c99b4daed164798f307244c9bde17b4f66014fbChris Forbes sprintf(str, " %s\n", newStr); 93735c99b4daed164798f307244c9bde17b4f66014fbChris Forbes errorString += str; 93745c99b4daed164798f307244c9bde17b4f66014fbChris Forbes } 93755c99b4daed164798f307244c9bde17b4f66014fbChris Forbes } 93765c99b4daed164798f307244c9bde17b4f66014fbChris Forbes // Log the message that we've built up: 93775c99b4daed164798f307244c9bde17b4f66014fbChris Forbes if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 9378315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(dev_data->device), __LINE__, VALIDATION_ERROR_14600a00, "DS", "%s. %s", errorString.c_str(), 9379315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_14600a00])) 93805c99b4daed164798f307244c9bde17b4f66014fbChris Forbes return true; 93815c99b4daed164798f307244c9bde17b4f66014fbChris Forbes } 93829ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski // Validate pCreateInfo->imageArrayLayers against VkSurfaceCapabilitiesKHR::maxImageArrayLayers: 93835c99b4daed164798f307244c9bde17b4f66014fbChris Forbes if ((pCreateInfo->imageArrayLayers < 1) || (pCreateInfo->imageArrayLayers > capabilities.maxImageArrayLayers)) { 93845c99b4daed164798f307244c9bde17b4f66014fbChris Forbes if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 9385315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(dev_data->device), __LINE__, VALIDATION_ERROR_146009f6, "DS", 93869ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski "%s called with a non-supported imageArrayLayers (i.e. %d). Minimum value is 1, maximum value is %d. %s", 93879ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski func_name, pCreateInfo->imageArrayLayers, capabilities.maxImageArrayLayers, 9388315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_146009f6])) 93895c99b4daed164798f307244c9bde17b4f66014fbChris Forbes return true; 93905c99b4daed164798f307244c9bde17b4f66014fbChris Forbes } 93919ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski // Validate pCreateInfo->imageUsage against VkSurfaceCapabilitiesKHR::supportedUsageFlags: 93925c99b4daed164798f307244c9bde17b4f66014fbChris Forbes if (pCreateInfo->imageUsage != (pCreateInfo->imageUsage & capabilities.supportedUsageFlags)) { 93935c99b4daed164798f307244c9bde17b4f66014fbChris Forbes if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 9394315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(dev_data->device), __LINE__, VALIDATION_ERROR_146009f8, "DS", 93959ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski "%s called with a non-supported pCreateInfo->imageUsage (i.e. 0x%08x). Supported flag bits are 0x%08x. %s", 93969ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski func_name, pCreateInfo->imageUsage, capabilities.supportedUsageFlags, 9397315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_146009f8])) 93985c99b4daed164798f307244c9bde17b4f66014fbChris Forbes return true; 93995c99b4daed164798f307244c9bde17b4f66014fbChris Forbes } 94007de258f87ca1192db116a66b209253793d276ebcChris Forbes } 9401d3b3114fb37a32af2ba563f784da54a877492b23Chris Forbes 94029ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski // Validate pCreateInfo values with the results of vkGetPhysicalDeviceSurfaceFormatsKHR(): 94035faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes if (physical_device_state->vkGetPhysicalDeviceSurfaceFormatsKHRState != QUERY_DETAILS) { 94045faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 94059b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(dev_data->device), __LINE__, DRAWSTATE_SWAPCHAIN_CREATE_BEFORE_QUERY, "DS", 94069ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski "%s called before calling vkGetPhysicalDeviceSurfaceFormatsKHR().", func_name)) 94075faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes return true; 94085faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes } else { 94099ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski // Validate pCreateInfo->imageFormat against VkSurfaceFormatKHR::format: 94105faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes bool foundFormat = false; 94115faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes bool foundColorSpace = false; 94125faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes bool foundMatch = false; 94135faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes for (auto const &format : physical_device_state->surface_formats) { 94145faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes if (pCreateInfo->imageFormat == format.format) { 94159ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski // Validate pCreateInfo->imageColorSpace against VkSurfaceFormatKHR::colorSpace: 94165faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes foundFormat = true; 94175faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes if (pCreateInfo->imageColorSpace == format.colorSpace) { 94185faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes foundMatch = true; 94195faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes break; 94205faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes } 94215faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes } else { 94225faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes if (pCreateInfo->imageColorSpace == format.colorSpace) { 94235faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes foundColorSpace = true; 94245faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes } 94255faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes } 94265faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes } 94275faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes if (!foundMatch) { 94285faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes if (!foundFormat) { 94295faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 9430315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(dev_data->device), __LINE__, VALIDATION_ERROR_146009f2, "DS", 9431bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski "%s called with a non-supported pCreateInfo->imageFormat (i.e. %d). %s", func_name, 9432315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis pCreateInfo->imageFormat, validation_error_map[VALIDATION_ERROR_146009f2])) 94332fbc1a61dff1781368a0c592c25985abb46e4891Mike Weiblen return true; 94342fbc1a61dff1781368a0c592c25985abb46e4891Mike Weiblen } 94352fbc1a61dff1781368a0c592c25985abb46e4891Mike Weiblen if (!foundColorSpace) { 94362fbc1a61dff1781368a0c592c25985abb46e4891Mike Weiblen if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 9437315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(dev_data->device), __LINE__, VALIDATION_ERROR_146009f2, "DS", 9438bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski "%s called with a non-supported pCreateInfo->imageColorSpace (i.e. %d). %s", func_name, 9439315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis pCreateInfo->imageColorSpace, validation_error_map[VALIDATION_ERROR_146009f2])) 94405faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes return true; 94415faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes } 94425faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes } 94435faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes } 94445faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes 94459ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski // Validate pCreateInfo values with the results of vkGetPhysicalDeviceSurfacePresentModesKHR(): 94469e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes if (physical_device_state->vkGetPhysicalDeviceSurfacePresentModesKHRState != QUERY_DETAILS) { 944725002b75574f762c62b1a00a595bab04ebb25452Mark Lobodzinski // FIFO is required to always be supported 94489e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes if (pCreateInfo->presentMode != VK_PRESENT_MODE_FIFO_KHR) { 94499e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 94509b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(dev_data->device), __LINE__, DRAWSTATE_SWAPCHAIN_CREATE_BEFORE_QUERY, "DS", 94519ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski "%s called before calling vkGetPhysicalDeviceSurfacePresentModesKHR().", func_name)) 94529e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes return true; 94539e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes } 94549e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes } else { 94559ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski // Validate pCreateInfo->presentMode against vkGetPhysicalDeviceSurfacePresentModesKHR(): 9456bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski bool foundMatch = std::find(physical_device_state->present_modes.begin(), physical_device_state->present_modes.end(), 94579e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes pCreateInfo->presentMode) != physical_device_state->present_modes.end(); 94589e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes if (!foundMatch) { 94599e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 9460315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(dev_data->device), __LINE__, VALIDATION_ERROR_14600a02, "DS", 94619ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski "%s called with a non-supported presentMode (i.e. %s). %s", func_name, 9462315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis string_VkPresentModeKHR(pCreateInfo->presentMode), validation_error_map[VALIDATION_ERROR_14600a02])) 94639e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes return true; 94649e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes } 94659e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes } 946687a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis // Validate state for shared presentable case 946787a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis if (VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR == pCreateInfo->presentMode || 946887a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR == pCreateInfo->presentMode) { 9469a149f1a0cb39b48b19822c8cf9ef2426cd2251dfMark Lobodzinski if (!dev_data->extensions.vk_khr_shared_presentable_image) { 947087a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 9471480a11822ef9a45f577f13644759c0895a49db19Tobin Ehlis HandleToUint64(dev_data->device), __LINE__, DRAWSTATE_EXTENSION_NOT_ENABLED, "DS", 94726084b78a58b438d27591b81efe30997ac9d88d3cMark Lobodzinski "%s called with presentMode %s which requires the VK_KHR_shared_presentable_image extension, which has not " 94736084b78a58b438d27591b81efe30997ac9d88d3cMark Lobodzinski "been enabled.", 94746084b78a58b438d27591b81efe30997ac9d88d3cMark Lobodzinski func_name, string_VkPresentModeKHR(pCreateInfo->presentMode))) 94756084b78a58b438d27591b81efe30997ac9d88d3cMark Lobodzinski return true; 94766084b78a58b438d27591b81efe30997ac9d88d3cMark Lobodzinski } else if (pCreateInfo->minImageCount != 1) { 94776084b78a58b438d27591b81efe30997ac9d88d3cMark Lobodzinski if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 9478315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis reinterpret_cast<uint64_t>(dev_data->device), __LINE__, VALIDATION_ERROR_14600ace, "DS", 947987a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis "%s called with presentMode %s, but minImageCount value is %d. For shared presentable image, minImageCount " 94806084b78a58b438d27591b81efe30997ac9d88d3cMark Lobodzinski "must be 1. %s", 94816084b78a58b438d27591b81efe30997ac9d88d3cMark Lobodzinski func_name, string_VkPresentModeKHR(pCreateInfo->presentMode), pCreateInfo->minImageCount, 9482315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_14600ace])) 948387a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis return true; 948487a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis } 948587a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis } 94869e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes 9487d3b3114fb37a32af2ba563f784da54a877492b23Chris Forbes return false; 9488d3b3114fb37a32af2ba563f784da54a877492b23Chris Forbes} 9489d3b3114fb37a32af2ba563f784da54a877492b23Chris Forbes 9490261dc1ef7a86b64cce92a6811bf80ee4ba364a48Mark Lobodzinskistatic void PostCallRecordCreateSwapchainKHR(layer_data *dev_data, VkResult result, const VkSwapchainCreateInfoKHR *pCreateInfo, 9491261dc1ef7a86b64cce92a6811bf80ee4ba364a48Mark Lobodzinski VkSwapchainKHR *pSwapchain, SURFACE_STATE *surface_state, 9492261dc1ef7a86b64cce92a6811bf80ee4ba364a48Mark Lobodzinski SWAPCHAIN_NODE *old_swapchain_state) { 94935b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (VK_SUCCESS == result) { 9494ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 9495ddc5201048319558ce66701163a4546ee957af19Chris Forbes auto swapchain_state = unique_ptr<SWAPCHAIN_NODE>(new SWAPCHAIN_NODE(pCreateInfo, *pSwapchain)); 949687a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis if (VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR == pCreateInfo->presentMode || 949787a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR == pCreateInfo->presentMode) { 949887a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis swapchain_state->shared_presentable = true; 949987a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis } 9500ddc5201048319558ce66701163a4546ee957af19Chris Forbes surface_state->swapchain = swapchain_state.get(); 950116a1f8f9c4af479b1873e82ff02360817fb658acChris Forbes dev_data->swapchainMap[*pSwapchain] = std::move(swapchain_state); 9502ddc5201048319558ce66701163a4546ee957af19Chris Forbes } else { 9503ddc5201048319558ce66701163a4546ee957af19Chris Forbes surface_state->swapchain = nullptr; 95045b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 9505ddc5201048319558ce66701163a4546ee957af19Chris Forbes // Spec requires that even if CreateSwapchainKHR fails, oldSwapchain behaves as replaced. 95065b5488456e5afa0487f95b805a2aba59b13d69f4Chris Forbes if (old_swapchain_state) { 95075b5488456e5afa0487f95b805a2aba59b13d69f4Chris Forbes old_swapchain_state->replaced = true; 95085b5488456e5afa0487f95b805a2aba59b13d69f4Chris Forbes } 9509ddc5201048319558ce66701163a4546ee957af19Chris Forbes surface_state->old_swapchain = old_swapchain_state; 9510261dc1ef7a86b64cce92a6811bf80ee4ba364a48Mark Lobodzinski return; 9511261dc1ef7a86b64cce92a6811bf80ee4ba364a48Mark Lobodzinski} 9512261dc1ef7a86b64cce92a6811bf80ee4ba364a48Mark Lobodzinski 9513261dc1ef7a86b64cce92a6811bf80ee4ba364a48Mark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL CreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo, 9514261dc1ef7a86b64cce92a6811bf80ee4ba364a48Mark Lobodzinski const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain) { 951556e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 95169a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto surface_state = GetSurfaceState(dev_data->instance_data, pCreateInfo->surface); 95179a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto old_swapchain_state = GetSwapchainNode(dev_data, pCreateInfo->oldSwapchain); 9518261dc1ef7a86b64cce92a6811bf80ee4ba364a48Mark Lobodzinski 95199ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski if (PreCallValidateCreateSwapchainKHR(dev_data, "vkCreateSwapChainKHR()", pCreateInfo, surface_state, old_swapchain_state)) { 9520261dc1ef7a86b64cce92a6811bf80ee4ba364a48Mark Lobodzinski return VK_ERROR_VALIDATION_FAILED_EXT; 9521261dc1ef7a86b64cce92a6811bf80ee4ba364a48Mark Lobodzinski } 9522261dc1ef7a86b64cce92a6811bf80ee4ba364a48Mark Lobodzinski 9523261dc1ef7a86b64cce92a6811bf80ee4ba364a48Mark Lobodzinski VkResult result = dev_data->dispatch_table.CreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain); 9524261dc1ef7a86b64cce92a6811bf80ee4ba364a48Mark Lobodzinski 9525261dc1ef7a86b64cce92a6811bf80ee4ba364a48Mark Lobodzinski PostCallRecordCreateSwapchainKHR(dev_data, result, pCreateInfo, pSwapchain, surface_state, old_swapchain_state); 9526ddc5201048319558ce66701163a4546ee957af19Chris Forbes 95275b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 95285b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 95295b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 9530bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL DestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks *pAllocator) { 953156e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 95323251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 95335b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 9534ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 95359a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto swapchain_data = GetSwapchainNode(dev_data, swapchain); 9536b110cb87b9478586719d7f7dc769b350857366baTobin Ehlis if (swapchain_data) { 9537b110cb87b9478586719d7f7dc769b350857366baTobin Ehlis if (swapchain_data->images.size() > 0) { 9538b110cb87b9478586719d7f7dc769b350857366baTobin Ehlis for (auto swapchain_image : swapchain_data->images) { 95395b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis auto image_sub = dev_data->imageSubresourceMap.find(swapchain_image); 95405b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (image_sub != dev_data->imageSubresourceMap.end()) { 95415b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (auto imgsubpair : image_sub->second) { 95425b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis auto image_item = dev_data->imageLayoutMap.find(imgsubpair); 95435b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (image_item != dev_data->imageLayoutMap.end()) { 95445b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis dev_data->imageLayoutMap.erase(image_item); 95455b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 95465b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 95475b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis dev_data->imageSubresourceMap.erase(image_sub); 95485b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 95499b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip = ClearMemoryObjectBindings(dev_data, HandleToUint64(swapchain_image), kVulkanObjectTypeSwapchainKHR); 955094c53c062f0ccc70ef0ada8e98edc90eadc4cb45Tobin Ehlis dev_data->imageMap.erase(swapchain_image); 95515b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 95525b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 9553ddc5201048319558ce66701163a4546ee957af19Chris Forbes 95549a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto surface_state = GetSurfaceState(dev_data->instance_data, swapchain_data->createInfo.surface); 9555ddc5201048319558ce66701163a4546ee957af19Chris Forbes if (surface_state) { 9556cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (surface_state->swapchain == swapchain_data) surface_state->swapchain = nullptr; 9557cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (surface_state->old_swapchain == swapchain_data) surface_state->old_swapchain = nullptr; 9558ddc5201048319558ce66701163a4546ee957af19Chris Forbes } 9559ddc5201048319558ce66701163a4546ee957af19Chris Forbes 956016a1f8f9c4af479b1873e82ff02360817fb658acChris Forbes dev_data->swapchainMap.erase(swapchain); 95615b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 9562b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 95633251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip) dev_data->dispatch_table.DestroySwapchainKHR(device, swapchain, pAllocator); 95645b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 95655b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 9566991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinskistatic bool PreCallValidateGetSwapchainImagesKHR(layer_data *device_data, SWAPCHAIN_NODE *swapchain_state, VkDevice device, 9567991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski uint32_t *pSwapchainImageCount, VkImage *pSwapchainImages) { 9568991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski bool skip = false; 9569991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski if (swapchain_state && pSwapchainImages) { 9570ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 9571991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski // Compare the preliminary value of *pSwapchainImageCount with the value this time: 9572991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski if (swapchain_state->vkGetSwapchainImagesKHRState == UNCALLED) { 9573991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 9574991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski HandleToUint64(device), __LINE__, SWAPCHAIN_PRIOR_COUNT, "DS", 9575991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski "vkGetSwapchainImagesKHR() called with non-NULL pSwapchainImageCount; but no prior positive " 9576991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski "value has been seen for pSwapchainImages."); 9577991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski } else if (*pSwapchainImageCount > swapchain_state->get_swapchain_image_count) { 9578991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 9579991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski HandleToUint64(device), __LINE__, SWAPCHAIN_INVALID_COUNT, "DS", 9580991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski "vkGetSwapchainImagesKHR() called with non-NULL pSwapchainImageCount, and with " 9581991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski "pSwapchainImages set to a value (%d) that is greater than the value (%d) that was returned when " 9582991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski "pSwapchainImageCount was NULL.", 9583991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski *pSwapchainImageCount, swapchain_state->get_swapchain_image_count); 9584991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski } 9585991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski } 9586991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski return skip; 9587991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski} 9588991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski 9589991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinskistatic void PostCallRecordGetSwapchainImagesKHR(layer_data *device_data, SWAPCHAIN_NODE *swapchain_state, VkDevice device, 9590991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski uint32_t *pSwapchainImageCount, VkImage *pSwapchainImages) { 9591ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 9592ee52d734440f0770b3ac5ebde5a137d2e40589deChris Forbes 9593991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski if (*pSwapchainImageCount > swapchain_state->images.size()) swapchain_state->images.resize(*pSwapchainImageCount); 9594ee52d734440f0770b3ac5ebde5a137d2e40589deChris Forbes 9595991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski if (pSwapchainImages) { 9596991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski if (swapchain_state->vkGetSwapchainImagesKHRState < QUERY_DETAILS) { 9597991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski swapchain_state->vkGetSwapchainImagesKHRState = QUERY_DETAILS; 9598991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski } 9599991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski for (uint32_t i = 0; i < *pSwapchainImageCount; ++i) { 9600991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski if (swapchain_state->images[i] != VK_NULL_HANDLE) continue; // Already retrieved this. 9601ee52d734440f0770b3ac5ebde5a137d2e40589deChris Forbes 96025b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis IMAGE_LAYOUT_NODE image_layout_node; 96035b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis image_layout_node.layout = VK_IMAGE_LAYOUT_UNDEFINED; 9604991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski image_layout_node.format = swapchain_state->createInfo.imageFormat; 96056d1373829eded68f6e080ff2c33e03231360ed57Tobin Ehlis // Add imageMap entries for each swapchain image 96066d1373829eded68f6e080ff2c33e03231360ed57Tobin Ehlis VkImageCreateInfo image_ci = {}; 9607eb6ea7587bdc06e98a89398f113fe3610d270dcbChris Forbes image_ci.flags = 0; 9608eb6ea7587bdc06e98a89398f113fe3610d270dcbChris Forbes image_ci.imageType = VK_IMAGE_TYPE_2D; 9609991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski image_ci.format = swapchain_state->createInfo.imageFormat; 9610991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski image_ci.extent.width = swapchain_state->createInfo.imageExtent.width; 9611991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski image_ci.extent.height = swapchain_state->createInfo.imageExtent.height; 9612d1a9776c1a22ec99a3ef0dd44e7f85a78a04d1edTony Barbour image_ci.extent.depth = 1; 9613eb6ea7587bdc06e98a89398f113fe3610d270dcbChris Forbes image_ci.mipLevels = 1; 9614991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski image_ci.arrayLayers = swapchain_state->createInfo.imageArrayLayers; 9615eb6ea7587bdc06e98a89398f113fe3610d270dcbChris Forbes image_ci.samples = VK_SAMPLE_COUNT_1_BIT; 9616eb6ea7587bdc06e98a89398f113fe3610d270dcbChris Forbes image_ci.tiling = VK_IMAGE_TILING_OPTIMAL; 9617991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski image_ci.usage = swapchain_state->createInfo.imageUsage; 9618991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski image_ci.sharingMode = swapchain_state->createInfo.imageSharingMode; 9619991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski device_data->imageMap[pSwapchainImages[i]] = unique_ptr<IMAGE_STATE>(new IMAGE_STATE(pSwapchainImages[i], &image_ci)); 9620991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski auto &image_state = device_data->imageMap[pSwapchainImages[i]]; 96211facd2c91911508b9fb61f54a56269841299f663Tobin Ehlis image_state->valid = false; 9622e46491ee6f16b9d29e68914fc6522aba2fde0ad4Tobin Ehlis image_state->binding.mem = MEMTRACKER_SWAP_CHAIN_IMAGE_KEY; 9623991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski swapchain_state->images[i] = pSwapchainImages[i]; 96245b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis ImageSubresourcePair subpair = {pSwapchainImages[i], false, VkImageSubresource()}; 9625991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski device_data->imageSubresourceMap[pSwapchainImages[i]].push_back(subpair); 9626991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski device_data->imageLayoutMap[subpair] = image_layout_node; 96275b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 96285b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 9629991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski 9630991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski if (*pSwapchainImageCount) { 9631991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski if (swapchain_state->vkGetSwapchainImagesKHRState < QUERY_COUNT) { 9632991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski swapchain_state->vkGetSwapchainImagesKHRState = QUERY_COUNT; 9633991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski } 9634991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski swapchain_state->get_swapchain_image_count = *pSwapchainImageCount; 9635991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski } 9636991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski} 9637991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski 9638991f2555bc4f571e30b584937c7959805dff67c6Mark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL GetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t *pSwapchainImageCount, 9639991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski VkImage *pSwapchainImages) { 9640991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 9641991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 9642991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski 9643991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski auto swapchain_state = GetSwapchainNode(device_data, swapchain); 9644991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski bool skip = PreCallValidateGetSwapchainImagesKHR(device_data, swapchain_state, device, pSwapchainImageCount, pSwapchainImages); 9645991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski 9646991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski if (!skip) { 9647991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski result = device_data->dispatch_table.GetSwapchainImagesKHR(device, swapchain, pSwapchainImageCount, pSwapchainImages); 9648991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski } 9649991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski 9650991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski if ((result == VK_SUCCESS || result == VK_INCOMPLETE)) { 9651991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski PostCallRecordGetSwapchainImagesKHR(device_data, swapchain_state, device, pSwapchainImageCount, pSwapchainImages); 9652991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski } 96535b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 96545b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 96555b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 965689d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR VkResult VKAPI_CALL QueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo) { 965756e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(queue), layer_data_map); 96583251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 96595b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 9660ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 96619a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto queue_state = GetQueueState(dev_data, queue); 96621671dfbfc53aa19dcf76d71c2dd1f8f2c4879174Chris Forbes 96636c87c6a8acda49a6406192a1b634e9bf060bd6fdChris Forbes for (uint32_t i = 0; i < pPresentInfo->waitSemaphoreCount; ++i) { 96649a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pSemaphore = GetSemaphoreNode(dev_data, pPresentInfo->pWaitSemaphores[i]); 96656c87c6a8acda49a6406192a1b634e9bf060bd6fdChris Forbes if (pSemaphore && !pSemaphore->signaled) { 96663251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0, 96673251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski __LINE__, DRAWSTATE_QUEUE_FORWARD_PROGRESS, "DS", 96683251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Queue 0x%p is waiting on semaphore 0x%" PRIx64 " that has no way to be signaled.", queue, 96699b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pPresentInfo->pWaitSemaphores[i])); 96705b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 96716c87c6a8acda49a6406192a1b634e9bf060bd6fdChris Forbes } 9672249eb117f85f5e0f3f3a83a2bf297893e0d054ceTobin Ehlis 96736c87c6a8acda49a6406192a1b634e9bf060bd6fdChris Forbes for (uint32_t i = 0; i < pPresentInfo->swapchainCount; ++i) { 96749a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto swapchain_data = GetSwapchainNode(dev_data, pPresentInfo->pSwapchains[i]); 9675a96bccebcf27add1b38bfe46c541e1484d7b4d88Chris Forbes if (swapchain_data) { 9676a96bccebcf27add1b38bfe46c541e1484d7b4d88Chris Forbes if (pPresentInfo->pImageIndices[i] >= swapchain_data->images.size()) { 96779b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip |= 96789b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, 96799b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pPresentInfo->pSwapchains[i]), __LINE__, DRAWSTATE_SWAPCHAIN_INVALID_IMAGE, "DS", 96809b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "vkQueuePresentKHR: Swapchain image index too large (%u). There are only %u images in this swapchain.", 96819b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus pPresentInfo->pImageIndices[i], (uint32_t)swapchain_data->images.size()); 9682bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski } else { 9683a96bccebcf27add1b38bfe46c541e1484d7b4d88Chris Forbes auto image = swapchain_data->images[pPresentInfo->pImageIndices[i]]; 96849a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto image_state = GetImageState(dev_data, image); 968587a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis 968687a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis if (image_state->shared_presentable) { 968787a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis image_state->layout_locked = true; 968887a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis } 9689c4f799ed5502f05ce97543e0500b4a19dc5f2461Mark Lobodzinski 96903251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateImageMemoryIsValid(dev_data, image_state, "vkQueuePresentKHR()"); 9691a96bccebcf27add1b38bfe46c541e1484d7b4d88Chris Forbes 96921facd2c91911508b9fb61f54a56269841299f663Tobin Ehlis if (!image_state->acquired) { 96933251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg( 9694bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, 96959b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pPresentInfo->pSwapchains[i]), __LINE__, DRAWSTATE_SWAPCHAIN_IMAGE_NOT_ACQUIRED, "DS", 9696bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski "vkQueuePresentKHR: Swapchain image index %u has not been acquired.", pPresentInfo->pImageIndices[i]); 9697a96bccebcf27add1b38bfe46c541e1484d7b4d88Chris Forbes } 9698a96bccebcf27add1b38bfe46c541e1484d7b4d88Chris Forbes 9699a96bccebcf27add1b38bfe46c541e1484d7b4d88Chris Forbes vector<VkImageLayout> layouts; 9700a96bccebcf27add1b38bfe46c541e1484d7b4d88Chris Forbes if (FindLayouts(dev_data, image, layouts)) { 9701a96bccebcf27add1b38bfe46c541e1484d7b4d88Chris Forbes for (auto layout : layouts) { 97026084b78a58b438d27591b81efe30997ac9d88d3cMark Lobodzinski if ((layout != VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) && 9703a149f1a0cb39b48b19822c8cf9ef2426cd2251dfMark Lobodzinski (!dev_data->extensions.vk_khr_shared_presentable_image || 97046084b78a58b438d27591b81efe30997ac9d88d3cMark Lobodzinski (layout != VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR))) { 97053251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= 97062fbc1a61dff1781368a0c592c25985abb46e4891Mike Weiblen log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT, 9707315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(queue), __LINE__, VALIDATION_ERROR_11200a20, "DS", 97082fbc1a61dff1781368a0c592c25985abb46e4891Mike Weiblen "Images passed to present must be in layout " 97096084b78a58b438d27591b81efe30997ac9d88d3cMark Lobodzinski "VK_IMAGE_LAYOUT_PRESENT_SRC_KHR or VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR but is in %s. %s", 9710315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis string_VkImageLayout(layout), validation_error_map[VALIDATION_ERROR_11200a20]); 9711a96bccebcf27add1b38bfe46c541e1484d7b4d88Chris Forbes } 97125b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 97135b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 97145b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 97151671dfbfc53aa19dcf76d71c2dd1f8f2c4879174Chris Forbes 97161671dfbfc53aa19dcf76d71c2dd1f8f2c4879174Chris Forbes // All physical devices and queue families are required to be able 97171671dfbfc53aa19dcf76d71c2dd1f8f2c4879174Chris Forbes // to present to any native window on Android; require the 97181671dfbfc53aa19dcf76d71c2dd1f8f2c4879174Chris Forbes // application to have established support on any other platform. 9719d4eaca34eca7f4b4e34190c441a579347bb2016aMark Lobodzinski if (!dev_data->instance_data->extensions.vk_khr_android_surface) { 97209a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto surface_state = GetSurfaceState(dev_data->instance_data, swapchain_data->createInfo.surface); 97211671dfbfc53aa19dcf76d71c2dd1f8f2c4879174Chris Forbes auto support_it = surface_state->gpu_queue_support.find({dev_data->physical_device, queue_state->queueFamilyIndex}); 97221671dfbfc53aa19dcf76d71c2dd1f8f2c4879174Chris Forbes 97231671dfbfc53aa19dcf76d71c2dd1f8f2c4879174Chris Forbes if (support_it == surface_state->gpu_queue_support.end()) { 97243251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= 97251671dfbfc53aa19dcf76d71c2dd1f8f2c4879174Chris Forbes log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, 97269b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pPresentInfo->pSwapchains[i]), __LINE__, DRAWSTATE_SWAPCHAIN_UNSUPPORTED_QUEUE, "DS", 9727cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "vkQueuePresentKHR: Presenting image without calling " 9728cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "vkGetPhysicalDeviceSurfaceSupportKHR"); 97291671dfbfc53aa19dcf76d71c2dd1f8f2c4879174Chris Forbes } else if (!support_it->second) { 97309b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip |= 97319b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, 9732315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pPresentInfo->pSwapchains[i]), __LINE__, VALIDATION_ERROR_31800a18, "DS", 97339b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "vkQueuePresentKHR: Presenting image on queue that cannot " 97349b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "present to this surface. %s", 9735315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_31800a18]); 97361671dfbfc53aa19dcf76d71c2dd1f8f2c4879174Chris Forbes } 97371671dfbfc53aa19dcf76d71c2dd1f8f2c4879174Chris Forbes } 97385b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 97395b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 9740c78bb8f84551ddfb3802d18c678500e26e4116cbTobin Ehlis if (pPresentInfo && pPresentInfo->pNext) { 9741c78bb8f84551ddfb3802d18c678500e26e4116cbTobin Ehlis // Verify ext struct 9742b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf const auto *present_regions = lvl_find_in_chain<VkPresentRegionsKHR>(pPresentInfo->pNext); 9743b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf if (present_regions) { 9744b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf for (uint32_t i = 0; i < present_regions->swapchainCount; ++i) { 9745b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf auto swapchain_data = GetSwapchainNode(dev_data, pPresentInfo->pSwapchains[i]); 9746b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf assert(swapchain_data); 9747b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf VkPresentRegionKHR region = present_regions->pRegions[i]; 9748b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf for (uint32_t j = 0; j < region.rectangleCount; ++j) { 9749b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf VkRectLayerKHR rect = region.pRectangles[j]; 9750b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf // TODO: Need to update these errors to their unique error ids when available 9751b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf if ((rect.offset.x + rect.extent.width) > swapchain_data->createInfo.imageExtent.width) { 9752b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 9753b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, HandleToUint64(pPresentInfo->pSwapchains[i]), 9754b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf __LINE__, DRAWSTATE_SWAPCHAIN_INVALID_IMAGE, "DS", 9755b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf "vkQueuePresentKHR(): For VkPresentRegionKHR down pNext " 9756b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf "chain, pRegion[%i].pRectangles[%i], the sum of offset.x " 9757b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf "(%i) and extent.width (%i) is greater than the " 9758b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf "corresponding swapchain's imageExtent.width (%i).", 9759b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf i, j, rect.offset.x, rect.extent.width, swapchain_data->createInfo.imageExtent.width); 9760b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf } 9761b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf if ((rect.offset.y + rect.extent.height) > swapchain_data->createInfo.imageExtent.height) { 9762b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 9763b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, HandleToUint64(pPresentInfo->pSwapchains[i]), 9764b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf __LINE__, DRAWSTATE_SWAPCHAIN_INVALID_IMAGE, "DS", 9765b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf "vkQueuePresentKHR(): For VkPresentRegionKHR down pNext " 9766b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf "chain, pRegion[%i].pRectangles[%i], the sum of offset.y " 9767b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf "(%i) and extent.height (%i) is greater than the " 9768b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf "corresponding swapchain's imageExtent.height (%i).", 9769b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf i, j, rect.offset.y, rect.extent.height, swapchain_data->createInfo.imageExtent.height); 9770b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf } 9771b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf if (rect.layer > swapchain_data->createInfo.imageArrayLayers) { 9772b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf skip |= log_msg( 9773b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, 9774b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf HandleToUint64(pPresentInfo->pSwapchains[i]), __LINE__, DRAWSTATE_SWAPCHAIN_INVALID_IMAGE, "DS", 9775b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf "vkQueuePresentKHR(): For VkPresentRegionKHR down pNext chain, pRegion[%i].pRectangles[%i], the " 9776b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf "layer (%i) is greater than the corresponding swapchain's imageArrayLayers (%i).", 9777b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf i, j, rect.layer, swapchain_data->createInfo.imageArrayLayers); 9778c78bb8f84551ddfb3802d18c678500e26e4116cbTobin Ehlis } 9779c78bb8f84551ddfb3802d18c678500e26e4116cbTobin Ehlis } 9780b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf } 9781b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf } 9782b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf 9783b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf const auto *present_times_info = lvl_find_in_chain<VkPresentTimesInfoGOOGLE>(pPresentInfo->pNext); 9784b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf if (present_times_info) { 9785b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf if (pPresentInfo->swapchainCount != present_times_info->swapchainCount) { 9786b65d7c4e9112072097dde6022999cb6240fc033bJohn Zulauf skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, 97879b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pPresentInfo->pSwapchains[0]), __LINE__, 97885f5e4095d630df9003597a928c86502e3fc83176Tobin Ehlis 9789315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_118009be, "DS", 97905f5e4095d630df9003597a928c86502e3fc83176Tobin Ehlis "vkQueuePresentKHR(): VkPresentTimesInfoGOOGLE.swapchainCount is %i but " 97915f5e4095d630df9003597a928c86502e3fc83176Tobin Ehlis "pPresentInfo->swapchainCount is %i. For VkPresentTimesInfoGOOGLE down pNext " 97925f5e4095d630df9003597a928c86502e3fc83176Tobin Ehlis "chain of VkPresentInfoKHR, VkPresentTimesInfoGOOGLE.swapchainCount " 97935f5e4095d630df9003597a928c86502e3fc83176Tobin Ehlis "must equal VkPresentInfoKHR.swapchainCount.", 97945f5e4095d630df9003597a928c86502e3fc83176Tobin Ehlis present_times_info->swapchainCount, pPresentInfo->swapchainCount); 9795c78bb8f84551ddfb3802d18c678500e26e4116cbTobin Ehlis } 9796c78bb8f84551ddfb3802d18c678500e26e4116cbTobin Ehlis } 9797c78bb8f84551ddfb3802d18c678500e26e4116cbTobin Ehlis } 97985b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 97993251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (skip) { 98006c87c6a8acda49a6406192a1b634e9bf060bd6fdChris Forbes return VK_ERROR_VALIDATION_FAILED_EXT; 98016c87c6a8acda49a6406192a1b634e9bf060bd6fdChris Forbes } 98026c87c6a8acda49a6406192a1b634e9bf060bd6fdChris Forbes 98034a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.QueuePresentKHR(queue, pPresentInfo); 98046c87c6a8acda49a6406192a1b634e9bf060bd6fdChris Forbes 98056c87c6a8acda49a6406192a1b634e9bf060bd6fdChris Forbes if (result != VK_ERROR_VALIDATION_FAILED_EXT) { 98066c87c6a8acda49a6406192a1b634e9bf060bd6fdChris Forbes // Semaphore waits occur before error generation, if the call reached 98076c87c6a8acda49a6406192a1b634e9bf060bd6fdChris Forbes // the ICD. (Confirm?) 98086c87c6a8acda49a6406192a1b634e9bf060bd6fdChris Forbes for (uint32_t i = 0; i < pPresentInfo->waitSemaphoreCount; ++i) { 98099a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pSemaphore = GetSemaphoreNode(dev_data, pPresentInfo->pWaitSemaphores[i]); 98109867daedbf52debc77d6568162ee21e071699b80Chris Forbes if (pSemaphore) { 98119867daedbf52debc77d6568162ee21e071699b80Chris Forbes pSemaphore->signaler.first = VK_NULL_HANDLE; 98126c87c6a8acda49a6406192a1b634e9bf060bd6fdChris Forbes pSemaphore->signaled = false; 98136c87c6a8acda49a6406192a1b634e9bf060bd6fdChris Forbes } 98146c87c6a8acda49a6406192a1b634e9bf060bd6fdChris Forbes } 98159867daedbf52debc77d6568162ee21e071699b80Chris Forbes 9816220a9249bd81543e570b3f38c79d9b1e82e0d0dbChris Forbes for (uint32_t i = 0; i < pPresentInfo->swapchainCount; ++i) { 9817220a9249bd81543e570b3f38c79d9b1e82e0d0dbChris Forbes // Note: this is imperfect, in that we can get confused about what 9818220a9249bd81543e570b3f38c79d9b1e82e0d0dbChris Forbes // did or didn't succeed-- but if the app does that, it's confused 9819220a9249bd81543e570b3f38c79d9b1e82e0d0dbChris Forbes // itself just as much. 9820220a9249bd81543e570b3f38c79d9b1e82e0d0dbChris Forbes auto local_result = pPresentInfo->pResults ? pPresentInfo->pResults[i] : result; 9821220a9249bd81543e570b3f38c79d9b1e82e0d0dbChris Forbes 9822cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (local_result != VK_SUCCESS && local_result != VK_SUBOPTIMAL_KHR) continue; // this present didn't actually happen. 9823220a9249bd81543e570b3f38c79d9b1e82e0d0dbChris Forbes 9824220a9249bd81543e570b3f38c79d9b1e82e0d0dbChris Forbes // Mark the image as having been released to the WSI 98259a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto swapchain_data = GetSwapchainNode(dev_data, pPresentInfo->pSwapchains[i]); 9826220a9249bd81543e570b3f38c79d9b1e82e0d0dbChris Forbes auto image = swapchain_data->images[pPresentInfo->pImageIndices[i]]; 98279a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto image_state = GetImageState(dev_data, image); 98281facd2c91911508b9fb61f54a56269841299f663Tobin Ehlis image_state->acquired = false; 9829220a9249bd81543e570b3f38c79d9b1e82e0d0dbChris Forbes } 9830220a9249bd81543e570b3f38c79d9b1e82e0d0dbChris Forbes 98319867daedbf52debc77d6568162ee21e071699b80Chris Forbes // Note: even though presentation is directed to a queue, there is no 98329867daedbf52debc77d6568162ee21e071699b80Chris Forbes // direct ordering between QP and subsequent work, so QP (and its 98339867daedbf52debc77d6568162ee21e071699b80Chris Forbes // semaphore waits) /never/ participate in any completion proof. 98346c87c6a8acda49a6406192a1b634e9bf060bd6fdChris Forbes } 98351344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis 98365b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 98375b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 98385b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 9839c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinskistatic bool PreCallValidateCreateSharedSwapchainsKHR(layer_data *dev_data, uint32_t swapchainCount, 9840c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski const VkSwapchainCreateInfoKHR *pCreateInfos, VkSwapchainKHR *pSwapchains, 9841c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski std::vector<SURFACE_STATE *> &surface_state, 9842c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski std::vector<SWAPCHAIN_NODE *> &old_swapchain_state) { 98430342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski if (pCreateInfos) { 9844ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 98450342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski for (uint32_t i = 0; i < swapchainCount; i++) { 98469a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis surface_state.push_back(GetSurfaceState(dev_data->instance_data, pCreateInfos[i].surface)); 98479a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis old_swapchain_state.push_back(GetSwapchainNode(dev_data, pCreateInfos[i].oldSwapchain)); 98489ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski std::stringstream func_name; 98499ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski func_name << "vkCreateSharedSwapchainsKHR[" << swapchainCount << "]"; 9850bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski if (PreCallValidateCreateSwapchainKHR(dev_data, func_name.str().c_str(), &pCreateInfos[i], surface_state[i], 9851bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski old_swapchain_state[i])) { 9852c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski return true; 98530342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski } 98540342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski } 98550342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski } 9856c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski return false; 9857c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski} 98580342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski 9859c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinskistatic void PostCallRecordCreateSharedSwapchainsKHR(layer_data *dev_data, VkResult result, uint32_t swapchainCount, 9860c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski const VkSwapchainCreateInfoKHR *pCreateInfos, VkSwapchainKHR *pSwapchains, 9861c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski std::vector<SURFACE_STATE *> &surface_state, 9862c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski std::vector<SWAPCHAIN_NODE *> &old_swapchain_state) { 98630342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski if (VK_SUCCESS == result) { 98640342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski for (uint32_t i = 0; i < swapchainCount; i++) { 98650342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski auto swapchain_state = unique_ptr<SWAPCHAIN_NODE>(new SWAPCHAIN_NODE(&pCreateInfos[i], pSwapchains[i])); 986687a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis if (VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR == pCreateInfos[i].presentMode || 986787a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR == pCreateInfos[i].presentMode) { 986887a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis swapchain_state->shared_presentable = true; 986987a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis } 98700342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski surface_state[i]->swapchain = swapchain_state.get(); 987116a1f8f9c4af479b1873e82ff02360817fb658acChris Forbes dev_data->swapchainMap[pSwapchains[i]] = std::move(swapchain_state); 98720342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski } 98730342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski } else { 98740342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski for (uint32_t i = 0; i < swapchainCount; i++) { 98750342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski surface_state[i]->swapchain = nullptr; 98760342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski } 98770342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski } 98780342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski // Spec requires that even if CreateSharedSwapchainKHR fails, oldSwapchain behaves as replaced. 98790342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski for (uint32_t i = 0; i < swapchainCount; i++) { 98800342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski if (old_swapchain_state[i]) { 98810342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski old_swapchain_state[i]->replaced = true; 98820342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski } 98830342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski surface_state[i]->old_swapchain = old_swapchain_state[i]; 98840342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski } 9885c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski return; 9886c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski} 9887c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski 9888c6cd632d064579a64e61d8704b411d0e4ace7adaMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL CreateSharedSwapchainsKHR(VkDevice device, uint32_t swapchainCount, 9889c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski const VkSwapchainCreateInfoKHR *pCreateInfos, 9890c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchains) { 989156e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 9892c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski std::vector<SURFACE_STATE *> surface_state; 9893c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski std::vector<SWAPCHAIN_NODE *> old_swapchain_state; 9894c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski 9895c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski if (PreCallValidateCreateSharedSwapchainsKHR(dev_data, swapchainCount, pCreateInfos, pSwapchains, surface_state, 9896c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski old_swapchain_state)) { 9897c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski return VK_ERROR_VALIDATION_FAILED_EXT; 9898c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski } 9899c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski 9900c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski VkResult result = 9901c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski dev_data->dispatch_table.CreateSharedSwapchainsKHR(device, swapchainCount, pCreateInfos, pAllocator, pSwapchains); 9902c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski 9903c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski PostCallRecordCreateSharedSwapchainsKHR(dev_data, result, swapchainCount, pCreateInfos, pSwapchains, surface_state, 9904c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski old_swapchain_state); 99050342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski 9906c827a5880dc3fabfc7d1a58bb62798649cab1181Mark Young return result; 9907c827a5880dc3fabfc7d1a58bb62798649cab1181Mark Young} 9908c827a5880dc3fabfc7d1a58bb62798649cab1181Mark Young 9909ca0956fd78425c5ce5f29a017d10807e6a24d331Mike Schuchardtstatic bool PreCallValidateAcquireNextImageKHR(layer_data *dev_data, VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, 9910ca0956fd78425c5ce5f29a017d10807e6a24d331Mike Schuchardt VkSemaphore semaphore, VkFence fence, uint32_t *pImageIndex) { 99113251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 9912449670637ef4214b33018f497cf10daeff9dc85bChris Forbes if (fence == VK_NULL_HANDLE && semaphore == VK_NULL_HANDLE) { 99133251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 99149b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(device), __LINE__, DRAWSTATE_SWAPCHAIN_NO_SYNC_FOR_ACQUIRE, "DS", 99153251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkAcquireNextImageKHR: Semaphore and fence cannot both be VK_NULL_HANDLE. There would be no way " 99163251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "to determine the completion of this operation."); 9917449670637ef4214b33018f497cf10daeff9dc85bChris Forbes } 9918449670637ef4214b33018f497cf10daeff9dc85bChris Forbes 99199a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pSemaphore = GetSemaphoreNode(dev_data, semaphore); 992006d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt if (pSemaphore && pSemaphore->scope == kSyncScopeInternal && pSemaphore->signaled) { 99213251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT, 9922315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(semaphore), __LINE__, VALIDATION_ERROR_16400a0c, "DS", 99233251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkAcquireNextImageKHR: Semaphore must not be currently signaled or in a wait state. %s", 9924315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_16400a0c]); 99255b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 9926f91af4dfe0646cf509616910a8ec2d72c423ccdaChris Forbes 99279a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pFence = GetFenceNode(dev_data, fence); 9928f91af4dfe0646cf509616910a8ec2d72c423ccdaChris Forbes if (pFence) { 99293251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateFenceForSubmit(dev_data, pFence); 99305b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 99314a5614452104c88cb04390dac882dd94ebdcc3deChris Forbes 99329a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto swapchain_data = GetSwapchainNode(dev_data, swapchain); 9933fc9f0448c3cb6ba4fc018fefe761bb43a1884846Chris Forbes if (swapchain_data->replaced) { 99343251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, 99359b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(swapchain), __LINE__, DRAWSTATE_SWAPCHAIN_REPLACED, "DS", 99363251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkAcquireNextImageKHR: This swapchain has been replaced. The application can still " 99373251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "present any images it has acquired, but cannot acquire any more."); 9938fc9f0448c3cb6ba4fc018fefe761bb43a1884846Chris Forbes } 9939fc9f0448c3cb6ba4fc018fefe761bb43a1884846Chris Forbes 99409a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto physical_device_state = GetPhysicalDeviceState(dev_data->instance_data, dev_data->physical_device); 99414a5614452104c88cb04390dac882dd94ebdcc3deChris Forbes if (physical_device_state->vkGetPhysicalDeviceSurfaceCapabilitiesKHRState != UNCALLED) { 99426569ab421f45f905e69fa7345bda4fe5b87e9045Mark Lobodzinski uint64_t acquired_images = std::count_if(swapchain_data->images.begin(), swapchain_data->images.end(), 99439a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis [=](VkImage image) { return GetImageState(dev_data, image)->acquired; }); 99444a5614452104c88cb04390dac882dd94ebdcc3deChris Forbes if (acquired_images > swapchain_data->images.size() - physical_device_state->surfaceCapabilities.minImageCount) { 99453251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= 99466569ab421f45f905e69fa7345bda4fe5b87e9045Mark Lobodzinski log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, 99479b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(swapchain), __LINE__, DRAWSTATE_SWAPCHAIN_TOO_MANY_IMAGES, "DS", 99486569ab421f45f905e69fa7345bda4fe5b87e9045Mark Lobodzinski "vkAcquireNextImageKHR: Application has already acquired the maximum number of images (0x%" PRIxLEAST64 ")", 99496569ab421f45f905e69fa7345bda4fe5b87e9045Mark Lobodzinski acquired_images); 99504a5614452104c88cb04390dac882dd94ebdcc3deChris Forbes } 99514a5614452104c88cb04390dac882dd94ebdcc3deChris Forbes } 995275269fc9e5cc9696ddf3dd28ff201c9b2526dc7aThomas Louis 995375269fc9e5cc9696ddf3dd28ff201c9b2526dc7aThomas Louis if (swapchain_data->images.size() == 0) { 99543251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, 99559b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(swapchain), __LINE__, DRAWSTATE_SWAPCHAIN_IMAGES_NOT_FOUND, "DS", 99563251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkAcquireNextImageKHR: No images found to acquire from. Application probably did not call " 99573251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkGetSwapchainImagesKHR after swapchain creation."); 995875269fc9e5cc9696ddf3dd28ff201c9b2526dc7aThomas Louis } 9959ca0956fd78425c5ce5f29a017d10807e6a24d331Mike Schuchardt return skip; 9960ca0956fd78425c5ce5f29a017d10807e6a24d331Mike Schuchardt} 9961ca0956fd78425c5ce5f29a017d10807e6a24d331Mike Schuchardt 9962ca0956fd78425c5ce5f29a017d10807e6a24d331Mike Schuchardtstatic void PostCallRecordAcquireNextImageKHR(layer_data *dev_data, VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, 9963ca0956fd78425c5ce5f29a017d10807e6a24d331Mike Schuchardt VkSemaphore semaphore, VkFence fence, uint32_t *pImageIndex) { 9964ca0956fd78425c5ce5f29a017d10807e6a24d331Mike Schuchardt auto pFence = GetFenceNode(dev_data, fence); 9965980fe4b66c791e16eadda9b51f833eb626c5572fMike Schuchardt if (pFence && pFence->scope == kSyncScopeInternal) { 9966980fe4b66c791e16eadda9b51f833eb626c5572fMike Schuchardt // Treat as inflight since it is valid to wait on this fence, even in cases where it is technically a temporary 9967980fe4b66c791e16eadda9b51f833eb626c5572fMike Schuchardt // import 9968980fe4b66c791e16eadda9b51f833eb626c5572fMike Schuchardt pFence->state = FENCE_INFLIGHT; 9969980fe4b66c791e16eadda9b51f833eb626c5572fMike Schuchardt pFence->signaler.first = VK_NULL_HANDLE; // ANI isn't on a queue, so this can't participate in a completion proof. 9970ca0956fd78425c5ce5f29a017d10807e6a24d331Mike Schuchardt } 9971ca0956fd78425c5ce5f29a017d10807e6a24d331Mike Schuchardt 9972ca0956fd78425c5ce5f29a017d10807e6a24d331Mike Schuchardt auto pSemaphore = GetSemaphoreNode(dev_data, semaphore); 9973980fe4b66c791e16eadda9b51f833eb626c5572fMike Schuchardt if (pSemaphore && pSemaphore->scope == kSyncScopeInternal) { 9974980fe4b66c791e16eadda9b51f833eb626c5572fMike Schuchardt // Treat as signaled since it is valid to wait on this semaphore, even in cases where it is technically a 9975980fe4b66c791e16eadda9b51f833eb626c5572fMike Schuchardt // temporary import 9976980fe4b66c791e16eadda9b51f833eb626c5572fMike Schuchardt pSemaphore->signaled = true; 9977980fe4b66c791e16eadda9b51f833eb626c5572fMike Schuchardt pSemaphore->signaler.first = VK_NULL_HANDLE; 9978ca0956fd78425c5ce5f29a017d10807e6a24d331Mike Schuchardt } 9979ca0956fd78425c5ce5f29a017d10807e6a24d331Mike Schuchardt 9980ca0956fd78425c5ce5f29a017d10807e6a24d331Mike Schuchardt // Mark the image as acquired. 9981ca0956fd78425c5ce5f29a017d10807e6a24d331Mike Schuchardt auto swapchain_data = GetSwapchainNode(dev_data, swapchain); 9982ca0956fd78425c5ce5f29a017d10807e6a24d331Mike Schuchardt auto image = swapchain_data->images[*pImageIndex]; 9983ca0956fd78425c5ce5f29a017d10807e6a24d331Mike Schuchardt auto image_state = GetImageState(dev_data, image); 9984ca0956fd78425c5ce5f29a017d10807e6a24d331Mike Schuchardt image_state->acquired = true; 9985ca0956fd78425c5ce5f29a017d10807e6a24d331Mike Schuchardt image_state->shared_presentable = swapchain_data->shared_presentable; 9986ca0956fd78425c5ce5f29a017d10807e6a24d331Mike Schuchardt} 998775269fc9e5cc9696ddf3dd28ff201c9b2526dc7aThomas Louis 9988ca0956fd78425c5ce5f29a017d10807e6a24d331Mike SchuchardtVKAPI_ATTR VkResult VKAPI_CALL AcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, 9989ca0956fd78425c5ce5f29a017d10807e6a24d331Mike Schuchardt VkSemaphore semaphore, VkFence fence, uint32_t *pImageIndex) { 9990ca0956fd78425c5ce5f29a017d10807e6a24d331Mike Schuchardt layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 9991ca0956fd78425c5ce5f29a017d10807e6a24d331Mike Schuchardt 9992ca0956fd78425c5ce5f29a017d10807e6a24d331Mike Schuchardt unique_lock_t lock(global_lock); 9993ca0956fd78425c5ce5f29a017d10807e6a24d331Mike Schuchardt bool skip = PreCallValidateAcquireNextImageKHR(dev_data, device, swapchain, timeout, semaphore, fence, pImageIndex); 9994b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 99951344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis 99963251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 9997f91af4dfe0646cf509616910a8ec2d72c423ccdaChris Forbes 99984a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.AcquireNextImageKHR(device, swapchain, timeout, semaphore, fence, pImageIndex); 9999f91af4dfe0646cf509616910a8ec2d72c423ccdaChris Forbes 10000f91af4dfe0646cf509616910a8ec2d72c423ccdaChris Forbes lock.lock(); 10001f91af4dfe0646cf509616910a8ec2d72c423ccdaChris Forbes if (result == VK_SUCCESS || result == VK_SUBOPTIMAL_KHR) { 10002ca0956fd78425c5ce5f29a017d10807e6a24d331Mike Schuchardt PostCallRecordAcquireNextImageKHR(dev_data, device, swapchain, timeout, semaphore, fence, pImageIndex); 100035b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 10004f91af4dfe0646cf509616910a8ec2d72c423ccdaChris Forbes lock.unlock(); 100051344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis 100065b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 100075b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 100085b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 10009f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL EnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount, 10010f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski VkPhysicalDevice *pPhysicalDevices) { 100113251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 1001256e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(instance), instance_layer_data_map); 10013bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis assert(instance_data); 10014219f00ffed576643641976122fa1db8e5fce5dc1Chris Forbes 10015bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis // For this instance, flag when vkEnumeratePhysicalDevices goes to QUERY_COUNT and then QUERY_DETAILS 10016bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis if (NULL == pPhysicalDevices) { 10017bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis instance_data->vkEnumeratePhysicalDevicesState = QUERY_COUNT; 10018f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski } else { 10019bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis if (UNCALLED == instance_data->vkEnumeratePhysicalDevicesState) { 10020bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis // Flag warning here. You can call this without having queried the count, but it may not be 10021bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis // robust on platforms with multiple physical devices. 100223251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(instance_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, 100233251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski 0, __LINE__, DEVLIMITS_MISSING_QUERY_COUNT, "DL", 100243251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Call sequence has vkEnumeratePhysicalDevices() w/ non-NULL pPhysicalDevices. You should first " 100253251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "call vkEnumeratePhysicalDevices() w/ NULL pPhysicalDevices to query pPhysicalDeviceCount."); 10026cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } // TODO : Could also flag a warning if re-calling this function in QUERY_DETAILS state 10027bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis else if (instance_data->physical_devices_count != *pPhysicalDeviceCount) { 10028bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis // Having actual count match count from app is not a requirement, so this can be a warning 100293251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(instance_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, 100303251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_COUNT_MISMATCH, "DL", 100313251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Call to vkEnumeratePhysicalDevices() w/ pPhysicalDeviceCount value %u, but actual count " 100323251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "supported by this instance is %u.", 100333251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski *pPhysicalDeviceCount, instance_data->physical_devices_count); 10034bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis } 10035bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis instance_data->vkEnumeratePhysicalDevicesState = QUERY_DETAILS; 10036f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski } 100373251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (skip) { 10038bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis return VK_ERROR_VALIDATION_FAILED_EXT; 10039bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis } 10040bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis VkResult result = instance_data->dispatch_table.EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices); 10041bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis if (NULL == pPhysicalDevices) { 10042bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis instance_data->physical_devices_count = *pPhysicalDeviceCount; 10043cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } else if (result == VK_SUCCESS) { // Save physical devices 10044bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++) { 10045bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis auto &phys_device_state = instance_data->physical_device_map[pPhysicalDevices[i]]; 10046bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis phys_device_state.phys_device = pPhysicalDevices[i]; 10047bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis // Init actual features for each physical device 10048bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis instance_data->dispatch_table.GetPhysicalDeviceFeatures(pPhysicalDevices[i], &phys_device_state.features); 10049bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis } 10050bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis } 10051bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis return result; 10052f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski} 10053f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski 1005443947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis// Common function to handle validation for GetPhysicalDeviceQueueFamilyProperties & 2KHR version 1005543947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlisstatic bool ValidateCommonGetPhysicalDeviceQueueFamilyProperties(instance_layer_data *instance_data, 1005643947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis PHYSICAL_DEVICE_STATE *pd_state, 100575770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus uint32_t requested_queue_family_property_count, bool qfp_null, 100585770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus const char *caller_name) { 1005943947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis bool skip = false; 100605770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus if (!qfp_null) { 100615770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus // Verify that for each physical device, this command is called first with NULL pQueueFamilyProperties in order to get count 1006243947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis if (UNCALLED == pd_state->vkGetPhysicalDeviceQueueFamilyPropertiesState) { 100635770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus skip |= log_msg( 100645770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus instance_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 100659b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pd_state->phys_device), __LINE__, DEVLIMITS_MISSING_QUERY_COUNT, "DL", 100665770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus "%s is called with non-NULL pQueueFamilyProperties before obtaining pQueueFamilyPropertyCount. It is recommended " 100675770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus "to first call %s with NULL pQueueFamilyProperties in order to obtain the maximal pQueueFamilyPropertyCount.", 100685770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus caller_name, caller_name); 100695770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus // Then verify that pCount that is passed in on second call matches what was returned 100705770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus } else if (pd_state->queue_family_count != requested_queue_family_property_count) { 100715770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus skip |= log_msg( 100725770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus instance_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 100739b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pd_state->phys_device), __LINE__, DEVLIMITS_COUNT_MISMATCH, "DL", 100745770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus "%s is called with non-NULL pQueueFamilyProperties and pQueueFamilyPropertyCount value %" PRIu32 100755770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus ", but the largest previously returned pQueueFamilyPropertyCount for this physicalDevice is %" PRIu32 100765770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus ". It is recommended to instead receive all the properties by calling %s with pQueueFamilyPropertyCount that was " 100775770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus "previously obtained by calling %s with NULL pQueueFamilyProperties.", 100785770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus caller_name, requested_queue_family_property_count, pd_state->queue_family_count, caller_name, caller_name); 1007943947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis } 1008043947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis pd_state->vkGetPhysicalDeviceQueueFamilyPropertiesState = QUERY_DETAILS; 1008143947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis } 100825770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 1008343947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis return skip; 1008443947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis} 1008543947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis 1008643947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlisstatic bool PreCallValidateGetPhysicalDeviceQueueFamilyProperties(instance_layer_data *instance_data, 100875770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus PHYSICAL_DEVICE_STATE *pd_state, 100885770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus uint32_t *pQueueFamilyPropertyCount, 1008943947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis VkQueueFamilyProperties *pQueueFamilyProperties) { 100905770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus return ValidateCommonGetPhysicalDeviceQueueFamilyProperties(instance_data, pd_state, *pQueueFamilyPropertyCount, 100915770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus (nullptr == pQueueFamilyProperties), 1009243947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis "vkGetPhysicalDeviceQueueFamilyProperties()"); 1009343947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis} 1009443947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis 1009543947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlisstatic bool PreCallValidateGetPhysicalDeviceQueueFamilyProperties2KHR(instance_layer_data *instance_data, 1009643947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis PHYSICAL_DEVICE_STATE *pd_state, 1009743947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis uint32_t *pQueueFamilyPropertyCount, 1009843947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis VkQueueFamilyProperties2KHR *pQueueFamilyProperties) { 100995770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus return ValidateCommonGetPhysicalDeviceQueueFamilyProperties(instance_data, pd_state, *pQueueFamilyPropertyCount, 101005770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus (nullptr == pQueueFamilyProperties), 1010143947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis "vkGetPhysicalDeviceQueueFamilyProperties2KHR()"); 1010243947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis} 1010343947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis 1010443947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis// Common function to update state for GetPhysicalDeviceQueueFamilyProperties & 2KHR version 1010543947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlisstatic void StateUpdateCommonGetPhysicalDeviceQueueFamilyProperties(PHYSICAL_DEVICE_STATE *pd_state, uint32_t count, 1010643947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis VkQueueFamilyProperties2KHR *pQueueFamilyProperties) { 1010743947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis if (!pQueueFamilyProperties) { 101085770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus if (UNCALLED == pd_state->vkGetPhysicalDeviceQueueFamilyPropertiesState) 101095770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus pd_state->vkGetPhysicalDeviceQueueFamilyPropertiesState = QUERY_COUNT; 101105770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus pd_state->queue_family_count = count; 1011143947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis } else { // Save queue family properties 101125770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus pd_state->vkGetPhysicalDeviceQueueFamilyPropertiesState = QUERY_DETAILS; 101135770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus pd_state->queue_family_count = std::max(pd_state->queue_family_count, count); 101145770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 101155770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus pd_state->queue_family_properties.resize(std::max(static_cast<uint32_t>(pd_state->queue_family_properties.size()), count)); 101165770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus for (uint32_t i = 0; i < count; ++i) { 1011743947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis pd_state->queue_family_properties[i] = pQueueFamilyProperties[i].queueFamilyProperties; 1011843947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis } 1011943947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis } 1012043947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis} 1012143947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis 1012243947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlisstatic void PostCallRecordGetPhysicalDeviceQueueFamilyProperties(PHYSICAL_DEVICE_STATE *pd_state, uint32_t count, 1012343947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis VkQueueFamilyProperties *pQueueFamilyProperties) { 1012443947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis VkQueueFamilyProperties2KHR *pqfp = nullptr; 1012543947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis std::vector<VkQueueFamilyProperties2KHR> qfp; 1012643947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis qfp.resize(count); 1012743947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis if (pQueueFamilyProperties) { 1012843947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis for (uint32_t i = 0; i < count; ++i) { 1012943947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis qfp[i].sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2_KHR; 1013043947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis qfp[i].pNext = nullptr; 1013143947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis qfp[i].queueFamilyProperties = pQueueFamilyProperties[i]; 1013243947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis } 1013343947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis pqfp = qfp.data(); 1013443947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis } 1013543947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis StateUpdateCommonGetPhysicalDeviceQueueFamilyProperties(pd_state, count, pqfp); 1013643947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis} 1013743947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis 1013843947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlisstatic void PostCallRecordGetPhysicalDeviceQueueFamilyProperties2KHR(PHYSICAL_DEVICE_STATE *pd_state, uint32_t count, 1013943947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis VkQueueFamilyProperties2KHR *pQueueFamilyProperties) { 1014043947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis StateUpdateCommonGetPhysicalDeviceQueueFamilyProperties(pd_state, count, pQueueFamilyProperties); 1014143947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis} 1014243947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis 101435770f8ad21c40b2475201e73e9368a899b6886d0Petr KrausVKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice, 101445770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus uint32_t *pQueueFamilyPropertyCount, 10145bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkQueueFamilyProperties *pQueueFamilyProperties) { 1014656e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map); 101479a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto physical_device_state = GetPhysicalDeviceState(instance_data, physicalDevice); 1014843947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis assert(physical_device_state); 10149ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 101505770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 101515770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus bool skip = PreCallValidateGetPhysicalDeviceQueueFamilyProperties(instance_data, physical_device_state, 101525770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus pQueueFamilyPropertyCount, pQueueFamilyProperties); 101535770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 101545770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus lock.unlock(); 101555770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 101565770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus if (skip) return; 101575770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 101585770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus instance_data->dispatch_table.GetPhysicalDeviceQueueFamilyProperties(physicalDevice, pQueueFamilyPropertyCount, 101595770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus pQueueFamilyProperties); 101605770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 101615770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus lock.lock(); 101625770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus PostCallRecordGetPhysicalDeviceQueueFamilyProperties(physical_device_state, *pQueueFamilyPropertyCount, pQueueFamilyProperties); 1016343947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis} 1016443947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis 1016543947a6175e3e942e04d902f4d18928168e2d0dbTobin EhlisVKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceQueueFamilyProperties2KHR(VkPhysicalDevice physicalDevice, 1016643947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis uint32_t *pQueueFamilyPropertyCount, 1016743947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis VkQueueFamilyProperties2KHR *pQueueFamilyProperties) { 1016856e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map); 101699a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto physical_device_state = GetPhysicalDeviceState(instance_data, physicalDevice); 1017043947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis assert(physical_device_state); 10171ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 101725770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 1017343947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis bool skip = PreCallValidateGetPhysicalDeviceQueueFamilyProperties2KHR(instance_data, physical_device_state, 1017443947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis pQueueFamilyPropertyCount, pQueueFamilyProperties); 101755770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 101765770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus lock.unlock(); 101775770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 101785770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus if (skip) return; 101795770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 1018043947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis instance_data->dispatch_table.GetPhysicalDeviceQueueFamilyProperties2KHR(physicalDevice, pQueueFamilyPropertyCount, 1018143947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis pQueueFamilyProperties); 101825770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 101835770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus lock.lock(); 1018443947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis PostCallRecordGetPhysicalDeviceQueueFamilyProperties2KHR(physical_device_state, *pQueueFamilyPropertyCount, 1018543947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis pQueueFamilyProperties); 10186cd569b3559a7f8dca06012165480a4e6d7e6c492Mark Lobodzinski} 10187cd569b3559a7f8dca06012165480a4e6d7e6c492Mark Lobodzinski 10188bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinskitemplate <typename TCreateInfo, typename FPtr> 10189bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinskistatic VkResult CreateSurface(VkInstance instance, TCreateInfo const *pCreateInfo, VkAllocationCallbacks const *pAllocator, 10190bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkSurfaceKHR *pSurface, FPtr fptr) { 1019156e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(instance), instance_layer_data_map); 10192747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes 10193747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes // Call down the call chain: 10194747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes VkResult result = (instance_data->dispatch_table.*fptr)(instance, pCreateInfo, pAllocator, pSurface); 10195747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes 10196747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes if (result == VK_SUCCESS) { 10197ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 10198747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes instance_data->surface_map[*pSurface] = SURFACE_STATE(*pSurface); 10199747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes lock.unlock(); 10200747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes } 10201747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes 10202747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes return result; 10203747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes} 10204747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes 10205747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris ForbesVKAPI_ATTR void VKAPI_CALL DestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks *pAllocator) { 102063251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 1020756e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(instance), instance_layer_data_map); 10208ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 102099a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto surface_state = GetSurfaceState(instance_data, surface); 10210747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes 10211991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski if ((surface_state) && (surface_state->swapchain)) { 10212991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski skip |= log_msg(instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, 10213991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski HandleToUint64(instance), __LINE__, VALIDATION_ERROR_26c009e4, "DS", 10214991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski "vkDestroySurfaceKHR() called before its associated VkSwapchainKHR was destroyed. %s", 10215991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski validation_error_map[VALIDATION_ERROR_26c009e4]); 10216747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes } 10217991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski instance_data->surface_map.erase(surface); 10218747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes lock.unlock(); 102193251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip) { 10220747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes instance_data->dispatch_table.DestroySurfaceKHR(instance, surface, pAllocator); 10221747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes } 10222747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes} 10223747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes 102246f2ed666809272002a31b3b4f8adf6581cb41819Norbert NopperVKAPI_ATTR VkResult VKAPI_CALL CreateDisplayPlaneSurfaceKHR(VkInstance instance, const VkDisplaySurfaceCreateInfoKHR *pCreateInfo, 102256f2ed666809272002a31b3b4f8adf6581cb41819Norbert Nopper const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { 102266f2ed666809272002a31b3b4f8adf6581cb41819Norbert Nopper return CreateSurface(instance, pCreateInfo, pAllocator, pSurface, &VkLayerInstanceDispatchTable::CreateDisplayPlaneSurfaceKHR); 102276f2ed666809272002a31b3b4f8adf6581cb41819Norbert Nopper} 102286f2ed666809272002a31b3b4f8adf6581cb41819Norbert Nopper 10229747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes#ifdef VK_USE_PLATFORM_ANDROID_KHR 10230747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris ForbesVKAPI_ATTR VkResult VKAPI_CALL CreateAndroidSurfaceKHR(VkInstance instance, const VkAndroidSurfaceCreateInfoKHR *pCreateInfo, 10231747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { 10232747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes return CreateSurface(instance, pCreateInfo, pAllocator, pSurface, &VkLayerInstanceDispatchTable::CreateAndroidSurfaceKHR); 10233747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes} 10234cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski#endif // VK_USE_PLATFORM_ANDROID_KHR 10235747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes 10236747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes#ifdef VK_USE_PLATFORM_MIR_KHR 10237747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris ForbesVKAPI_ATTR VkResult VKAPI_CALL CreateMirSurfaceKHR(VkInstance instance, const VkMirSurfaceCreateInfoKHR *pCreateInfo, 10238747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { 10239747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes return CreateSurface(instance, pCreateInfo, pAllocator, pSurface, &VkLayerInstanceDispatchTable::CreateMirSurfaceKHR); 10240747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes} 10241f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 10242f25d461667ca2db55147d2be49f179945edf24dbPetr KrausVKAPI_ATTR VkBool32 VKAPI_CALL GetPhysicalDeviceMirPresentationSupportKHR(VkPhysicalDevice physicalDevice, 10243f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus uint32_t queueFamilyIndex, MirConnection *connection) { 10244f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus bool skip = false; 10245f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map); 10246f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 10247ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 10248f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus const auto pd_state = GetPhysicalDeviceState(instance_data, physicalDevice); 10249f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 10250315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidatePhysicalDeviceQueueFamily(instance_data, pd_state, queueFamilyIndex, VALIDATION_ERROR_2d2009e2, 10251f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus "vkGetPhysicalDeviceMirPresentationSupportKHR", "queueFamilyIndex"); 10252f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 10253f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus lock.unlock(); 10254f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 10255f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus if (skip) return VK_FALSE; 10256f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 10257f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus // Call down the call chain: 10258f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus VkBool32 result = 10259f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus instance_data->dispatch_table.GetPhysicalDeviceMirPresentationSupportKHR(physicalDevice, queueFamilyIndex, connection); 10260f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 10261f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus return result; 10262f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus} 10263cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski#endif // VK_USE_PLATFORM_MIR_KHR 10264747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes 10265747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes#ifdef VK_USE_PLATFORM_WAYLAND_KHR 10266747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris ForbesVKAPI_ATTR VkResult VKAPI_CALL CreateWaylandSurfaceKHR(VkInstance instance, const VkWaylandSurfaceCreateInfoKHR *pCreateInfo, 10267747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { 10268a9c6cc532ce0ef61d48d1419a96aae51b0e4c64aTobin Ehlis return CreateSurface(instance, pCreateInfo, pAllocator, pSurface, &VkLayerInstanceDispatchTable::CreateWaylandSurfaceKHR); 10269747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes} 10270f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 10271f25d461667ca2db55147d2be49f179945edf24dbPetr KrausVKAPI_ATTR VkBool32 VKAPI_CALL GetPhysicalDeviceWaylandPresentationSupportKHR(VkPhysicalDevice physicalDevice, 10272f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus uint32_t queueFamilyIndex, 10273f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus struct wl_display *display) { 10274f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus bool skip = false; 10275f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map); 10276f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 10277ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 10278f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus const auto pd_state = GetPhysicalDeviceState(instance_data, physicalDevice); 10279f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 10280315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidatePhysicalDeviceQueueFamily(instance_data, pd_state, queueFamilyIndex, VALIDATION_ERROR_2f000a34, 10281f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus "vkGetPhysicalDeviceWaylandPresentationSupportKHR", "queueFamilyIndex"); 10282f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 10283f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus lock.unlock(); 10284f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 10285f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus if (skip) return VK_FALSE; 10286f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 10287f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus // Call down the call chain: 10288f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus VkBool32 result = 10289f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus instance_data->dispatch_table.GetPhysicalDeviceWaylandPresentationSupportKHR(physicalDevice, queueFamilyIndex, display); 10290f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 10291f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus return result; 10292f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus} 10293cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski#endif // VK_USE_PLATFORM_WAYLAND_KHR 10294747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes 10295747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes#ifdef VK_USE_PLATFORM_WIN32_KHR 10296747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris ForbesVKAPI_ATTR VkResult VKAPI_CALL CreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR *pCreateInfo, 10297747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { 10298747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes return CreateSurface(instance, pCreateInfo, pAllocator, pSurface, &VkLayerInstanceDispatchTable::CreateWin32SurfaceKHR); 10299747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes} 10300f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 10301f25d461667ca2db55147d2be49f179945edf24dbPetr KrausVKAPI_ATTR VkBool32 VKAPI_CALL GetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice physicalDevice, 10302f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus uint32_t queueFamilyIndex) { 10303f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus bool skip = false; 10304f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map); 10305f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 10306ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 10307f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus const auto pd_state = GetPhysicalDeviceState(instance_data, physicalDevice); 10308f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 10309315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidatePhysicalDeviceQueueFamily(instance_data, pd_state, queueFamilyIndex, VALIDATION_ERROR_2f200a3a, 10310f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus "vkGetPhysicalDeviceWin32PresentationSupportKHR", "queueFamilyIndex"); 10311f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 10312f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus lock.unlock(); 10313f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 10314f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus if (skip) return VK_FALSE; 10315f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 10316f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus // Call down the call chain: 10317f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus VkBool32 result = instance_data->dispatch_table.GetPhysicalDeviceWin32PresentationSupportKHR(physicalDevice, queueFamilyIndex); 10318f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 10319f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus return result; 10320f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus} 10321cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski#endif // VK_USE_PLATFORM_WIN32_KHR 10322747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes 10323747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes#ifdef VK_USE_PLATFORM_XCB_KHR 10324747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris ForbesVKAPI_ATTR VkResult VKAPI_CALL CreateXcbSurfaceKHR(VkInstance instance, const VkXcbSurfaceCreateInfoKHR *pCreateInfo, 10325747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { 10326747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes return CreateSurface(instance, pCreateInfo, pAllocator, pSurface, &VkLayerInstanceDispatchTable::CreateXcbSurfaceKHR); 10327747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes} 10328f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 10329f25d461667ca2db55147d2be49f179945edf24dbPetr KrausVKAPI_ATTR VkBool32 VKAPI_CALL GetPhysicalDeviceXcbPresentationSupportKHR(VkPhysicalDevice physicalDevice, 10330f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus uint32_t queueFamilyIndex, xcb_connection_t *connection, 10331f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus xcb_visualid_t visual_id) { 10332f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus bool skip = false; 10333f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map); 10334f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 10335ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 10336f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus const auto pd_state = GetPhysicalDeviceState(instance_data, physicalDevice); 10337f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 10338315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidatePhysicalDeviceQueueFamily(instance_data, pd_state, queueFamilyIndex, VALIDATION_ERROR_2f400a40, 10339f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus "vkGetPhysicalDeviceXcbPresentationSupportKHR", "queueFamilyIndex"); 10340f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 10341f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus lock.unlock(); 10342f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 10343f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus if (skip) return VK_FALSE; 10344f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 10345f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus // Call down the call chain: 10346f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus VkBool32 result = instance_data->dispatch_table.GetPhysicalDeviceXcbPresentationSupportKHR(physicalDevice, queueFamilyIndex, 10347f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus connection, visual_id); 10348f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 10349f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus return result; 10350f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus} 10351cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski#endif // VK_USE_PLATFORM_XCB_KHR 10352747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes 10353747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes#ifdef VK_USE_PLATFORM_XLIB_KHR 10354747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris ForbesVKAPI_ATTR VkResult VKAPI_CALL CreateXlibSurfaceKHR(VkInstance instance, const VkXlibSurfaceCreateInfoKHR *pCreateInfo, 10355bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { 10356747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes return CreateSurface(instance, pCreateInfo, pAllocator, pSurface, &VkLayerInstanceDispatchTable::CreateXlibSurfaceKHR); 10357747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes} 10358f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 10359f25d461667ca2db55147d2be49f179945edf24dbPetr KrausVKAPI_ATTR VkBool32 VKAPI_CALL GetPhysicalDeviceXlibPresentationSupportKHR(VkPhysicalDevice physicalDevice, 10360f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus uint32_t queueFamilyIndex, Display *dpy, 10361f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus VisualID visualID) { 10362f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus bool skip = false; 10363f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map); 10364f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 10365ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 10366f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus const auto pd_state = GetPhysicalDeviceState(instance_data, physicalDevice); 10367f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 10368315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidatePhysicalDeviceQueueFamily(instance_data, pd_state, queueFamilyIndex, VALIDATION_ERROR_2f600a46, 10369f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus "vkGetPhysicalDeviceXlibPresentationSupportKHR", "queueFamilyIndex"); 10370f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 10371f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus lock.unlock(); 10372f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 10373f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus if (skip) return VK_FALSE; 10374f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 10375f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus // Call down the call chain: 10376f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus VkBool32 result = 10377f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus instance_data->dispatch_table.GetPhysicalDeviceXlibPresentationSupportKHR(physicalDevice, queueFamilyIndex, dpy, visualID); 10378f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 10379f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus return result; 10380f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus} 10381cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski#endif // VK_USE_PLATFORM_XLIB_KHR 10382747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes 1038340921785005eb449ec7c18229f0d84c879708b8aChris ForbesVKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, 1038440921785005eb449ec7c18229f0d84c879708b8aChris Forbes VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) { 1038556e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis auto instance_data = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map); 1038640921785005eb449ec7c18229f0d84c879708b8aChris Forbes 10387ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 103889a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto physical_device_state = GetPhysicalDeviceState(instance_data, physicalDevice); 1038940921785005eb449ec7c18229f0d84c879708b8aChris Forbes lock.unlock(); 1039040921785005eb449ec7c18229f0d84c879708b8aChris Forbes 10391bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski auto result = 10392bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski instance_data->dispatch_table.GetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, pSurfaceCapabilities); 1039340921785005eb449ec7c18229f0d84c879708b8aChris Forbes 1039440921785005eb449ec7c18229f0d84c879708b8aChris Forbes if (result == VK_SUCCESS) { 1039540921785005eb449ec7c18229f0d84c879708b8aChris Forbes physical_device_state->vkGetPhysicalDeviceSurfaceCapabilitiesKHRState = QUERY_DETAILS; 1039640921785005eb449ec7c18229f0d84c879708b8aChris Forbes physical_device_state->surfaceCapabilities = *pSurfaceCapabilities; 1039740921785005eb449ec7c18229f0d84c879708b8aChris Forbes } 1039840921785005eb449ec7c18229f0d84c879708b8aChris Forbes 1039940921785005eb449ec7c18229f0d84c879708b8aChris Forbes return result; 1040040921785005eb449ec7c18229f0d84c879708b8aChris Forbes} 1040140921785005eb449ec7c18229f0d84c879708b8aChris Forbes 1040235b630211642e709485879a2e8859736f0ab16a0Mike Schuchardtstatic void PostCallRecordGetPhysicalDeviceSurfaceCapabilities2KHR(instance_layer_data *instanceData, 1040335b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt VkPhysicalDevice physicalDevice, 1040435b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt VkSurfaceCapabilities2KHR *pSurfaceCapabilities) { 10405ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 1040635b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt auto physicalDeviceState = GetPhysicalDeviceState(instanceData, physicalDevice); 1040735b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt physicalDeviceState->vkGetPhysicalDeviceSurfaceCapabilitiesKHRState = QUERY_DETAILS; 1040835b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt physicalDeviceState->surfaceCapabilities = pSurfaceCapabilities->surfaceCapabilities; 1040935b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt} 1041035b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt 1041135b630211642e709485879a2e8859736f0ab16a0Mike SchuchardtVKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice, 1041235b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, 1041335b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt VkSurfaceCapabilities2KHR *pSurfaceCapabilities) { 1041435b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt auto instanceData = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map); 1041535b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt 1041635b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt auto result = 1041735b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt instanceData->dispatch_table.GetPhysicalDeviceSurfaceCapabilities2KHR(physicalDevice, pSurfaceInfo, pSurfaceCapabilities); 1041835b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt 1041935b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt if (result == VK_SUCCESS) { 1042035b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt PostCallRecordGetPhysicalDeviceSurfaceCapabilities2KHR(instanceData, physicalDevice, pSurfaceCapabilities); 1042135b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt } 1042235b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt 1042335b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt return result; 1042435b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt} 1042535b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt 1042635b630211642e709485879a2e8859736f0ab16a0Mike Schuchardtstatic void PostCallRecordGetPhysicalDeviceSurfaceCapabilities2EXT(instance_layer_data *instanceData, 1042735b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt VkPhysicalDevice physicalDevice, 1042835b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt VkSurfaceCapabilities2EXT *pSurfaceCapabilities) { 10429ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 1043035b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt auto physicalDeviceState = GetPhysicalDeviceState(instanceData, physicalDevice); 1043135b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt physicalDeviceState->vkGetPhysicalDeviceSurfaceCapabilitiesKHRState = QUERY_DETAILS; 1043235b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt physicalDeviceState->surfaceCapabilities.minImageCount = pSurfaceCapabilities->minImageCount; 1043335b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt physicalDeviceState->surfaceCapabilities.maxImageCount = pSurfaceCapabilities->maxImageCount; 1043435b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt physicalDeviceState->surfaceCapabilities.currentExtent = pSurfaceCapabilities->currentExtent; 1043535b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt physicalDeviceState->surfaceCapabilities.minImageExtent = pSurfaceCapabilities->minImageExtent; 1043635b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt physicalDeviceState->surfaceCapabilities.maxImageExtent = pSurfaceCapabilities->maxImageExtent; 1043735b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt physicalDeviceState->surfaceCapabilities.maxImageArrayLayers = pSurfaceCapabilities->maxImageArrayLayers; 1043835b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt physicalDeviceState->surfaceCapabilities.supportedTransforms = pSurfaceCapabilities->supportedTransforms; 1043935b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt physicalDeviceState->surfaceCapabilities.currentTransform = pSurfaceCapabilities->currentTransform; 1044035b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt physicalDeviceState->surfaceCapabilities.supportedCompositeAlpha = pSurfaceCapabilities->supportedCompositeAlpha; 1044135b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt physicalDeviceState->surfaceCapabilities.supportedUsageFlags = pSurfaceCapabilities->supportedUsageFlags; 1044235b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt} 1044335b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt 1044435b630211642e709485879a2e8859736f0ab16a0Mike SchuchardtVKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceCapabilities2EXT(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, 1044535b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt VkSurfaceCapabilities2EXT *pSurfaceCapabilities) { 1044635b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt auto instanceData = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map); 1044735b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt 1044835b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt auto result = 1044935b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt instanceData->dispatch_table.GetPhysicalDeviceSurfaceCapabilities2EXT(physicalDevice, surface, pSurfaceCapabilities); 1045035b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt 1045135b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt if (result == VK_SUCCESS) { 1045235b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt PostCallRecordGetPhysicalDeviceSurfaceCapabilities2EXT(instanceData, physicalDevice, pSurfaceCapabilities); 1045335b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt } 1045435b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt 1045535b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt return result; 1045635b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt} 1045735b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt 10458418a8711f3301f3027a900bb45daaf0892f4e644Chris ForbesVKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, 10459418a8711f3301f3027a900bb45daaf0892f4e644Chris Forbes VkSurfaceKHR surface, VkBool32 *pSupported) { 10460f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus bool skip = false; 1046156e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis auto instance_data = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map); 10462f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 10463ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 10464f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus const auto pd_state = GetPhysicalDeviceState(instance_data, physicalDevice); 104659a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto surface_state = GetSurfaceState(instance_data, surface); 10466f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 10467315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidatePhysicalDeviceQueueFamily(instance_data, pd_state, queueFamilyIndex, VALIDATION_ERROR_2ee009ea, 10468f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus "vkGetPhysicalDeviceSurfaceSupportKHR", "queueFamilyIndex"); 10469f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 10470418a8711f3301f3027a900bb45daaf0892f4e644Chris Forbes lock.unlock(); 10471418a8711f3301f3027a900bb45daaf0892f4e644Chris Forbes 10472f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 10473f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 10474bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski auto result = 10475bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski instance_data->dispatch_table.GetPhysicalDeviceSurfaceSupportKHR(physicalDevice, queueFamilyIndex, surface, pSupported); 10476418a8711f3301f3027a900bb45daaf0892f4e644Chris Forbes 10477418a8711f3301f3027a900bb45daaf0892f4e644Chris Forbes if (result == VK_SUCCESS) { 104780bbc015828bdb99e85e6731ce92428557902701fPetr Kraus surface_state->gpu_queue_support[{physicalDevice, queueFamilyIndex}] = (*pSupported == VK_TRUE); 10479418a8711f3301f3027a900bb45daaf0892f4e644Chris Forbes } 10480418a8711f3301f3027a900bb45daaf0892f4e644Chris Forbes 10481418a8711f3301f3027a900bb45daaf0892f4e644Chris Forbes return result; 10482418a8711f3301f3027a900bb45daaf0892f4e644Chris Forbes} 10483418a8711f3301f3027a900bb45daaf0892f4e644Chris Forbes 104849e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris ForbesVKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, 104859e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes uint32_t *pPresentModeCount, 104869e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes VkPresentModeKHR *pPresentModes) { 104873251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 1048856e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis auto instance_data = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map); 10489ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 104909e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes // TODO: this isn't quite right. available modes may differ by surface AND physical device. 104919a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto physical_device_state = GetPhysicalDeviceState(instance_data, physicalDevice); 10492bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski auto &call_state = physical_device_state->vkGetPhysicalDeviceSurfacePresentModesKHRState; 104939e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes 104949e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes if (pPresentModes) { 104959e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes // Compare the preliminary value of *pPresentModeCount with the value this time: 10496bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski auto prev_mode_count = (uint32_t)physical_device_state->present_modes.size(); 104979e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes switch (call_state) { 10498cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski case UNCALLED: 104993251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg( 10500bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski instance_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 105019b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(physicalDevice), __LINE__, DEVLIMITS_MUST_QUERY_COUNT, "DL", 10502cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "vkGetPhysicalDeviceSurfacePresentModesKHR() called with non-NULL pPresentModeCount; but no prior positive " 10503cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "value has been seen for pPresentModeCount."); 10504cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 10505cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski default: 10506cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski // both query count and query details 10507cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (*pPresentModeCount != prev_mode_count) { 105083251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(instance_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, 105099b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, HandleToUint64(physicalDevice), __LINE__, 105109b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus DEVLIMITS_COUNT_MISMATCH, "DL", 105113251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkGetPhysicalDeviceSurfacePresentModesKHR() called with *pPresentModeCount (%u) that " 105123251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "differs from the value " 105133251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "(%u) that was returned when pPresentModes was NULL.", 105143251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski *pPresentModeCount, prev_mode_count); 10515cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } 10516cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 105179e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes } 105189e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes } 105199e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes lock.unlock(); 105209e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes 105213251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 105229e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes 10523bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski auto result = instance_data->dispatch_table.GetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, pPresentModeCount, 10524bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski pPresentModes); 105259e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes 105269e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes if (result == VK_SUCCESS || result == VK_INCOMPLETE) { 105279e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes lock.lock(); 105289e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes 105299e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes if (*pPresentModeCount) { 10530cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (call_state < QUERY_COUNT) call_state = QUERY_COUNT; 105319e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes if (*pPresentModeCount > physical_device_state->present_modes.size()) 105329e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes physical_device_state->present_modes.resize(*pPresentModeCount); 105339e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes } 105349e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes if (pPresentModes) { 10535cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (call_state < QUERY_DETAILS) call_state = QUERY_DETAILS; 105369e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes for (uint32_t i = 0; i < *pPresentModeCount; i++) { 105379e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes physical_device_state->present_modes[i] = pPresentModes[i]; 105389e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes } 105399e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes } 105405faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes } 105415faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes 105425faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes return result; 105435faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes} 105445faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes 105455faa662f6859b01c72d79027abde363d5f10dcd7Chris ForbesVKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, 105465faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes uint32_t *pSurfaceFormatCount, 105475faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes VkSurfaceFormatKHR *pSurfaceFormats) { 105483251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 1054956e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis auto instance_data = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map); 10550ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 105519a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto physical_device_state = GetPhysicalDeviceState(instance_data, physicalDevice); 10552bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski auto &call_state = physical_device_state->vkGetPhysicalDeviceSurfaceFormatsKHRState; 105535faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes 105545faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes if (pSurfaceFormats) { 10555bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski auto prev_format_count = (uint32_t)physical_device_state->surface_formats.size(); 105565faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes 105575faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes switch (call_state) { 10558cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski case UNCALLED: 10559cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski // Since we haven't recorded a preliminary value of *pSurfaceFormatCount, that likely means that the application 10560cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski // didn't 10561cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski // previously call this function with a NULL value of pSurfaceFormats: 105623251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg( 10563bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski instance_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 105649b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(physicalDevice), __LINE__, DEVLIMITS_MUST_QUERY_COUNT, "DL", 10565cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "vkGetPhysicalDeviceSurfaceFormatsKHR() called with non-NULL pSurfaceFormatCount; but no prior positive " 10566cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "value has been seen for pSurfaceFormats."); 10567cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 10568cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski default: 10569cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (prev_format_count != *pSurfaceFormatCount) { 105703251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg( 10571cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski instance_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, 105729b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, HandleToUint64(physicalDevice), __LINE__, 10573cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski DEVLIMITS_COUNT_MISMATCH, "DL", 10574cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "vkGetPhysicalDeviceSurfaceFormatsKHR() called with non-NULL pSurfaceFormatCount, and with pSurfaceFormats " 10575cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "set " 10576cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "to " 10577cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "a value (%u) that is greater than the value (%u) that was returned when pSurfaceFormatCount was NULL.", 10578cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski *pSurfaceFormatCount, prev_format_count); 10579cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } 10580cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 105819e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes } 105829e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes } 105835faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes lock.unlock(); 105845faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes 105853251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 105869e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes 105875faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes // Call down the call chain: 105885faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes auto result = instance_data->dispatch_table.GetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, pSurfaceFormatCount, 105895faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes pSurfaceFormats); 105905faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes 105915faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes if (result == VK_SUCCESS || result == VK_INCOMPLETE) { 105925faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes lock.lock(); 105935faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes 105945faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes if (*pSurfaceFormatCount) { 10595cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (call_state < QUERY_COUNT) call_state = QUERY_COUNT; 105965faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes if (*pSurfaceFormatCount > physical_device_state->surface_formats.size()) 105975faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes physical_device_state->surface_formats.resize(*pSurfaceFormatCount); 105985faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes } 105995faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes if (pSurfaceFormats) { 10600cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (call_state < QUERY_DETAILS) call_state = QUERY_DETAILS; 106015faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes for (uint32_t i = 0; i < *pSurfaceFormatCount; i++) { 106025faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes physical_device_state->surface_formats[i] = pSurfaceFormats[i]; 106035faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes } 106045faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes } 106055faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes } 106069e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes return result; 106079e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes} 106089e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes 1060935b630211642e709485879a2e8859736f0ab16a0Mike Schuchardtstatic void PostCallRecordGetPhysicalDeviceSurfaceFormats2KHR(instance_layer_data *instanceData, VkPhysicalDevice physicalDevice, 1061035b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt uint32_t *pSurfaceFormatCount, VkSurfaceFormat2KHR *pSurfaceFormats) { 10611ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 1061235b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt auto physicalDeviceState = GetPhysicalDeviceState(instanceData, physicalDevice); 1061335b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt if (*pSurfaceFormatCount) { 1061435b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt if (physicalDeviceState->vkGetPhysicalDeviceSurfaceFormatsKHRState < QUERY_COUNT) { 1061535b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt physicalDeviceState->vkGetPhysicalDeviceSurfaceFormatsKHRState = QUERY_COUNT; 1061635b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt } 1061735b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt if (*pSurfaceFormatCount > physicalDeviceState->surface_formats.size()) 1061835b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt physicalDeviceState->surface_formats.resize(*pSurfaceFormatCount); 1061935b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt } 1062035b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt if (pSurfaceFormats) { 1062135b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt if (physicalDeviceState->vkGetPhysicalDeviceSurfaceFormatsKHRState < QUERY_DETAILS) { 1062235b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt physicalDeviceState->vkGetPhysicalDeviceSurfaceFormatsKHRState = QUERY_DETAILS; 1062335b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt } 1062435b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt for (uint32_t i = 0; i < *pSurfaceFormatCount; i++) { 1062535b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt physicalDeviceState->surface_formats[i] = pSurfaceFormats[i].surfaceFormat; 1062635b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt } 1062735b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt } 1062835b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt} 1062935b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt 1063035b630211642e709485879a2e8859736f0ab16a0Mike SchuchardtVKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice, 1063135b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, 1063235b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt uint32_t *pSurfaceFormatCount, 1063335b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt VkSurfaceFormat2KHR *pSurfaceFormats) { 1063435b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt auto instanceData = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map); 1063535b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt auto result = instanceData->dispatch_table.GetPhysicalDeviceSurfaceFormats2KHR(physicalDevice, pSurfaceInfo, 1063635b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt pSurfaceFormatCount, pSurfaceFormats); 1063735b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt if (result == VK_SUCCESS || result == VK_INCOMPLETE) { 1063835b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt PostCallRecordGetPhysicalDeviceSurfaceFormats2KHR(instanceData, physicalDevice, pSurfaceFormatCount, pSurfaceFormats); 1063935b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt } 1064035b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt return result; 1064135b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt} 1064235b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt 10643bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL CreateDebugReportCallbackEXT(VkInstance instance, 10644bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkDebugReportCallbackCreateInfoEXT *pCreateInfo, 10645bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkAllocationCallbacks *pAllocator, 10646bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkDebugReportCallbackEXT *pMsgCallback) { 1064756e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(instance), instance_layer_data_map); 106489172b640a0ae6a92f24ad0609d92b2c228cde89cChris Forbes VkResult res = instance_data->dispatch_table.CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pMsgCallback); 106495b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (VK_SUCCESS == res) { 10650ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 106518860b85a52096f9f9b28616bc37feed505497a54Chris Forbes res = layer_create_msg_callback(instance_data->report_data, false, pCreateInfo, pAllocator, pMsgCallback); 106525b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 106535b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return res; 106545b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 106555b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 10656bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL DestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT msgCallback, 1065789d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I Wu const VkAllocationCallbacks *pAllocator) { 1065856e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(instance), instance_layer_data_map); 106599172b640a0ae6a92f24ad0609d92b2c228cde89cChris Forbes instance_data->dispatch_table.DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator); 10660ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 106618860b85a52096f9f9b28616bc37feed505497a54Chris Forbes layer_destroy_msg_callback(instance_data->report_data, msgCallback, pAllocator); 106625b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 106635b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 10664bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL DebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags, 10665bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkDebugReportObjectTypeEXT objType, uint64_t object, size_t location, 10666bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski int32_t msgCode, const char *pLayerPrefix, const char *pMsg) { 1066756e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(instance), instance_layer_data_map); 106689172b640a0ae6a92f24ad0609d92b2c228cde89cChris Forbes instance_data->dispatch_table.DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix, pMsg); 106695b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 106705b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 10671bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties *pProperties) { 10672a4e71cd8b4e77502943dd894ed95426a25dffbd5Chia-I Wu return util_GetLayerProperties(1, &global_layer, pCount, pProperties); 10673a4e71cd8b4e77502943dd894ed95426a25dffbd5Chia-I Wu} 10674a4e71cd8b4e77502943dd894ed95426a25dffbd5Chia-I Wu 10675bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount, 10676bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkLayerProperties *pProperties) { 10677a4e71cd8b4e77502943dd894ed95426a25dffbd5Chia-I Wu return util_GetLayerProperties(1, &global_layer, pCount, pProperties); 10678a4e71cd8b4e77502943dd894ed95426a25dffbd5Chia-I Wu} 10679a4e71cd8b4e77502943dd894ed95426a25dffbd5Chia-I Wu 10680bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount, 10681bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkExtensionProperties *pProperties) { 10682a4e71cd8b4e77502943dd894ed95426a25dffbd5Chia-I Wu if (pLayerName && !strcmp(pLayerName, global_layer.layerName)) 10683a4e71cd8b4e77502943dd894ed95426a25dffbd5Chia-I Wu return util_GetExtensionProperties(1, instance_extensions, pCount, pProperties); 10684a4e71cd8b4e77502943dd894ed95426a25dffbd5Chia-I Wu 10685a4e71cd8b4e77502943dd894ed95426a25dffbd5Chia-I Wu return VK_ERROR_LAYER_NOT_PRESENT; 10686a4e71cd8b4e77502943dd894ed95426a25dffbd5Chia-I Wu} 10687a4e71cd8b4e77502943dd894ed95426a25dffbd5Chia-I Wu 10688bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char *pLayerName, 10689bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski uint32_t *pCount, VkExtensionProperties *pProperties) { 10690fe772548f7a48b12772483e8faecc956fb76eb42Chris Forbes if (pLayerName && !strcmp(pLayerName, global_layer.layerName)) return util_GetExtensionProperties(1, device_extensions, pCount, pProperties); 10691a8f4a23b1e9c068717eda47cc583a93f447c77e3Chia-I Wu 10692a8f4a23b1e9c068717eda47cc583a93f447c77e3Chia-I Wu assert(physicalDevice); 10693a8f4a23b1e9c068717eda47cc583a93f447c77e3Chia-I Wu 1069456e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map); 106959172b640a0ae6a92f24ad0609d92b2c228cde89cChris Forbes return instance_data->dispatch_table.EnumerateDeviceExtensionProperties(physicalDevice, NULL, pCount, pProperties); 1069608939232d080c94fc7b4c5ad348644928beb1519Chia-I Wu} 1069708939232d080c94fc7b4c5ad348644928beb1519Chia-I Wu 10698582b6ed09649188d55ed3b6237352caf9f3384a9Mike WeiblenVKAPI_ATTR VkResult VKAPI_CALL EnumeratePhysicalDeviceGroupsKHX( 10699582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen VkInstance instance, uint32_t *pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupPropertiesKHX *pPhysicalDeviceGroupProperties) { 107003251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 10701582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(instance), instance_layer_data_map); 10702582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen 10703582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen if (instance_data) { 10704582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen // For this instance, flag when EnumeratePhysicalDeviceGroupsKHX goes to QUERY_COUNT and then QUERY_DETAILS. 10705582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen if (NULL == pPhysicalDeviceGroupProperties) { 10706582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen instance_data->vkEnumeratePhysicalDeviceGroupsState = QUERY_COUNT; 10707582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen } else { 10708582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen if (UNCALLED == instance_data->vkEnumeratePhysicalDeviceGroupsState) { 10709582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen // Flag warning here. You can call this without having queried the count, but it may not be 10710582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen // robust on platforms with multiple physical devices. 107113251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(instance_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, 107123251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, 0, __LINE__, DEVLIMITS_MISSING_QUERY_COUNT, "DL", 107133251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Call sequence has vkEnumeratePhysicalDeviceGroupsKHX() w/ non-NULL " 107143251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "pPhysicalDeviceGroupProperties. You should first " 107153251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "call vkEnumeratePhysicalDeviceGroupsKHX() w/ NULL pPhysicalDeviceGroupProperties to query " 107163251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "pPhysicalDeviceGroupCount."); 10717582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen } // TODO : Could also flag a warning if re-calling this function in QUERY_DETAILS state 10718582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen else if (instance_data->physical_device_groups_count != *pPhysicalDeviceGroupCount) { 10719582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen // Having actual count match count from app is not a requirement, so this can be a warning 107203251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= 10721582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen log_msg(instance_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, 107223251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_COUNT_MISMATCH, "DL", 107233251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Call to vkEnumeratePhysicalDeviceGroupsKHX() w/ pPhysicalDeviceGroupCount value %u, but actual count " 107243251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "supported by this instance is %u.", 107253251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski *pPhysicalDeviceGroupCount, instance_data->physical_device_groups_count); 10726582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen } 10727582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen instance_data->vkEnumeratePhysicalDeviceGroupsState = QUERY_DETAILS; 10728582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen } 107293251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (skip) { 10730582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen return VK_ERROR_VALIDATION_FAILED_EXT; 10731582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen } 10732582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen VkResult result = instance_data->dispatch_table.EnumeratePhysicalDeviceGroupsKHX(instance, pPhysicalDeviceGroupCount, 10733582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen pPhysicalDeviceGroupProperties); 10734582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen if (NULL == pPhysicalDeviceGroupProperties) { 10735582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen instance_data->physical_device_groups_count = *pPhysicalDeviceGroupCount; 10736582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen } else if (result == VK_SUCCESS) { // Save physical devices 10737582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen for (uint32_t i = 0; i < *pPhysicalDeviceGroupCount; i++) { 10738582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen for (uint32_t j = 0; j < pPhysicalDeviceGroupProperties[i].physicalDeviceCount; j++) { 10739582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen VkPhysicalDevice cur_phys_dev = pPhysicalDeviceGroupProperties[i].physicalDevices[j]; 10740582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen auto &phys_device_state = instance_data->physical_device_map[cur_phys_dev]; 10741582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen phys_device_state.phys_device = cur_phys_dev; 10742582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen // Init actual features for each physical device 10743582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen instance_data->dispatch_table.GetPhysicalDeviceFeatures(cur_phys_dev, &phys_device_state.features); 10744582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen } 10745582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen } 10746582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen } 10747582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen return result; 10748582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen } else { 10749582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen log_msg(instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, 0, __LINE__, 107509b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus DEVLIMITS_INVALID_INSTANCE, "DL", 107519b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "Invalid instance (0x%" PRIxLEAST64 ") passed into vkEnumeratePhysicalDeviceGroupsKHX().", 107529b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(instance)); 10753582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen } 10754582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen return VK_ERROR_VALIDATION_FAILED_EXT; 10755582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen} 10756582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen 107576246f8feba03ddc787c31b3daa6a50d4ef01024fMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL CreateDescriptorUpdateTemplateKHR(VkDevice device, 107586246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski const VkDescriptorUpdateTemplateCreateInfoKHR *pCreateInfo, 107596246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski const VkAllocationCallbacks *pAllocator, 107606246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski VkDescriptorUpdateTemplateKHR *pDescriptorUpdateTemplate) { 107616246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 10762a538cd4fff983b172362b0bba58f984124481a1cMark Lobodzinski VkResult result = 10763a538cd4fff983b172362b0bba58f984124481a1cMark Lobodzinski dev_data->dispatch_table.CreateDescriptorUpdateTemplateKHR(device, pCreateInfo, pAllocator, pDescriptorUpdateTemplate); 107646246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski if (VK_SUCCESS == result) { 10765ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 107666246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski // Shadow template createInfo for later updates 10767a538cd4fff983b172362b0bba58f984124481a1cMark Lobodzinski safe_VkDescriptorUpdateTemplateCreateInfoKHR *local_create_info = 10768a538cd4fff983b172362b0bba58f984124481a1cMark Lobodzinski new safe_VkDescriptorUpdateTemplateCreateInfoKHR(pCreateInfo); 107696246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski std::unique_ptr<TEMPLATE_STATE> template_state(new TEMPLATE_STATE(*pDescriptorUpdateTemplate, local_create_info)); 107706246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski dev_data->desc_template_map[*pDescriptorUpdateTemplate] = std::move(template_state); 107716246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski } 107726246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski return result; 107736246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski} 107746246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski 107756246f8feba03ddc787c31b3daa6a50d4ef01024fMark LobodzinskiVKAPI_ATTR void VKAPI_CALL DestroyDescriptorUpdateTemplateKHR(VkDevice device, 107766246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate, 107776246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski const VkAllocationCallbacks *pAllocator) { 107786246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 10779ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 107806246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski dev_data->desc_template_map.erase(descriptorUpdateTemplate); 107816246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski lock.unlock(); 107826246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski dev_data->dispatch_table.DestroyDescriptorUpdateTemplateKHR(device, descriptorUpdateTemplate, pAllocator); 107836246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski} 107846246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski 1078525f3712aed1cebdcb7c92eb25c5f1cc6e5986ac4Mark Lobodzinski// PostCallRecord* handles recording state updates following call down chain to UpdateDescriptorSetsWithTemplate() 1078625f3712aed1cebdcb7c92eb25c5f1cc6e5986ac4Mark Lobodzinskistatic void PostCallRecordUpdateDescriptorSetWithTemplateKHR(layer_data *device_data, VkDescriptorSet descriptorSet, 1078725f3712aed1cebdcb7c92eb25c5f1cc6e5986ac4Mark Lobodzinski VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate, 1078825f3712aed1cebdcb7c92eb25c5f1cc6e5986ac4Mark Lobodzinski const void *pData) { 1078967fe2a610e6fc19f5bf11df4b663cef1f6c4e9caMark Lobodzinski auto const template_map_entry = device_data->desc_template_map.find(descriptorUpdateTemplate); 1079067fe2a610e6fc19f5bf11df4b663cef1f6c4e9caMark Lobodzinski if (template_map_entry == device_data->desc_template_map.end()) { 1079167fe2a610e6fc19f5bf11df4b663cef1f6c4e9caMark Lobodzinski assert(0); 1079267fe2a610e6fc19f5bf11df4b663cef1f6c4e9caMark Lobodzinski } 1079367fe2a610e6fc19f5bf11df4b663cef1f6c4e9caMark Lobodzinski 1079425f3712aed1cebdcb7c92eb25c5f1cc6e5986ac4Mark Lobodzinski cvdescriptorset::PerformUpdateDescriptorSetsWithTemplateKHR(device_data, descriptorSet, template_map_entry->second, pData); 1079567fe2a610e6fc19f5bf11df4b663cef1f6c4e9caMark Lobodzinski} 1079667fe2a610e6fc19f5bf11df4b663cef1f6c4e9caMark Lobodzinski 107976246f8feba03ddc787c31b3daa6a50d4ef01024fMark LobodzinskiVKAPI_ATTR void VKAPI_CALL UpdateDescriptorSetWithTemplateKHR(VkDevice device, VkDescriptorSet descriptorSet, 107986246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate, 107996246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski const void *pData) { 1080067fe2a610e6fc19f5bf11df4b663cef1f6c4e9caMark Lobodzinski layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 1080167fe2a610e6fc19f5bf11df4b663cef1f6c4e9caMark Lobodzinski device_data->dispatch_table.UpdateDescriptorSetWithTemplateKHR(device, descriptorSet, descriptorUpdateTemplate, pData); 1080267fe2a610e6fc19f5bf11df4b663cef1f6c4e9caMark Lobodzinski 1080367fe2a610e6fc19f5bf11df4b663cef1f6c4e9caMark Lobodzinski PostCallRecordUpdateDescriptorSetWithTemplateKHR(device_data, descriptorSet, descriptorUpdateTemplate, pData); 108046246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski} 108056246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski 108066246f8feba03ddc787c31b3daa6a50d4ef01024fMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdPushDescriptorSetWithTemplateKHR(VkCommandBuffer commandBuffer, 108076246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate, 108086246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski VkPipelineLayout layout, uint32_t set, const void *pData) { 108096246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 108106246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski dev_data->dispatch_table.CmdPushDescriptorSetWithTemplateKHR(commandBuffer, descriptorUpdateTemplate, layout, set, pData); 108116246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski} 108126246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski 10813991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinskistatic void PostCallRecordGetPhysicalDeviceDisplayPlanePropertiesKHR(instance_layer_data *instanceData, 10814991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, 10815991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski VkDisplayPlanePropertiesKHR *pProperties) { 10816ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 10817991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski auto physical_device_state = GetPhysicalDeviceState(instanceData, physicalDevice); 10818991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski 10819991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski if (*pPropertyCount) { 108207c9b2aea1e047762ea9cff97ddd1fd33b5efc71dChris Forbes if (physical_device_state->vkGetPhysicalDeviceDisplayPlanePropertiesKHRState < QUERY_COUNT) { 108217c9b2aea1e047762ea9cff97ddd1fd33b5efc71dChris Forbes physical_device_state->vkGetPhysicalDeviceDisplayPlanePropertiesKHRState = QUERY_COUNT; 10822991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski } 10823991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski physical_device_state->display_plane_property_count = *pPropertyCount; 10824991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski } 10825991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski if (pProperties) { 108267c9b2aea1e047762ea9cff97ddd1fd33b5efc71dChris Forbes if (physical_device_state->vkGetPhysicalDeviceDisplayPlanePropertiesKHRState < QUERY_DETAILS) { 108277c9b2aea1e047762ea9cff97ddd1fd33b5efc71dChris Forbes physical_device_state->vkGetPhysicalDeviceDisplayPlanePropertiesKHRState = QUERY_DETAILS; 10828991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski } 10829991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski } 10830991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski} 10831991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski 10832991f2555bc4f571e30b584937c7959805dff67c6Mark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceDisplayPlanePropertiesKHR(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, 10833991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski VkDisplayPlanePropertiesKHR *pProperties) { 10834991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski VkResult result = VK_SUCCESS; 10835991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map); 10836991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski 10837991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski result = instance_data->dispatch_table.GetPhysicalDeviceDisplayPlanePropertiesKHR(physicalDevice, pPropertyCount, pProperties); 10838991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski 10839991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski if (result == VK_SUCCESS || result == VK_INCOMPLETE) { 10840991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski PostCallRecordGetPhysicalDeviceDisplayPlanePropertiesKHR(instance_data, physicalDevice, pPropertyCount, pProperties); 10841991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski } 10842991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski 10843991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski return result; 10844991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski} 10845991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski 10846991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinskistatic bool ValidateGetPhysicalDeviceDisplayPlanePropertiesKHRQuery(instance_layer_data *instance_data, 10847991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski VkPhysicalDevice physicalDevice, uint32_t planeIndex, 10848991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski const char *api_name) { 10849991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski bool skip = false; 10850991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski auto physical_device_state = GetPhysicalDeviceState(instance_data, physicalDevice); 108517c9b2aea1e047762ea9cff97ddd1fd33b5efc71dChris Forbes if (physical_device_state->vkGetPhysicalDeviceDisplayPlanePropertiesKHRState == UNCALLED) { 10852991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski skip |= log_msg( 10853991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski instance_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 10854991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski HandleToUint64(physicalDevice), __LINE__, SWAPCHAIN_GET_SUPPORTED_DISPLAYS_WITHOUT_QUERY, "DL", 10855991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski "Potential problem with calling %s() without first querying vkGetPhysicalDeviceDisplayPlanePropertiesKHR.", api_name); 10856991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski } else { 10857991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski if (planeIndex >= physical_device_state->display_plane_property_count) { 10858991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski skip |= log_msg( 10859991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 10860991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski HandleToUint64(physicalDevice), __LINE__, VALIDATION_ERROR_29c009c2, "DL", 10861991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski "%s(): planeIndex must be in the range [0, %d] that was returned by vkGetPhysicalDeviceDisplayPlanePropertiesKHR. " 10862991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski "Do you have the plane index hardcoded? %s", 10863991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski api_name, physical_device_state->display_plane_property_count - 1, validation_error_map[VALIDATION_ERROR_29c009c2]); 10864991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski } 10865991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski } 10866991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski return skip; 10867991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski} 10868991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski 10869991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinskistatic bool PreCallValidateGetDisplayPlaneSupportedDisplaysKHR(instance_layer_data *instance_data, VkPhysicalDevice physicalDevice, 10870991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski uint32_t planeIndex) { 10871991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski bool skip = false; 10872ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 10873991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski skip |= ValidateGetPhysicalDeviceDisplayPlanePropertiesKHRQuery(instance_data, physicalDevice, planeIndex, 10874991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski "vkGetDisplayPlaneSupportedDisplaysKHR"); 10875991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski return skip; 10876991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski} 10877991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski 10878991f2555bc4f571e30b584937c7959805dff67c6Mark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL GetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice, uint32_t planeIndex, 10879991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski uint32_t *pDisplayCount, VkDisplayKHR *pDisplays) { 10880991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 10881991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map); 10882991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski bool skip = PreCallValidateGetDisplayPlaneSupportedDisplaysKHR(instance_data, physicalDevice, planeIndex); 10883991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski if (!skip) { 10884991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski result = 10885991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski instance_data->dispatch_table.GetDisplayPlaneSupportedDisplaysKHR(physicalDevice, planeIndex, pDisplayCount, pDisplays); 10886991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski } 10887991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski return result; 10888991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski} 10889991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski 10890991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinskistatic bool PreCallValidateGetDisplayPlaneCapabilitiesKHR(instance_layer_data *instance_data, VkPhysicalDevice physicalDevice, 10891991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski uint32_t planeIndex) { 10892991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski bool skip = false; 10893ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 10894991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski skip |= ValidateGetPhysicalDeviceDisplayPlanePropertiesKHRQuery(instance_data, physicalDevice, planeIndex, 10895991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski "vkGetDisplayPlaneCapabilitiesKHR"); 10896991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski return skip; 10897991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski} 10898991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski 10899991f2555bc4f571e30b584937c7959805dff67c6Mark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL GetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkDisplayModeKHR mode, 10900991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski uint32_t planeIndex, VkDisplayPlaneCapabilitiesKHR *pCapabilities) { 10901991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 10902991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map); 10903991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski bool skip = PreCallValidateGetDisplayPlaneCapabilitiesKHR(instance_data, physicalDevice, planeIndex); 10904991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski 10905991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski if (!skip) { 10906991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski result = instance_data->dispatch_table.GetDisplayPlaneCapabilitiesKHR(physicalDevice, mode, planeIndex, pCapabilities); 10907991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski } 10908991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski 10909991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski return result; 10910991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski} 10911991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski 109126dd9a6bc380bc606441fb036974f0ddadff4d0c8Mark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL DebugMarkerSetObjectNameEXT(VkDevice device, const VkDebugMarkerObjectNameInfoEXT *pNameInfo) { 109131f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour std::unique_lock<std::mutex> lock(global_lock); 109141f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 109151f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour if (pNameInfo->pObjectName) { 109161f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour device_data->report_data->debugObjectNameMap->insert( 109171f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour std::make_pair<uint64_t, std::string>((uint64_t &&)pNameInfo->object, pNameInfo->pObjectName)); 109181f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour } else { 109191f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour device_data->report_data->debugObjectNameMap->erase(pNameInfo->object); 109201f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour } 109211f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour lock.unlock(); 109221f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour VkResult result = device_data->dispatch_table.DebugMarkerSetObjectNameEXT(device, pNameInfo); 109231f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour return result; 109241f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour} 109251f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour 109261f53907e108555555ac7cc8e0daf639279ca67d4Tony BarbourVKAPI_ATTR VkResult VKAPI_CALL DebugMarkerSetObjectTagEXT(VkDevice device, VkDebugMarkerObjectTagInfoEXT *pTagInfo) { 109271f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 109281f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour VkResult result = device_data->dispatch_table.DebugMarkerSetObjectTagEXT(device, pTagInfo); 109291f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour return result; 109301f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour} 109311f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour 109321f53907e108555555ac7cc8e0daf639279ca67d4Tony BarbourVKAPI_ATTR void VKAPI_CALL CmdDebugMarkerBeginEXT(VkCommandBuffer commandBuffer, VkDebugMarkerMarkerInfoEXT *pMarkerInfo) { 109331f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour layer_data *device_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 109341f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour device_data->dispatch_table.CmdDebugMarkerBeginEXT(commandBuffer, pMarkerInfo); 109351f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour} 109361f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour 109371f53907e108555555ac7cc8e0daf639279ca67d4Tony BarbourVKAPI_ATTR void VKAPI_CALL CmdDebugMarkerEndEXT(VkCommandBuffer commandBuffer) { 109381f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour layer_data *device_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 109391f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour device_data->dispatch_table.CmdDebugMarkerEndEXT(commandBuffer); 109401f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour} 109411f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour 109421f53907e108555555ac7cc8e0daf639279ca67d4Tony BarbourVKAPI_ATTR void VKAPI_CALL CmdDebugMarkerInsertEXT(VkCommandBuffer commandBuffer, VkDebugMarkerMarkerInfoEXT *pMarkerInfo) { 109431f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour layer_data *device_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 109441f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour device_data->dispatch_table.CmdDebugMarkerInsertEXT(commandBuffer, pMarkerInfo); 109451f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour} 109461f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour 109473616276bb0053c612c0a8d223e81ae3808b1b2c4Mark LobodzinskiVKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice device, const char *funcName); 109483616276bb0053c612c0a8d223e81ae3808b1b2c4Mark LobodzinskiVKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetPhysicalDeviceProcAddr(VkInstance instance, const char *funcName); 109493616276bb0053c612c0a8d223e81ae3808b1b2c4Mark LobodzinskiVKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance, const char *funcName); 109503616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski 109513616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski// Map of all APIs to be intercepted by this layer 10952804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardtstatic const std::unordered_map<std::string, void *> name_to_funcptr_map = { 109533616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetInstanceProcAddr", (void*)GetInstanceProcAddr}, 109543616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vk_layerGetPhysicalDeviceProcAddr", (void*)GetPhysicalDeviceProcAddr}, 109553616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetDeviceProcAddr", (void*)GetDeviceProcAddr}, 109563616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateInstance", (void*)CreateInstance}, 109573616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateDevice", (void*)CreateDevice}, 109583616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkEnumeratePhysicalDevices", (void*)EnumeratePhysicalDevices}, 109593616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetPhysicalDeviceQueueFamilyProperties", (void*)GetPhysicalDeviceQueueFamilyProperties}, 109603616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroyInstance", (void*)DestroyInstance}, 109613616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkEnumerateInstanceLayerProperties", (void*)EnumerateInstanceLayerProperties}, 109623616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkEnumerateDeviceLayerProperties", (void*)EnumerateDeviceLayerProperties}, 109633616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkEnumerateInstanceExtensionProperties", (void*)EnumerateInstanceExtensionProperties}, 109643616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkEnumerateDeviceExtensionProperties", (void*)EnumerateDeviceExtensionProperties}, 109653616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateDescriptorUpdateTemplateKHR", (void*)CreateDescriptorUpdateTemplateKHR}, 109663616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroyDescriptorUpdateTemplateKHR", (void*)DestroyDescriptorUpdateTemplateKHR}, 109673616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkUpdateDescriptorSetWithTemplateKHR", (void*)UpdateDescriptorSetWithTemplateKHR}, 109683616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdPushDescriptorSetWithTemplateKHR", (void*)CmdPushDescriptorSetWithTemplateKHR}, 1096943839a7f8cf2180734f7b8ed3514eda94a63107aMark Lobodzinski {"vkCmdPushDescriptorSetKHR", (void*)CmdPushDescriptorSetKHR}, 109703616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateSwapchainKHR", (void*)CreateSwapchainKHR}, 109713616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroySwapchainKHR", (void*)DestroySwapchainKHR}, 109723616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetSwapchainImagesKHR", (void*)GetSwapchainImagesKHR}, 109733616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkAcquireNextImageKHR", (void*)AcquireNextImageKHR}, 109743616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkQueuePresentKHR", (void*)QueuePresentKHR}, 109753616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkQueueSubmit", (void*)QueueSubmit}, 109763616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkWaitForFences", (void*)WaitForFences}, 109773616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetFenceStatus", (void*)GetFenceStatus}, 109783616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkQueueWaitIdle", (void*)QueueWaitIdle}, 109793616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDeviceWaitIdle", (void*)DeviceWaitIdle}, 109803616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetDeviceQueue", (void*)GetDeviceQueue}, 109813616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroyDevice", (void*)DestroyDevice}, 109823616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroyFence", (void*)DestroyFence}, 109833616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkResetFences", (void*)ResetFences}, 109843616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroySemaphore", (void*)DestroySemaphore}, 109853616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroyEvent", (void*)DestroyEvent}, 109863616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroyQueryPool", (void*)DestroyQueryPool}, 109873616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroyBuffer", (void*)DestroyBuffer}, 109883616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroyBufferView", (void*)DestroyBufferView}, 109893616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroyImage", (void*)DestroyImage}, 109903616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroyImageView", (void*)DestroyImageView}, 109913616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroyShaderModule", (void*)DestroyShaderModule}, 109923616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroyPipeline", (void*)DestroyPipeline}, 109933616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroyPipelineLayout", (void*)DestroyPipelineLayout}, 109943616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroySampler", (void*)DestroySampler}, 109953616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroyDescriptorSetLayout", (void*)DestroyDescriptorSetLayout}, 109963616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroyDescriptorPool", (void*)DestroyDescriptorPool}, 109973616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroyFramebuffer", (void*)DestroyFramebuffer}, 109983616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroyRenderPass", (void*)DestroyRenderPass}, 109993616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateBuffer", (void*)CreateBuffer}, 110003616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateBufferView", (void*)CreateBufferView}, 110013616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateImage", (void*)CreateImage}, 110023616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateImageView", (void*)CreateImageView}, 110033616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateFence", (void*)CreateFence}, 110043616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreatePipelineCache", (void*)CreatePipelineCache}, 110053616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroyPipelineCache", (void*)DestroyPipelineCache}, 110063616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetPipelineCacheData", (void*)GetPipelineCacheData}, 110073616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkMergePipelineCaches", (void*)MergePipelineCaches}, 110083616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateGraphicsPipelines", (void*)CreateGraphicsPipelines}, 110093616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateComputePipelines", (void*)CreateComputePipelines}, 110103616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateSampler", (void*)CreateSampler}, 110113616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateDescriptorSetLayout", (void*)CreateDescriptorSetLayout}, 110123616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreatePipelineLayout", (void*)CreatePipelineLayout}, 110133616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateDescriptorPool", (void*)CreateDescriptorPool}, 110143616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkResetDescriptorPool", (void*)ResetDescriptorPool}, 110153616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkAllocateDescriptorSets", (void*)AllocateDescriptorSets}, 110163616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkFreeDescriptorSets", (void*)FreeDescriptorSets}, 110173616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkUpdateDescriptorSets", (void*)UpdateDescriptorSets}, 110183616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateCommandPool", (void*)CreateCommandPool}, 110193616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroyCommandPool", (void*)DestroyCommandPool}, 110203616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkResetCommandPool", (void*)ResetCommandPool}, 110213616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateQueryPool", (void*)CreateQueryPool}, 110223616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkAllocateCommandBuffers", (void*)AllocateCommandBuffers}, 110233616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkFreeCommandBuffers", (void*)FreeCommandBuffers}, 110243616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkBeginCommandBuffer", (void*)BeginCommandBuffer}, 110253616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkEndCommandBuffer", (void*)EndCommandBuffer}, 110263616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkResetCommandBuffer", (void*)ResetCommandBuffer}, 110273616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdBindPipeline", (void*)CmdBindPipeline}, 110283616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdSetViewport", (void*)CmdSetViewport}, 110293616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdSetScissor", (void*)CmdSetScissor}, 110303616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdSetLineWidth", (void*)CmdSetLineWidth}, 110313616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdSetDepthBias", (void*)CmdSetDepthBias}, 110323616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdSetBlendConstants", (void*)CmdSetBlendConstants}, 110333616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdSetDepthBounds", (void*)CmdSetDepthBounds}, 110343616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdSetStencilCompareMask", (void*)CmdSetStencilCompareMask}, 110353616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdSetStencilWriteMask", (void*)CmdSetStencilWriteMask}, 110363616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdSetStencilReference", (void*)CmdSetStencilReference}, 110373616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdBindDescriptorSets", (void*)CmdBindDescriptorSets}, 110383616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdBindVertexBuffers", (void*)CmdBindVertexBuffers}, 110393616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdBindIndexBuffer", (void*)CmdBindIndexBuffer}, 110403616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdDraw", (void*)CmdDraw}, 110413616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdDrawIndexed", (void*)CmdDrawIndexed}, 110423616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdDrawIndirect", (void*)CmdDrawIndirect}, 110433616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdDrawIndexedIndirect", (void*)CmdDrawIndexedIndirect}, 110443616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdDispatch", (void*)CmdDispatch}, 110453616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdDispatchIndirect", (void*)CmdDispatchIndirect}, 110463616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdCopyBuffer", (void*)CmdCopyBuffer}, 110473616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdCopyImage", (void*)CmdCopyImage}, 110483616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdBlitImage", (void*)CmdBlitImage}, 110493616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdCopyBufferToImage", (void*)CmdCopyBufferToImage}, 110503616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdCopyImageToBuffer", (void*)CmdCopyImageToBuffer}, 110513616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdUpdateBuffer", (void*)CmdUpdateBuffer}, 110523616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdFillBuffer", (void*)CmdFillBuffer}, 110533616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdClearColorImage", (void*)CmdClearColorImage}, 110543616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdClearDepthStencilImage", (void*)CmdClearDepthStencilImage}, 110553616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdClearAttachments", (void*)CmdClearAttachments}, 110563616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdResolveImage", (void*)CmdResolveImage}, 110573616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetImageSubresourceLayout", (void*)GetImageSubresourceLayout}, 110583616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdSetEvent", (void*)CmdSetEvent}, 110593616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdResetEvent", (void*)CmdResetEvent}, 110603616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdWaitEvents", (void*)CmdWaitEvents}, 110613616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdPipelineBarrier", (void*)CmdPipelineBarrier}, 110623616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdBeginQuery", (void*)CmdBeginQuery}, 110633616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdEndQuery", (void*)CmdEndQuery}, 110643616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdResetQueryPool", (void*)CmdResetQueryPool}, 110653616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdCopyQueryPoolResults", (void*)CmdCopyQueryPoolResults}, 110663616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdPushConstants", (void*)CmdPushConstants}, 110673616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdWriteTimestamp", (void*)CmdWriteTimestamp}, 110683616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateFramebuffer", (void*)CreateFramebuffer}, 110693616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateShaderModule", (void*)CreateShaderModule}, 110703616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateRenderPass", (void*)CreateRenderPass}, 110713616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdBeginRenderPass", (void*)CmdBeginRenderPass}, 110723616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdNextSubpass", (void*)CmdNextSubpass}, 110733616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdEndRenderPass", (void*)CmdEndRenderPass}, 110743616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdExecuteCommands", (void*)CmdExecuteCommands}, 110751f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour {"vkCmdDebugMarkerBeginEXT", (void*)CmdDebugMarkerBeginEXT}, 110761f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour {"vkCmdDebugMarkerEndEXT", (void*)CmdDebugMarkerEndEXT}, 110771f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour {"vkCmdDebugMarkerInsertEXT", (void*)CmdDebugMarkerInsertEXT}, 110781f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour {"vkDebugMarkerSetObjectNameEXT", (void*)DebugMarkerSetObjectNameEXT}, 110791f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour {"vkDebugMarkerSetObjectTagEXT", (void*)DebugMarkerSetObjectTagEXT}, 110803616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkSetEvent", (void*)SetEvent}, 110813616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkMapMemory", (void*)MapMemory}, 110823616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkUnmapMemory", (void*)UnmapMemory}, 110833616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkFlushMappedMemoryRanges", (void*)FlushMappedMemoryRanges}, 110843616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkInvalidateMappedMemoryRanges", (void*)InvalidateMappedMemoryRanges}, 110853616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkAllocateMemory", (void*)AllocateMemory}, 110863616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkFreeMemory", (void*)FreeMemory}, 110873616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkBindBufferMemory", (void*)BindBufferMemory}, 110883616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetBufferMemoryRequirements", (void*)GetBufferMemoryRequirements}, 110893616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetImageMemoryRequirements", (void*)GetImageMemoryRequirements}, 110903616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetQueryPoolResults", (void*)GetQueryPoolResults}, 110913616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkBindImageMemory", (void*)BindImageMemory}, 110923616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkQueueBindSparse", (void*)QueueBindSparse}, 110933616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateSemaphore", (void*)CreateSemaphore}, 110943616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateEvent", (void*)CreateEvent}, 110953616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski#ifdef VK_USE_PLATFORM_ANDROID_KHR 110963616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateAndroidSurfaceKHR", (void*)CreateAndroidSurfaceKHR}, 110973616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski#endif 110983616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski#ifdef VK_USE_PLATFORM_MIR_KHR 110993616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateMirSurfaceKHR", (void*)CreateMirSurfaceKHR}, 111003616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetPhysicalDeviceMirPresentationSupportKHR", (void*)GetPhysicalDeviceMirPresentationSupportKHR}, 111013616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski#endif 111023616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski#ifdef VK_USE_PLATFORM_WAYLAND_KHR 111033616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateWaylandSurfaceKHR", (void*)CreateWaylandSurfaceKHR}, 111043616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetPhysicalDeviceWaylandPresentationSupportKHR", (void*)GetPhysicalDeviceWaylandPresentationSupportKHR}, 111053616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski#endif 111063616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski#ifdef VK_USE_PLATFORM_WIN32_KHR 111073616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateWin32SurfaceKHR", (void*)CreateWin32SurfaceKHR}, 111083616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetPhysicalDeviceWin32PresentationSupportKHR", (void*)GetPhysicalDeviceWin32PresentationSupportKHR}, 1110906d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt {"vkImportSemaphoreWin32HandleKHR", (void*)ImportSemaphoreWin32HandleKHR}, 1111006d5c171f0bb0acbed8120af6bac43f13a869e3fMike Schuchardt {"vkGetSemaphoreWin32HandleKHR", (void*)GetSemaphoreWin32HandleKHR}, 11111804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt {"vkImportFenceWin32HandleKHR", (void*)ImportFenceWin32HandleKHR}, 11112804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt {"vkGetFenceWin32HandleKHR", (void*)GetFenceWin32HandleKHR}, 111133616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski#endif 111143616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski#ifdef VK_USE_PLATFORM_XCB_KHR 111153616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateXcbSurfaceKHR", (void*)CreateXcbSurfaceKHR}, 111163616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetPhysicalDeviceXcbPresentationSupportKHR", (void*)GetPhysicalDeviceXcbPresentationSupportKHR}, 111173616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski#endif 111183616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski#ifdef VK_USE_PLATFORM_XLIB_KHR 111193616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateXlibSurfaceKHR", (void*)CreateXlibSurfaceKHR}, 111203616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetPhysicalDeviceXlibPresentationSupportKHR", (void*)GetPhysicalDeviceXlibPresentationSupportKHR}, 111213616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski#endif 111223616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateDisplayPlaneSurfaceKHR", (void*)CreateDisplayPlaneSurfaceKHR}, 111233616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroySurfaceKHR", (void*)DestroySurfaceKHR}, 111243616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetPhysicalDeviceSurfaceCapabilitiesKHR", (void*)GetPhysicalDeviceSurfaceCapabilitiesKHR}, 111253616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetPhysicalDeviceSurfaceCapabilities2KHR", (void*)GetPhysicalDeviceSurfaceCapabilities2KHR}, 111263616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetPhysicalDeviceSurfaceCapabilities2EXT", (void*)GetPhysicalDeviceSurfaceCapabilities2EXT}, 111273616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetPhysicalDeviceSurfaceSupportKHR", (void*)GetPhysicalDeviceSurfaceSupportKHR}, 111283616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetPhysicalDeviceSurfacePresentModesKHR", (void*)GetPhysicalDeviceSurfacePresentModesKHR}, 111293616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetPhysicalDeviceSurfaceFormatsKHR", (void*)GetPhysicalDeviceSurfaceFormatsKHR}, 111303616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetPhysicalDeviceSurfaceFormats2KHR", (void*)GetPhysicalDeviceSurfaceFormats2KHR}, 111313616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetPhysicalDeviceQueueFamilyProperties2KHR", (void*)GetPhysicalDeviceQueueFamilyProperties2KHR}, 111323616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkEnumeratePhysicalDeviceGroupsKHX", (void*)EnumeratePhysicalDeviceGroupsKHX}, 111333616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateDebugReportCallbackEXT", (void*)CreateDebugReportCallbackEXT}, 111343616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroyDebugReportCallbackEXT", (void*)DestroyDebugReportCallbackEXT}, 111353616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDebugReportMessageEXT", (void*)DebugReportMessageEXT}, 11136991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski {"vkGetPhysicalDeviceDisplayPlanePropertiesKHR", (void*)GetPhysicalDeviceDisplayPlanePropertiesKHR}, 11137c8fe10051b18a353adf7e5a6f015b12deaeffab4Mike Schuchardt {"vkGetDisplayPlaneSupportedDisplaysKHR", (void*)GetDisplayPlaneSupportedDisplaysKHR}, 11138c8fe10051b18a353adf7e5a6f015b12deaeffab4Mike Schuchardt {"vkGetDisplayPlaneCapabilitiesKHR", (void*)GetDisplayPlaneCapabilitiesKHR}, 1113916f39f23c20176b9ff809d10d76b62663e1adabdMike Schuchardt {"vkImportSemaphoreFdKHR", (void*)ImportSemaphoreFdKHR}, 1114016f39f23c20176b9ff809d10d76b62663e1adabdMike Schuchardt {"vkGetSemaphoreFdKHR", (void*)GetSemaphoreFdKHR}, 11141804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt {"vkImportFenceFdKHR", (void*)ImportFenceFdKHR}, 11142804e95a8a6a78f03a0325a78fd2b250a575ce3ceMike Schuchardt {"vkGetFenceFdKHR", (void*)GetFenceFdKHR}, 11143fe772548f7a48b12772483e8faecc956fb76eb42Chris Forbes {"vkCreateValidationCacheEXT", (void*)CreateValidationCacheEXT}, 11144fe772548f7a48b12772483e8faecc956fb76eb42Chris Forbes {"vkDestroyValidationCacheEXT", (void*)DestroyValidationCacheEXT}, 11145fe772548f7a48b12772483e8faecc956fb76eb42Chris Forbes {"vkGetValidationCacheDataEXT", (void*)GetValidationCacheDataEXT}, 11146fe772548f7a48b12772483e8faecc956fb76eb42Chris Forbes {"vkMergeValidationCachesEXT", (void*)MergeValidationCachesEXT}, 111473616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski}; 11148b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young 111493616276bb0053c612c0a8d223e81ae3808b1b2c4Mark LobodzinskiVKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice device, const char *funcName) { 111503616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski assert(device); 111513616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 111525b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 111533616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski // Is API to be intercepted by this layer? 111543616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski const auto &item = name_to_funcptr_map.find(funcName); 111553616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski if (item != name_to_funcptr_map.end()) { 111563616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski return reinterpret_cast<PFN_vkVoidFunction>(item->second); 111573616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski } 1115809a2f8128f58f032b73d29fab5afd789626562c3Chia-I Wu 111593616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski auto &table = device_data->dispatch_table; 11160cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (!table.GetDeviceProcAddr) return nullptr; 111613616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski return table.GetDeviceProcAddr(device, funcName); 111625b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 111635b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 1116489d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance, const char *funcName) { 111653616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski instance_layer_data *instance_data; 111663616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski // Is API to be intercepted by this layer? 111673616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski const auto &item = name_to_funcptr_map.find(funcName); 111683616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski if (item != name_to_funcptr_map.end()) { 111693616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski return reinterpret_cast<PFN_vkVoidFunction>(item->second); 111703616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski } 11171b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young 111723616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski instance_data = GetLayerDataPtr(get_dispatch_key(instance), instance_layer_data_map); 111734a0754042cf090e131e9e769d8a3633c228625beChris Forbes auto &table = instance_data->dispatch_table; 11174cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (!table.GetInstanceProcAddr) return nullptr; 111754a0754042cf090e131e9e769d8a3633c228625beChris Forbes return table.GetInstanceProcAddr(instance, funcName); 111765b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 1117708939232d080c94fc7b4c5ad348644928beb1519Chia-I Wu 11178b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark YoungVKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetPhysicalDeviceProcAddr(VkInstance instance, const char *funcName) { 11179b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young assert(instance); 1118056e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(instance), instance_layer_data_map); 11181b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young 11182b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young auto &table = instance_data->dispatch_table; 11183cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (!table.GetPhysicalDeviceProcAddr) return nullptr; 11184b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young return table.GetPhysicalDeviceProcAddr(instance, funcName); 11185b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young} 11186b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young 11187cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski} // namespace core_validation 11188d16a2fd05d0b6bd20c7274560c88e37e4b3adefcChia-I Wu 11189a4e71cd8b4e77502943dd894ed95426a25dffbd5Chia-I Wu// loader-layer interface v0, just wrappers since there is only a layer 11190d16a2fd05d0b6bd20c7274560c88e37e4b3adefcChia-I Wu 11191bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount, 11192bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkExtensionProperties *pProperties) { 11193a4e71cd8b4e77502943dd894ed95426a25dffbd5Chia-I Wu return core_validation::EnumerateInstanceExtensionProperties(pLayerName, pCount, pProperties); 1119408939232d080c94fc7b4c5ad348644928beb1519Chia-I Wu} 1119508939232d080c94fc7b4c5ad348644928beb1519Chia-I Wu 11196bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(uint32_t *pCount, 11197bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkLayerProperties *pProperties) { 11198a4e71cd8b4e77502943dd894ed95426a25dffbd5Chia-I Wu return core_validation::EnumerateInstanceLayerProperties(pCount, pProperties); 1119908939232d080c94fc7b4c5ad348644928beb1519Chia-I Wu} 1120008939232d080c94fc7b4c5ad348644928beb1519Chia-I Wu 11201bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount, 11202bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkLayerProperties *pProperties) { 11203a4e71cd8b4e77502943dd894ed95426a25dffbd5Chia-I Wu // the layer command handles VK_NULL_HANDLE just fine internally 11204a4e71cd8b4e77502943dd894ed95426a25dffbd5Chia-I Wu assert(physicalDevice == VK_NULL_HANDLE); 11205a4e71cd8b4e77502943dd894ed95426a25dffbd5Chia-I Wu return core_validation::EnumerateDeviceLayerProperties(VK_NULL_HANDLE, pCount, pProperties); 11206d16a2fd05d0b6bd20c7274560c88e37e4b3adefcChia-I Wu} 11207d16a2fd05d0b6bd20c7274560c88e37e4b3adefcChia-I Wu 11208d16a2fd05d0b6bd20c7274560c88e37e4b3adefcChia-I WuVK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, 11209d16a2fd05d0b6bd20c7274560c88e37e4b3adefcChia-I Wu const char *pLayerName, uint32_t *pCount, 11210d16a2fd05d0b6bd20c7274560c88e37e4b3adefcChia-I Wu VkExtensionProperties *pProperties) { 11211a4e71cd8b4e77502943dd894ed95426a25dffbd5Chia-I Wu // the layer command handles VK_NULL_HANDLE just fine internally 11212a4e71cd8b4e77502943dd894ed95426a25dffbd5Chia-I Wu assert(physicalDevice == VK_NULL_HANDLE); 11213a8f4a23b1e9c068717eda47cc583a93f447c77e3Chia-I Wu return core_validation::EnumerateDeviceExtensionProperties(VK_NULL_HANDLE, pLayerName, pCount, pProperties); 11214d16a2fd05d0b6bd20c7274560c88e37e4b3adefcChia-I Wu} 11215d16a2fd05d0b6bd20c7274560c88e37e4b3adefcChia-I Wu 11216d16a2fd05d0b6bd20c7274560c88e37e4b3adefcChia-I WuVK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice dev, const char *funcName) { 1121789d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I Wu return core_validation::GetDeviceProcAddr(dev, funcName); 11218d16a2fd05d0b6bd20c7274560c88e37e4b3adefcChia-I Wu} 11219d16a2fd05d0b6bd20c7274560c88e37e4b3adefcChia-I Wu 11220d16a2fd05d0b6bd20c7274560c88e37e4b3adefcChia-I WuVK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *funcName) { 1122189d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I Wu return core_validation::GetInstanceProcAddr(instance, funcName); 1122208939232d080c94fc7b4c5ad348644928beb1519Chia-I Wu} 11223b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young 11224bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_layerGetPhysicalDeviceProcAddr(VkInstance instance, 11225bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const char *funcName) { 11226b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young return core_validation::GetPhysicalDeviceProcAddr(instance, funcName); 11227b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young} 11228b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young 11229b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark YoungVK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkNegotiateLoaderLayerInterfaceVersion(VkNegotiateLayerInterface *pVersionStruct) { 11230b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young assert(pVersionStruct != NULL); 11231b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young assert(pVersionStruct->sType == LAYER_NEGOTIATE_INTERFACE_STRUCT); 11232b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young 11233b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young // Fill in the function pointers if our version is at least capable of having the structure contain them. 11234b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young if (pVersionStruct->loaderLayerInterfaceVersion >= 2) { 11235b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young pVersionStruct->pfnGetInstanceProcAddr = vkGetInstanceProcAddr; 11236b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young pVersionStruct->pfnGetDeviceProcAddr = vkGetDeviceProcAddr; 11237b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young pVersionStruct->pfnGetPhysicalDeviceProcAddr = vk_layerGetPhysicalDeviceProcAddr; 11238b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young } 11239b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young 11240b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young if (pVersionStruct->loaderLayerInterfaceVersion < CURRENT_LOADER_LAYER_INTERFACE_VERSION) { 11241b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young core_validation::loader_layer_if_version = pVersionStruct->loaderLayerInterfaceVersion; 11242b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young } else if (pVersionStruct->loaderLayerInterfaceVersion > CURRENT_LOADER_LAYER_INTERFACE_VERSION) { 11243b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young pVersionStruct->loaderLayerInterfaceVersion = CURRENT_LOADER_LAYER_INTERFACE_VERSION; 11244b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young } 11245b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young 11246b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young return VK_SUCCESS; 11247b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young} 11248