1*b7893ccfSSadaf Ebrahimi#!/usr/bin/python3 -i 2*b7893ccfSSadaf Ebrahimi# 3*b7893ccfSSadaf Ebrahimi# Copyright (c) 2015-2019 Valve Corporation 4*b7893ccfSSadaf Ebrahimi# Copyright (c) 2015-2019 LunarG, Inc. 5*b7893ccfSSadaf Ebrahimi# Copyright (c) 2015-2019 Google Inc. 6*b7893ccfSSadaf Ebrahimi# 7*b7893ccfSSadaf Ebrahimi# Licensed under the Apache License, Version 2.0 (the "License"); 8*b7893ccfSSadaf Ebrahimi# you may not use this file except in compliance with the License. 9*b7893ccfSSadaf Ebrahimi# You may obtain a copy of the License at 10*b7893ccfSSadaf Ebrahimi# 11*b7893ccfSSadaf Ebrahimi# http://www.apache.org/licenses/LICENSE-2.0 12*b7893ccfSSadaf Ebrahimi# 13*b7893ccfSSadaf Ebrahimi# Unless required by applicable law or agreed to in writing, software 14*b7893ccfSSadaf Ebrahimi# distributed under the License is distributed on an "AS IS" BASIS, 15*b7893ccfSSadaf Ebrahimi# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16*b7893ccfSSadaf Ebrahimi# See the License for the specific language governing permissions and 17*b7893ccfSSadaf Ebrahimi# limitations under the License. 18*b7893ccfSSadaf Ebrahimi# 19*b7893ccfSSadaf Ebrahimi# Author: Tobin Ehlis <[email protected]> 20*b7893ccfSSadaf Ebrahimi# Author: Mark Lobodzinski <[email protected]> 21*b7893ccfSSadaf Ebrahimi# 22*b7893ccfSSadaf Ebrahimi# This script generates the dispatch portion of a factory layer which intercepts 23*b7893ccfSSadaf Ebrahimi# all Vulkan functions. The resultant factory layer allows rapid development of 24*b7893ccfSSadaf Ebrahimi# layers and interceptors. 25*b7893ccfSSadaf Ebrahimi 26*b7893ccfSSadaf Ebrahimiimport os,re,sys 27*b7893ccfSSadaf Ebrahimifrom generator import * 28*b7893ccfSSadaf Ebrahimifrom common_codegen import * 29*b7893ccfSSadaf Ebrahimi 30*b7893ccfSSadaf Ebrahimi# LayerFactoryGeneratorOptions - subclass of GeneratorOptions. 31*b7893ccfSSadaf Ebrahimi# 32*b7893ccfSSadaf Ebrahimi# Adds options used by LayerFactoryOutputGenerator objects during factory 33*b7893ccfSSadaf Ebrahimi# layer generation. 34*b7893ccfSSadaf Ebrahimi# 35*b7893ccfSSadaf Ebrahimi# Additional members 36*b7893ccfSSadaf Ebrahimi# prefixText - list of strings to prefix generated header with 37*b7893ccfSSadaf Ebrahimi# (usually a copyright statement + calling convention macros). 38*b7893ccfSSadaf Ebrahimi# protectFile - True if multiple inclusion protection should be 39*b7893ccfSSadaf Ebrahimi# generated (based on the filename) around the entire header. 40*b7893ccfSSadaf Ebrahimi# protectFeature - True if #ifndef..#endif protection should be 41*b7893ccfSSadaf Ebrahimi# generated around a feature interface in the header file. 42*b7893ccfSSadaf Ebrahimi# genFuncPointers - True if function pointer typedefs should be 43*b7893ccfSSadaf Ebrahimi# generated 44*b7893ccfSSadaf Ebrahimi# protectProto - If conditional protection should be generated 45*b7893ccfSSadaf Ebrahimi# around prototype declarations, set to either '#ifdef' 46*b7893ccfSSadaf Ebrahimi# to require opt-in (#ifdef protectProtoStr) or '#ifndef' 47*b7893ccfSSadaf Ebrahimi# to require opt-out (#ifndef protectProtoStr). Otherwise 48*b7893ccfSSadaf Ebrahimi# set to None. 49*b7893ccfSSadaf Ebrahimi# protectProtoStr - #ifdef/#ifndef symbol to use around prototype 50*b7893ccfSSadaf Ebrahimi# declarations, if protectProto is set 51*b7893ccfSSadaf Ebrahimi# apicall - string to use for the function declaration prefix, 52*b7893ccfSSadaf Ebrahimi# such as APICALL on Windows. 53*b7893ccfSSadaf Ebrahimi# apientry - string to use for the calling convention macro, 54*b7893ccfSSadaf Ebrahimi# in typedefs, such as APIENTRY. 55*b7893ccfSSadaf Ebrahimi# apientryp - string to use for the calling convention macro 56*b7893ccfSSadaf Ebrahimi# in function pointer typedefs, such as APIENTRYP. 57*b7893ccfSSadaf Ebrahimi# indentFuncProto - True if prototype declarations should put each 58*b7893ccfSSadaf Ebrahimi# parameter on a separate line 59*b7893ccfSSadaf Ebrahimi# indentFuncPointer - True if typedefed function pointers should put each 60*b7893ccfSSadaf Ebrahimi# parameter on a separate line 61*b7893ccfSSadaf Ebrahimi# alignFuncParam - if nonzero and parameters are being put on a 62*b7893ccfSSadaf Ebrahimi# separate line, align parameter names at the specified column 63*b7893ccfSSadaf Ebrahimiclass LayerChassisGeneratorOptions(GeneratorOptions): 64*b7893ccfSSadaf Ebrahimi def __init__(self, 65*b7893ccfSSadaf Ebrahimi conventions = None, 66*b7893ccfSSadaf Ebrahimi filename = None, 67*b7893ccfSSadaf Ebrahimi directory = '.', 68*b7893ccfSSadaf Ebrahimi apiname = None, 69*b7893ccfSSadaf Ebrahimi profile = None, 70*b7893ccfSSadaf Ebrahimi versions = '.*', 71*b7893ccfSSadaf Ebrahimi emitversions = '.*', 72*b7893ccfSSadaf Ebrahimi defaultExtensions = None, 73*b7893ccfSSadaf Ebrahimi addExtensions = None, 74*b7893ccfSSadaf Ebrahimi removeExtensions = None, 75*b7893ccfSSadaf Ebrahimi emitExtensions = None, 76*b7893ccfSSadaf Ebrahimi sortProcedure = regSortFeatures, 77*b7893ccfSSadaf Ebrahimi prefixText = "", 78*b7893ccfSSadaf Ebrahimi genFuncPointers = True, 79*b7893ccfSSadaf Ebrahimi protectFile = True, 80*b7893ccfSSadaf Ebrahimi protectFeature = True, 81*b7893ccfSSadaf Ebrahimi apicall = '', 82*b7893ccfSSadaf Ebrahimi apientry = '', 83*b7893ccfSSadaf Ebrahimi apientryp = '', 84*b7893ccfSSadaf Ebrahimi indentFuncProto = True, 85*b7893ccfSSadaf Ebrahimi indentFuncPointer = False, 86*b7893ccfSSadaf Ebrahimi alignFuncParam = 0, 87*b7893ccfSSadaf Ebrahimi helper_file_type = '', 88*b7893ccfSSadaf Ebrahimi expandEnumerants = True): 89*b7893ccfSSadaf Ebrahimi GeneratorOptions.__init__(self, conventions, filename, directory, apiname, profile, 90*b7893ccfSSadaf Ebrahimi versions, emitversions, defaultExtensions, 91*b7893ccfSSadaf Ebrahimi addExtensions, removeExtensions, emitExtensions, sortProcedure) 92*b7893ccfSSadaf Ebrahimi self.prefixText = prefixText 93*b7893ccfSSadaf Ebrahimi self.genFuncPointers = genFuncPointers 94*b7893ccfSSadaf Ebrahimi self.protectFile = protectFile 95*b7893ccfSSadaf Ebrahimi self.protectFeature = protectFeature 96*b7893ccfSSadaf Ebrahimi self.apicall = apicall 97*b7893ccfSSadaf Ebrahimi self.apientry = apientry 98*b7893ccfSSadaf Ebrahimi self.apientryp = apientryp 99*b7893ccfSSadaf Ebrahimi self.indentFuncProto = indentFuncProto 100*b7893ccfSSadaf Ebrahimi self.indentFuncPointer = indentFuncPointer 101*b7893ccfSSadaf Ebrahimi self.alignFuncParam = alignFuncParam 102*b7893ccfSSadaf Ebrahimi 103*b7893ccfSSadaf Ebrahimi# LayerChassisOutputGenerator - subclass of OutputGenerator. 104*b7893ccfSSadaf Ebrahimi# Generates a LayerFactory layer that intercepts all API entrypoints 105*b7893ccfSSadaf Ebrahimi# This is intended to be used as a starting point for creating custom layers 106*b7893ccfSSadaf Ebrahimi# 107*b7893ccfSSadaf Ebrahimi# ---- methods ---- 108*b7893ccfSSadaf Ebrahimi# LayerChassisOutputGenerator(errFile, warnFile, diagFile) - args as for 109*b7893ccfSSadaf Ebrahimi# OutputGenerator. Defines additional internal state. 110*b7893ccfSSadaf Ebrahimi# ---- methods overriding base class ---- 111*b7893ccfSSadaf Ebrahimi# beginFile(genOpts) 112*b7893ccfSSadaf Ebrahimi# endFile() 113*b7893ccfSSadaf Ebrahimi# beginFeature(interface, emit) 114*b7893ccfSSadaf Ebrahimi# endFeature() 115*b7893ccfSSadaf Ebrahimi# genType(typeinfo,name) 116*b7893ccfSSadaf Ebrahimi# genStruct(typeinfo,name) 117*b7893ccfSSadaf Ebrahimi# genGroup(groupinfo,name) 118*b7893ccfSSadaf Ebrahimi# genEnum(enuminfo, name) 119*b7893ccfSSadaf Ebrahimi# genCmd(cmdinfo) 120*b7893ccfSSadaf Ebrahimiclass LayerChassisOutputGenerator(OutputGenerator): 121*b7893ccfSSadaf Ebrahimi """Generate specified API interfaces in a specific style, such as a C header""" 122*b7893ccfSSadaf Ebrahimi # This is an ordered list of sections in the header file. 123*b7893ccfSSadaf Ebrahimi TYPE_SECTIONS = ['include', 'define', 'basetype', 'handle', 'enum', 124*b7893ccfSSadaf Ebrahimi 'group', 'bitmask', 'funcpointer', 'struct'] 125*b7893ccfSSadaf Ebrahimi ALL_SECTIONS = TYPE_SECTIONS + ['command'] 126*b7893ccfSSadaf Ebrahimi 127*b7893ccfSSadaf Ebrahimi manual_functions = [ 128*b7893ccfSSadaf Ebrahimi # Include functions here to be interecpted w/ manually implemented function bodies 129*b7893ccfSSadaf Ebrahimi 'vkGetDeviceProcAddr', 130*b7893ccfSSadaf Ebrahimi 'vkGetInstanceProcAddr', 131*b7893ccfSSadaf Ebrahimi 'vkCreateDevice', 132*b7893ccfSSadaf Ebrahimi 'vkDestroyDevice', 133*b7893ccfSSadaf Ebrahimi 'vkCreateInstance', 134*b7893ccfSSadaf Ebrahimi 'vkDestroyInstance', 135*b7893ccfSSadaf Ebrahimi 'vkEnumerateInstanceLayerProperties', 136*b7893ccfSSadaf Ebrahimi 'vkEnumerateInstanceExtensionProperties', 137*b7893ccfSSadaf Ebrahimi 'vkEnumerateDeviceLayerProperties', 138*b7893ccfSSadaf Ebrahimi 'vkEnumerateDeviceExtensionProperties', 139*b7893ccfSSadaf Ebrahimi # Functions that are handled explicitly due to chassis architecture violations 140*b7893ccfSSadaf Ebrahimi 'vkCreateGraphicsPipelines', 141*b7893ccfSSadaf Ebrahimi 'vkCreateComputePipelines', 142*b7893ccfSSadaf Ebrahimi 'vkCreateRayTracingPipelinesNV', 143*b7893ccfSSadaf Ebrahimi 'vkCreatePipelineLayout', 144*b7893ccfSSadaf Ebrahimi 'vkCreateShaderModule', 145*b7893ccfSSadaf Ebrahimi 'vkAllocateDescriptorSets', 146*b7893ccfSSadaf Ebrahimi # ValidationCache functions do not get dispatched 147*b7893ccfSSadaf Ebrahimi 'vkCreateValidationCacheEXT', 148*b7893ccfSSadaf Ebrahimi 'vkDestroyValidationCacheEXT', 149*b7893ccfSSadaf Ebrahimi 'vkMergeValidationCachesEXT', 150*b7893ccfSSadaf Ebrahimi 'vkGetValidationCacheDataEXT', 151*b7893ccfSSadaf Ebrahimi # We don't wanna hook this function 152*b7893ccfSSadaf Ebrahimi 'vkGetPhysicalDeviceProcAddr', 153*b7893ccfSSadaf Ebrahimi ] 154*b7893ccfSSadaf Ebrahimi 155*b7893ccfSSadaf Ebrahimi alt_ret_codes = [ 156*b7893ccfSSadaf Ebrahimi # Include functions here which must tolerate VK_INCOMPLETE as a return code 157*b7893ccfSSadaf Ebrahimi 'vkEnumeratePhysicalDevices', 158*b7893ccfSSadaf Ebrahimi 'vkEnumeratePhysicalDeviceGroupsKHR', 159*b7893ccfSSadaf Ebrahimi 'vkGetValidationCacheDataEXT', 160*b7893ccfSSadaf Ebrahimi 'vkGetPipelineCacheData', 161*b7893ccfSSadaf Ebrahimi 'vkGetShaderInfoAMD', 162*b7893ccfSSadaf Ebrahimi 'vkGetPhysicalDeviceDisplayPropertiesKHR', 163*b7893ccfSSadaf Ebrahimi 'vkGetPhysicalDeviceDisplayProperties2KHR', 164*b7893ccfSSadaf Ebrahimi 'vkGetPhysicalDeviceDisplayPlanePropertiesKHR', 165*b7893ccfSSadaf Ebrahimi 'vkGetDisplayPlaneSupportedDisplaysKHR', 166*b7893ccfSSadaf Ebrahimi 'vkGetDisplayModePropertiesKHR', 167*b7893ccfSSadaf Ebrahimi 'vkGetDisplayModeProperties2KHR', 168*b7893ccfSSadaf Ebrahimi 'vkGetPhysicalDeviceSurfaceFormatsKHR', 169*b7893ccfSSadaf Ebrahimi 'vkGetPhysicalDeviceSurfacePresentModesKHR', 170*b7893ccfSSadaf Ebrahimi 'vkGetPhysicalDevicePresentRectanglesKHR', 171*b7893ccfSSadaf Ebrahimi 'vkGetPastPresentationTimingGOOGLE', 172*b7893ccfSSadaf Ebrahimi 'vkGetSwapchainImagesKHR', 173*b7893ccfSSadaf Ebrahimi 'vkEnumerateInstanceLayerProperties', 174*b7893ccfSSadaf Ebrahimi 'vkEnumerateDeviceLayerProperties', 175*b7893ccfSSadaf Ebrahimi 'vkEnumerateInstanceExtensionProperties', 176*b7893ccfSSadaf Ebrahimi 'vkEnumerateDeviceExtensionProperties', 177*b7893ccfSSadaf Ebrahimi 'vkGetPhysicalDeviceCalibrateableTimeDomainsEXT', 178*b7893ccfSSadaf Ebrahimi ] 179*b7893ccfSSadaf Ebrahimi 180*b7893ccfSSadaf Ebrahimi pre_dispatch_debug_utils_functions = { 181*b7893ccfSSadaf Ebrahimi 'vkDebugMarkerSetObjectNameEXT' : 'layer_data->report_data->DebugReportSetMarkerObjectName(pNameInfo);', 182*b7893ccfSSadaf Ebrahimi 'vkSetDebugUtilsObjectNameEXT' : 'layer_data->report_data->DebugReportSetUtilsObjectName(pNameInfo);', 183*b7893ccfSSadaf Ebrahimi 'vkQueueBeginDebugUtilsLabelEXT' : 'BeginQueueDebugUtilsLabel(layer_data->report_data, queue, pLabelInfo);', 184*b7893ccfSSadaf Ebrahimi 'vkQueueInsertDebugUtilsLabelEXT' : 'InsertQueueDebugUtilsLabel(layer_data->report_data, queue, pLabelInfo);', 185*b7893ccfSSadaf Ebrahimi } 186*b7893ccfSSadaf Ebrahimi 187*b7893ccfSSadaf Ebrahimi post_dispatch_debug_utils_functions = { 188*b7893ccfSSadaf Ebrahimi 'vkQueueEndDebugUtilsLabelEXT' : 'EndQueueDebugUtilsLabel(layer_data->report_data, queue);', 189*b7893ccfSSadaf Ebrahimi 'vkCreateDebugReportCallbackEXT' : 'layer_create_report_callback(layer_data->report_data, false, pCreateInfo, pAllocator, pCallback);', 190*b7893ccfSSadaf Ebrahimi 'vkDestroyDebugReportCallbackEXT' : 'layer_destroy_report_callback(layer_data->report_data, callback, pAllocator);', 191*b7893ccfSSadaf Ebrahimi 'vkCreateDebugUtilsMessengerEXT' : 'layer_create_messenger_callback(layer_data->report_data, false, pCreateInfo, pAllocator, pMessenger);', 192*b7893ccfSSadaf Ebrahimi 'vkDestroyDebugUtilsMessengerEXT' : 'layer_destroy_messenger_callback(layer_data->report_data, messenger, pAllocator);', 193*b7893ccfSSadaf Ebrahimi } 194*b7893ccfSSadaf Ebrahimi 195*b7893ccfSSadaf Ebrahimi precallvalidate_loop = "for (auto intercept : layer_data->object_dispatch) {" 196*b7893ccfSSadaf Ebrahimi precallrecord_loop = precallvalidate_loop 197*b7893ccfSSadaf Ebrahimi postcallrecord_loop = "for (auto intercept : layer_data->object_dispatch) {" 198*b7893ccfSSadaf Ebrahimi 199*b7893ccfSSadaf Ebrahimi inline_custom_header_preamble = """ 200*b7893ccfSSadaf Ebrahimi#define NOMINMAX 201*b7893ccfSSadaf Ebrahimi#include <atomic> 202*b7893ccfSSadaf Ebrahimi#include <mutex> 203*b7893ccfSSadaf Ebrahimi#include <cinttypes> 204*b7893ccfSSadaf Ebrahimi#include <stdio.h> 205*b7893ccfSSadaf Ebrahimi#include <stdlib.h> 206*b7893ccfSSadaf Ebrahimi#include <string.h> 207*b7893ccfSSadaf Ebrahimi#include <unordered_map> 208*b7893ccfSSadaf Ebrahimi#include <unordered_set> 209*b7893ccfSSadaf Ebrahimi#include <algorithm> 210*b7893ccfSSadaf Ebrahimi#include <memory> 211*b7893ccfSSadaf Ebrahimi 212*b7893ccfSSadaf Ebrahimi#include "vk_loader_platform.h" 213*b7893ccfSSadaf Ebrahimi#include "vulkan/vulkan.h" 214*b7893ccfSSadaf Ebrahimi#include "vk_layer_config.h" 215*b7893ccfSSadaf Ebrahimi#include "vk_layer_data.h" 216*b7893ccfSSadaf Ebrahimi#include "vk_layer_logging.h" 217*b7893ccfSSadaf Ebrahimi#include "vk_object_types.h" 218*b7893ccfSSadaf Ebrahimi#include "vulkan/vk_layer.h" 219*b7893ccfSSadaf Ebrahimi#include "vk_enum_string_helper.h" 220*b7893ccfSSadaf Ebrahimi#include "vk_layer_extension_utils.h" 221*b7893ccfSSadaf Ebrahimi#include "vk_layer_utils.h" 222*b7893ccfSSadaf Ebrahimi#include "vulkan/vk_layer.h" 223*b7893ccfSSadaf Ebrahimi#include "vk_dispatch_table_helper.h" 224*b7893ccfSSadaf Ebrahimi#include "vk_extension_helper.h" 225*b7893ccfSSadaf Ebrahimi#include "vk_safe_struct.h" 226*b7893ccfSSadaf Ebrahimi#include "vk_typemap_helper.h" 227*b7893ccfSSadaf Ebrahimi 228*b7893ccfSSadaf Ebrahimi 229*b7893ccfSSadaf Ebrahimiextern std::atomic<uint64_t> global_unique_id; 230*b7893ccfSSadaf Ebrahimiextern vl_concurrent_unordered_map<uint64_t, uint64_t, 4> unique_id_mapping; 231*b7893ccfSSadaf Ebrahimi""" 232*b7893ccfSSadaf Ebrahimi 233*b7893ccfSSadaf Ebrahimi inline_custom_header_class_definition = """ 234*b7893ccfSSadaf Ebrahimi 235*b7893ccfSSadaf Ebrahimi// Layer object type identifiers 236*b7893ccfSSadaf Ebrahimienum LayerObjectTypeId { 237*b7893ccfSSadaf Ebrahimi LayerObjectTypeInstance, // Container for an instance dispatch object 238*b7893ccfSSadaf Ebrahimi LayerObjectTypeDevice, // Container for a device dispatch object 239*b7893ccfSSadaf Ebrahimi LayerObjectTypeThreading, // Instance or device threading layer object 240*b7893ccfSSadaf Ebrahimi LayerObjectTypeParameterValidation, // Instance or device parameter validation layer object 241*b7893ccfSSadaf Ebrahimi LayerObjectTypeObjectTracker, // Instance or device object tracker layer object 242*b7893ccfSSadaf Ebrahimi LayerObjectTypeCoreValidation, // Instance or device core validation layer object 243*b7893ccfSSadaf Ebrahimi LayerObjectTypeBestPractices, // Instance or device best practices layer object 244*b7893ccfSSadaf Ebrahimi}; 245*b7893ccfSSadaf Ebrahimi 246*b7893ccfSSadaf Ebrahimistruct TEMPLATE_STATE { 247*b7893ccfSSadaf Ebrahimi VkDescriptorUpdateTemplateKHR desc_update_template; 248*b7893ccfSSadaf Ebrahimi safe_VkDescriptorUpdateTemplateCreateInfo create_info; 249*b7893ccfSSadaf Ebrahimi 250*b7893ccfSSadaf Ebrahimi TEMPLATE_STATE(VkDescriptorUpdateTemplateKHR update_template, safe_VkDescriptorUpdateTemplateCreateInfo *pCreateInfo) 251*b7893ccfSSadaf Ebrahimi : desc_update_template(update_template), create_info(*pCreateInfo) {} 252*b7893ccfSSadaf Ebrahimi}; 253*b7893ccfSSadaf Ebrahimi 254*b7893ccfSSadaf Ebrahimiclass LAYER_PHYS_DEV_PROPERTIES { 255*b7893ccfSSadaf Ebrahimipublic: 256*b7893ccfSSadaf Ebrahimi VkPhysicalDeviceProperties properties; 257*b7893ccfSSadaf Ebrahimi std::vector<VkQueueFamilyProperties> queue_family_properties; 258*b7893ccfSSadaf Ebrahimi}; 259*b7893ccfSSadaf Ebrahimi 260*b7893ccfSSadaf Ebrahimitypedef enum ValidationCheckDisables { 261*b7893ccfSSadaf Ebrahimi VALIDATION_CHECK_DISABLE_COMMAND_BUFFER_STATE, 262*b7893ccfSSadaf Ebrahimi VALIDATION_CHECK_DISABLE_OBJECT_IN_USE, 263*b7893ccfSSadaf Ebrahimi VALIDATION_CHECK_DISABLE_IDLE_DESCRIPTOR_SET, 264*b7893ccfSSadaf Ebrahimi VALIDATION_CHECK_DISABLE_PUSH_CONSTANT_RANGE, 265*b7893ccfSSadaf Ebrahimi VALIDATION_CHECK_DISABLE_QUERY_VALIDATION, 266*b7893ccfSSadaf Ebrahimi VALIDATION_CHECK_DISABLE_IMAGE_LAYOUT_VALIDATION, 267*b7893ccfSSadaf Ebrahimi} ValidationCheckDisables; 268*b7893ccfSSadaf Ebrahimi 269*b7893ccfSSadaf Ebrahimitypedef enum VkValidationFeatureEnable { 270*b7893ccfSSadaf Ebrahimi VK_VALIDATION_FEATURE_ENABLE_BEST_PRACTICES, 271*b7893ccfSSadaf Ebrahimi} VkValidationFeatureEnable; 272*b7893ccfSSadaf Ebrahimi 273*b7893ccfSSadaf Ebrahimi 274*b7893ccfSSadaf Ebrahimi// CHECK_DISABLED struct is a container for bools that can block validation checks from being performed. 275*b7893ccfSSadaf Ebrahimi// These bools are all "false" by default meaning that all checks are enabled. Enum values can be specified 276*b7893ccfSSadaf Ebrahimi// via the vk_layer_setting.txt config file or at CreateInstance time via the VK_EXT_validation_features extension 277*b7893ccfSSadaf Ebrahimi// that can selectively disable checks. 278*b7893ccfSSadaf Ebrahimistruct CHECK_DISABLED { 279*b7893ccfSSadaf Ebrahimi bool command_buffer_state; // Skip command buffer state validation 280*b7893ccfSSadaf Ebrahimi bool object_in_use; // Skip all object in_use checking 281*b7893ccfSSadaf Ebrahimi bool idle_descriptor_set; // Skip check to verify that descriptor set is not in-use 282*b7893ccfSSadaf Ebrahimi bool push_constant_range; // Skip push constant range checks 283*b7893ccfSSadaf Ebrahimi bool query_validation; // Disable all core validation query-related checks 284*b7893ccfSSadaf Ebrahimi bool image_layout_validation; // Disable image layout validation 285*b7893ccfSSadaf Ebrahimi bool object_tracking; // Disable object lifetime validation 286*b7893ccfSSadaf Ebrahimi bool core_checks; // Disable core validation checks 287*b7893ccfSSadaf Ebrahimi bool thread_safety; // Disable thread safety validation 288*b7893ccfSSadaf Ebrahimi bool stateless_checks; // Disable stateless validation checks 289*b7893ccfSSadaf Ebrahimi bool handle_wrapping; // Disable unique handles/handle wrapping 290*b7893ccfSSadaf Ebrahimi bool shader_validation; // Skip validation for shaders 291*b7893ccfSSadaf Ebrahimi 292*b7893ccfSSadaf Ebrahimi void SetAll(bool value) { std::fill(&command_buffer_state, &shader_validation + 1, value); } 293*b7893ccfSSadaf Ebrahimi}; 294*b7893ccfSSadaf Ebrahimi 295*b7893ccfSSadaf Ebrahimistruct CHECK_ENABLED { 296*b7893ccfSSadaf Ebrahimi bool gpu_validation; 297*b7893ccfSSadaf Ebrahimi bool gpu_validation_reserve_binding_slot; 298*b7893ccfSSadaf Ebrahimi bool best_practices; 299*b7893ccfSSadaf Ebrahimi 300*b7893ccfSSadaf Ebrahimi void SetAll(bool value) { std::fill(&gpu_validation, &gpu_validation_reserve_binding_slot + 1, value); } 301*b7893ccfSSadaf Ebrahimi}; 302*b7893ccfSSadaf Ebrahimi 303*b7893ccfSSadaf Ebrahimi// Layer chassis validation object base class definition 304*b7893ccfSSadaf Ebrahimiclass ValidationObject { 305*b7893ccfSSadaf Ebrahimi public: 306*b7893ccfSSadaf Ebrahimi uint32_t api_version; 307*b7893ccfSSadaf Ebrahimi debug_report_data* report_data = nullptr; 308*b7893ccfSSadaf Ebrahimi std::vector<VkDebugReportCallbackEXT> logging_callback; 309*b7893ccfSSadaf Ebrahimi std::vector<VkDebugUtilsMessengerEXT> logging_messenger; 310*b7893ccfSSadaf Ebrahimi 311*b7893ccfSSadaf Ebrahimi VkLayerInstanceDispatchTable instance_dispatch_table; 312*b7893ccfSSadaf Ebrahimi VkLayerDispatchTable device_dispatch_table; 313*b7893ccfSSadaf Ebrahimi 314*b7893ccfSSadaf Ebrahimi InstanceExtensions instance_extensions; 315*b7893ccfSSadaf Ebrahimi DeviceExtensions device_extensions = {}; 316*b7893ccfSSadaf Ebrahimi CHECK_DISABLED disabled = {}; 317*b7893ccfSSadaf Ebrahimi CHECK_ENABLED enabled = {}; 318*b7893ccfSSadaf Ebrahimi 319*b7893ccfSSadaf Ebrahimi VkInstance instance = VK_NULL_HANDLE; 320*b7893ccfSSadaf Ebrahimi VkPhysicalDevice physical_device = VK_NULL_HANDLE; 321*b7893ccfSSadaf Ebrahimi VkDevice device = VK_NULL_HANDLE; 322*b7893ccfSSadaf Ebrahimi LAYER_PHYS_DEV_PROPERTIES phys_dev_properties = {}; 323*b7893ccfSSadaf Ebrahimi 324*b7893ccfSSadaf Ebrahimi std::vector<ValidationObject*> object_dispatch; 325*b7893ccfSSadaf Ebrahimi LayerObjectTypeId container_type; 326*b7893ccfSSadaf Ebrahimi 327*b7893ccfSSadaf Ebrahimi std::string layer_name = "CHASSIS"; 328*b7893ccfSSadaf Ebrahimi 329*b7893ccfSSadaf Ebrahimi // Constructor 330*b7893ccfSSadaf Ebrahimi ValidationObject(){}; 331*b7893ccfSSadaf Ebrahimi // Destructor 332*b7893ccfSSadaf Ebrahimi virtual ~ValidationObject() {}; 333*b7893ccfSSadaf Ebrahimi 334*b7893ccfSSadaf Ebrahimi std::mutex validation_object_mutex; 335*b7893ccfSSadaf Ebrahimi virtual std::unique_lock<std::mutex> write_lock() { 336*b7893ccfSSadaf Ebrahimi return std::unique_lock<std::mutex>(validation_object_mutex); 337*b7893ccfSSadaf Ebrahimi } 338*b7893ccfSSadaf Ebrahimi 339*b7893ccfSSadaf Ebrahimi ValidationObject* GetValidationObject(std::vector<ValidationObject*>& object_dispatch, LayerObjectTypeId object_type) { 340*b7893ccfSSadaf Ebrahimi for (auto validation_object : object_dispatch) { 341*b7893ccfSSadaf Ebrahimi if (validation_object->container_type == object_type) { 342*b7893ccfSSadaf Ebrahimi return validation_object; 343*b7893ccfSSadaf Ebrahimi } 344*b7893ccfSSadaf Ebrahimi } 345*b7893ccfSSadaf Ebrahimi return nullptr; 346*b7893ccfSSadaf Ebrahimi }; 347*b7893ccfSSadaf Ebrahimi 348*b7893ccfSSadaf Ebrahimi // Handle Wrapping Data 349*b7893ccfSSadaf Ebrahimi // Reverse map display handles 350*b7893ccfSSadaf Ebrahimi vl_concurrent_unordered_map<VkDisplayKHR, uint64_t, 0> display_id_reverse_mapping; 351*b7893ccfSSadaf Ebrahimi // Wrapping Descriptor Template Update structures requires access to the template createinfo structs 352*b7893ccfSSadaf Ebrahimi std::unordered_map<uint64_t, std::unique_ptr<TEMPLATE_STATE>> desc_template_createinfo_map; 353*b7893ccfSSadaf Ebrahimi struct SubpassesUsageStates { 354*b7893ccfSSadaf Ebrahimi std::unordered_set<uint32_t> subpasses_using_color_attachment; 355*b7893ccfSSadaf Ebrahimi std::unordered_set<uint32_t> subpasses_using_depthstencil_attachment; 356*b7893ccfSSadaf Ebrahimi }; 357*b7893ccfSSadaf Ebrahimi // Uses unwrapped handles 358*b7893ccfSSadaf Ebrahimi std::unordered_map<VkRenderPass, SubpassesUsageStates> renderpasses_states; 359*b7893ccfSSadaf Ebrahimi // Map of wrapped swapchain handles to arrays of wrapped swapchain image IDs 360*b7893ccfSSadaf Ebrahimi // Each swapchain has an immutable list of wrapped swapchain image IDs -- always return these IDs if they exist 361*b7893ccfSSadaf Ebrahimi std::unordered_map<VkSwapchainKHR, std::vector<VkImage>> swapchain_wrapped_image_handle_map; 362*b7893ccfSSadaf Ebrahimi // Map of wrapped descriptor pools to set of wrapped descriptor sets allocated from each pool 363*b7893ccfSSadaf Ebrahimi std::unordered_map<VkDescriptorPool, std::unordered_set<VkDescriptorSet>> pool_descriptor_sets_map; 364*b7893ccfSSadaf Ebrahimi 365*b7893ccfSSadaf Ebrahimi 366*b7893ccfSSadaf Ebrahimi // Unwrap a handle. 367*b7893ccfSSadaf Ebrahimi template <typename HandleType> 368*b7893ccfSSadaf Ebrahimi HandleType Unwrap(HandleType wrappedHandle) { 369*b7893ccfSSadaf Ebrahimi auto iter = unique_id_mapping.find(reinterpret_cast<uint64_t const &>(wrappedHandle)); 370*b7893ccfSSadaf Ebrahimi if (iter == unique_id_mapping.end()) 371*b7893ccfSSadaf Ebrahimi return (HandleType)0; 372*b7893ccfSSadaf Ebrahimi return (HandleType)iter->second; 373*b7893ccfSSadaf Ebrahimi } 374*b7893ccfSSadaf Ebrahimi 375*b7893ccfSSadaf Ebrahimi // Wrap a newly created handle with a new unique ID, and return the new ID. 376*b7893ccfSSadaf Ebrahimi template <typename HandleType> 377*b7893ccfSSadaf Ebrahimi HandleType WrapNew(HandleType newlyCreatedHandle) { 378*b7893ccfSSadaf Ebrahimi auto unique_id = global_unique_id++; 379*b7893ccfSSadaf Ebrahimi unique_id_mapping.insert_or_assign(unique_id, reinterpret_cast<uint64_t const &>(newlyCreatedHandle)); 380*b7893ccfSSadaf Ebrahimi return (HandleType)unique_id; 381*b7893ccfSSadaf Ebrahimi } 382*b7893ccfSSadaf Ebrahimi 383*b7893ccfSSadaf Ebrahimi // Specialized handling for VkDisplayKHR. Adds an entry to enable reverse-lookup. 384*b7893ccfSSadaf Ebrahimi VkDisplayKHR WrapDisplay(VkDisplayKHR newlyCreatedHandle, ValidationObject *map_data) { 385*b7893ccfSSadaf Ebrahimi auto unique_id = global_unique_id++; 386*b7893ccfSSadaf Ebrahimi unique_id_mapping.insert_or_assign(unique_id, reinterpret_cast<uint64_t const &>(newlyCreatedHandle)); 387*b7893ccfSSadaf Ebrahimi map_data->display_id_reverse_mapping.insert_or_assign(newlyCreatedHandle, unique_id); 388*b7893ccfSSadaf Ebrahimi return (VkDisplayKHR)unique_id; 389*b7893ccfSSadaf Ebrahimi } 390*b7893ccfSSadaf Ebrahimi 391*b7893ccfSSadaf Ebrahimi // VkDisplayKHR objects don't have a single point of creation, so we need to see if one already exists in the map before 392*b7893ccfSSadaf Ebrahimi // creating another. 393*b7893ccfSSadaf Ebrahimi VkDisplayKHR MaybeWrapDisplay(VkDisplayKHR handle, ValidationObject *map_data) { 394*b7893ccfSSadaf Ebrahimi // See if this display is already known 395*b7893ccfSSadaf Ebrahimi auto it = map_data->display_id_reverse_mapping.find(handle); 396*b7893ccfSSadaf Ebrahimi if (it != map_data->display_id_reverse_mapping.end()) return (VkDisplayKHR)it->second; 397*b7893ccfSSadaf Ebrahimi // Unknown, so wrap 398*b7893ccfSSadaf Ebrahimi return WrapDisplay(handle, map_data); 399*b7893ccfSSadaf Ebrahimi } 400*b7893ccfSSadaf Ebrahimi 401*b7893ccfSSadaf Ebrahimi // Pre/post hook point declarations 402*b7893ccfSSadaf Ebrahimi""" 403*b7893ccfSSadaf Ebrahimi 404*b7893ccfSSadaf Ebrahimi inline_copyright_message = """ 405*b7893ccfSSadaf Ebrahimi// This file is ***GENERATED***. Do Not Edit. 406*b7893ccfSSadaf Ebrahimi// See layer_chassis_generator.py for modifications. 407*b7893ccfSSadaf Ebrahimi 408*b7893ccfSSadaf Ebrahimi/* Copyright (c) 2015-2019 The Khronos Group Inc. 409*b7893ccfSSadaf Ebrahimi * Copyright (c) 2015-2019 Valve Corporation 410*b7893ccfSSadaf Ebrahimi * Copyright (c) 2015-2019 LunarG, Inc. 411*b7893ccfSSadaf Ebrahimi * Copyright (c) 2015-2019 Google Inc. 412*b7893ccfSSadaf Ebrahimi * 413*b7893ccfSSadaf Ebrahimi * Licensed under the Apache License, Version 2.0 (the "License"); 414*b7893ccfSSadaf Ebrahimi * you may not use this file except in compliance with the License. 415*b7893ccfSSadaf Ebrahimi * You may obtain a copy of the License at 416*b7893ccfSSadaf Ebrahimi * 417*b7893ccfSSadaf Ebrahimi * http://www.apache.org/licenses/LICENSE-2.0 418*b7893ccfSSadaf Ebrahimi * 419*b7893ccfSSadaf Ebrahimi * Unless required by applicable law or agreed to in writing, software 420*b7893ccfSSadaf Ebrahimi * distributed under the License is distributed on an "AS IS" BASIS, 421*b7893ccfSSadaf Ebrahimi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 422*b7893ccfSSadaf Ebrahimi * See the License for the specific language governing permissions and 423*b7893ccfSSadaf Ebrahimi * limitations under the License. 424*b7893ccfSSadaf Ebrahimi * 425*b7893ccfSSadaf Ebrahimi * Author: Mark Lobodzinski <[email protected]> 426*b7893ccfSSadaf Ebrahimi */""" 427*b7893ccfSSadaf Ebrahimi 428*b7893ccfSSadaf Ebrahimi inline_custom_source_preamble = """ 429*b7893ccfSSadaf Ebrahimi 430*b7893ccfSSadaf Ebrahimi#include <string.h> 431*b7893ccfSSadaf Ebrahimi#include <mutex> 432*b7893ccfSSadaf Ebrahimi 433*b7893ccfSSadaf Ebrahimi#define VALIDATION_ERROR_MAP_IMPL 434*b7893ccfSSadaf Ebrahimi 435*b7893ccfSSadaf Ebrahimi#include "chassis.h" 436*b7893ccfSSadaf Ebrahimi#include "layer_chassis_dispatch.h" 437*b7893ccfSSadaf Ebrahimi 438*b7893ccfSSadaf Ebrahimistd::unordered_map<void*, ValidationObject*> layer_data_map; 439*b7893ccfSSadaf Ebrahimi 440*b7893ccfSSadaf Ebrahimi// Global unique object identifier. 441*b7893ccfSSadaf Ebrahimistd::atomic<uint64_t> global_unique_id(1ULL); 442*b7893ccfSSadaf Ebrahimi// Map uniqueID to actual object handle. Accesses to the map itself are 443*b7893ccfSSadaf Ebrahimi// internally synchronized. 444*b7893ccfSSadaf Ebrahimivl_concurrent_unordered_map<uint64_t, uint64_t, 4> unique_id_mapping; 445*b7893ccfSSadaf Ebrahimi 446*b7893ccfSSadaf Ebrahimi// TODO: This variable controls handle wrapping -- in the future it should be hooked 447*b7893ccfSSadaf Ebrahimi// up to the new VALIDATION_FEATURES extension. Temporarily, control with a compile-time flag. 448*b7893ccfSSadaf Ebrahimi#if defined(LAYER_CHASSIS_CAN_WRAP_HANDLES) 449*b7893ccfSSadaf Ebrahimibool wrap_handles = true; 450*b7893ccfSSadaf Ebrahimi#else 451*b7893ccfSSadaf Ebrahimibool wrap_handles = false; 452*b7893ccfSSadaf Ebrahimi#endif 453*b7893ccfSSadaf Ebrahimi 454*b7893ccfSSadaf Ebrahimi// Set layer name -- Khronos layer name overrides any other defined names 455*b7893ccfSSadaf Ebrahimi#if BUILD_KHRONOS_VALIDATION 456*b7893ccfSSadaf Ebrahimi#define OBJECT_LAYER_NAME "VK_LAYER_KHRONOS_validation" 457*b7893ccfSSadaf Ebrahimi#define OBJECT_LAYER_DESCRIPTION "khronos_validation" 458*b7893ccfSSadaf Ebrahimi#elif BUILD_OBJECT_TRACKER 459*b7893ccfSSadaf Ebrahimi#define OBJECT_LAYER_NAME "VK_LAYER_LUNARG_object_tracker" 460*b7893ccfSSadaf Ebrahimi#define OBJECT_LAYER_DESCRIPTION "lunarg_object_tracker" 461*b7893ccfSSadaf Ebrahimi#elif BUILD_THREAD_SAFETY 462*b7893ccfSSadaf Ebrahimi#define OBJECT_LAYER_NAME "VK_LAYER_GOOGLE_threading" 463*b7893ccfSSadaf Ebrahimi#define OBJECT_LAYER_DESCRIPTION "google_thread_checker" 464*b7893ccfSSadaf Ebrahimi#elif BUILD_PARAMETER_VALIDATION 465*b7893ccfSSadaf Ebrahimi#define OBJECT_LAYER_NAME "VK_LAYER_LUNARG_parameter_validation" 466*b7893ccfSSadaf Ebrahimi#define OBJECT_LAYER_DESCRIPTION "lunarg_parameter_validation" 467*b7893ccfSSadaf Ebrahimi#elif BUILD_CORE_VALIDATION 468*b7893ccfSSadaf Ebrahimi#define OBJECT_LAYER_NAME "VK_LAYER_LUNARG_core_validation" 469*b7893ccfSSadaf Ebrahimi#define OBJECT_LAYER_DESCRIPTION "lunarg_core_validation" 470*b7893ccfSSadaf Ebrahimi#else 471*b7893ccfSSadaf Ebrahimi#define OBJECT_LAYER_NAME "VK_LAYER_GOOGLE_unique_objects" 472*b7893ccfSSadaf Ebrahimi#define OBJECT_LAYER_DESCRIPTION "lunarg_unique_objects" 473*b7893ccfSSadaf Ebrahimi#endif 474*b7893ccfSSadaf Ebrahimi 475*b7893ccfSSadaf Ebrahimi// Include layer validation object definitions 476*b7893ccfSSadaf Ebrahimi#if BUILD_OBJECT_TRACKER 477*b7893ccfSSadaf Ebrahimi#include "object_lifetime_validation.h" 478*b7893ccfSSadaf Ebrahimi#endif 479*b7893ccfSSadaf Ebrahimi#if BUILD_THREAD_SAFETY 480*b7893ccfSSadaf Ebrahimi#include "thread_safety.h" 481*b7893ccfSSadaf Ebrahimi#endif 482*b7893ccfSSadaf Ebrahimi#if BUILD_PARAMETER_VALIDATION 483*b7893ccfSSadaf Ebrahimi#include "stateless_validation.h" 484*b7893ccfSSadaf Ebrahimi#endif 485*b7893ccfSSadaf Ebrahimi#if BUILD_CORE_VALIDATION 486*b7893ccfSSadaf Ebrahimi#include "core_validation.h" 487*b7893ccfSSadaf Ebrahimi#endif 488*b7893ccfSSadaf Ebrahimi#if BUILD_BEST_PRACTICES 489*b7893ccfSSadaf Ebrahimi#include "best_practices.h" 490*b7893ccfSSadaf Ebrahimi#endif 491*b7893ccfSSadaf Ebrahimi 492*b7893ccfSSadaf Ebrahiminamespace vulkan_layer_chassis { 493*b7893ccfSSadaf Ebrahimi 494*b7893ccfSSadaf Ebrahimiusing std::unordered_map; 495*b7893ccfSSadaf Ebrahimi 496*b7893ccfSSadaf Ebrahimistatic const VkLayerProperties global_layer = { 497*b7893ccfSSadaf Ebrahimi OBJECT_LAYER_NAME, VK_LAYER_API_VERSION, 1, "LunarG validation Layer", 498*b7893ccfSSadaf Ebrahimi}; 499*b7893ccfSSadaf Ebrahimi 500*b7893ccfSSadaf Ebrahimistatic const VkExtensionProperties instance_extensions[] = {{VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION}, 501*b7893ccfSSadaf Ebrahimi {VK_EXT_DEBUG_UTILS_EXTENSION_NAME, VK_EXT_DEBUG_UTILS_SPEC_VERSION}}; 502*b7893ccfSSadaf Ebrahimistatic const VkExtensionProperties device_extensions[] = { 503*b7893ccfSSadaf Ebrahimi {VK_EXT_VALIDATION_CACHE_EXTENSION_NAME, VK_EXT_VALIDATION_CACHE_SPEC_VERSION}, 504*b7893ccfSSadaf Ebrahimi {VK_EXT_DEBUG_MARKER_EXTENSION_NAME, VK_EXT_DEBUG_MARKER_SPEC_VERSION}, 505*b7893ccfSSadaf Ebrahimi}; 506*b7893ccfSSadaf Ebrahimi 507*b7893ccfSSadaf Ebrahimitypedef struct { 508*b7893ccfSSadaf Ebrahimi bool is_instance_api; 509*b7893ccfSSadaf Ebrahimi void* funcptr; 510*b7893ccfSSadaf Ebrahimi} function_data; 511*b7893ccfSSadaf Ebrahimi 512*b7893ccfSSadaf Ebrahimiextern const std::unordered_map<std::string, function_data> name_to_funcptr_map; 513*b7893ccfSSadaf Ebrahimi 514*b7893ccfSSadaf Ebrahimi// Manually written functions 515*b7893ccfSSadaf Ebrahimi 516*b7893ccfSSadaf Ebrahimi// Check enabled instance extensions against supported instance extension whitelist 517*b7893ccfSSadaf Ebrahimistatic void InstanceExtensionWhitelist(ValidationObject *layer_data, const VkInstanceCreateInfo *pCreateInfo, VkInstance instance) { 518*b7893ccfSSadaf Ebrahimi for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) { 519*b7893ccfSSadaf Ebrahimi // Check for recognized instance extensions 520*b7893ccfSSadaf Ebrahimi if (!white_list(pCreateInfo->ppEnabledExtensionNames[i], kInstanceExtensionNames)) { 521*b7893ccfSSadaf Ebrahimi log_msg(layer_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 522*b7893ccfSSadaf Ebrahimi kVUIDUndefined, 523*b7893ccfSSadaf Ebrahimi "Instance Extension %s is not supported by this layer. Using this extension may adversely affect validation " 524*b7893ccfSSadaf Ebrahimi "results and/or produce undefined behavior.", 525*b7893ccfSSadaf Ebrahimi pCreateInfo->ppEnabledExtensionNames[i]); 526*b7893ccfSSadaf Ebrahimi } 527*b7893ccfSSadaf Ebrahimi } 528*b7893ccfSSadaf Ebrahimi} 529*b7893ccfSSadaf Ebrahimi 530*b7893ccfSSadaf Ebrahimi// Check enabled device extensions against supported device extension whitelist 531*b7893ccfSSadaf Ebrahimistatic void DeviceExtensionWhitelist(ValidationObject *layer_data, const VkDeviceCreateInfo *pCreateInfo, VkDevice device) { 532*b7893ccfSSadaf Ebrahimi for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) { 533*b7893ccfSSadaf Ebrahimi // Check for recognized device extensions 534*b7893ccfSSadaf Ebrahimi if (!white_list(pCreateInfo->ppEnabledExtensionNames[i], kDeviceExtensionNames)) { 535*b7893ccfSSadaf Ebrahimi log_msg(layer_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 536*b7893ccfSSadaf Ebrahimi kVUIDUndefined, 537*b7893ccfSSadaf Ebrahimi "Device Extension %s is not supported by this layer. Using this extension may adversely affect validation " 538*b7893ccfSSadaf Ebrahimi "results and/or produce undefined behavior.", 539*b7893ccfSSadaf Ebrahimi pCreateInfo->ppEnabledExtensionNames[i]); 540*b7893ccfSSadaf Ebrahimi } 541*b7893ccfSSadaf Ebrahimi } 542*b7893ccfSSadaf Ebrahimi} 543*b7893ccfSSadaf Ebrahimi 544*b7893ccfSSadaf Ebrahimi 545*b7893ccfSSadaf Ebrahimi// Process validation features, flags and settings specified through extensions, a layer settings file, or environment variables 546*b7893ccfSSadaf Ebrahimi 547*b7893ccfSSadaf Ebrahimistatic const std::unordered_map<std::string, VkValidationFeatureDisableEXT> VkValFeatureDisableLookup = { 548*b7893ccfSSadaf Ebrahimi {"VK_VALIDATION_FEATURE_DISABLE_SHADERS_EXT", VK_VALIDATION_FEATURE_DISABLE_SHADERS_EXT}, 549*b7893ccfSSadaf Ebrahimi {"VK_VALIDATION_FEATURE_DISABLE_THREAD_SAFETY_EXT", VK_VALIDATION_FEATURE_DISABLE_THREAD_SAFETY_EXT}, 550*b7893ccfSSadaf Ebrahimi {"VK_VALIDATION_FEATURE_DISABLE_API_PARAMETERS_EXT", VK_VALIDATION_FEATURE_DISABLE_API_PARAMETERS_EXT}, 551*b7893ccfSSadaf Ebrahimi {"VK_VALIDATION_FEATURE_DISABLE_OBJECT_LIFETIMES_EXT", VK_VALIDATION_FEATURE_DISABLE_OBJECT_LIFETIMES_EXT}, 552*b7893ccfSSadaf Ebrahimi {"VK_VALIDATION_FEATURE_DISABLE_CORE_CHECKS_EXT", VK_VALIDATION_FEATURE_DISABLE_CORE_CHECKS_EXT}, 553*b7893ccfSSadaf Ebrahimi {"VK_VALIDATION_FEATURE_DISABLE_UNIQUE_HANDLES_EXT", VK_VALIDATION_FEATURE_DISABLE_UNIQUE_HANDLES_EXT}, 554*b7893ccfSSadaf Ebrahimi {"VK_VALIDATION_FEATURE_DISABLE_ALL_EXT", VK_VALIDATION_FEATURE_DISABLE_ALL_EXT}, 555*b7893ccfSSadaf Ebrahimi}; 556*b7893ccfSSadaf Ebrahimi 557*b7893ccfSSadaf Ebrahimistatic const std::unordered_map<std::string, VkValidationFeatureEnableEXT> VkValFeatureEnableLookup = { 558*b7893ccfSSadaf Ebrahimi {"VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT", VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT}, 559*b7893ccfSSadaf Ebrahimi {"VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT", VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT}, 560*b7893ccfSSadaf Ebrahimi}; 561*b7893ccfSSadaf Ebrahimi 562*b7893ccfSSadaf Ebrahimistatic const std::unordered_map<std::string, VkValidationFeatureEnable> VkValFeatureEnableLookup2 = { 563*b7893ccfSSadaf Ebrahimi {"VK_VALIDATION_FEATURE_ENABLE_BEST_PRACTICES", VK_VALIDATION_FEATURE_ENABLE_BEST_PRACTICES}, 564*b7893ccfSSadaf Ebrahimi}; 565*b7893ccfSSadaf Ebrahimi 566*b7893ccfSSadaf Ebrahimistatic const std::unordered_map<std::string, ValidationCheckDisables> ValidationDisableLookup = { 567*b7893ccfSSadaf Ebrahimi {"VALIDATION_CHECK_DISABLE_COMMAND_BUFFER_STATE", VALIDATION_CHECK_DISABLE_COMMAND_BUFFER_STATE}, 568*b7893ccfSSadaf Ebrahimi {"VALIDATION_CHECK_DISABLE_OBJECT_IN_USE", VALIDATION_CHECK_DISABLE_OBJECT_IN_USE}, 569*b7893ccfSSadaf Ebrahimi {"VALIDATION_CHECK_DISABLE_IDLE_DESCRIPTOR_SET", VALIDATION_CHECK_DISABLE_IDLE_DESCRIPTOR_SET}, 570*b7893ccfSSadaf Ebrahimi {"VALIDATION_CHECK_DISABLE_PUSH_CONSTANT_RANGE", VALIDATION_CHECK_DISABLE_PUSH_CONSTANT_RANGE}, 571*b7893ccfSSadaf Ebrahimi {"VALIDATION_CHECK_DISABLE_QUERY_VALIDATION", VALIDATION_CHECK_DISABLE_QUERY_VALIDATION}, 572*b7893ccfSSadaf Ebrahimi {"VALIDATION_CHECK_DISABLE_IMAGE_LAYOUT_VALIDATION", VALIDATION_CHECK_DISABLE_IMAGE_LAYOUT_VALIDATION}, 573*b7893ccfSSadaf Ebrahimi}; 574*b7893ccfSSadaf Ebrahimi 575*b7893ccfSSadaf Ebrahimi// Set the local disable flag for the appropriate VALIDATION_CHECK_DISABLE enum 576*b7893ccfSSadaf Ebrahimivoid SetValidationDisable(CHECK_DISABLED* disable_data, const ValidationCheckDisables disable_id) { 577*b7893ccfSSadaf Ebrahimi switch (disable_id) { 578*b7893ccfSSadaf Ebrahimi case VALIDATION_CHECK_DISABLE_COMMAND_BUFFER_STATE: 579*b7893ccfSSadaf Ebrahimi disable_data->command_buffer_state = true; 580*b7893ccfSSadaf Ebrahimi break; 581*b7893ccfSSadaf Ebrahimi case VALIDATION_CHECK_DISABLE_OBJECT_IN_USE: 582*b7893ccfSSadaf Ebrahimi disable_data->object_in_use = true; 583*b7893ccfSSadaf Ebrahimi break; 584*b7893ccfSSadaf Ebrahimi case VALIDATION_CHECK_DISABLE_IDLE_DESCRIPTOR_SET: 585*b7893ccfSSadaf Ebrahimi disable_data->idle_descriptor_set = true; 586*b7893ccfSSadaf Ebrahimi break; 587*b7893ccfSSadaf Ebrahimi case VALIDATION_CHECK_DISABLE_PUSH_CONSTANT_RANGE: 588*b7893ccfSSadaf Ebrahimi disable_data->push_constant_range = true; 589*b7893ccfSSadaf Ebrahimi break; 590*b7893ccfSSadaf Ebrahimi case VALIDATION_CHECK_DISABLE_QUERY_VALIDATION: 591*b7893ccfSSadaf Ebrahimi disable_data->query_validation = true; 592*b7893ccfSSadaf Ebrahimi break; 593*b7893ccfSSadaf Ebrahimi case VALIDATION_CHECK_DISABLE_IMAGE_LAYOUT_VALIDATION: 594*b7893ccfSSadaf Ebrahimi disable_data->image_layout_validation = true; 595*b7893ccfSSadaf Ebrahimi break; 596*b7893ccfSSadaf Ebrahimi default: 597*b7893ccfSSadaf Ebrahimi assert(true); 598*b7893ccfSSadaf Ebrahimi } 599*b7893ccfSSadaf Ebrahimi} 600*b7893ccfSSadaf Ebrahimi 601*b7893ccfSSadaf Ebrahimi// Set the local disable flag for a single VK_VALIDATION_FEATURE_DISABLE_* flag 602*b7893ccfSSadaf Ebrahimivoid SetValidationFeatureDisable(CHECK_DISABLED* disable_data, const VkValidationFeatureDisableEXT feature_disable) { 603*b7893ccfSSadaf Ebrahimi switch (feature_disable) { 604*b7893ccfSSadaf Ebrahimi case VK_VALIDATION_FEATURE_DISABLE_SHADERS_EXT: 605*b7893ccfSSadaf Ebrahimi disable_data->shader_validation = true; 606*b7893ccfSSadaf Ebrahimi break; 607*b7893ccfSSadaf Ebrahimi case VK_VALIDATION_FEATURE_DISABLE_THREAD_SAFETY_EXT: 608*b7893ccfSSadaf Ebrahimi disable_data->thread_safety = true; 609*b7893ccfSSadaf Ebrahimi break; 610*b7893ccfSSadaf Ebrahimi case VK_VALIDATION_FEATURE_DISABLE_API_PARAMETERS_EXT: 611*b7893ccfSSadaf Ebrahimi disable_data->stateless_checks = true; 612*b7893ccfSSadaf Ebrahimi break; 613*b7893ccfSSadaf Ebrahimi case VK_VALIDATION_FEATURE_DISABLE_OBJECT_LIFETIMES_EXT: 614*b7893ccfSSadaf Ebrahimi disable_data->object_tracking = true; 615*b7893ccfSSadaf Ebrahimi break; 616*b7893ccfSSadaf Ebrahimi case VK_VALIDATION_FEATURE_DISABLE_CORE_CHECKS_EXT: 617*b7893ccfSSadaf Ebrahimi disable_data->core_checks = true; 618*b7893ccfSSadaf Ebrahimi break; 619*b7893ccfSSadaf Ebrahimi case VK_VALIDATION_FEATURE_DISABLE_UNIQUE_HANDLES_EXT: 620*b7893ccfSSadaf Ebrahimi disable_data->handle_wrapping = true; 621*b7893ccfSSadaf Ebrahimi break; 622*b7893ccfSSadaf Ebrahimi case VK_VALIDATION_FEATURE_DISABLE_ALL_EXT: 623*b7893ccfSSadaf Ebrahimi // Set all disabled flags to true 624*b7893ccfSSadaf Ebrahimi disable_data->SetAll(true); 625*b7893ccfSSadaf Ebrahimi break; 626*b7893ccfSSadaf Ebrahimi default: 627*b7893ccfSSadaf Ebrahimi break; 628*b7893ccfSSadaf Ebrahimi } 629*b7893ccfSSadaf Ebrahimi} 630*b7893ccfSSadaf Ebrahimi 631*b7893ccfSSadaf Ebrahimi// Set the local enable flag for a single VK_VALIDATION_FEATURE_ENABLE_* flag 632*b7893ccfSSadaf Ebrahimivoid SetValidationFeatureEnable(CHECK_ENABLED *enable_data, const VkValidationFeatureEnableEXT feature_enable) { 633*b7893ccfSSadaf Ebrahimi switch (feature_enable) { 634*b7893ccfSSadaf Ebrahimi case VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT: 635*b7893ccfSSadaf Ebrahimi enable_data->gpu_validation = true; 636*b7893ccfSSadaf Ebrahimi break; 637*b7893ccfSSadaf Ebrahimi case VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT: 638*b7893ccfSSadaf Ebrahimi enable_data->gpu_validation_reserve_binding_slot = true; 639*b7893ccfSSadaf Ebrahimi break; 640*b7893ccfSSadaf Ebrahimi default: 641*b7893ccfSSadaf Ebrahimi break; 642*b7893ccfSSadaf Ebrahimi } 643*b7893ccfSSadaf Ebrahimi} 644*b7893ccfSSadaf Ebrahimi 645*b7893ccfSSadaf Ebrahimivoid SetValidationFeatureEnable(CHECK_ENABLED *enable_data, const VkValidationFeatureEnable feature_enable) { 646*b7893ccfSSadaf Ebrahimi switch(feature_enable) { 647*b7893ccfSSadaf Ebrahimi case VK_VALIDATION_FEATURE_ENABLE_BEST_PRACTICES: 648*b7893ccfSSadaf Ebrahimi enable_data->best_practices = true; 649*b7893ccfSSadaf Ebrahimi break; 650*b7893ccfSSadaf Ebrahimi default: 651*b7893ccfSSadaf Ebrahimi break; 652*b7893ccfSSadaf Ebrahimi } 653*b7893ccfSSadaf Ebrahimi} 654*b7893ccfSSadaf Ebrahimi 655*b7893ccfSSadaf Ebrahimi// Set the local disable flag for settings specified through the VK_EXT_validation_flags extension 656*b7893ccfSSadaf Ebrahimivoid SetValidationFlags(CHECK_DISABLED* disables, const VkValidationFlagsEXT* val_flags_struct) { 657*b7893ccfSSadaf Ebrahimi for (uint32_t i = 0; i < val_flags_struct->disabledValidationCheckCount; ++i) { 658*b7893ccfSSadaf Ebrahimi switch (val_flags_struct->pDisabledValidationChecks[i]) { 659*b7893ccfSSadaf Ebrahimi case VK_VALIDATION_CHECK_SHADERS_EXT: 660*b7893ccfSSadaf Ebrahimi disables->shader_validation = true; 661*b7893ccfSSadaf Ebrahimi break; 662*b7893ccfSSadaf Ebrahimi case VK_VALIDATION_CHECK_ALL_EXT: 663*b7893ccfSSadaf Ebrahimi // Set all disabled flags to true 664*b7893ccfSSadaf Ebrahimi disables->SetAll(true); 665*b7893ccfSSadaf Ebrahimi break; 666*b7893ccfSSadaf Ebrahimi default: 667*b7893ccfSSadaf Ebrahimi break; 668*b7893ccfSSadaf Ebrahimi } 669*b7893ccfSSadaf Ebrahimi } 670*b7893ccfSSadaf Ebrahimi} 671*b7893ccfSSadaf Ebrahimi 672*b7893ccfSSadaf Ebrahimi// Process Validation Features flags specified through the ValidationFeature extension 673*b7893ccfSSadaf Ebrahimivoid SetValidationFeatures(CHECK_DISABLED *disable_data, CHECK_ENABLED *enable_data, 674*b7893ccfSSadaf Ebrahimi const VkValidationFeaturesEXT *val_features_struct) { 675*b7893ccfSSadaf Ebrahimi for (uint32_t i = 0; i < val_features_struct->disabledValidationFeatureCount; ++i) { 676*b7893ccfSSadaf Ebrahimi SetValidationFeatureDisable(disable_data, val_features_struct->pDisabledValidationFeatures[i]); 677*b7893ccfSSadaf Ebrahimi } 678*b7893ccfSSadaf Ebrahimi for (uint32_t i = 0; i < val_features_struct->enabledValidationFeatureCount; ++i) { 679*b7893ccfSSadaf Ebrahimi SetValidationFeatureEnable(enable_data, val_features_struct->pEnabledValidationFeatures[i]); 680*b7893ccfSSadaf Ebrahimi } 681*b7893ccfSSadaf Ebrahimi} 682*b7893ccfSSadaf Ebrahimi 683*b7893ccfSSadaf Ebrahimi// Given a string representation of a list of enable enum values, call the appropriate setter function 684*b7893ccfSSadaf Ebrahimivoid SetLocalEnableSetting(std::string list_of_enables, std::string delimiter, CHECK_ENABLED* enables) { 685*b7893ccfSSadaf Ebrahimi size_t pos = 0; 686*b7893ccfSSadaf Ebrahimi std::string token; 687*b7893ccfSSadaf Ebrahimi while (list_of_enables.length() != 0) { 688*b7893ccfSSadaf Ebrahimi pos = list_of_enables.find(delimiter); 689*b7893ccfSSadaf Ebrahimi if (pos != std::string::npos) { 690*b7893ccfSSadaf Ebrahimi token = list_of_enables.substr(0, pos); 691*b7893ccfSSadaf Ebrahimi } else { 692*b7893ccfSSadaf Ebrahimi pos = list_of_enables.length() - delimiter.length(); 693*b7893ccfSSadaf Ebrahimi token = list_of_enables; 694*b7893ccfSSadaf Ebrahimi } 695*b7893ccfSSadaf Ebrahimi if (token.find("VK_VALIDATION_FEATURE_ENABLE_") != std::string::npos) { 696*b7893ccfSSadaf Ebrahimi auto result = VkValFeatureEnableLookup.find(token); 697*b7893ccfSSadaf Ebrahimi if (result != VkValFeatureEnableLookup.end()) { 698*b7893ccfSSadaf Ebrahimi SetValidationFeatureEnable(enables, result->second); 699*b7893ccfSSadaf Ebrahimi } else { 700*b7893ccfSSadaf Ebrahimi auto result2 = VkValFeatureEnableLookup2.find(token); 701*b7893ccfSSadaf Ebrahimi if (result2 != VkValFeatureEnableLookup2.end()) { 702*b7893ccfSSadaf Ebrahimi SetValidationFeatureEnable(enables, result2->second); 703*b7893ccfSSadaf Ebrahimi } 704*b7893ccfSSadaf Ebrahimi } 705*b7893ccfSSadaf Ebrahimi } 706*b7893ccfSSadaf Ebrahimi list_of_enables.erase(0, pos + delimiter.length()); 707*b7893ccfSSadaf Ebrahimi } 708*b7893ccfSSadaf Ebrahimi} 709*b7893ccfSSadaf Ebrahimi 710*b7893ccfSSadaf Ebrahimi// Given a string representation of a list of disable enum values, call the appropriate setter function 711*b7893ccfSSadaf Ebrahimivoid SetLocalDisableSetting(std::string list_of_disables, std::string delimiter, CHECK_DISABLED* disables) { 712*b7893ccfSSadaf Ebrahimi size_t pos = 0; 713*b7893ccfSSadaf Ebrahimi std::string token; 714*b7893ccfSSadaf Ebrahimi while (list_of_disables.length() != 0) { 715*b7893ccfSSadaf Ebrahimi pos = list_of_disables.find(delimiter); 716*b7893ccfSSadaf Ebrahimi if (pos != std::string::npos) { 717*b7893ccfSSadaf Ebrahimi token = list_of_disables.substr(0, pos); 718*b7893ccfSSadaf Ebrahimi } else { 719*b7893ccfSSadaf Ebrahimi pos = list_of_disables.length() - delimiter.length(); 720*b7893ccfSSadaf Ebrahimi token = list_of_disables; 721*b7893ccfSSadaf Ebrahimi } 722*b7893ccfSSadaf Ebrahimi if (token.find("VK_VALIDATION_FEATURE_DISABLE_") != std::string::npos) { 723*b7893ccfSSadaf Ebrahimi auto result = VkValFeatureDisableLookup.find(token); 724*b7893ccfSSadaf Ebrahimi if (result != VkValFeatureDisableLookup.end()) { 725*b7893ccfSSadaf Ebrahimi SetValidationFeatureDisable(disables, result->second); 726*b7893ccfSSadaf Ebrahimi } 727*b7893ccfSSadaf Ebrahimi } 728*b7893ccfSSadaf Ebrahimi if (token.find("VALIDATION_CHECK_DISABLE_") != std::string::npos) { 729*b7893ccfSSadaf Ebrahimi auto result = ValidationDisableLookup.find(token); 730*b7893ccfSSadaf Ebrahimi if (result != ValidationDisableLookup.end()) { 731*b7893ccfSSadaf Ebrahimi SetValidationDisable(disables, result->second); 732*b7893ccfSSadaf Ebrahimi } 733*b7893ccfSSadaf Ebrahimi } 734*b7893ccfSSadaf Ebrahimi list_of_disables.erase(0, pos + delimiter.length()); 735*b7893ccfSSadaf Ebrahimi } 736*b7893ccfSSadaf Ebrahimi} 737*b7893ccfSSadaf Ebrahimi 738*b7893ccfSSadaf Ebrahimi// Process enables and disables set though the vk_layer_settings.txt config file or through an environment variable 739*b7893ccfSSadaf Ebrahimivoid ProcessConfigAndEnvSettings(const char* layer_description, CHECK_ENABLED* enables, CHECK_DISABLED* disables) { 740*b7893ccfSSadaf Ebrahimi std::string enable_key = layer_description; 741*b7893ccfSSadaf Ebrahimi std::string disable_key = layer_description; 742*b7893ccfSSadaf Ebrahimi enable_key.append(".enables"); 743*b7893ccfSSadaf Ebrahimi disable_key.append(".disables"); 744*b7893ccfSSadaf Ebrahimi std::string list_of_config_enables = getLayerOption(enable_key.c_str()); 745*b7893ccfSSadaf Ebrahimi std::string list_of_env_enables = GetLayerEnvVar("VK_LAYER_ENABLES"); 746*b7893ccfSSadaf Ebrahimi std::string list_of_config_disables = getLayerOption(disable_key.c_str()); 747*b7893ccfSSadaf Ebrahimi std::string list_of_env_disables = GetLayerEnvVar("VK_LAYER_DISABLES"); 748*b7893ccfSSadaf Ebrahimi#if defined(_WIN32) 749*b7893ccfSSadaf Ebrahimi std::string env_delimiter = ";"; 750*b7893ccfSSadaf Ebrahimi#else 751*b7893ccfSSadaf Ebrahimi std::string env_delimiter = ":"; 752*b7893ccfSSadaf Ebrahimi#endif 753*b7893ccfSSadaf Ebrahimi SetLocalEnableSetting(list_of_config_enables, ",", enables); 754*b7893ccfSSadaf Ebrahimi SetLocalEnableSetting(list_of_env_enables, env_delimiter, enables); 755*b7893ccfSSadaf Ebrahimi SetLocalDisableSetting(list_of_config_disables, ",", disables); 756*b7893ccfSSadaf Ebrahimi SetLocalDisableSetting(list_of_env_disables, env_delimiter, disables); 757*b7893ccfSSadaf Ebrahimi} 758*b7893ccfSSadaf Ebrahimi 759*b7893ccfSSadaf Ebrahimi 760*b7893ccfSSadaf Ebrahimi// Non-code-generated chassis API functions 761*b7893ccfSSadaf Ebrahimi 762*b7893ccfSSadaf EbrahimiVKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice device, const char *funcName) { 763*b7893ccfSSadaf Ebrahimi auto layer_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 764*b7893ccfSSadaf Ebrahimi if (!ApiParentExtensionEnabled(funcName, &layer_data->device_extensions)) { 765*b7893ccfSSadaf Ebrahimi return nullptr; 766*b7893ccfSSadaf Ebrahimi } 767*b7893ccfSSadaf Ebrahimi const auto &item = name_to_funcptr_map.find(funcName); 768*b7893ccfSSadaf Ebrahimi if (item != name_to_funcptr_map.end()) { 769*b7893ccfSSadaf Ebrahimi if (item->second.is_instance_api) { 770*b7893ccfSSadaf Ebrahimi return nullptr; 771*b7893ccfSSadaf Ebrahimi } else { 772*b7893ccfSSadaf Ebrahimi return reinterpret_cast<PFN_vkVoidFunction>(item->second.funcptr); 773*b7893ccfSSadaf Ebrahimi } 774*b7893ccfSSadaf Ebrahimi } 775*b7893ccfSSadaf Ebrahimi auto &table = layer_data->device_dispatch_table; 776*b7893ccfSSadaf Ebrahimi if (!table.GetDeviceProcAddr) return nullptr; 777*b7893ccfSSadaf Ebrahimi return table.GetDeviceProcAddr(device, funcName); 778*b7893ccfSSadaf Ebrahimi} 779*b7893ccfSSadaf Ebrahimi 780*b7893ccfSSadaf EbrahimiVKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance, const char *funcName) { 781*b7893ccfSSadaf Ebrahimi const auto &item = name_to_funcptr_map.find(funcName); 782*b7893ccfSSadaf Ebrahimi if (item != name_to_funcptr_map.end()) { 783*b7893ccfSSadaf Ebrahimi return reinterpret_cast<PFN_vkVoidFunction>(item->second.funcptr); 784*b7893ccfSSadaf Ebrahimi } 785*b7893ccfSSadaf Ebrahimi auto layer_data = GetLayerDataPtr(get_dispatch_key(instance), layer_data_map); 786*b7893ccfSSadaf Ebrahimi auto &table = layer_data->instance_dispatch_table; 787*b7893ccfSSadaf Ebrahimi if (!table.GetInstanceProcAddr) return nullptr; 788*b7893ccfSSadaf Ebrahimi return table.GetInstanceProcAddr(instance, funcName); 789*b7893ccfSSadaf Ebrahimi} 790*b7893ccfSSadaf Ebrahimi 791*b7893ccfSSadaf EbrahimiVKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties *pProperties) { 792*b7893ccfSSadaf Ebrahimi return util_GetLayerProperties(1, &global_layer, pCount, pProperties); 793*b7893ccfSSadaf Ebrahimi} 794*b7893ccfSSadaf Ebrahimi 795*b7893ccfSSadaf EbrahimiVKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount, 796*b7893ccfSSadaf Ebrahimi VkLayerProperties *pProperties) { 797*b7893ccfSSadaf Ebrahimi return util_GetLayerProperties(1, &global_layer, pCount, pProperties); 798*b7893ccfSSadaf Ebrahimi} 799*b7893ccfSSadaf Ebrahimi 800*b7893ccfSSadaf EbrahimiVKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount, 801*b7893ccfSSadaf Ebrahimi VkExtensionProperties *pProperties) { 802*b7893ccfSSadaf Ebrahimi if (pLayerName && !strcmp(pLayerName, global_layer.layerName)) 803*b7893ccfSSadaf Ebrahimi return util_GetExtensionProperties(ARRAY_SIZE(instance_extensions), instance_extensions, pCount, pProperties); 804*b7893ccfSSadaf Ebrahimi 805*b7893ccfSSadaf Ebrahimi return VK_ERROR_LAYER_NOT_PRESENT; 806*b7893ccfSSadaf Ebrahimi} 807*b7893ccfSSadaf Ebrahimi 808*b7893ccfSSadaf EbrahimiVKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char *pLayerName, 809*b7893ccfSSadaf Ebrahimi uint32_t *pCount, VkExtensionProperties *pProperties) { 810*b7893ccfSSadaf Ebrahimi if (pLayerName && !strcmp(pLayerName, global_layer.layerName)) return util_GetExtensionProperties(ARRAY_SIZE(device_extensions), device_extensions, pCount, pProperties); 811*b7893ccfSSadaf Ebrahimi assert(physicalDevice); 812*b7893ccfSSadaf Ebrahimi auto layer_data = GetLayerDataPtr(get_dispatch_key(physicalDevice), layer_data_map); 813*b7893ccfSSadaf Ebrahimi return layer_data->instance_dispatch_table.EnumerateDeviceExtensionProperties(physicalDevice, pLayerName, pCount, pProperties); 814*b7893ccfSSadaf Ebrahimi} 815*b7893ccfSSadaf Ebrahimi 816*b7893ccfSSadaf EbrahimiVKAPI_ATTR VkResult VKAPI_CALL CreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, 817*b7893ccfSSadaf Ebrahimi VkInstance *pInstance) { 818*b7893ccfSSadaf Ebrahimi VkLayerInstanceCreateInfo* chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO); 819*b7893ccfSSadaf Ebrahimi 820*b7893ccfSSadaf Ebrahimi assert(chain_info->u.pLayerInfo); 821*b7893ccfSSadaf Ebrahimi PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr; 822*b7893ccfSSadaf Ebrahimi PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance)fpGetInstanceProcAddr(NULL, "vkCreateInstance"); 823*b7893ccfSSadaf Ebrahimi if (fpCreateInstance == NULL) return VK_ERROR_INITIALIZATION_FAILED; 824*b7893ccfSSadaf Ebrahimi chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext; 825*b7893ccfSSadaf Ebrahimi uint32_t specified_version = (pCreateInfo->pApplicationInfo ? pCreateInfo->pApplicationInfo->apiVersion : VK_API_VERSION_1_0); 826*b7893ccfSSadaf Ebrahimi uint32_t api_version = (specified_version < VK_API_VERSION_1_1) ? VK_API_VERSION_1_0 : VK_API_VERSION_1_1; 827*b7893ccfSSadaf Ebrahimi 828*b7893ccfSSadaf Ebrahimi CHECK_ENABLED local_enables {}; 829*b7893ccfSSadaf Ebrahimi CHECK_DISABLED local_disables {}; 830*b7893ccfSSadaf Ebrahimi const auto *validation_features_ext = lvl_find_in_chain<VkValidationFeaturesEXT>(pCreateInfo->pNext); 831*b7893ccfSSadaf Ebrahimi if (validation_features_ext) { 832*b7893ccfSSadaf Ebrahimi SetValidationFeatures(&local_disables, &local_enables, validation_features_ext); 833*b7893ccfSSadaf Ebrahimi } 834*b7893ccfSSadaf Ebrahimi const auto *validation_flags_ext = lvl_find_in_chain<VkValidationFlagsEXT>(pCreateInfo->pNext); 835*b7893ccfSSadaf Ebrahimi if (validation_flags_ext) { 836*b7893ccfSSadaf Ebrahimi SetValidationFlags(&local_disables, validation_flags_ext); 837*b7893ccfSSadaf Ebrahimi } 838*b7893ccfSSadaf Ebrahimi ProcessConfigAndEnvSettings(OBJECT_LAYER_DESCRIPTION, &local_enables, &local_disables); 839*b7893ccfSSadaf Ebrahimi 840*b7893ccfSSadaf Ebrahimi // Create temporary dispatch vector for pre-calls until instance is created 841*b7893ccfSSadaf Ebrahimi std::vector<ValidationObject*> local_object_dispatch; 842*b7893ccfSSadaf Ebrahimi // Add VOs to dispatch vector. Order here will be the validation dispatch order! 843*b7893ccfSSadaf Ebrahimi#if BUILD_THREAD_SAFETY 844*b7893ccfSSadaf Ebrahimi auto thread_checker = new ThreadSafety; 845*b7893ccfSSadaf Ebrahimi if (!local_disables.thread_safety) { 846*b7893ccfSSadaf Ebrahimi local_object_dispatch.emplace_back(thread_checker); 847*b7893ccfSSadaf Ebrahimi } 848*b7893ccfSSadaf Ebrahimi thread_checker->container_type = LayerObjectTypeThreading; 849*b7893ccfSSadaf Ebrahimi thread_checker->api_version = api_version; 850*b7893ccfSSadaf Ebrahimi#endif 851*b7893ccfSSadaf Ebrahimi#if BUILD_PARAMETER_VALIDATION 852*b7893ccfSSadaf Ebrahimi auto parameter_validation = new StatelessValidation; 853*b7893ccfSSadaf Ebrahimi if (!local_disables.stateless_checks) { 854*b7893ccfSSadaf Ebrahimi local_object_dispatch.emplace_back(parameter_validation); 855*b7893ccfSSadaf Ebrahimi } 856*b7893ccfSSadaf Ebrahimi parameter_validation->container_type = LayerObjectTypeParameterValidation; 857*b7893ccfSSadaf Ebrahimi parameter_validation->api_version = api_version; 858*b7893ccfSSadaf Ebrahimi#endif 859*b7893ccfSSadaf Ebrahimi#if BUILD_OBJECT_TRACKER 860*b7893ccfSSadaf Ebrahimi auto object_tracker = new ObjectLifetimes; 861*b7893ccfSSadaf Ebrahimi if (!local_disables.object_tracking) { 862*b7893ccfSSadaf Ebrahimi local_object_dispatch.emplace_back(object_tracker); 863*b7893ccfSSadaf Ebrahimi } 864*b7893ccfSSadaf Ebrahimi object_tracker->container_type = LayerObjectTypeObjectTracker; 865*b7893ccfSSadaf Ebrahimi object_tracker->api_version = api_version; 866*b7893ccfSSadaf Ebrahimi#endif 867*b7893ccfSSadaf Ebrahimi#if BUILD_CORE_VALIDATION 868*b7893ccfSSadaf Ebrahimi auto core_checks = new CoreChecks; 869*b7893ccfSSadaf Ebrahimi if (!local_disables.core_checks) { 870*b7893ccfSSadaf Ebrahimi local_object_dispatch.emplace_back(core_checks); 871*b7893ccfSSadaf Ebrahimi } 872*b7893ccfSSadaf Ebrahimi core_checks->container_type = LayerObjectTypeCoreValidation; 873*b7893ccfSSadaf Ebrahimi core_checks->api_version = api_version; 874*b7893ccfSSadaf Ebrahimi#endif 875*b7893ccfSSadaf Ebrahimi#if BUILD_BEST_PRACTICES 876*b7893ccfSSadaf Ebrahimi auto best_practices = new BestPractices; 877*b7893ccfSSadaf Ebrahimi if (local_enables.best_practices) { 878*b7893ccfSSadaf Ebrahimi local_object_dispatch.emplace_back(best_practices); 879*b7893ccfSSadaf Ebrahimi } 880*b7893ccfSSadaf Ebrahimi best_practices->container_type = LayerObjectTypeBestPractices; 881*b7893ccfSSadaf Ebrahimi best_practices->api_version = api_version; 882*b7893ccfSSadaf Ebrahimi#endif 883*b7893ccfSSadaf Ebrahimi 884*b7893ccfSSadaf Ebrahimi // If handle wrapping is disabled via the ValidationFeatures extension, override build flag 885*b7893ccfSSadaf Ebrahimi if (local_disables.handle_wrapping) { 886*b7893ccfSSadaf Ebrahimi wrap_handles = false; 887*b7893ccfSSadaf Ebrahimi } 888*b7893ccfSSadaf Ebrahimi 889*b7893ccfSSadaf Ebrahimi // Init dispatch array and call registration functions 890*b7893ccfSSadaf Ebrahimi for (auto intercept : local_object_dispatch) { 891*b7893ccfSSadaf Ebrahimi intercept->PreCallValidateCreateInstance(pCreateInfo, pAllocator, pInstance); 892*b7893ccfSSadaf Ebrahimi } 893*b7893ccfSSadaf Ebrahimi for (auto intercept : local_object_dispatch) { 894*b7893ccfSSadaf Ebrahimi intercept->PreCallRecordCreateInstance(pCreateInfo, pAllocator, pInstance); 895*b7893ccfSSadaf Ebrahimi } 896*b7893ccfSSadaf Ebrahimi 897*b7893ccfSSadaf Ebrahimi VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance); 898*b7893ccfSSadaf Ebrahimi if (result != VK_SUCCESS) return result; 899*b7893ccfSSadaf Ebrahimi 900*b7893ccfSSadaf Ebrahimi auto framework = GetLayerDataPtr(get_dispatch_key(*pInstance), layer_data_map); 901*b7893ccfSSadaf Ebrahimi 902*b7893ccfSSadaf Ebrahimi framework->object_dispatch = local_object_dispatch; 903*b7893ccfSSadaf Ebrahimi framework->container_type = LayerObjectTypeInstance; 904*b7893ccfSSadaf Ebrahimi framework->disabled = local_disables; 905*b7893ccfSSadaf Ebrahimi framework->enabled = local_enables; 906*b7893ccfSSadaf Ebrahimi 907*b7893ccfSSadaf Ebrahimi framework->instance = *pInstance; 908*b7893ccfSSadaf Ebrahimi layer_init_instance_dispatch_table(*pInstance, &framework->instance_dispatch_table, fpGetInstanceProcAddr); 909*b7893ccfSSadaf Ebrahimi framework->report_data = debug_utils_create_instance(&framework->instance_dispatch_table, *pInstance, pCreateInfo->enabledExtensionCount, 910*b7893ccfSSadaf Ebrahimi pCreateInfo->ppEnabledExtensionNames); 911*b7893ccfSSadaf Ebrahimi framework->api_version = api_version; 912*b7893ccfSSadaf Ebrahimi framework->instance_extensions.InitFromInstanceCreateInfo(specified_version, pCreateInfo); 913*b7893ccfSSadaf Ebrahimi 914*b7893ccfSSadaf Ebrahimi layer_debug_messenger_actions(framework->report_data, framework->logging_messenger, pAllocator, OBJECT_LAYER_DESCRIPTION); 915*b7893ccfSSadaf Ebrahimi 916*b7893ccfSSadaf Ebrahimi#if BUILD_OBJECT_TRACKER 917*b7893ccfSSadaf Ebrahimi object_tracker->report_data = framework->report_data; 918*b7893ccfSSadaf Ebrahimi object_tracker->instance_dispatch_table = framework->instance_dispatch_table; 919*b7893ccfSSadaf Ebrahimi object_tracker->enabled = framework->enabled; 920*b7893ccfSSadaf Ebrahimi object_tracker->disabled = framework->disabled; 921*b7893ccfSSadaf Ebrahimi#endif 922*b7893ccfSSadaf Ebrahimi#if BUILD_THREAD_SAFETY 923*b7893ccfSSadaf Ebrahimi thread_checker->report_data = framework->report_data; 924*b7893ccfSSadaf Ebrahimi thread_checker->instance_dispatch_table = framework->instance_dispatch_table; 925*b7893ccfSSadaf Ebrahimi thread_checker->enabled = framework->enabled; 926*b7893ccfSSadaf Ebrahimi thread_checker->disabled = framework->disabled; 927*b7893ccfSSadaf Ebrahimi#endif 928*b7893ccfSSadaf Ebrahimi#if BUILD_PARAMETER_VALIDATION 929*b7893ccfSSadaf Ebrahimi parameter_validation->report_data = framework->report_data; 930*b7893ccfSSadaf Ebrahimi parameter_validation->instance_dispatch_table = framework->instance_dispatch_table; 931*b7893ccfSSadaf Ebrahimi parameter_validation->enabled = framework->enabled; 932*b7893ccfSSadaf Ebrahimi parameter_validation->disabled = framework->disabled; 933*b7893ccfSSadaf Ebrahimi#endif 934*b7893ccfSSadaf Ebrahimi#if BUILD_CORE_VALIDATION 935*b7893ccfSSadaf Ebrahimi core_checks->report_data = framework->report_data; 936*b7893ccfSSadaf Ebrahimi core_checks->instance_dispatch_table = framework->instance_dispatch_table; 937*b7893ccfSSadaf Ebrahimi core_checks->instance = *pInstance; 938*b7893ccfSSadaf Ebrahimi core_checks->enabled = framework->enabled; 939*b7893ccfSSadaf Ebrahimi core_checks->disabled = framework->disabled; 940*b7893ccfSSadaf Ebrahimi core_checks->instance_state = core_checks; 941*b7893ccfSSadaf Ebrahimi#endif 942*b7893ccfSSadaf Ebrahimi#if BUILD_BEST_PRACTICES 943*b7893ccfSSadaf Ebrahimi best_practices->report_data = framework->report_data; 944*b7893ccfSSadaf Ebrahimi best_practices->instance_dispatch_table = framework->instance_dispatch_table; 945*b7893ccfSSadaf Ebrahimi best_practices->enabled = framework->enabled; 946*b7893ccfSSadaf Ebrahimi best_practices->disabled = framework->disabled; 947*b7893ccfSSadaf Ebrahimi#endif 948*b7893ccfSSadaf Ebrahimi 949*b7893ccfSSadaf Ebrahimi for (auto intercept : framework->object_dispatch) { 950*b7893ccfSSadaf Ebrahimi intercept->PostCallRecordCreateInstance(pCreateInfo, pAllocator, pInstance, result); 951*b7893ccfSSadaf Ebrahimi } 952*b7893ccfSSadaf Ebrahimi 953*b7893ccfSSadaf Ebrahimi InstanceExtensionWhitelist(framework, pCreateInfo, *pInstance); 954*b7893ccfSSadaf Ebrahimi 955*b7893ccfSSadaf Ebrahimi return result; 956*b7893ccfSSadaf Ebrahimi} 957*b7893ccfSSadaf Ebrahimi 958*b7893ccfSSadaf EbrahimiVKAPI_ATTR void VKAPI_CALL DestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) { 959*b7893ccfSSadaf Ebrahimi dispatch_key key = get_dispatch_key(instance); 960*b7893ccfSSadaf Ebrahimi auto layer_data = GetLayerDataPtr(key, layer_data_map); 961*b7893ccfSSadaf Ebrahimi """ + precallvalidate_loop + """ 962*b7893ccfSSadaf Ebrahimi auto lock = intercept->write_lock(); 963*b7893ccfSSadaf Ebrahimi intercept->PreCallValidateDestroyInstance(instance, pAllocator); 964*b7893ccfSSadaf Ebrahimi } 965*b7893ccfSSadaf Ebrahimi """ + precallrecord_loop + """ 966*b7893ccfSSadaf Ebrahimi auto lock = intercept->write_lock(); 967*b7893ccfSSadaf Ebrahimi intercept->PreCallRecordDestroyInstance(instance, pAllocator); 968*b7893ccfSSadaf Ebrahimi } 969*b7893ccfSSadaf Ebrahimi 970*b7893ccfSSadaf Ebrahimi layer_data->instance_dispatch_table.DestroyInstance(instance, pAllocator); 971*b7893ccfSSadaf Ebrahimi 972*b7893ccfSSadaf Ebrahimi """ + postcallrecord_loop + """ 973*b7893ccfSSadaf Ebrahimi auto lock = intercept->write_lock(); 974*b7893ccfSSadaf Ebrahimi intercept->PostCallRecordDestroyInstance(instance, pAllocator); 975*b7893ccfSSadaf Ebrahimi } 976*b7893ccfSSadaf Ebrahimi // Clean up logging callback, if any 977*b7893ccfSSadaf Ebrahimi while (layer_data->logging_messenger.size() > 0) { 978*b7893ccfSSadaf Ebrahimi VkDebugUtilsMessengerEXT messenger = layer_data->logging_messenger.back(); 979*b7893ccfSSadaf Ebrahimi layer_destroy_messenger_callback(layer_data->report_data, messenger, pAllocator); 980*b7893ccfSSadaf Ebrahimi layer_data->logging_messenger.pop_back(); 981*b7893ccfSSadaf Ebrahimi } 982*b7893ccfSSadaf Ebrahimi while (layer_data->logging_callback.size() > 0) { 983*b7893ccfSSadaf Ebrahimi VkDebugReportCallbackEXT callback = layer_data->logging_callback.back(); 984*b7893ccfSSadaf Ebrahimi layer_destroy_report_callback(layer_data->report_data, callback, pAllocator); 985*b7893ccfSSadaf Ebrahimi layer_data->logging_callback.pop_back(); 986*b7893ccfSSadaf Ebrahimi } 987*b7893ccfSSadaf Ebrahimi 988*b7893ccfSSadaf Ebrahimi layer_debug_utils_destroy_instance(layer_data->report_data); 989*b7893ccfSSadaf Ebrahimi 990*b7893ccfSSadaf Ebrahimi for (auto item = layer_data->object_dispatch.begin(); item != layer_data->object_dispatch.end(); item++) { 991*b7893ccfSSadaf Ebrahimi delete *item; 992*b7893ccfSSadaf Ebrahimi } 993*b7893ccfSSadaf Ebrahimi FreeLayerDataPtr(key, layer_data_map); 994*b7893ccfSSadaf Ebrahimi} 995*b7893ccfSSadaf Ebrahimi 996*b7893ccfSSadaf EbrahimiVKAPI_ATTR VkResult VKAPI_CALL CreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo *pCreateInfo, 997*b7893ccfSSadaf Ebrahimi const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) { 998*b7893ccfSSadaf Ebrahimi VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO); 999*b7893ccfSSadaf Ebrahimi 1000*b7893ccfSSadaf Ebrahimi auto instance_interceptor = GetLayerDataPtr(get_dispatch_key(gpu), layer_data_map); 1001*b7893ccfSSadaf Ebrahimi 1002*b7893ccfSSadaf Ebrahimi PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr; 1003*b7893ccfSSadaf Ebrahimi PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr; 1004*b7893ccfSSadaf Ebrahimi PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice)fpGetInstanceProcAddr(instance_interceptor->instance, "vkCreateDevice"); 1005*b7893ccfSSadaf Ebrahimi if (fpCreateDevice == NULL) { 1006*b7893ccfSSadaf Ebrahimi return VK_ERROR_INITIALIZATION_FAILED; 1007*b7893ccfSSadaf Ebrahimi } 1008*b7893ccfSSadaf Ebrahimi chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext; 1009*b7893ccfSSadaf Ebrahimi 1010*b7893ccfSSadaf Ebrahimi // Get physical device limits for device 1011*b7893ccfSSadaf Ebrahimi VkPhysicalDeviceProperties device_properties = {}; 1012*b7893ccfSSadaf Ebrahimi instance_interceptor->instance_dispatch_table.GetPhysicalDeviceProperties(gpu, &device_properties); 1013*b7893ccfSSadaf Ebrahimi 1014*b7893ccfSSadaf Ebrahimi // Setup the validation tables based on the application API version from the instance and the capabilities of the device driver 1015*b7893ccfSSadaf Ebrahimi uint32_t effective_api_version = std::min(device_properties.apiVersion, instance_interceptor->api_version); 1016*b7893ccfSSadaf Ebrahimi 1017*b7893ccfSSadaf Ebrahimi DeviceExtensions device_extensions = {}; 1018*b7893ccfSSadaf Ebrahimi device_extensions.InitFromDeviceCreateInfo(&instance_interceptor->instance_extensions, effective_api_version, pCreateInfo); 1019*b7893ccfSSadaf Ebrahimi for (auto item : instance_interceptor->object_dispatch) { 1020*b7893ccfSSadaf Ebrahimi item->device_extensions = device_extensions; 1021*b7893ccfSSadaf Ebrahimi } 1022*b7893ccfSSadaf Ebrahimi 1023*b7893ccfSSadaf Ebrahimi safe_VkDeviceCreateInfo modified_create_info(pCreateInfo); 1024*b7893ccfSSadaf Ebrahimi 1025*b7893ccfSSadaf Ebrahimi bool skip = false; 1026*b7893ccfSSadaf Ebrahimi for (auto intercept : instance_interceptor->object_dispatch) { 1027*b7893ccfSSadaf Ebrahimi auto lock = intercept->write_lock(); 1028*b7893ccfSSadaf Ebrahimi skip |= intercept->PreCallValidateCreateDevice(gpu, pCreateInfo, pAllocator, pDevice); 1029*b7893ccfSSadaf Ebrahimi if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 1030*b7893ccfSSadaf Ebrahimi } 1031*b7893ccfSSadaf Ebrahimi for (auto intercept : instance_interceptor->object_dispatch) { 1032*b7893ccfSSadaf Ebrahimi auto lock = intercept->write_lock(); 1033*b7893ccfSSadaf Ebrahimi intercept->PreCallRecordCreateDevice(gpu, pCreateInfo, pAllocator, pDevice, &modified_create_info); 1034*b7893ccfSSadaf Ebrahimi } 1035*b7893ccfSSadaf Ebrahimi 1036*b7893ccfSSadaf Ebrahimi VkResult result = fpCreateDevice(gpu, reinterpret_cast<VkDeviceCreateInfo *>(&modified_create_info), pAllocator, pDevice); 1037*b7893ccfSSadaf Ebrahimi if (result != VK_SUCCESS) { 1038*b7893ccfSSadaf Ebrahimi return result; 1039*b7893ccfSSadaf Ebrahimi } 1040*b7893ccfSSadaf Ebrahimi 1041*b7893ccfSSadaf Ebrahimi auto device_interceptor = GetLayerDataPtr(get_dispatch_key(*pDevice), layer_data_map); 1042*b7893ccfSSadaf Ebrahimi device_interceptor->container_type = LayerObjectTypeDevice; 1043*b7893ccfSSadaf Ebrahimi 1044*b7893ccfSSadaf Ebrahimi // Save local info in device object 1045*b7893ccfSSadaf Ebrahimi device_interceptor->phys_dev_properties.properties = device_properties; 1046*b7893ccfSSadaf Ebrahimi device_interceptor->api_version = device_interceptor->device_extensions.InitFromDeviceCreateInfo( 1047*b7893ccfSSadaf Ebrahimi &instance_interceptor->instance_extensions, effective_api_version, pCreateInfo); 1048*b7893ccfSSadaf Ebrahimi device_interceptor->device_extensions = device_extensions; 1049*b7893ccfSSadaf Ebrahimi 1050*b7893ccfSSadaf Ebrahimi layer_init_device_dispatch_table(*pDevice, &device_interceptor->device_dispatch_table, fpGetDeviceProcAddr); 1051*b7893ccfSSadaf Ebrahimi 1052*b7893ccfSSadaf Ebrahimi device_interceptor->device = *pDevice; 1053*b7893ccfSSadaf Ebrahimi device_interceptor->physical_device = gpu; 1054*b7893ccfSSadaf Ebrahimi device_interceptor->instance = instance_interceptor->instance; 1055*b7893ccfSSadaf Ebrahimi device_interceptor->report_data = layer_debug_utils_create_device(instance_interceptor->report_data, *pDevice); 1056*b7893ccfSSadaf Ebrahimi 1057*b7893ccfSSadaf Ebrahimi // Note that this defines the order in which the layer validation objects are called 1058*b7893ccfSSadaf Ebrahimi#if BUILD_THREAD_SAFETY 1059*b7893ccfSSadaf Ebrahimi auto thread_safety = new ThreadSafety; 1060*b7893ccfSSadaf Ebrahimi thread_safety->container_type = LayerObjectTypeThreading; 1061*b7893ccfSSadaf Ebrahimi if (!instance_interceptor->disabled.thread_safety) { 1062*b7893ccfSSadaf Ebrahimi device_interceptor->object_dispatch.emplace_back(thread_safety); 1063*b7893ccfSSadaf Ebrahimi } 1064*b7893ccfSSadaf Ebrahimi#endif 1065*b7893ccfSSadaf Ebrahimi#if BUILD_PARAMETER_VALIDATION 1066*b7893ccfSSadaf Ebrahimi auto stateless_validation = new StatelessValidation; 1067*b7893ccfSSadaf Ebrahimi stateless_validation->container_type = LayerObjectTypeParameterValidation; 1068*b7893ccfSSadaf Ebrahimi if (!instance_interceptor->disabled.stateless_checks) { 1069*b7893ccfSSadaf Ebrahimi device_interceptor->object_dispatch.emplace_back(stateless_validation); 1070*b7893ccfSSadaf Ebrahimi } 1071*b7893ccfSSadaf Ebrahimi#endif 1072*b7893ccfSSadaf Ebrahimi#if BUILD_OBJECT_TRACKER 1073*b7893ccfSSadaf Ebrahimi auto object_tracker = new ObjectLifetimes; 1074*b7893ccfSSadaf Ebrahimi object_tracker->container_type = LayerObjectTypeObjectTracker; 1075*b7893ccfSSadaf Ebrahimi if (!instance_interceptor->disabled.object_tracking) { 1076*b7893ccfSSadaf Ebrahimi device_interceptor->object_dispatch.emplace_back(object_tracker); 1077*b7893ccfSSadaf Ebrahimi } 1078*b7893ccfSSadaf Ebrahimi#endif 1079*b7893ccfSSadaf Ebrahimi#if BUILD_CORE_VALIDATION 1080*b7893ccfSSadaf Ebrahimi auto core_checks = new CoreChecks; 1081*b7893ccfSSadaf Ebrahimi core_checks->container_type = LayerObjectTypeCoreValidation; 1082*b7893ccfSSadaf Ebrahimi core_checks->instance_state = reinterpret_cast<CoreChecks *>( 1083*b7893ccfSSadaf Ebrahimi core_checks->GetValidationObject(instance_interceptor->object_dispatch, LayerObjectTypeCoreValidation)); 1084*b7893ccfSSadaf Ebrahimi if (!instance_interceptor->disabled.core_checks) { 1085*b7893ccfSSadaf Ebrahimi device_interceptor->object_dispatch.emplace_back(core_checks); 1086*b7893ccfSSadaf Ebrahimi } 1087*b7893ccfSSadaf Ebrahimi#endif 1088*b7893ccfSSadaf Ebrahimi#if BUILD_BEST_PRACTICES 1089*b7893ccfSSadaf Ebrahimi auto best_practices = new BestPractices; 1090*b7893ccfSSadaf Ebrahimi best_practices->container_type = LayerObjectTypeBestPractices; 1091*b7893ccfSSadaf Ebrahimi if (instance_interceptor->enabled.best_practices) { 1092*b7893ccfSSadaf Ebrahimi device_interceptor->object_dispatch.emplace_back(best_practices); 1093*b7893ccfSSadaf Ebrahimi } 1094*b7893ccfSSadaf Ebrahimi#endif 1095*b7893ccfSSadaf Ebrahimi 1096*b7893ccfSSadaf Ebrahimi // Set per-intercept common data items 1097*b7893ccfSSadaf Ebrahimi for (auto dev_intercept : device_interceptor->object_dispatch) { 1098*b7893ccfSSadaf Ebrahimi dev_intercept->device = *pDevice; 1099*b7893ccfSSadaf Ebrahimi dev_intercept->physical_device = gpu; 1100*b7893ccfSSadaf Ebrahimi dev_intercept->instance = instance_interceptor->instance; 1101*b7893ccfSSadaf Ebrahimi dev_intercept->report_data = device_interceptor->report_data; 1102*b7893ccfSSadaf Ebrahimi dev_intercept->device_dispatch_table = device_interceptor->device_dispatch_table; 1103*b7893ccfSSadaf Ebrahimi dev_intercept->api_version = device_interceptor->api_version; 1104*b7893ccfSSadaf Ebrahimi dev_intercept->disabled = instance_interceptor->disabled; 1105*b7893ccfSSadaf Ebrahimi dev_intercept->enabled = instance_interceptor->enabled; 1106*b7893ccfSSadaf Ebrahimi dev_intercept->instance_dispatch_table = instance_interceptor->instance_dispatch_table; 1107*b7893ccfSSadaf Ebrahimi dev_intercept->instance_extensions = instance_interceptor->instance_extensions; 1108*b7893ccfSSadaf Ebrahimi dev_intercept->device_extensions = device_interceptor->device_extensions; 1109*b7893ccfSSadaf Ebrahimi } 1110*b7893ccfSSadaf Ebrahimi 1111*b7893ccfSSadaf Ebrahimi for (auto intercept : instance_interceptor->object_dispatch) { 1112*b7893ccfSSadaf Ebrahimi auto lock = intercept->write_lock(); 1113*b7893ccfSSadaf Ebrahimi intercept->PostCallRecordCreateDevice(gpu, pCreateInfo, pAllocator, pDevice, result); 1114*b7893ccfSSadaf Ebrahimi } 1115*b7893ccfSSadaf Ebrahimi 1116*b7893ccfSSadaf Ebrahimi DeviceExtensionWhitelist(device_interceptor, pCreateInfo, *pDevice); 1117*b7893ccfSSadaf Ebrahimi 1118*b7893ccfSSadaf Ebrahimi return result; 1119*b7893ccfSSadaf Ebrahimi} 1120*b7893ccfSSadaf Ebrahimi 1121*b7893ccfSSadaf EbrahimiVKAPI_ATTR void VKAPI_CALL DestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) { 1122*b7893ccfSSadaf Ebrahimi dispatch_key key = get_dispatch_key(device); 1123*b7893ccfSSadaf Ebrahimi auto layer_data = GetLayerDataPtr(key, layer_data_map); 1124*b7893ccfSSadaf Ebrahimi """ + precallvalidate_loop + """ 1125*b7893ccfSSadaf Ebrahimi auto lock = intercept->write_lock(); 1126*b7893ccfSSadaf Ebrahimi intercept->PreCallValidateDestroyDevice(device, pAllocator); 1127*b7893ccfSSadaf Ebrahimi } 1128*b7893ccfSSadaf Ebrahimi """ + precallrecord_loop + """ 1129*b7893ccfSSadaf Ebrahimi auto lock = intercept->write_lock(); 1130*b7893ccfSSadaf Ebrahimi intercept->PreCallRecordDestroyDevice(device, pAllocator); 1131*b7893ccfSSadaf Ebrahimi } 1132*b7893ccfSSadaf Ebrahimi layer_debug_utils_destroy_device(device); 1133*b7893ccfSSadaf Ebrahimi 1134*b7893ccfSSadaf Ebrahimi layer_data->device_dispatch_table.DestroyDevice(device, pAllocator); 1135*b7893ccfSSadaf Ebrahimi 1136*b7893ccfSSadaf Ebrahimi """ + postcallrecord_loop + """ 1137*b7893ccfSSadaf Ebrahimi auto lock = intercept->write_lock(); 1138*b7893ccfSSadaf Ebrahimi intercept->PostCallRecordDestroyDevice(device, pAllocator); 1139*b7893ccfSSadaf Ebrahimi } 1140*b7893ccfSSadaf Ebrahimi 1141*b7893ccfSSadaf Ebrahimi for (auto item = layer_data->object_dispatch.begin(); item != layer_data->object_dispatch.end(); item++) { 1142*b7893ccfSSadaf Ebrahimi delete *item; 1143*b7893ccfSSadaf Ebrahimi } 1144*b7893ccfSSadaf Ebrahimi FreeLayerDataPtr(key, layer_data_map); 1145*b7893ccfSSadaf Ebrahimi} 1146*b7893ccfSSadaf Ebrahimi 1147*b7893ccfSSadaf Ebrahimi 1148*b7893ccfSSadaf Ebrahimi// Special-case APIs for which core_validation needs custom parameter lists and/or modifies parameters 1149*b7893ccfSSadaf Ebrahimi 1150*b7893ccfSSadaf EbrahimiVKAPI_ATTR VkResult VKAPI_CALL CreateGraphicsPipelines( 1151*b7893ccfSSadaf Ebrahimi VkDevice device, 1152*b7893ccfSSadaf Ebrahimi VkPipelineCache pipelineCache, 1153*b7893ccfSSadaf Ebrahimi uint32_t createInfoCount, 1154*b7893ccfSSadaf Ebrahimi const VkGraphicsPipelineCreateInfo* pCreateInfos, 1155*b7893ccfSSadaf Ebrahimi const VkAllocationCallbacks* pAllocator, 1156*b7893ccfSSadaf Ebrahimi VkPipeline* pPipelines) { 1157*b7893ccfSSadaf Ebrahimi auto layer_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 1158*b7893ccfSSadaf Ebrahimi bool skip = false; 1159*b7893ccfSSadaf Ebrahimi 1160*b7893ccfSSadaf Ebrahimi#ifdef BUILD_CORE_VALIDATION 1161*b7893ccfSSadaf Ebrahimi create_graphics_pipeline_api_state cgpl_state{}; 1162*b7893ccfSSadaf Ebrahimi#else 1163*b7893ccfSSadaf Ebrahimi struct create_graphics_pipeline_api_state { 1164*b7893ccfSSadaf Ebrahimi const VkGraphicsPipelineCreateInfo* pCreateInfos; 1165*b7893ccfSSadaf Ebrahimi } cgpl_state; 1166*b7893ccfSSadaf Ebrahimi#endif 1167*b7893ccfSSadaf Ebrahimi cgpl_state.pCreateInfos = pCreateInfos; 1168*b7893ccfSSadaf Ebrahimi 1169*b7893ccfSSadaf Ebrahimi for (auto intercept : layer_data->object_dispatch) { 1170*b7893ccfSSadaf Ebrahimi auto lock = intercept->write_lock(); 1171*b7893ccfSSadaf Ebrahimi skip |= intercept->PreCallValidateCreateGraphicsPipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines, &cgpl_state); 1172*b7893ccfSSadaf Ebrahimi if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 1173*b7893ccfSSadaf Ebrahimi } 1174*b7893ccfSSadaf Ebrahimi for (auto intercept : layer_data->object_dispatch) { 1175*b7893ccfSSadaf Ebrahimi auto lock = intercept->write_lock(); 1176*b7893ccfSSadaf Ebrahimi intercept->PreCallRecordCreateGraphicsPipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines, &cgpl_state); 1177*b7893ccfSSadaf Ebrahimi } 1178*b7893ccfSSadaf Ebrahimi 1179*b7893ccfSSadaf Ebrahimi VkResult result = DispatchCreateGraphicsPipelines(device, pipelineCache, createInfoCount, cgpl_state.pCreateInfos, pAllocator, pPipelines); 1180*b7893ccfSSadaf Ebrahimi 1181*b7893ccfSSadaf Ebrahimi for (auto intercept : layer_data->object_dispatch) { 1182*b7893ccfSSadaf Ebrahimi auto lock = intercept->write_lock(); 1183*b7893ccfSSadaf Ebrahimi intercept->PostCallRecordCreateGraphicsPipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines, result, &cgpl_state); 1184*b7893ccfSSadaf Ebrahimi } 1185*b7893ccfSSadaf Ebrahimi return result; 1186*b7893ccfSSadaf Ebrahimi} 1187*b7893ccfSSadaf Ebrahimi 1188*b7893ccfSSadaf Ebrahimi// This API saves some core_validation pipeline state state on the stack for performance purposes 1189*b7893ccfSSadaf EbrahimiVKAPI_ATTR VkResult VKAPI_CALL CreateComputePipelines( 1190*b7893ccfSSadaf Ebrahimi VkDevice device, 1191*b7893ccfSSadaf Ebrahimi VkPipelineCache pipelineCache, 1192*b7893ccfSSadaf Ebrahimi uint32_t createInfoCount, 1193*b7893ccfSSadaf Ebrahimi const VkComputePipelineCreateInfo* pCreateInfos, 1194*b7893ccfSSadaf Ebrahimi const VkAllocationCallbacks* pAllocator, 1195*b7893ccfSSadaf Ebrahimi VkPipeline* pPipelines) { 1196*b7893ccfSSadaf Ebrahimi auto layer_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 1197*b7893ccfSSadaf Ebrahimi bool skip = false; 1198*b7893ccfSSadaf Ebrahimi 1199*b7893ccfSSadaf Ebrahimi#ifdef BUILD_CORE_VALIDATION 1200*b7893ccfSSadaf Ebrahimi create_compute_pipeline_api_state ccpl_state{}; 1201*b7893ccfSSadaf Ebrahimi#else 1202*b7893ccfSSadaf Ebrahimi struct create_compute_pipeline_api_state { 1203*b7893ccfSSadaf Ebrahimi const VkComputePipelineCreateInfo* pCreateInfos; 1204*b7893ccfSSadaf Ebrahimi } ccpl_state; 1205*b7893ccfSSadaf Ebrahimi#endif 1206*b7893ccfSSadaf Ebrahimi ccpl_state.pCreateInfos = pCreateInfos; 1207*b7893ccfSSadaf Ebrahimi 1208*b7893ccfSSadaf Ebrahimi for (auto intercept : layer_data->object_dispatch) { 1209*b7893ccfSSadaf Ebrahimi auto lock = intercept->write_lock(); 1210*b7893ccfSSadaf Ebrahimi skip |= intercept->PreCallValidateCreateComputePipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines, &ccpl_state); 1211*b7893ccfSSadaf Ebrahimi if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 1212*b7893ccfSSadaf Ebrahimi } 1213*b7893ccfSSadaf Ebrahimi for (auto intercept : layer_data->object_dispatch) { 1214*b7893ccfSSadaf Ebrahimi auto lock = intercept->write_lock(); 1215*b7893ccfSSadaf Ebrahimi intercept->PreCallRecordCreateComputePipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines, &ccpl_state); 1216*b7893ccfSSadaf Ebrahimi } 1217*b7893ccfSSadaf Ebrahimi VkResult result = DispatchCreateComputePipelines(device, pipelineCache, createInfoCount, ccpl_state.pCreateInfos, pAllocator, pPipelines); 1218*b7893ccfSSadaf Ebrahimi for (auto intercept : layer_data->object_dispatch) { 1219*b7893ccfSSadaf Ebrahimi auto lock = intercept->write_lock(); 1220*b7893ccfSSadaf Ebrahimi intercept->PostCallRecordCreateComputePipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines, result, &ccpl_state); 1221*b7893ccfSSadaf Ebrahimi } 1222*b7893ccfSSadaf Ebrahimi return result; 1223*b7893ccfSSadaf Ebrahimi} 1224*b7893ccfSSadaf Ebrahimi 1225*b7893ccfSSadaf EbrahimiVKAPI_ATTR VkResult VKAPI_CALL CreateRayTracingPipelinesNV( 1226*b7893ccfSSadaf Ebrahimi VkDevice device, 1227*b7893ccfSSadaf Ebrahimi VkPipelineCache pipelineCache, 1228*b7893ccfSSadaf Ebrahimi uint32_t createInfoCount, 1229*b7893ccfSSadaf Ebrahimi const VkRayTracingPipelineCreateInfoNV* pCreateInfos, 1230*b7893ccfSSadaf Ebrahimi const VkAllocationCallbacks* pAllocator, 1231*b7893ccfSSadaf Ebrahimi VkPipeline* pPipelines) { 1232*b7893ccfSSadaf Ebrahimi auto layer_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 1233*b7893ccfSSadaf Ebrahimi bool skip = false; 1234*b7893ccfSSadaf Ebrahimi 1235*b7893ccfSSadaf Ebrahimi#ifdef BUILD_CORE_VALIDATION 1236*b7893ccfSSadaf Ebrahimi create_ray_tracing_pipeline_api_state crtpl_state{}; 1237*b7893ccfSSadaf Ebrahimi#else 1238*b7893ccfSSadaf Ebrahimi struct create_ray_tracing_pipeline_api_state { 1239*b7893ccfSSadaf Ebrahimi const VkRayTracingPipelineCreateInfoNV* pCreateInfos; 1240*b7893ccfSSadaf Ebrahimi } crtpl_state; 1241*b7893ccfSSadaf Ebrahimi#endif 1242*b7893ccfSSadaf Ebrahimi crtpl_state.pCreateInfos = pCreateInfos; 1243*b7893ccfSSadaf Ebrahimi 1244*b7893ccfSSadaf Ebrahimi for (auto intercept : layer_data->object_dispatch) { 1245*b7893ccfSSadaf Ebrahimi auto lock = intercept->write_lock(); 1246*b7893ccfSSadaf Ebrahimi skip |= intercept->PreCallValidateCreateRayTracingPipelinesNV(device, pipelineCache, createInfoCount, pCreateInfos, 1247*b7893ccfSSadaf Ebrahimi pAllocator, pPipelines, &crtpl_state); 1248*b7893ccfSSadaf Ebrahimi if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 1249*b7893ccfSSadaf Ebrahimi } 1250*b7893ccfSSadaf Ebrahimi for (auto intercept : layer_data->object_dispatch) { 1251*b7893ccfSSadaf Ebrahimi auto lock = intercept->write_lock(); 1252*b7893ccfSSadaf Ebrahimi intercept->PreCallRecordCreateRayTracingPipelinesNV(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, 1253*b7893ccfSSadaf Ebrahimi pPipelines, &crtpl_state); 1254*b7893ccfSSadaf Ebrahimi } 1255*b7893ccfSSadaf Ebrahimi VkResult result = DispatchCreateRayTracingPipelinesNV(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines); 1256*b7893ccfSSadaf Ebrahimi for (auto intercept : layer_data->object_dispatch) { 1257*b7893ccfSSadaf Ebrahimi auto lock = intercept->write_lock(); 1258*b7893ccfSSadaf Ebrahimi intercept->PostCallRecordCreateRayTracingPipelinesNV(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, 1259*b7893ccfSSadaf Ebrahimi pPipelines, result, &crtpl_state); 1260*b7893ccfSSadaf Ebrahimi } 1261*b7893ccfSSadaf Ebrahimi return result; 1262*b7893ccfSSadaf Ebrahimi} 1263*b7893ccfSSadaf Ebrahimi 1264*b7893ccfSSadaf Ebrahimi// This API needs the ability to modify a down-chain parameter 1265*b7893ccfSSadaf EbrahimiVKAPI_ATTR VkResult VKAPI_CALL CreatePipelineLayout( 1266*b7893ccfSSadaf Ebrahimi VkDevice device, 1267*b7893ccfSSadaf Ebrahimi const VkPipelineLayoutCreateInfo* pCreateInfo, 1268*b7893ccfSSadaf Ebrahimi const VkAllocationCallbacks* pAllocator, 1269*b7893ccfSSadaf Ebrahimi VkPipelineLayout* pPipelineLayout) { 1270*b7893ccfSSadaf Ebrahimi auto layer_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 1271*b7893ccfSSadaf Ebrahimi bool skip = false; 1272*b7893ccfSSadaf Ebrahimi 1273*b7893ccfSSadaf Ebrahimi#ifndef BUILD_CORE_VALIDATION 1274*b7893ccfSSadaf Ebrahimi struct create_pipeline_layout_api_state { 1275*b7893ccfSSadaf Ebrahimi VkPipelineLayoutCreateInfo modified_create_info; 1276*b7893ccfSSadaf Ebrahimi }; 1277*b7893ccfSSadaf Ebrahimi#endif 1278*b7893ccfSSadaf Ebrahimi create_pipeline_layout_api_state cpl_state{}; 1279*b7893ccfSSadaf Ebrahimi cpl_state.modified_create_info = *pCreateInfo; 1280*b7893ccfSSadaf Ebrahimi 1281*b7893ccfSSadaf Ebrahimi for (auto intercept : layer_data->object_dispatch) { 1282*b7893ccfSSadaf Ebrahimi auto lock = intercept->write_lock(); 1283*b7893ccfSSadaf Ebrahimi skip |= intercept->PreCallValidateCreatePipelineLayout(device, pCreateInfo, pAllocator, pPipelineLayout); 1284*b7893ccfSSadaf Ebrahimi if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 1285*b7893ccfSSadaf Ebrahimi } 1286*b7893ccfSSadaf Ebrahimi for (auto intercept : layer_data->object_dispatch) { 1287*b7893ccfSSadaf Ebrahimi auto lock = intercept->write_lock(); 1288*b7893ccfSSadaf Ebrahimi intercept->PreCallRecordCreatePipelineLayout(device, pCreateInfo, pAllocator, pPipelineLayout, &cpl_state); 1289*b7893ccfSSadaf Ebrahimi } 1290*b7893ccfSSadaf Ebrahimi VkResult result = DispatchCreatePipelineLayout(device, &cpl_state.modified_create_info, pAllocator, pPipelineLayout); 1291*b7893ccfSSadaf Ebrahimi for (auto intercept : layer_data->object_dispatch) { 1292*b7893ccfSSadaf Ebrahimi auto lock = intercept->write_lock(); 1293*b7893ccfSSadaf Ebrahimi intercept->PostCallRecordCreatePipelineLayout(device, pCreateInfo, pAllocator, pPipelineLayout, result); 1294*b7893ccfSSadaf Ebrahimi } 1295*b7893ccfSSadaf Ebrahimi return result; 1296*b7893ccfSSadaf Ebrahimi} 1297*b7893ccfSSadaf Ebrahimi 1298*b7893ccfSSadaf Ebrahimi// This API needs some local stack data for performance reasons and also may modify a parameter 1299*b7893ccfSSadaf EbrahimiVKAPI_ATTR VkResult VKAPI_CALL CreateShaderModule( 1300*b7893ccfSSadaf Ebrahimi VkDevice device, 1301*b7893ccfSSadaf Ebrahimi const VkShaderModuleCreateInfo* pCreateInfo, 1302*b7893ccfSSadaf Ebrahimi const VkAllocationCallbacks* pAllocator, 1303*b7893ccfSSadaf Ebrahimi VkShaderModule* pShaderModule) { 1304*b7893ccfSSadaf Ebrahimi auto layer_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 1305*b7893ccfSSadaf Ebrahimi bool skip = false; 1306*b7893ccfSSadaf Ebrahimi 1307*b7893ccfSSadaf Ebrahimi#ifndef BUILD_CORE_VALIDATION 1308*b7893ccfSSadaf Ebrahimi struct create_shader_module_api_state { 1309*b7893ccfSSadaf Ebrahimi VkShaderModuleCreateInfo instrumented_create_info; 1310*b7893ccfSSadaf Ebrahimi }; 1311*b7893ccfSSadaf Ebrahimi#endif 1312*b7893ccfSSadaf Ebrahimi create_shader_module_api_state csm_state{}; 1313*b7893ccfSSadaf Ebrahimi csm_state.instrumented_create_info = *pCreateInfo; 1314*b7893ccfSSadaf Ebrahimi 1315*b7893ccfSSadaf Ebrahimi for (auto intercept : layer_data->object_dispatch) { 1316*b7893ccfSSadaf Ebrahimi auto lock = intercept->write_lock(); 1317*b7893ccfSSadaf Ebrahimi skip |= intercept->PreCallValidateCreateShaderModule(device, pCreateInfo, pAllocator, pShaderModule, &csm_state); 1318*b7893ccfSSadaf Ebrahimi if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 1319*b7893ccfSSadaf Ebrahimi } 1320*b7893ccfSSadaf Ebrahimi for (auto intercept : layer_data->object_dispatch) { 1321*b7893ccfSSadaf Ebrahimi auto lock = intercept->write_lock(); 1322*b7893ccfSSadaf Ebrahimi intercept->PreCallRecordCreateShaderModule(device, pCreateInfo, pAllocator, pShaderModule, &csm_state); 1323*b7893ccfSSadaf Ebrahimi } 1324*b7893ccfSSadaf Ebrahimi VkResult result = DispatchCreateShaderModule(device, &csm_state.instrumented_create_info, pAllocator, pShaderModule); 1325*b7893ccfSSadaf Ebrahimi for (auto intercept : layer_data->object_dispatch) { 1326*b7893ccfSSadaf Ebrahimi auto lock = intercept->write_lock(); 1327*b7893ccfSSadaf Ebrahimi intercept->PostCallRecordCreateShaderModule(device, pCreateInfo, pAllocator, pShaderModule, result, &csm_state); 1328*b7893ccfSSadaf Ebrahimi } 1329*b7893ccfSSadaf Ebrahimi return result; 1330*b7893ccfSSadaf Ebrahimi} 1331*b7893ccfSSadaf Ebrahimi 1332*b7893ccfSSadaf EbrahimiVKAPI_ATTR VkResult VKAPI_CALL AllocateDescriptorSets( 1333*b7893ccfSSadaf Ebrahimi VkDevice device, 1334*b7893ccfSSadaf Ebrahimi const VkDescriptorSetAllocateInfo* pAllocateInfo, 1335*b7893ccfSSadaf Ebrahimi VkDescriptorSet* pDescriptorSets) { 1336*b7893ccfSSadaf Ebrahimi auto layer_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 1337*b7893ccfSSadaf Ebrahimi bool skip = false; 1338*b7893ccfSSadaf Ebrahimi 1339*b7893ccfSSadaf Ebrahimi#ifdef BUILD_CORE_VALIDATION 1340*b7893ccfSSadaf Ebrahimi cvdescriptorset::AllocateDescriptorSetsData ads_state(pAllocateInfo->descriptorSetCount); 1341*b7893ccfSSadaf Ebrahimi#else 1342*b7893ccfSSadaf Ebrahimi struct ads_state {} ads_state; 1343*b7893ccfSSadaf Ebrahimi#endif 1344*b7893ccfSSadaf Ebrahimi 1345*b7893ccfSSadaf Ebrahimi for (auto intercept : layer_data->object_dispatch) { 1346*b7893ccfSSadaf Ebrahimi auto lock = intercept->write_lock(); 1347*b7893ccfSSadaf Ebrahimi skip |= intercept->PreCallValidateAllocateDescriptorSets(device, pAllocateInfo, pDescriptorSets, &ads_state); 1348*b7893ccfSSadaf Ebrahimi if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 1349*b7893ccfSSadaf Ebrahimi } 1350*b7893ccfSSadaf Ebrahimi for (auto intercept : layer_data->object_dispatch) { 1351*b7893ccfSSadaf Ebrahimi auto lock = intercept->write_lock(); 1352*b7893ccfSSadaf Ebrahimi intercept->PreCallRecordAllocateDescriptorSets(device, pAllocateInfo, pDescriptorSets); 1353*b7893ccfSSadaf Ebrahimi } 1354*b7893ccfSSadaf Ebrahimi VkResult result = DispatchAllocateDescriptorSets(device, pAllocateInfo, pDescriptorSets); 1355*b7893ccfSSadaf Ebrahimi for (auto intercept : layer_data->object_dispatch) { 1356*b7893ccfSSadaf Ebrahimi auto lock = intercept->write_lock(); 1357*b7893ccfSSadaf Ebrahimi intercept->PostCallRecordAllocateDescriptorSets(device, pAllocateInfo, pDescriptorSets, result, &ads_state); 1358*b7893ccfSSadaf Ebrahimi } 1359*b7893ccfSSadaf Ebrahimi return result; 1360*b7893ccfSSadaf Ebrahimi} 1361*b7893ccfSSadaf Ebrahimi 1362*b7893ccfSSadaf Ebrahimi 1363*b7893ccfSSadaf Ebrahimi 1364*b7893ccfSSadaf Ebrahimi 1365*b7893ccfSSadaf Ebrahimi 1366*b7893ccfSSadaf Ebrahimi// ValidationCache APIs do not dispatch 1367*b7893ccfSSadaf Ebrahimi 1368*b7893ccfSSadaf EbrahimiVKAPI_ATTR VkResult VKAPI_CALL CreateValidationCacheEXT( 1369*b7893ccfSSadaf Ebrahimi VkDevice device, 1370*b7893ccfSSadaf Ebrahimi const VkValidationCacheCreateInfoEXT* pCreateInfo, 1371*b7893ccfSSadaf Ebrahimi const VkAllocationCallbacks* pAllocator, 1372*b7893ccfSSadaf Ebrahimi VkValidationCacheEXT* pValidationCache) { 1373*b7893ccfSSadaf Ebrahimi auto layer_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 1374*b7893ccfSSadaf Ebrahimi VkResult result = VK_SUCCESS; 1375*b7893ccfSSadaf Ebrahimi 1376*b7893ccfSSadaf Ebrahimi ValidationObject *validation_data = layer_data->GetValidationObject(layer_data->object_dispatch, LayerObjectTypeCoreValidation); 1377*b7893ccfSSadaf Ebrahimi if (validation_data) { 1378*b7893ccfSSadaf Ebrahimi auto lock = validation_data->write_lock(); 1379*b7893ccfSSadaf Ebrahimi result = validation_data->CoreLayerCreateValidationCacheEXT(device, pCreateInfo, pAllocator, pValidationCache); 1380*b7893ccfSSadaf Ebrahimi } 1381*b7893ccfSSadaf Ebrahimi return result; 1382*b7893ccfSSadaf Ebrahimi} 1383*b7893ccfSSadaf Ebrahimi 1384*b7893ccfSSadaf EbrahimiVKAPI_ATTR void VKAPI_CALL DestroyValidationCacheEXT( 1385*b7893ccfSSadaf Ebrahimi VkDevice device, 1386*b7893ccfSSadaf Ebrahimi VkValidationCacheEXT validationCache, 1387*b7893ccfSSadaf Ebrahimi const VkAllocationCallbacks* pAllocator) { 1388*b7893ccfSSadaf Ebrahimi auto layer_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 1389*b7893ccfSSadaf Ebrahimi 1390*b7893ccfSSadaf Ebrahimi ValidationObject *validation_data = layer_data->GetValidationObject(layer_data->object_dispatch, LayerObjectTypeCoreValidation); 1391*b7893ccfSSadaf Ebrahimi if (validation_data) { 1392*b7893ccfSSadaf Ebrahimi auto lock = validation_data->write_lock(); 1393*b7893ccfSSadaf Ebrahimi validation_data->CoreLayerDestroyValidationCacheEXT(device, validationCache, pAllocator); 1394*b7893ccfSSadaf Ebrahimi } 1395*b7893ccfSSadaf Ebrahimi} 1396*b7893ccfSSadaf Ebrahimi 1397*b7893ccfSSadaf EbrahimiVKAPI_ATTR VkResult VKAPI_CALL MergeValidationCachesEXT( 1398*b7893ccfSSadaf Ebrahimi VkDevice device, 1399*b7893ccfSSadaf Ebrahimi VkValidationCacheEXT dstCache, 1400*b7893ccfSSadaf Ebrahimi uint32_t srcCacheCount, 1401*b7893ccfSSadaf Ebrahimi const VkValidationCacheEXT* pSrcCaches) { 1402*b7893ccfSSadaf Ebrahimi auto layer_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 1403*b7893ccfSSadaf Ebrahimi VkResult result = VK_SUCCESS; 1404*b7893ccfSSadaf Ebrahimi 1405*b7893ccfSSadaf Ebrahimi ValidationObject *validation_data = layer_data->GetValidationObject(layer_data->object_dispatch, LayerObjectTypeCoreValidation); 1406*b7893ccfSSadaf Ebrahimi if (validation_data) { 1407*b7893ccfSSadaf Ebrahimi auto lock = validation_data->write_lock(); 1408*b7893ccfSSadaf Ebrahimi result = validation_data->CoreLayerMergeValidationCachesEXT(device, dstCache, srcCacheCount, pSrcCaches); 1409*b7893ccfSSadaf Ebrahimi } 1410*b7893ccfSSadaf Ebrahimi return result; 1411*b7893ccfSSadaf Ebrahimi} 1412*b7893ccfSSadaf Ebrahimi 1413*b7893ccfSSadaf EbrahimiVKAPI_ATTR VkResult VKAPI_CALL GetValidationCacheDataEXT( 1414*b7893ccfSSadaf Ebrahimi VkDevice device, 1415*b7893ccfSSadaf Ebrahimi VkValidationCacheEXT validationCache, 1416*b7893ccfSSadaf Ebrahimi size_t* pDataSize, 1417*b7893ccfSSadaf Ebrahimi void* pData) { 1418*b7893ccfSSadaf Ebrahimi auto layer_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 1419*b7893ccfSSadaf Ebrahimi VkResult result = VK_SUCCESS; 1420*b7893ccfSSadaf Ebrahimi 1421*b7893ccfSSadaf Ebrahimi ValidationObject *validation_data = layer_data->GetValidationObject(layer_data->object_dispatch, LayerObjectTypeCoreValidation); 1422*b7893ccfSSadaf Ebrahimi if (validation_data) { 1423*b7893ccfSSadaf Ebrahimi auto lock = validation_data->write_lock(); 1424*b7893ccfSSadaf Ebrahimi result = validation_data->CoreLayerGetValidationCacheDataEXT(device, validationCache, pDataSize, pData); 1425*b7893ccfSSadaf Ebrahimi } 1426*b7893ccfSSadaf Ebrahimi return result; 1427*b7893ccfSSadaf Ebrahimi 1428*b7893ccfSSadaf Ebrahimi}""" 1429*b7893ccfSSadaf Ebrahimi 1430*b7893ccfSSadaf Ebrahimi inline_custom_validation_class_definitions = """ 1431*b7893ccfSSadaf Ebrahimi virtual VkResult CoreLayerCreateValidationCacheEXT(VkDevice device, const VkValidationCacheCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkValidationCacheEXT* pValidationCache) { return VK_SUCCESS; }; 1432*b7893ccfSSadaf Ebrahimi virtual void CoreLayerDestroyValidationCacheEXT(VkDevice device, VkValidationCacheEXT validationCache, const VkAllocationCallbacks* pAllocator) {}; 1433*b7893ccfSSadaf Ebrahimi virtual VkResult CoreLayerMergeValidationCachesEXT(VkDevice device, VkValidationCacheEXT dstCache, uint32_t srcCacheCount, const VkValidationCacheEXT* pSrcCaches) { return VK_SUCCESS; }; 1434*b7893ccfSSadaf Ebrahimi virtual VkResult CoreLayerGetValidationCacheDataEXT(VkDevice device, VkValidationCacheEXT validationCache, size_t* pDataSize, void* pData) { return VK_SUCCESS; }; 1435*b7893ccfSSadaf Ebrahimi 1436*b7893ccfSSadaf Ebrahimi // Allow additional state parameter for CreateGraphicsPipelines 1437*b7893ccfSSadaf Ebrahimi virtual bool PreCallValidateCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkGraphicsPipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines, void* cgpl_state) { 1438*b7893ccfSSadaf Ebrahimi return PreCallValidateCreateGraphicsPipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines); 1439*b7893ccfSSadaf Ebrahimi }; 1440*b7893ccfSSadaf Ebrahimi virtual void PreCallRecordCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkGraphicsPipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines, void* cgpl_state) { 1441*b7893ccfSSadaf Ebrahimi PreCallRecordCreateGraphicsPipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines); 1442*b7893ccfSSadaf Ebrahimi }; 1443*b7893ccfSSadaf Ebrahimi virtual void PostCallRecordCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkGraphicsPipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines, VkResult result, void* cgpl_state) { 1444*b7893ccfSSadaf Ebrahimi PostCallRecordCreateGraphicsPipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines, result); 1445*b7893ccfSSadaf Ebrahimi }; 1446*b7893ccfSSadaf Ebrahimi 1447*b7893ccfSSadaf Ebrahimi // Allow additional state parameter for CreateComputePipelines 1448*b7893ccfSSadaf Ebrahimi virtual bool PreCallValidateCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkComputePipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines, void* pipe_state) { 1449*b7893ccfSSadaf Ebrahimi return PreCallValidateCreateComputePipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines); 1450*b7893ccfSSadaf Ebrahimi }; 1451*b7893ccfSSadaf Ebrahimi virtual void PreCallRecordCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkComputePipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines, void* ccpl_state) { 1452*b7893ccfSSadaf Ebrahimi PreCallRecordCreateComputePipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines); 1453*b7893ccfSSadaf Ebrahimi }; 1454*b7893ccfSSadaf Ebrahimi virtual void PostCallRecordCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkComputePipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines, VkResult result, void* pipe_state) { 1455*b7893ccfSSadaf Ebrahimi PostCallRecordCreateComputePipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines, result); 1456*b7893ccfSSadaf Ebrahimi }; 1457*b7893ccfSSadaf Ebrahimi 1458*b7893ccfSSadaf Ebrahimi // Allow additional state parameter for CreateRayTracingPipelinesNV 1459*b7893ccfSSadaf Ebrahimi virtual bool PreCallValidateCreateRayTracingPipelinesNV(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkRayTracingPipelineCreateInfoNV* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines, void* pipe_state) { 1460*b7893ccfSSadaf Ebrahimi return PreCallValidateCreateRayTracingPipelinesNV(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines); 1461*b7893ccfSSadaf Ebrahimi }; 1462*b7893ccfSSadaf Ebrahimi virtual void PreCallRecordCreateRayTracingPipelinesNV(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkRayTracingPipelineCreateInfoNV* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines, void* ccpl_state) { 1463*b7893ccfSSadaf Ebrahimi PreCallRecordCreateRayTracingPipelinesNV(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines); 1464*b7893ccfSSadaf Ebrahimi }; 1465*b7893ccfSSadaf Ebrahimi virtual void PostCallRecordCreateRayTracingPipelinesNV(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkRayTracingPipelineCreateInfoNV* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines, VkResult result, void* pipe_state) { 1466*b7893ccfSSadaf Ebrahimi PostCallRecordCreateRayTracingPipelinesNV(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines, result); 1467*b7893ccfSSadaf Ebrahimi }; 1468*b7893ccfSSadaf Ebrahimi 1469*b7893ccfSSadaf Ebrahimi // Allow modification of a down-chain parameter for CreatePipelineLayout 1470*b7893ccfSSadaf Ebrahimi virtual void PreCallRecordCreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPipelineLayout* pPipelineLayout, void *cpl_state) { 1471*b7893ccfSSadaf Ebrahimi PreCallRecordCreatePipelineLayout(device, pCreateInfo, pAllocator, pPipelineLayout); 1472*b7893ccfSSadaf Ebrahimi }; 1473*b7893ccfSSadaf Ebrahimi 1474*b7893ccfSSadaf Ebrahimi // Enable the CreateShaderModule API to take an extra argument for state preservation and paramter modification 1475*b7893ccfSSadaf Ebrahimi virtual bool PreCallValidateCreateShaderModule(VkDevice device, const VkShaderModuleCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkShaderModule* pShaderModule, void* csm_state) { 1476*b7893ccfSSadaf Ebrahimi return PreCallValidateCreateShaderModule(device, pCreateInfo, pAllocator, pShaderModule); 1477*b7893ccfSSadaf Ebrahimi }; 1478*b7893ccfSSadaf Ebrahimi virtual void PreCallRecordCreateShaderModule(VkDevice device, const VkShaderModuleCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkShaderModule* pShaderModule, void* csm_state) { 1479*b7893ccfSSadaf Ebrahimi PreCallRecordCreateShaderModule(device, pCreateInfo, pAllocator, pShaderModule); 1480*b7893ccfSSadaf Ebrahimi }; 1481*b7893ccfSSadaf Ebrahimi virtual void PostCallRecordCreateShaderModule(VkDevice device, const VkShaderModuleCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkShaderModule* pShaderModule, VkResult result, void* csm_state) { 1482*b7893ccfSSadaf Ebrahimi PostCallRecordCreateShaderModule(device, pCreateInfo, pAllocator, pShaderModule, result); 1483*b7893ccfSSadaf Ebrahimi }; 1484*b7893ccfSSadaf Ebrahimi 1485*b7893ccfSSadaf Ebrahimi // Allow AllocateDescriptorSets to use some local stack storage for performance purposes 1486*b7893ccfSSadaf Ebrahimi virtual bool PreCallValidateAllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo* pAllocateInfo, VkDescriptorSet* pDescriptorSets, void* ads_state) { 1487*b7893ccfSSadaf Ebrahimi return PreCallValidateAllocateDescriptorSets(device, pAllocateInfo, pDescriptorSets); 1488*b7893ccfSSadaf Ebrahimi }; 1489*b7893ccfSSadaf Ebrahimi virtual void PostCallRecordAllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo* pAllocateInfo, VkDescriptorSet* pDescriptorSets, VkResult result, void* ads_state) { 1490*b7893ccfSSadaf Ebrahimi PostCallRecordAllocateDescriptorSets(device, pAllocateInfo, pDescriptorSets, result); 1491*b7893ccfSSadaf Ebrahimi }; 1492*b7893ccfSSadaf Ebrahimi 1493*b7893ccfSSadaf Ebrahimi // Modify a parameter to CreateDevice 1494*b7893ccfSSadaf Ebrahimi virtual void PreCallRecordCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice, safe_VkDeviceCreateInfo *modified_create_info) { 1495*b7893ccfSSadaf Ebrahimi PreCallRecordCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice); 1496*b7893ccfSSadaf Ebrahimi }; 1497*b7893ccfSSadaf Ebrahimi""" 1498*b7893ccfSSadaf Ebrahimi 1499*b7893ccfSSadaf Ebrahimi inline_custom_source_postamble = """ 1500*b7893ccfSSadaf Ebrahimi// loader-layer interface v0, just wrappers since there is only a layer 1501*b7893ccfSSadaf Ebrahimi 1502*b7893ccfSSadaf EbrahimiVK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount, 1503*b7893ccfSSadaf Ebrahimi VkExtensionProperties *pProperties) { 1504*b7893ccfSSadaf Ebrahimi return vulkan_layer_chassis::EnumerateInstanceExtensionProperties(pLayerName, pCount, pProperties); 1505*b7893ccfSSadaf Ebrahimi} 1506*b7893ccfSSadaf Ebrahimi 1507*b7893ccfSSadaf EbrahimiVK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(uint32_t *pCount, 1508*b7893ccfSSadaf Ebrahimi VkLayerProperties *pProperties) { 1509*b7893ccfSSadaf Ebrahimi return vulkan_layer_chassis::EnumerateInstanceLayerProperties(pCount, pProperties); 1510*b7893ccfSSadaf Ebrahimi} 1511*b7893ccfSSadaf Ebrahimi 1512*b7893ccfSSadaf EbrahimiVK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount, 1513*b7893ccfSSadaf Ebrahimi VkLayerProperties *pProperties) { 1514*b7893ccfSSadaf Ebrahimi // the layer command handles VK_NULL_HANDLE just fine internally 1515*b7893ccfSSadaf Ebrahimi assert(physicalDevice == VK_NULL_HANDLE); 1516*b7893ccfSSadaf Ebrahimi return vulkan_layer_chassis::EnumerateDeviceLayerProperties(VK_NULL_HANDLE, pCount, pProperties); 1517*b7893ccfSSadaf Ebrahimi} 1518*b7893ccfSSadaf Ebrahimi 1519*b7893ccfSSadaf EbrahimiVK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, 1520*b7893ccfSSadaf Ebrahimi const char *pLayerName, uint32_t *pCount, 1521*b7893ccfSSadaf Ebrahimi VkExtensionProperties *pProperties) { 1522*b7893ccfSSadaf Ebrahimi // the layer command handles VK_NULL_HANDLE just fine internally 1523*b7893ccfSSadaf Ebrahimi assert(physicalDevice == VK_NULL_HANDLE); 1524*b7893ccfSSadaf Ebrahimi return vulkan_layer_chassis::EnumerateDeviceExtensionProperties(VK_NULL_HANDLE, pLayerName, pCount, pProperties); 1525*b7893ccfSSadaf Ebrahimi} 1526*b7893ccfSSadaf Ebrahimi 1527*b7893ccfSSadaf EbrahimiVK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice dev, const char *funcName) { 1528*b7893ccfSSadaf Ebrahimi return vulkan_layer_chassis::GetDeviceProcAddr(dev, funcName); 1529*b7893ccfSSadaf Ebrahimi} 1530*b7893ccfSSadaf Ebrahimi 1531*b7893ccfSSadaf EbrahimiVK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *funcName) { 1532*b7893ccfSSadaf Ebrahimi return vulkan_layer_chassis::GetInstanceProcAddr(instance, funcName); 1533*b7893ccfSSadaf Ebrahimi} 1534*b7893ccfSSadaf Ebrahimi 1535*b7893ccfSSadaf EbrahimiVK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkNegotiateLoaderLayerInterfaceVersion(VkNegotiateLayerInterface *pVersionStruct) { 1536*b7893ccfSSadaf Ebrahimi assert(pVersionStruct != NULL); 1537*b7893ccfSSadaf Ebrahimi assert(pVersionStruct->sType == LAYER_NEGOTIATE_INTERFACE_STRUCT); 1538*b7893ccfSSadaf Ebrahimi 1539*b7893ccfSSadaf Ebrahimi // Fill in the function pointers if our version is at least capable of having the structure contain them. 1540*b7893ccfSSadaf Ebrahimi if (pVersionStruct->loaderLayerInterfaceVersion >= 2) { 1541*b7893ccfSSadaf Ebrahimi pVersionStruct->pfnGetInstanceProcAddr = vkGetInstanceProcAddr; 1542*b7893ccfSSadaf Ebrahimi pVersionStruct->pfnGetDeviceProcAddr = vkGetDeviceProcAddr; 1543*b7893ccfSSadaf Ebrahimi pVersionStruct->pfnGetPhysicalDeviceProcAddr = nullptr; 1544*b7893ccfSSadaf Ebrahimi } 1545*b7893ccfSSadaf Ebrahimi 1546*b7893ccfSSadaf Ebrahimi return VK_SUCCESS; 1547*b7893ccfSSadaf Ebrahimi}""" 1548*b7893ccfSSadaf Ebrahimi 1549*b7893ccfSSadaf Ebrahimi 1550*b7893ccfSSadaf Ebrahimi def __init__(self, 1551*b7893ccfSSadaf Ebrahimi errFile = sys.stderr, 1552*b7893ccfSSadaf Ebrahimi warnFile = sys.stderr, 1553*b7893ccfSSadaf Ebrahimi diagFile = sys.stdout): 1554*b7893ccfSSadaf Ebrahimi OutputGenerator.__init__(self, errFile, warnFile, diagFile) 1555*b7893ccfSSadaf Ebrahimi # Internal state - accumulators for different inner block text 1556*b7893ccfSSadaf Ebrahimi self.sections = dict([(section, []) for section in self.ALL_SECTIONS]) 1557*b7893ccfSSadaf Ebrahimi self.intercepts = [] 1558*b7893ccfSSadaf Ebrahimi self.layer_factory = '' # String containing base layer factory class definition 1559*b7893ccfSSadaf Ebrahimi 1560*b7893ccfSSadaf Ebrahimi # Check if the parameter passed in is a pointer to an array 1561*b7893ccfSSadaf Ebrahimi def paramIsArray(self, param): 1562*b7893ccfSSadaf Ebrahimi return param.attrib.get('len') is not None 1563*b7893ccfSSadaf Ebrahimi 1564*b7893ccfSSadaf Ebrahimi # Check if the parameter passed in is a pointer 1565*b7893ccfSSadaf Ebrahimi def paramIsPointer(self, param): 1566*b7893ccfSSadaf Ebrahimi ispointer = False 1567*b7893ccfSSadaf Ebrahimi for elem in param: 1568*b7893ccfSSadaf Ebrahimi if elem.tag == 'type' and elem.tail is not None and '*' in elem.tail: 1569*b7893ccfSSadaf Ebrahimi ispointer = True 1570*b7893ccfSSadaf Ebrahimi return ispointer 1571*b7893ccfSSadaf Ebrahimi 1572*b7893ccfSSadaf Ebrahimi # 1573*b7893ccfSSadaf Ebrahimi # 1574*b7893ccfSSadaf Ebrahimi def beginFile(self, genOpts): 1575*b7893ccfSSadaf Ebrahimi OutputGenerator.beginFile(self, genOpts) 1576*b7893ccfSSadaf Ebrahimi # Output Copyright 1577*b7893ccfSSadaf Ebrahimi write(self.inline_copyright_message, file=self.outFile) 1578*b7893ccfSSadaf Ebrahimi # Multiple inclusion protection 1579*b7893ccfSSadaf Ebrahimi self.header = False 1580*b7893ccfSSadaf Ebrahimi if (self.genOpts.filename and 'h' == self.genOpts.filename[-1]): 1581*b7893ccfSSadaf Ebrahimi self.header = True 1582*b7893ccfSSadaf Ebrahimi write('#pragma once', file=self.outFile) 1583*b7893ccfSSadaf Ebrahimi self.newline() 1584*b7893ccfSSadaf Ebrahimi if self.header: 1585*b7893ccfSSadaf Ebrahimi write(self.inline_custom_header_preamble, file=self.outFile) 1586*b7893ccfSSadaf Ebrahimi else: 1587*b7893ccfSSadaf Ebrahimi write(self.inline_custom_source_preamble, file=self.outFile) 1588*b7893ccfSSadaf Ebrahimi self.layer_factory += self.inline_custom_header_class_definition 1589*b7893ccfSSadaf Ebrahimi # 1590*b7893ccfSSadaf Ebrahimi # 1591*b7893ccfSSadaf Ebrahimi def endFile(self): 1592*b7893ccfSSadaf Ebrahimi # Finish C++ namespace and multiple inclusion protection 1593*b7893ccfSSadaf Ebrahimi self.newline() 1594*b7893ccfSSadaf Ebrahimi if not self.header: 1595*b7893ccfSSadaf Ebrahimi # Record intercepted procedures 1596*b7893ccfSSadaf Ebrahimi write('// Map of intercepted ApiName to its associated function data', file=self.outFile) 1597*b7893ccfSSadaf Ebrahimi write('const std::unordered_map<std::string, function_data> name_to_funcptr_map = {', file=self.outFile) 1598*b7893ccfSSadaf Ebrahimi write('\n'.join(self.intercepts), file=self.outFile) 1599*b7893ccfSSadaf Ebrahimi write('};\n', file=self.outFile) 1600*b7893ccfSSadaf Ebrahimi self.newline() 1601*b7893ccfSSadaf Ebrahimi write('} // namespace vulkan_layer_chassis', file=self.outFile) 1602*b7893ccfSSadaf Ebrahimi if self.header: 1603*b7893ccfSSadaf Ebrahimi self.newline() 1604*b7893ccfSSadaf Ebrahimi # Output Layer Factory Class Definitions 1605*b7893ccfSSadaf Ebrahimi self.layer_factory += self.inline_custom_validation_class_definitions 1606*b7893ccfSSadaf Ebrahimi self.layer_factory += '};\n\n' 1607*b7893ccfSSadaf Ebrahimi self.layer_factory += 'extern std::unordered_map<void*, ValidationObject*> layer_data_map;' 1608*b7893ccfSSadaf Ebrahimi write(self.layer_factory, file=self.outFile) 1609*b7893ccfSSadaf Ebrahimi else: 1610*b7893ccfSSadaf Ebrahimi write(self.inline_custom_source_postamble, file=self.outFile) 1611*b7893ccfSSadaf Ebrahimi # Finish processing in superclass 1612*b7893ccfSSadaf Ebrahimi OutputGenerator.endFile(self) 1613*b7893ccfSSadaf Ebrahimi 1614*b7893ccfSSadaf Ebrahimi def beginFeature(self, interface, emit): 1615*b7893ccfSSadaf Ebrahimi # Start processing in superclass 1616*b7893ccfSSadaf Ebrahimi OutputGenerator.beginFeature(self, interface, emit) 1617*b7893ccfSSadaf Ebrahimi # Get feature extra protect 1618*b7893ccfSSadaf Ebrahimi self.featureExtraProtect = GetFeatureProtect(interface) 1619*b7893ccfSSadaf Ebrahimi # Accumulate includes, defines, types, enums, function pointer typedefs, end function prototypes separately for this 1620*b7893ccfSSadaf Ebrahimi # feature. They're only printed in endFeature(). 1621*b7893ccfSSadaf Ebrahimi self.sections = dict([(section, []) for section in self.ALL_SECTIONS]) 1622*b7893ccfSSadaf Ebrahimi 1623*b7893ccfSSadaf Ebrahimi def endFeature(self): 1624*b7893ccfSSadaf Ebrahimi # Actually write the interface to the output file. 1625*b7893ccfSSadaf Ebrahimi if (self.emit): 1626*b7893ccfSSadaf Ebrahimi self.newline() 1627*b7893ccfSSadaf Ebrahimi # If type declarations are needed by other features based on this one, it may be necessary to suppress the ExtraProtect, 1628*b7893ccfSSadaf Ebrahimi # or move it below the 'for section...' loop. 1629*b7893ccfSSadaf Ebrahimi if (self.featureExtraProtect != None): 1630*b7893ccfSSadaf Ebrahimi write('#ifdef', self.featureExtraProtect, file=self.outFile) 1631*b7893ccfSSadaf Ebrahimi for section in self.TYPE_SECTIONS: 1632*b7893ccfSSadaf Ebrahimi contents = self.sections[section] 1633*b7893ccfSSadaf Ebrahimi if contents: 1634*b7893ccfSSadaf Ebrahimi write('\n'.join(contents), file=self.outFile) 1635*b7893ccfSSadaf Ebrahimi self.newline() 1636*b7893ccfSSadaf Ebrahimi if (self.sections['command']): 1637*b7893ccfSSadaf Ebrahimi write('\n'.join(self.sections['command']), end=u'', file=self.outFile) 1638*b7893ccfSSadaf Ebrahimi self.newline() 1639*b7893ccfSSadaf Ebrahimi if (self.featureExtraProtect != None): 1640*b7893ccfSSadaf Ebrahimi write('#endif //', self.featureExtraProtect, file=self.outFile) 1641*b7893ccfSSadaf Ebrahimi # Finish processing in superclass 1642*b7893ccfSSadaf Ebrahimi OutputGenerator.endFeature(self) 1643*b7893ccfSSadaf Ebrahimi # 1644*b7893ccfSSadaf Ebrahimi # Append a definition to the specified section 1645*b7893ccfSSadaf Ebrahimi def appendSection(self, section, text): 1646*b7893ccfSSadaf Ebrahimi self.sections[section].append(text) 1647*b7893ccfSSadaf Ebrahimi # 1648*b7893ccfSSadaf Ebrahimi # Type generation 1649*b7893ccfSSadaf Ebrahimi def genType(self, typeinfo, name, alias): 1650*b7893ccfSSadaf Ebrahimi pass 1651*b7893ccfSSadaf Ebrahimi # 1652*b7893ccfSSadaf Ebrahimi # Struct (e.g. C "struct" type) generation. This is a special case of the <type> tag where the contents are 1653*b7893ccfSSadaf Ebrahimi # interpreted as a set of <member> tags instead of freeform C type declarations. The <member> tags are just like <param> 1654*b7893ccfSSadaf Ebrahimi # tags - they are a declaration of a struct or union member. Only simple member declarations are supported (no nested 1655*b7893ccfSSadaf Ebrahimi # structs etc.) 1656*b7893ccfSSadaf Ebrahimi def genStruct(self, typeinfo, typeName): 1657*b7893ccfSSadaf Ebrahimi OutputGenerator.genStruct(self, typeinfo, typeName) 1658*b7893ccfSSadaf Ebrahimi body = 'typedef ' + typeinfo.elem.get('category') + ' ' + typeName + ' {\n' 1659*b7893ccfSSadaf Ebrahimi # paramdecl = self.makeCParamDecl(typeinfo.elem, self.genOpts.alignFuncParam) 1660*b7893ccfSSadaf Ebrahimi for member in typeinfo.elem.findall('.//member'): 1661*b7893ccfSSadaf Ebrahimi body += self.makeCParamDecl(member, self.genOpts.alignFuncParam) 1662*b7893ccfSSadaf Ebrahimi body += ';\n' 1663*b7893ccfSSadaf Ebrahimi body += '} ' + typeName + ';\n' 1664*b7893ccfSSadaf Ebrahimi self.appendSection('struct', body) 1665*b7893ccfSSadaf Ebrahimi # 1666*b7893ccfSSadaf Ebrahimi # Group (e.g. C "enum" type) generation. These are concatenated together with other types. 1667*b7893ccfSSadaf Ebrahimi def genGroup(self, groupinfo, groupName, alias): 1668*b7893ccfSSadaf Ebrahimi pass 1669*b7893ccfSSadaf Ebrahimi # Enumerant generation 1670*b7893ccfSSadaf Ebrahimi # <enum> tags may specify their values in several ways, but are usually just integers. 1671*b7893ccfSSadaf Ebrahimi def genEnum(self, enuminfo, name, alias): 1672*b7893ccfSSadaf Ebrahimi pass 1673*b7893ccfSSadaf Ebrahimi # 1674*b7893ccfSSadaf Ebrahimi # Customize Cdecl for layer factory base class 1675*b7893ccfSSadaf Ebrahimi def BaseClassCdecl(self, elem, name): 1676*b7893ccfSSadaf Ebrahimi raw = self.makeCDecls(elem)[1] 1677*b7893ccfSSadaf Ebrahimi 1678*b7893ccfSSadaf Ebrahimi # Toss everything before the undecorated name 1679*b7893ccfSSadaf Ebrahimi prototype = raw.split("VKAPI_PTR *PFN_vk")[1] 1680*b7893ccfSSadaf Ebrahimi prototype = prototype.replace(")", "", 1) 1681*b7893ccfSSadaf Ebrahimi prototype = prototype.replace(";", " {};") 1682*b7893ccfSSadaf Ebrahimi 1683*b7893ccfSSadaf Ebrahimi # Build up pre/post call virtual function declarations 1684*b7893ccfSSadaf Ebrahimi pre_call_validate = 'virtual bool PreCallValidate' + prototype 1685*b7893ccfSSadaf Ebrahimi pre_call_validate = pre_call_validate.replace("{}", " { return false; }") 1686*b7893ccfSSadaf Ebrahimi pre_call_record = 'virtual void PreCallRecord' + prototype 1687*b7893ccfSSadaf Ebrahimi post_call_record = 'virtual void PostCallRecord' + prototype 1688*b7893ccfSSadaf Ebrahimi resulttype = elem.find('proto/type') 1689*b7893ccfSSadaf Ebrahimi if resulttype.text == 'VkResult': 1690*b7893ccfSSadaf Ebrahimi post_call_record = post_call_record.replace(')', ', VkResult result)') 1691*b7893ccfSSadaf Ebrahimi return ' %s\n %s\n %s\n' % (pre_call_validate, pre_call_record, post_call_record) 1692*b7893ccfSSadaf Ebrahimi # 1693*b7893ccfSSadaf Ebrahimi # Command generation 1694*b7893ccfSSadaf Ebrahimi def genCmd(self, cmdinfo, name, alias): 1695*b7893ccfSSadaf Ebrahimi ignore_functions = [ 1696*b7893ccfSSadaf Ebrahimi 'vkEnumerateInstanceVersion', 1697*b7893ccfSSadaf Ebrahimi ] 1698*b7893ccfSSadaf Ebrahimi 1699*b7893ccfSSadaf Ebrahimi if name in ignore_functions: 1700*b7893ccfSSadaf Ebrahimi return 1701*b7893ccfSSadaf Ebrahimi 1702*b7893ccfSSadaf Ebrahimi if self.header: # In the header declare all intercepts 1703*b7893ccfSSadaf Ebrahimi self.appendSection('command', '') 1704*b7893ccfSSadaf Ebrahimi self.appendSection('command', self.makeCDecls(cmdinfo.elem)[0]) 1705*b7893ccfSSadaf Ebrahimi if (self.featureExtraProtect != None): 1706*b7893ccfSSadaf Ebrahimi self.layer_factory += '#ifdef %s\n' % self.featureExtraProtect 1707*b7893ccfSSadaf Ebrahimi # Update base class with virtual function declarations 1708*b7893ccfSSadaf Ebrahimi if 'ValidationCache' not in name: 1709*b7893ccfSSadaf Ebrahimi self.layer_factory += self.BaseClassCdecl(cmdinfo.elem, name) 1710*b7893ccfSSadaf Ebrahimi if (self.featureExtraProtect != None): 1711*b7893ccfSSadaf Ebrahimi self.layer_factory += '#endif\n' 1712*b7893ccfSSadaf Ebrahimi return 1713*b7893ccfSSadaf Ebrahimi 1714*b7893ccfSSadaf Ebrahimi is_instance = 'false' 1715*b7893ccfSSadaf Ebrahimi dispatchable_type = cmdinfo.elem.find('param/type').text 1716*b7893ccfSSadaf Ebrahimi if dispatchable_type in ["VkPhysicalDevice", "VkInstance"] or name == 'vkCreateInstance': 1717*b7893ccfSSadaf Ebrahimi is_instance = 'true' 1718*b7893ccfSSadaf Ebrahimi 1719*b7893ccfSSadaf Ebrahimi if name in self.manual_functions: 1720*b7893ccfSSadaf Ebrahimi if 'ValidationCache' not in name: 1721*b7893ccfSSadaf Ebrahimi self.intercepts += [ ' {"%s", {%s, (void*)%s}},' % (name, is_instance, name[2:]) ] 1722*b7893ccfSSadaf Ebrahimi else: 1723*b7893ccfSSadaf Ebrahimi self.intercepts += [ '#ifdef BUILD_CORE_VALIDATION' ] 1724*b7893ccfSSadaf Ebrahimi 1725*b7893ccfSSadaf Ebrahimi self.intercepts += [ ' {"%s", {%s, (void*)%s}},' % (name, is_instance, name[2:]) ] 1726*b7893ccfSSadaf Ebrahimi self.intercepts += [ '#endif' ] 1727*b7893ccfSSadaf Ebrahimi return 1728*b7893ccfSSadaf Ebrahimi # Record that the function will be intercepted 1729*b7893ccfSSadaf Ebrahimi if (self.featureExtraProtect != None): 1730*b7893ccfSSadaf Ebrahimi self.intercepts += [ '#ifdef %s' % self.featureExtraProtect ] 1731*b7893ccfSSadaf Ebrahimi self.intercepts += [ ' {"%s", {%s, (void*)%s}},' % (name, is_instance, name[2:]) ] 1732*b7893ccfSSadaf Ebrahimi if (self.featureExtraProtect != None): 1733*b7893ccfSSadaf Ebrahimi self.intercepts += [ '#endif' ] 1734*b7893ccfSSadaf Ebrahimi OutputGenerator.genCmd(self, cmdinfo, name, alias) 1735*b7893ccfSSadaf Ebrahimi # 1736*b7893ccfSSadaf Ebrahimi decls = self.makeCDecls(cmdinfo.elem) 1737*b7893ccfSSadaf Ebrahimi self.appendSection('command', '') 1738*b7893ccfSSadaf Ebrahimi self.appendSection('command', '%s {' % decls[0][:-1]) 1739*b7893ccfSSadaf Ebrahimi # Setup common to call wrappers. First parameter is always dispatchable 1740*b7893ccfSSadaf Ebrahimi dispatchable_name = cmdinfo.elem.find('param/name').text 1741*b7893ccfSSadaf Ebrahimi self.appendSection('command', ' auto layer_data = GetLayerDataPtr(get_dispatch_key(%s), layer_data_map);' % (dispatchable_name)) 1742*b7893ccfSSadaf Ebrahimi api_function_name = cmdinfo.elem.attrib.get('name') 1743*b7893ccfSSadaf Ebrahimi params = cmdinfo.elem.findall('param/name') 1744*b7893ccfSSadaf Ebrahimi paramstext = ', '.join([str(param.text) for param in params]) 1745*b7893ccfSSadaf Ebrahimi API = api_function_name.replace('vk','Dispatch') + '(' 1746*b7893ccfSSadaf Ebrahimi 1747*b7893ccfSSadaf Ebrahimi # Declare result variable, if any. 1748*b7893ccfSSadaf Ebrahimi return_map = { 1749*b7893ccfSSadaf Ebrahimi 'PFN_vkVoidFunction': 'return nullptr;', 1750*b7893ccfSSadaf Ebrahimi 'VkBool32': 'return VK_FALSE;', 1751*b7893ccfSSadaf Ebrahimi 'VkDeviceAddress': 'return 0;', 1752*b7893ccfSSadaf Ebrahimi 'VkResult': 'return VK_ERROR_VALIDATION_FAILED_EXT;', 1753*b7893ccfSSadaf Ebrahimi 'void': 'return;', 1754*b7893ccfSSadaf Ebrahimi 'uint32_t': 'return 0;' 1755*b7893ccfSSadaf Ebrahimi } 1756*b7893ccfSSadaf Ebrahimi resulttype = cmdinfo.elem.find('proto/type') 1757*b7893ccfSSadaf Ebrahimi assignresult = '' 1758*b7893ccfSSadaf Ebrahimi if (resulttype.text != 'void'): 1759*b7893ccfSSadaf Ebrahimi assignresult = resulttype.text + ' result = ' 1760*b7893ccfSSadaf Ebrahimi 1761*b7893ccfSSadaf Ebrahimi # Set up skip and locking 1762*b7893ccfSSadaf Ebrahimi self.appendSection('command', ' bool skip = false;') 1763*b7893ccfSSadaf Ebrahimi 1764*b7893ccfSSadaf Ebrahimi # Generate pre-call validation source code 1765*b7893ccfSSadaf Ebrahimi self.appendSection('command', ' %s' % self.precallvalidate_loop) 1766*b7893ccfSSadaf Ebrahimi self.appendSection('command', ' auto lock = intercept->write_lock();') 1767*b7893ccfSSadaf Ebrahimi self.appendSection('command', ' skip |= intercept->PreCallValidate%s(%s);' % (api_function_name[2:], paramstext)) 1768*b7893ccfSSadaf Ebrahimi self.appendSection('command', ' if (skip) %s' % return_map[resulttype.text]) 1769*b7893ccfSSadaf Ebrahimi self.appendSection('command', ' }') 1770*b7893ccfSSadaf Ebrahimi 1771*b7893ccfSSadaf Ebrahimi # Generate pre-call state recording source code 1772*b7893ccfSSadaf Ebrahimi self.appendSection('command', ' %s' % self.precallrecord_loop) 1773*b7893ccfSSadaf Ebrahimi self.appendSection('command', ' auto lock = intercept->write_lock();') 1774*b7893ccfSSadaf Ebrahimi self.appendSection('command', ' intercept->PreCallRecord%s(%s);' % (api_function_name[2:], paramstext)) 1775*b7893ccfSSadaf Ebrahimi self.appendSection('command', ' }') 1776*b7893ccfSSadaf Ebrahimi 1777*b7893ccfSSadaf Ebrahimi # Insert pre-dispatch debug utils function call 1778*b7893ccfSSadaf Ebrahimi if name in self.pre_dispatch_debug_utils_functions: 1779*b7893ccfSSadaf Ebrahimi self.appendSection('command', ' %s' % self.pre_dispatch_debug_utils_functions[name]) 1780*b7893ccfSSadaf Ebrahimi 1781*b7893ccfSSadaf Ebrahimi # Output dispatch (down-chain) function call 1782*b7893ccfSSadaf Ebrahimi self.appendSection('command', ' ' + assignresult + API + paramstext + ');') 1783*b7893ccfSSadaf Ebrahimi 1784*b7893ccfSSadaf Ebrahimi # Insert post-dispatch debug utils function call 1785*b7893ccfSSadaf Ebrahimi if name in self.post_dispatch_debug_utils_functions: 1786*b7893ccfSSadaf Ebrahimi self.appendSection('command', ' %s' % self.post_dispatch_debug_utils_functions[name]) 1787*b7893ccfSSadaf Ebrahimi 1788*b7893ccfSSadaf Ebrahimi # Generate post-call object processing source code 1789*b7893ccfSSadaf Ebrahimi self.appendSection('command', ' %s' % self.postcallrecord_loop) 1790*b7893ccfSSadaf Ebrahimi returnparam = '' 1791*b7893ccfSSadaf Ebrahimi if (resulttype.text == 'VkResult'): 1792*b7893ccfSSadaf Ebrahimi returnparam = ', result' 1793*b7893ccfSSadaf Ebrahimi self.appendSection('command', ' auto lock = intercept->write_lock();') 1794*b7893ccfSSadaf Ebrahimi self.appendSection('command', ' intercept->PostCallRecord%s(%s%s);' % (api_function_name[2:], paramstext, returnparam)) 1795*b7893ccfSSadaf Ebrahimi self.appendSection('command', ' }') 1796*b7893ccfSSadaf Ebrahimi # Return result variable, if any. 1797*b7893ccfSSadaf Ebrahimi if (resulttype.text != 'void'): 1798*b7893ccfSSadaf Ebrahimi self.appendSection('command', ' return result;') 1799*b7893ccfSSadaf Ebrahimi self.appendSection('command', '}') 1800*b7893ccfSSadaf Ebrahimi # 1801*b7893ccfSSadaf Ebrahimi # Override makeProtoName to drop the "vk" prefix 1802*b7893ccfSSadaf Ebrahimi def makeProtoName(self, name, tail): 1803*b7893ccfSSadaf Ebrahimi return self.genOpts.apientry + name[2:] + tail 1804