validation_state.cpp 57 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744
  1. // Copyright (c) 2015-2016 The Khronos Group Inc.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include "source/val/validation_state.h"
  15. #include <cassert>
  16. #include <stack>
  17. #include <utility>
  18. #include "source/opcode.h"
  19. #include "source/spirv_constant.h"
  20. #include "source/spirv_target_env.h"
  21. #include "source/val/basic_block.h"
  22. #include "source/val/construct.h"
  23. #include "source/val/function.h"
  24. #include "spirv-tools/libspirv.h"
  25. namespace spvtools {
  26. namespace val {
  27. namespace {
  28. ModuleLayoutSection InstructionLayoutSection(
  29. ModuleLayoutSection current_section, SpvOp op) {
  30. // See Section 2.4
  31. if (spvOpcodeGeneratesType(op) || spvOpcodeIsConstant(op))
  32. return kLayoutTypes;
  33. switch (op) {
  34. case SpvOpCapability:
  35. return kLayoutCapabilities;
  36. case SpvOpExtension:
  37. return kLayoutExtensions;
  38. case SpvOpExtInstImport:
  39. return kLayoutExtInstImport;
  40. case SpvOpMemoryModel:
  41. return kLayoutMemoryModel;
  42. case SpvOpEntryPoint:
  43. return kLayoutEntryPoint;
  44. case SpvOpExecutionMode:
  45. case SpvOpExecutionModeId:
  46. return kLayoutExecutionMode;
  47. case SpvOpSourceContinued:
  48. case SpvOpSource:
  49. case SpvOpSourceExtension:
  50. case SpvOpString:
  51. return kLayoutDebug1;
  52. case SpvOpName:
  53. case SpvOpMemberName:
  54. return kLayoutDebug2;
  55. case SpvOpModuleProcessed:
  56. return kLayoutDebug3;
  57. case SpvOpDecorate:
  58. case SpvOpMemberDecorate:
  59. case SpvOpGroupDecorate:
  60. case SpvOpGroupMemberDecorate:
  61. case SpvOpDecorationGroup:
  62. case SpvOpDecorateId:
  63. case SpvOpDecorateStringGOOGLE:
  64. case SpvOpMemberDecorateStringGOOGLE:
  65. return kLayoutAnnotations;
  66. case SpvOpTypeForwardPointer:
  67. return kLayoutTypes;
  68. case SpvOpVariable:
  69. if (current_section == kLayoutTypes) return kLayoutTypes;
  70. return kLayoutFunctionDefinitions;
  71. case SpvOpExtInst:
  72. // SpvOpExtInst is only allowed in types section for certain extended
  73. // instruction sets. This will be checked separately.
  74. if (current_section == kLayoutTypes) return kLayoutTypes;
  75. return kLayoutFunctionDefinitions;
  76. case SpvOpLine:
  77. case SpvOpNoLine:
  78. case SpvOpUndef:
  79. if (current_section == kLayoutTypes) return kLayoutTypes;
  80. return kLayoutFunctionDefinitions;
  81. case SpvOpFunction:
  82. case SpvOpFunctionParameter:
  83. case SpvOpFunctionEnd:
  84. if (current_section == kLayoutFunctionDeclarations)
  85. return kLayoutFunctionDeclarations;
  86. return kLayoutFunctionDefinitions;
  87. default:
  88. break;
  89. }
  90. return kLayoutFunctionDefinitions;
  91. }
  92. bool IsInstructionInLayoutSection(ModuleLayoutSection layout, SpvOp op) {
  93. return layout == InstructionLayoutSection(layout, op);
  94. }
  95. // Counts the number of instructions and functions in the file.
  96. spv_result_t CountInstructions(void* user_data,
  97. const spv_parsed_instruction_t* inst) {
  98. ValidationState_t& _ = *(reinterpret_cast<ValidationState_t*>(user_data));
  99. if (inst->opcode == SpvOpFunction) _.increment_total_functions();
  100. _.increment_total_instructions();
  101. return SPV_SUCCESS;
  102. }
  103. spv_result_t setHeader(void* user_data, spv_endianness_t, uint32_t,
  104. uint32_t version, uint32_t generator, uint32_t id_bound,
  105. uint32_t) {
  106. ValidationState_t& vstate =
  107. *(reinterpret_cast<ValidationState_t*>(user_data));
  108. vstate.setIdBound(id_bound);
  109. vstate.setGenerator(generator);
  110. vstate.setVersion(version);
  111. return SPV_SUCCESS;
  112. }
  113. // Add features based on SPIR-V core version number.
  114. void UpdateFeaturesBasedOnSpirvVersion(ValidationState_t::Feature* features,
  115. uint32_t version) {
  116. assert(features);
  117. if (version >= SPV_SPIRV_VERSION_WORD(1, 4)) {
  118. features->select_between_composites = true;
  119. features->copy_memory_permits_two_memory_accesses = true;
  120. features->uconvert_spec_constant_op = true;
  121. features->nonwritable_var_in_function_or_private = true;
  122. }
  123. }
  124. } // namespace
  125. ValidationState_t::ValidationState_t(const spv_const_context ctx,
  126. const spv_const_validator_options opt,
  127. const uint32_t* words,
  128. const size_t num_words,
  129. const uint32_t max_warnings)
  130. : context_(ctx),
  131. options_(opt),
  132. words_(words),
  133. num_words_(num_words),
  134. unresolved_forward_ids_{},
  135. operand_names_{},
  136. current_layout_section_(kLayoutCapabilities),
  137. module_functions_(),
  138. module_capabilities_(),
  139. module_extensions_(),
  140. ordered_instructions_(),
  141. all_definitions_(),
  142. global_vars_(),
  143. local_vars_(),
  144. struct_nesting_depth_(),
  145. struct_has_nested_blockorbufferblock_struct_(),
  146. grammar_(ctx),
  147. addressing_model_(SpvAddressingModelMax),
  148. memory_model_(SpvMemoryModelMax),
  149. pointer_size_and_alignment_(0),
  150. in_function_(false),
  151. num_of_warnings_(0),
  152. max_num_of_warnings_(max_warnings) {
  153. assert(opt && "Validator options may not be Null.");
  154. const auto env = context_->target_env;
  155. if (spvIsVulkanEnv(env)) {
  156. // Vulkan 1.1 includes VK_KHR_relaxed_block_layout in core.
  157. if (env != SPV_ENV_VULKAN_1_0) {
  158. features_.env_relaxed_block_layout = true;
  159. }
  160. }
  161. // Only attempt to count if we have words, otherwise let the other validation
  162. // fail and generate an error.
  163. if (num_words > 0) {
  164. // Count the number of instructions in the binary.
  165. // This parse should not produce any error messages. Hijack the context and
  166. // replace the message consumer so that we do not pollute any state in input
  167. // consumer.
  168. spv_context_t hijacked_context = *ctx;
  169. hijacked_context.consumer = [](spv_message_level_t, const char*,
  170. const spv_position_t&, const char*) {};
  171. spvBinaryParse(&hijacked_context, this, words, num_words, setHeader,
  172. CountInstructions,
  173. /* diagnostic = */ nullptr);
  174. preallocateStorage();
  175. }
  176. UpdateFeaturesBasedOnSpirvVersion(&features_, version_);
  177. friendly_mapper_ = spvtools::MakeUnique<spvtools::FriendlyNameMapper>(
  178. context_, words_, num_words_);
  179. name_mapper_ = friendly_mapper_->GetNameMapper();
  180. }
  181. void ValidationState_t::preallocateStorage() {
  182. ordered_instructions_.reserve(total_instructions_);
  183. module_functions_.reserve(total_functions_);
  184. }
  185. spv_result_t ValidationState_t::ForwardDeclareId(uint32_t id) {
  186. unresolved_forward_ids_.insert(id);
  187. return SPV_SUCCESS;
  188. }
  189. spv_result_t ValidationState_t::RemoveIfForwardDeclared(uint32_t id) {
  190. unresolved_forward_ids_.erase(id);
  191. return SPV_SUCCESS;
  192. }
  193. spv_result_t ValidationState_t::RegisterForwardPointer(uint32_t id) {
  194. forward_pointer_ids_.insert(id);
  195. return SPV_SUCCESS;
  196. }
  197. bool ValidationState_t::IsForwardPointer(uint32_t id) const {
  198. return (forward_pointer_ids_.find(id) != forward_pointer_ids_.end());
  199. }
  200. void ValidationState_t::AssignNameToId(uint32_t id, std::string name) {
  201. operand_names_[id] = name;
  202. }
  203. std::string ValidationState_t::getIdName(uint32_t id) const {
  204. const std::string id_name = name_mapper_(id);
  205. std::stringstream out;
  206. out << id << "[%" << id_name << "]";
  207. return out.str();
  208. }
  209. size_t ValidationState_t::unresolved_forward_id_count() const {
  210. return unresolved_forward_ids_.size();
  211. }
  212. std::vector<uint32_t> ValidationState_t::UnresolvedForwardIds() const {
  213. std::vector<uint32_t> out(std::begin(unresolved_forward_ids_),
  214. std::end(unresolved_forward_ids_));
  215. return out;
  216. }
  217. bool ValidationState_t::IsDefinedId(uint32_t id) const {
  218. return all_definitions_.find(id) != std::end(all_definitions_);
  219. }
  220. const Instruction* ValidationState_t::FindDef(uint32_t id) const {
  221. auto it = all_definitions_.find(id);
  222. if (it == all_definitions_.end()) return nullptr;
  223. return it->second;
  224. }
  225. Instruction* ValidationState_t::FindDef(uint32_t id) {
  226. auto it = all_definitions_.find(id);
  227. if (it == all_definitions_.end()) return nullptr;
  228. return it->second;
  229. }
  230. ModuleLayoutSection ValidationState_t::current_layout_section() const {
  231. return current_layout_section_;
  232. }
  233. void ValidationState_t::ProgressToNextLayoutSectionOrder() {
  234. // Guard against going past the last element(kLayoutFunctionDefinitions)
  235. if (current_layout_section_ <= kLayoutFunctionDefinitions) {
  236. current_layout_section_ =
  237. static_cast<ModuleLayoutSection>(current_layout_section_ + 1);
  238. }
  239. }
  240. bool ValidationState_t::IsOpcodeInPreviousLayoutSection(SpvOp op) {
  241. ModuleLayoutSection section =
  242. InstructionLayoutSection(current_layout_section_, op);
  243. return section < current_layout_section_;
  244. }
  245. bool ValidationState_t::IsOpcodeInCurrentLayoutSection(SpvOp op) {
  246. return IsInstructionInLayoutSection(current_layout_section_, op);
  247. }
  248. DiagnosticStream ValidationState_t::diag(spv_result_t error_code,
  249. const Instruction* inst) {
  250. if (error_code == SPV_WARNING) {
  251. if (num_of_warnings_ == max_num_of_warnings_) {
  252. DiagnosticStream({0, 0, 0}, context_->consumer, "", error_code)
  253. << "Other warnings have been suppressed.\n";
  254. }
  255. if (num_of_warnings_ >= max_num_of_warnings_) {
  256. return DiagnosticStream({0, 0, 0}, nullptr, "", error_code);
  257. }
  258. ++num_of_warnings_;
  259. }
  260. std::string disassembly;
  261. if (inst) disassembly = Disassemble(*inst);
  262. return DiagnosticStream({0, 0, inst ? inst->LineNum() : 0},
  263. context_->consumer, disassembly, error_code);
  264. }
  265. std::vector<Function>& ValidationState_t::functions() {
  266. return module_functions_;
  267. }
  268. Function& ValidationState_t::current_function() {
  269. assert(in_function_body());
  270. return module_functions_.back();
  271. }
  272. const Function& ValidationState_t::current_function() const {
  273. assert(in_function_body());
  274. return module_functions_.back();
  275. }
  276. const Function* ValidationState_t::function(uint32_t id) const {
  277. const auto it = id_to_function_.find(id);
  278. if (it == id_to_function_.end()) return nullptr;
  279. return it->second;
  280. }
  281. Function* ValidationState_t::function(uint32_t id) {
  282. auto it = id_to_function_.find(id);
  283. if (it == id_to_function_.end()) return nullptr;
  284. return it->second;
  285. }
  286. bool ValidationState_t::in_function_body() const { return in_function_; }
  287. bool ValidationState_t::in_block() const {
  288. return module_functions_.empty() == false &&
  289. module_functions_.back().current_block() != nullptr;
  290. }
  291. void ValidationState_t::RegisterCapability(SpvCapability cap) {
  292. // Avoid redundant work. Otherwise the recursion could induce work
  293. // quadrdatic in the capability dependency depth. (Ok, not much, but
  294. // it's something.)
  295. if (module_capabilities_.Contains(cap)) return;
  296. module_capabilities_.Add(cap);
  297. spv_operand_desc desc;
  298. if (SPV_SUCCESS ==
  299. grammar_.lookupOperand(SPV_OPERAND_TYPE_CAPABILITY, cap, &desc)) {
  300. CapabilitySet(desc->numCapabilities, desc->capabilities)
  301. .ForEach([this](SpvCapability c) { RegisterCapability(c); });
  302. }
  303. switch (cap) {
  304. case SpvCapabilityKernel:
  305. features_.group_ops_reduce_and_scans = true;
  306. break;
  307. case SpvCapabilityInt8:
  308. features_.use_int8_type = true;
  309. features_.declare_int8_type = true;
  310. break;
  311. case SpvCapabilityStorageBuffer8BitAccess:
  312. case SpvCapabilityUniformAndStorageBuffer8BitAccess:
  313. case SpvCapabilityStoragePushConstant8:
  314. case SpvCapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR:
  315. features_.declare_int8_type = true;
  316. break;
  317. case SpvCapabilityInt16:
  318. features_.declare_int16_type = true;
  319. break;
  320. case SpvCapabilityFloat16:
  321. case SpvCapabilityFloat16Buffer:
  322. features_.declare_float16_type = true;
  323. break;
  324. case SpvCapabilityStorageUniformBufferBlock16:
  325. case SpvCapabilityStorageUniform16:
  326. case SpvCapabilityStoragePushConstant16:
  327. case SpvCapabilityStorageInputOutput16:
  328. case SpvCapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR:
  329. features_.declare_int16_type = true;
  330. features_.declare_float16_type = true;
  331. features_.free_fp_rounding_mode = true;
  332. break;
  333. case SpvCapabilityVariablePointers:
  334. features_.variable_pointers = true;
  335. features_.variable_pointers_storage_buffer = true;
  336. break;
  337. case SpvCapabilityVariablePointersStorageBuffer:
  338. features_.variable_pointers_storage_buffer = true;
  339. break;
  340. default:
  341. break;
  342. }
  343. }
  344. void ValidationState_t::RegisterExtension(Extension ext) {
  345. if (module_extensions_.Contains(ext)) return;
  346. module_extensions_.Add(ext);
  347. switch (ext) {
  348. case kSPV_AMD_gpu_shader_half_float:
  349. case kSPV_AMD_gpu_shader_half_float_fetch:
  350. // SPV_AMD_gpu_shader_half_float enables float16 type.
  351. // https://github.com/KhronosGroup/SPIRV-Tools/issues/1375
  352. features_.declare_float16_type = true;
  353. break;
  354. case kSPV_AMD_gpu_shader_int16:
  355. // This is not yet in the extension, but it's recommended for it.
  356. // See https://github.com/KhronosGroup/glslang/issues/848
  357. features_.uconvert_spec_constant_op = true;
  358. break;
  359. case kSPV_AMD_shader_ballot:
  360. // The grammar doesn't encode the fact that SPV_AMD_shader_ballot
  361. // enables the use of group operations Reduce, InclusiveScan,
  362. // and ExclusiveScan. Enable it manually.
  363. // https://github.com/KhronosGroup/SPIRV-Tools/issues/991
  364. features_.group_ops_reduce_and_scans = true;
  365. break;
  366. default:
  367. break;
  368. }
  369. }
  370. bool ValidationState_t::HasAnyOfCapabilities(
  371. const CapabilitySet& capabilities) const {
  372. return module_capabilities_.HasAnyOf(capabilities);
  373. }
  374. bool ValidationState_t::HasAnyOfExtensions(
  375. const ExtensionSet& extensions) const {
  376. return module_extensions_.HasAnyOf(extensions);
  377. }
  378. void ValidationState_t::set_addressing_model(SpvAddressingModel am) {
  379. addressing_model_ = am;
  380. switch (am) {
  381. case SpvAddressingModelPhysical32:
  382. pointer_size_and_alignment_ = 4;
  383. break;
  384. default:
  385. // fall through
  386. case SpvAddressingModelPhysical64:
  387. case SpvAddressingModelPhysicalStorageBuffer64EXT:
  388. pointer_size_and_alignment_ = 8;
  389. break;
  390. }
  391. }
  392. SpvAddressingModel ValidationState_t::addressing_model() const {
  393. return addressing_model_;
  394. }
  395. void ValidationState_t::set_memory_model(SpvMemoryModel mm) {
  396. memory_model_ = mm;
  397. }
  398. SpvMemoryModel ValidationState_t::memory_model() const { return memory_model_; }
  399. spv_result_t ValidationState_t::RegisterFunction(
  400. uint32_t id, uint32_t ret_type_id, SpvFunctionControlMask function_control,
  401. uint32_t function_type_id) {
  402. assert(in_function_body() == false &&
  403. "RegisterFunction can only be called when parsing the binary outside "
  404. "of another function");
  405. in_function_ = true;
  406. module_functions_.emplace_back(id, ret_type_id, function_control,
  407. function_type_id);
  408. id_to_function_.emplace(id, &current_function());
  409. // TODO(umar): validate function type and type_id
  410. return SPV_SUCCESS;
  411. }
  412. spv_result_t ValidationState_t::RegisterFunctionEnd() {
  413. assert(in_function_body() == true &&
  414. "RegisterFunctionEnd can only be called when parsing the binary "
  415. "inside of another function");
  416. assert(in_block() == false &&
  417. "RegisterFunctionParameter can only be called when parsing the binary "
  418. "ouside of a block");
  419. current_function().RegisterFunctionEnd();
  420. in_function_ = false;
  421. return SPV_SUCCESS;
  422. }
  423. Instruction* ValidationState_t::AddOrderedInstruction(
  424. const spv_parsed_instruction_t* inst) {
  425. ordered_instructions_.emplace_back(inst);
  426. ordered_instructions_.back().SetLineNum(ordered_instructions_.size());
  427. return &ordered_instructions_.back();
  428. }
  429. // Improves diagnostic messages by collecting names of IDs
  430. void ValidationState_t::RegisterDebugInstruction(const Instruction* inst) {
  431. switch (inst->opcode()) {
  432. case SpvOpName: {
  433. const auto target = inst->GetOperandAs<uint32_t>(0);
  434. const auto* str = reinterpret_cast<const char*>(inst->words().data() +
  435. inst->operand(1).offset);
  436. AssignNameToId(target, str);
  437. break;
  438. }
  439. case SpvOpMemberName: {
  440. const auto target = inst->GetOperandAs<uint32_t>(0);
  441. const auto* str = reinterpret_cast<const char*>(inst->words().data() +
  442. inst->operand(2).offset);
  443. AssignNameToId(target, str);
  444. break;
  445. }
  446. case SpvOpSourceContinued:
  447. case SpvOpSource:
  448. case SpvOpSourceExtension:
  449. case SpvOpString:
  450. case SpvOpLine:
  451. case SpvOpNoLine:
  452. default:
  453. break;
  454. }
  455. }
  456. void ValidationState_t::RegisterInstruction(Instruction* inst) {
  457. if (inst->id()) all_definitions_.insert(std::make_pair(inst->id(), inst));
  458. // If the instruction is using an OpTypeSampledImage as an operand, it should
  459. // be recorded. The validator will ensure that all usages of an
  460. // OpTypeSampledImage and its definition are in the same basic block.
  461. for (uint16_t i = 0; i < inst->operands().size(); ++i) {
  462. const spv_parsed_operand_t& operand = inst->operand(i);
  463. if (SPV_OPERAND_TYPE_ID == operand.type) {
  464. const uint32_t operand_word = inst->word(operand.offset);
  465. Instruction* operand_inst = FindDef(operand_word);
  466. if (operand_inst && SpvOpSampledImage == operand_inst->opcode()) {
  467. RegisterSampledImageConsumer(operand_word, inst);
  468. }
  469. }
  470. }
  471. }
  472. std::vector<Instruction*> ValidationState_t::getSampledImageConsumers(
  473. uint32_t sampled_image_id) const {
  474. std::vector<Instruction*> result;
  475. auto iter = sampled_image_consumers_.find(sampled_image_id);
  476. if (iter != sampled_image_consumers_.end()) {
  477. result = iter->second;
  478. }
  479. return result;
  480. }
  481. void ValidationState_t::RegisterSampledImageConsumer(uint32_t sampled_image_id,
  482. Instruction* consumer) {
  483. sampled_image_consumers_[sampled_image_id].push_back(consumer);
  484. }
  485. uint32_t ValidationState_t::getIdBound() const { return id_bound_; }
  486. void ValidationState_t::setIdBound(const uint32_t bound) { id_bound_ = bound; }
  487. bool ValidationState_t::RegisterUniqueTypeDeclaration(const Instruction* inst) {
  488. std::vector<uint32_t> key;
  489. key.push_back(static_cast<uint32_t>(inst->opcode()));
  490. for (size_t index = 0; index < inst->operands().size(); ++index) {
  491. const spv_parsed_operand_t& operand = inst->operand(index);
  492. if (operand.type == SPV_OPERAND_TYPE_RESULT_ID) continue;
  493. const int words_begin = operand.offset;
  494. const int words_end = words_begin + operand.num_words;
  495. assert(words_end <= static_cast<int>(inst->words().size()));
  496. key.insert(key.end(), inst->words().begin() + words_begin,
  497. inst->words().begin() + words_end);
  498. }
  499. return unique_type_declarations_.insert(std::move(key)).second;
  500. }
  501. uint32_t ValidationState_t::GetTypeId(uint32_t id) const {
  502. const Instruction* inst = FindDef(id);
  503. return inst ? inst->type_id() : 0;
  504. }
  505. SpvOp ValidationState_t::GetIdOpcode(uint32_t id) const {
  506. const Instruction* inst = FindDef(id);
  507. return inst ? inst->opcode() : SpvOpNop;
  508. }
  509. uint32_t ValidationState_t::GetComponentType(uint32_t id) const {
  510. const Instruction* inst = FindDef(id);
  511. assert(inst);
  512. switch (inst->opcode()) {
  513. case SpvOpTypeFloat:
  514. case SpvOpTypeInt:
  515. case SpvOpTypeBool:
  516. return id;
  517. case SpvOpTypeVector:
  518. return inst->word(2);
  519. case SpvOpTypeMatrix:
  520. return GetComponentType(inst->word(2));
  521. case SpvOpTypeCooperativeMatrixNV:
  522. return inst->word(2);
  523. default:
  524. break;
  525. }
  526. if (inst->type_id()) return GetComponentType(inst->type_id());
  527. assert(0);
  528. return 0;
  529. }
  530. uint32_t ValidationState_t::GetDimension(uint32_t id) const {
  531. const Instruction* inst = FindDef(id);
  532. assert(inst);
  533. switch (inst->opcode()) {
  534. case SpvOpTypeFloat:
  535. case SpvOpTypeInt:
  536. case SpvOpTypeBool:
  537. return 1;
  538. case SpvOpTypeVector:
  539. case SpvOpTypeMatrix:
  540. return inst->word(3);
  541. case SpvOpTypeCooperativeMatrixNV:
  542. // Actual dimension isn't known, return 0
  543. return 0;
  544. default:
  545. break;
  546. }
  547. if (inst->type_id()) return GetDimension(inst->type_id());
  548. assert(0);
  549. return 0;
  550. }
  551. uint32_t ValidationState_t::GetBitWidth(uint32_t id) const {
  552. const uint32_t component_type_id = GetComponentType(id);
  553. const Instruction* inst = FindDef(component_type_id);
  554. assert(inst);
  555. if (inst->opcode() == SpvOpTypeFloat || inst->opcode() == SpvOpTypeInt)
  556. return inst->word(2);
  557. if (inst->opcode() == SpvOpTypeBool) return 1;
  558. assert(0);
  559. return 0;
  560. }
  561. bool ValidationState_t::IsVoidType(uint32_t id) const {
  562. const Instruction* inst = FindDef(id);
  563. assert(inst);
  564. return inst->opcode() == SpvOpTypeVoid;
  565. }
  566. bool ValidationState_t::IsFloatScalarType(uint32_t id) const {
  567. const Instruction* inst = FindDef(id);
  568. assert(inst);
  569. return inst->opcode() == SpvOpTypeFloat;
  570. }
  571. bool ValidationState_t::IsFloatVectorType(uint32_t id) const {
  572. const Instruction* inst = FindDef(id);
  573. assert(inst);
  574. if (inst->opcode() == SpvOpTypeVector) {
  575. return IsFloatScalarType(GetComponentType(id));
  576. }
  577. return false;
  578. }
  579. bool ValidationState_t::IsFloatScalarOrVectorType(uint32_t id) const {
  580. const Instruction* inst = FindDef(id);
  581. assert(inst);
  582. if (inst->opcode() == SpvOpTypeFloat) {
  583. return true;
  584. }
  585. if (inst->opcode() == SpvOpTypeVector) {
  586. return IsFloatScalarType(GetComponentType(id));
  587. }
  588. return false;
  589. }
  590. bool ValidationState_t::IsIntScalarType(uint32_t id) const {
  591. const Instruction* inst = FindDef(id);
  592. assert(inst);
  593. return inst->opcode() == SpvOpTypeInt;
  594. }
  595. bool ValidationState_t::IsIntVectorType(uint32_t id) const {
  596. const Instruction* inst = FindDef(id);
  597. assert(inst);
  598. if (inst->opcode() == SpvOpTypeVector) {
  599. return IsIntScalarType(GetComponentType(id));
  600. }
  601. return false;
  602. }
  603. bool ValidationState_t::IsIntScalarOrVectorType(uint32_t id) const {
  604. const Instruction* inst = FindDef(id);
  605. assert(inst);
  606. if (inst->opcode() == SpvOpTypeInt) {
  607. return true;
  608. }
  609. if (inst->opcode() == SpvOpTypeVector) {
  610. return IsIntScalarType(GetComponentType(id));
  611. }
  612. return false;
  613. }
  614. bool ValidationState_t::IsUnsignedIntScalarType(uint32_t id) const {
  615. const Instruction* inst = FindDef(id);
  616. assert(inst);
  617. return inst->opcode() == SpvOpTypeInt && inst->word(3) == 0;
  618. }
  619. bool ValidationState_t::IsUnsignedIntVectorType(uint32_t id) const {
  620. const Instruction* inst = FindDef(id);
  621. assert(inst);
  622. if (inst->opcode() == SpvOpTypeVector) {
  623. return IsUnsignedIntScalarType(GetComponentType(id));
  624. }
  625. return false;
  626. }
  627. bool ValidationState_t::IsSignedIntScalarType(uint32_t id) const {
  628. const Instruction* inst = FindDef(id);
  629. assert(inst);
  630. return inst->opcode() == SpvOpTypeInt && inst->word(3) == 1;
  631. }
  632. bool ValidationState_t::IsSignedIntVectorType(uint32_t id) const {
  633. const Instruction* inst = FindDef(id);
  634. assert(inst);
  635. if (inst->opcode() == SpvOpTypeVector) {
  636. return IsSignedIntScalarType(GetComponentType(id));
  637. }
  638. return false;
  639. }
  640. bool ValidationState_t::IsBoolScalarType(uint32_t id) const {
  641. const Instruction* inst = FindDef(id);
  642. assert(inst);
  643. return inst->opcode() == SpvOpTypeBool;
  644. }
  645. bool ValidationState_t::IsBoolVectorType(uint32_t id) const {
  646. const Instruction* inst = FindDef(id);
  647. assert(inst);
  648. if (inst->opcode() == SpvOpTypeVector) {
  649. return IsBoolScalarType(GetComponentType(id));
  650. }
  651. return false;
  652. }
  653. bool ValidationState_t::IsBoolScalarOrVectorType(uint32_t id) const {
  654. const Instruction* inst = FindDef(id);
  655. assert(inst);
  656. if (inst->opcode() == SpvOpTypeBool) {
  657. return true;
  658. }
  659. if (inst->opcode() == SpvOpTypeVector) {
  660. return IsBoolScalarType(GetComponentType(id));
  661. }
  662. return false;
  663. }
  664. bool ValidationState_t::IsFloatMatrixType(uint32_t id) const {
  665. const Instruction* inst = FindDef(id);
  666. assert(inst);
  667. if (inst->opcode() == SpvOpTypeMatrix) {
  668. return IsFloatScalarType(GetComponentType(id));
  669. }
  670. return false;
  671. }
  672. bool ValidationState_t::GetMatrixTypeInfo(uint32_t id, uint32_t* num_rows,
  673. uint32_t* num_cols,
  674. uint32_t* column_type,
  675. uint32_t* component_type) const {
  676. if (!id) return false;
  677. const Instruction* mat_inst = FindDef(id);
  678. assert(mat_inst);
  679. if (mat_inst->opcode() != SpvOpTypeMatrix) return false;
  680. const uint32_t vec_type = mat_inst->word(2);
  681. const Instruction* vec_inst = FindDef(vec_type);
  682. assert(vec_inst);
  683. if (vec_inst->opcode() != SpvOpTypeVector) {
  684. assert(0);
  685. return false;
  686. }
  687. *num_cols = mat_inst->word(3);
  688. *num_rows = vec_inst->word(3);
  689. *column_type = mat_inst->word(2);
  690. *component_type = vec_inst->word(2);
  691. return true;
  692. }
  693. bool ValidationState_t::GetStructMemberTypes(
  694. uint32_t struct_type_id, std::vector<uint32_t>* member_types) const {
  695. member_types->clear();
  696. if (!struct_type_id) return false;
  697. const Instruction* inst = FindDef(struct_type_id);
  698. assert(inst);
  699. if (inst->opcode() != SpvOpTypeStruct) return false;
  700. *member_types =
  701. std::vector<uint32_t>(inst->words().cbegin() + 2, inst->words().cend());
  702. if (member_types->empty()) return false;
  703. return true;
  704. }
  705. bool ValidationState_t::IsPointerType(uint32_t id) const {
  706. const Instruction* inst = FindDef(id);
  707. assert(inst);
  708. return inst->opcode() == SpvOpTypePointer;
  709. }
  710. bool ValidationState_t::GetPointerTypeInfo(uint32_t id, uint32_t* data_type,
  711. uint32_t* storage_class) const {
  712. if (!id) return false;
  713. const Instruction* inst = FindDef(id);
  714. assert(inst);
  715. if (inst->opcode() != SpvOpTypePointer) return false;
  716. *storage_class = inst->word(2);
  717. *data_type = inst->word(3);
  718. return true;
  719. }
  720. bool ValidationState_t::IsCooperativeMatrixType(uint32_t id) const {
  721. const Instruction* inst = FindDef(id);
  722. assert(inst);
  723. return inst->opcode() == SpvOpTypeCooperativeMatrixNV;
  724. }
  725. bool ValidationState_t::IsFloatCooperativeMatrixType(uint32_t id) const {
  726. if (!IsCooperativeMatrixType(id)) return false;
  727. return IsFloatScalarType(FindDef(id)->word(2));
  728. }
  729. bool ValidationState_t::IsIntCooperativeMatrixType(uint32_t id) const {
  730. if (!IsCooperativeMatrixType(id)) return false;
  731. return IsIntScalarType(FindDef(id)->word(2));
  732. }
  733. bool ValidationState_t::IsUnsignedIntCooperativeMatrixType(uint32_t id) const {
  734. if (!IsCooperativeMatrixType(id)) return false;
  735. return IsUnsignedIntScalarType(FindDef(id)->word(2));
  736. }
  737. spv_result_t ValidationState_t::CooperativeMatrixShapesMatch(
  738. const Instruction* inst, uint32_t m1, uint32_t m2) {
  739. const auto m1_type = FindDef(m1);
  740. const auto m2_type = FindDef(m2);
  741. if (m1_type->opcode() != SpvOpTypeCooperativeMatrixNV ||
  742. m2_type->opcode() != SpvOpTypeCooperativeMatrixNV) {
  743. return diag(SPV_ERROR_INVALID_DATA, inst)
  744. << "Expected cooperative matrix types";
  745. }
  746. uint32_t m1_scope_id = m1_type->GetOperandAs<uint32_t>(2);
  747. uint32_t m1_rows_id = m1_type->GetOperandAs<uint32_t>(3);
  748. uint32_t m1_cols_id = m1_type->GetOperandAs<uint32_t>(4);
  749. uint32_t m2_scope_id = m2_type->GetOperandAs<uint32_t>(2);
  750. uint32_t m2_rows_id = m2_type->GetOperandAs<uint32_t>(3);
  751. uint32_t m2_cols_id = m2_type->GetOperandAs<uint32_t>(4);
  752. bool m1_is_int32 = false, m1_is_const_int32 = false, m2_is_int32 = false,
  753. m2_is_const_int32 = false;
  754. uint32_t m1_value = 0, m2_value = 0;
  755. std::tie(m1_is_int32, m1_is_const_int32, m1_value) =
  756. EvalInt32IfConst(m1_scope_id);
  757. std::tie(m2_is_int32, m2_is_const_int32, m2_value) =
  758. EvalInt32IfConst(m2_scope_id);
  759. if (m1_is_const_int32 && m2_is_const_int32 && m1_value != m2_value) {
  760. return diag(SPV_ERROR_INVALID_DATA, inst)
  761. << "Expected scopes of Matrix and Result Type to be "
  762. << "identical";
  763. }
  764. std::tie(m1_is_int32, m1_is_const_int32, m1_value) =
  765. EvalInt32IfConst(m1_rows_id);
  766. std::tie(m2_is_int32, m2_is_const_int32, m2_value) =
  767. EvalInt32IfConst(m2_rows_id);
  768. if (m1_is_const_int32 && m2_is_const_int32 && m1_value != m2_value) {
  769. return diag(SPV_ERROR_INVALID_DATA, inst)
  770. << "Expected rows of Matrix type and Result Type to be "
  771. << "identical";
  772. }
  773. std::tie(m1_is_int32, m1_is_const_int32, m1_value) =
  774. EvalInt32IfConst(m1_cols_id);
  775. std::tie(m2_is_int32, m2_is_const_int32, m2_value) =
  776. EvalInt32IfConst(m2_cols_id);
  777. if (m1_is_const_int32 && m2_is_const_int32 && m1_value != m2_value) {
  778. return diag(SPV_ERROR_INVALID_DATA, inst)
  779. << "Expected columns of Matrix type and Result Type to be "
  780. << "identical";
  781. }
  782. return SPV_SUCCESS;
  783. }
  784. uint32_t ValidationState_t::GetOperandTypeId(const Instruction* inst,
  785. size_t operand_index) const {
  786. return GetTypeId(inst->GetOperandAs<uint32_t>(operand_index));
  787. }
  788. bool ValidationState_t::GetConstantValUint64(uint32_t id, uint64_t* val) const {
  789. const Instruction* inst = FindDef(id);
  790. if (!inst) {
  791. assert(0 && "Instruction not found");
  792. return false;
  793. }
  794. if (inst->opcode() != SpvOpConstant && inst->opcode() != SpvOpSpecConstant)
  795. return false;
  796. if (!IsIntScalarType(inst->type_id())) return false;
  797. if (inst->words().size() == 4) {
  798. *val = inst->word(3);
  799. } else {
  800. assert(inst->words().size() == 5);
  801. *val = inst->word(3);
  802. *val |= uint64_t(inst->word(4)) << 32;
  803. }
  804. return true;
  805. }
  806. std::tuple<bool, bool, uint32_t> ValidationState_t::EvalInt32IfConst(
  807. uint32_t id) const {
  808. const Instruction* const inst = FindDef(id);
  809. assert(inst);
  810. const uint32_t type = inst->type_id();
  811. if (type == 0 || !IsIntScalarType(type) || GetBitWidth(type) != 32) {
  812. return std::make_tuple(false, false, 0);
  813. }
  814. // Spec constant values cannot be evaluated so don't consider constant for
  815. // the purpose of this method.
  816. if (!spvOpcodeIsConstant(inst->opcode()) ||
  817. spvOpcodeIsSpecConstant(inst->opcode())) {
  818. return std::make_tuple(true, false, 0);
  819. }
  820. if (inst->opcode() == SpvOpConstantNull) {
  821. return std::make_tuple(true, true, 0);
  822. }
  823. assert(inst->words().size() == 4);
  824. return std::make_tuple(true, true, inst->word(3));
  825. }
  826. void ValidationState_t::ComputeFunctionToEntryPointMapping() {
  827. for (const uint32_t entry_point : entry_points()) {
  828. std::stack<uint32_t> call_stack;
  829. std::set<uint32_t> visited;
  830. call_stack.push(entry_point);
  831. while (!call_stack.empty()) {
  832. const uint32_t called_func_id = call_stack.top();
  833. call_stack.pop();
  834. if (!visited.insert(called_func_id).second) continue;
  835. function_to_entry_points_[called_func_id].push_back(entry_point);
  836. const Function* called_func = function(called_func_id);
  837. if (called_func) {
  838. // Other checks should error out on this invalid SPIR-V.
  839. for (const uint32_t new_call : called_func->function_call_targets()) {
  840. call_stack.push(new_call);
  841. }
  842. }
  843. }
  844. }
  845. }
  846. void ValidationState_t::ComputeRecursiveEntryPoints() {
  847. for (const Function& func : functions()) {
  848. std::stack<uint32_t> call_stack;
  849. std::set<uint32_t> visited;
  850. for (const uint32_t new_call : func.function_call_targets()) {
  851. call_stack.push(new_call);
  852. }
  853. while (!call_stack.empty()) {
  854. const uint32_t called_func_id = call_stack.top();
  855. call_stack.pop();
  856. if (!visited.insert(called_func_id).second) continue;
  857. if (called_func_id == func.id()) {
  858. for (const uint32_t entry_point :
  859. function_to_entry_points_[called_func_id])
  860. recursive_entry_points_.insert(entry_point);
  861. break;
  862. }
  863. const Function* called_func = function(called_func_id);
  864. if (called_func) {
  865. // Other checks should error out on this invalid SPIR-V.
  866. for (const uint32_t new_call : called_func->function_call_targets()) {
  867. call_stack.push(new_call);
  868. }
  869. }
  870. }
  871. }
  872. }
  873. const std::vector<uint32_t>& ValidationState_t::FunctionEntryPoints(
  874. uint32_t func) const {
  875. auto iter = function_to_entry_points_.find(func);
  876. if (iter == function_to_entry_points_.end()) {
  877. return empty_ids_;
  878. } else {
  879. return iter->second;
  880. }
  881. }
  882. std::set<uint32_t> ValidationState_t::EntryPointReferences(uint32_t id) const {
  883. std::set<uint32_t> referenced_entry_points;
  884. const auto inst = FindDef(id);
  885. if (!inst) return referenced_entry_points;
  886. std::vector<const Instruction*> stack;
  887. stack.push_back(inst);
  888. while (!stack.empty()) {
  889. const auto current_inst = stack.back();
  890. stack.pop_back();
  891. if (const auto func = current_inst->function()) {
  892. // Instruction lives in a function, we can stop searching.
  893. const auto function_entry_points = FunctionEntryPoints(func->id());
  894. referenced_entry_points.insert(function_entry_points.begin(),
  895. function_entry_points.end());
  896. } else {
  897. // Instruction is in the global scope, keep searching its uses.
  898. for (auto pair : current_inst->uses()) {
  899. const auto next_inst = pair.first;
  900. stack.push_back(next_inst);
  901. }
  902. }
  903. }
  904. return referenced_entry_points;
  905. }
  906. std::string ValidationState_t::Disassemble(const Instruction& inst) const {
  907. const spv_parsed_instruction_t& c_inst(inst.c_inst());
  908. return Disassemble(c_inst.words, c_inst.num_words);
  909. }
  910. std::string ValidationState_t::Disassemble(const uint32_t* words,
  911. uint16_t num_words) const {
  912. uint32_t disassembly_options = SPV_BINARY_TO_TEXT_OPTION_NO_HEADER |
  913. SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES;
  914. return spvInstructionBinaryToText(context()->target_env, words, num_words,
  915. words_, num_words_, disassembly_options);
  916. }
  917. bool ValidationState_t::LogicallyMatch(const Instruction* lhs,
  918. const Instruction* rhs,
  919. bool check_decorations) {
  920. if (lhs->opcode() != rhs->opcode()) {
  921. return false;
  922. }
  923. if (check_decorations) {
  924. const auto& dec_a = id_decorations(lhs->id());
  925. const auto& dec_b = id_decorations(rhs->id());
  926. for (const auto& dec : dec_b) {
  927. if (std::find(dec_a.begin(), dec_a.end(), dec) == dec_a.end()) {
  928. return false;
  929. }
  930. }
  931. }
  932. if (lhs->opcode() == SpvOpTypeArray) {
  933. // Size operands must match.
  934. if (lhs->GetOperandAs<uint32_t>(2u) != rhs->GetOperandAs<uint32_t>(2u)) {
  935. return false;
  936. }
  937. // Elements must match or logically match.
  938. const auto lhs_ele_id = lhs->GetOperandAs<uint32_t>(1u);
  939. const auto rhs_ele_id = rhs->GetOperandAs<uint32_t>(1u);
  940. if (lhs_ele_id == rhs_ele_id) {
  941. return true;
  942. }
  943. const auto lhs_ele = FindDef(lhs_ele_id);
  944. const auto rhs_ele = FindDef(rhs_ele_id);
  945. if (!lhs_ele || !rhs_ele) {
  946. return false;
  947. }
  948. return LogicallyMatch(lhs_ele, rhs_ele, check_decorations);
  949. } else if (lhs->opcode() == SpvOpTypeStruct) {
  950. // Number of elements must match.
  951. if (lhs->operands().size() != rhs->operands().size()) {
  952. return false;
  953. }
  954. for (size_t i = 1u; i < lhs->operands().size(); ++i) {
  955. const auto lhs_ele_id = lhs->GetOperandAs<uint32_t>(i);
  956. const auto rhs_ele_id = rhs->GetOperandAs<uint32_t>(i);
  957. // Elements must match or logically match.
  958. if (lhs_ele_id == rhs_ele_id) {
  959. continue;
  960. }
  961. const auto lhs_ele = FindDef(lhs_ele_id);
  962. const auto rhs_ele = FindDef(rhs_ele_id);
  963. if (!lhs_ele || !rhs_ele) {
  964. return false;
  965. }
  966. if (!LogicallyMatch(lhs_ele, rhs_ele, check_decorations)) {
  967. return false;
  968. }
  969. }
  970. // All checks passed.
  971. return true;
  972. }
  973. // No other opcodes are acceptable at this point. Arrays and structs are
  974. // caught above and if they're elements are not arrays or structs they are
  975. // required to match exactly.
  976. return false;
  977. }
  978. const Instruction* ValidationState_t::TracePointer(
  979. const Instruction* inst) const {
  980. auto base_ptr = inst;
  981. while (base_ptr->opcode() == SpvOpAccessChain ||
  982. base_ptr->opcode() == SpvOpInBoundsAccessChain ||
  983. base_ptr->opcode() == SpvOpPtrAccessChain ||
  984. base_ptr->opcode() == SpvOpInBoundsPtrAccessChain ||
  985. base_ptr->opcode() == SpvOpCopyObject) {
  986. base_ptr = FindDef(base_ptr->GetOperandAs<uint32_t>(2u));
  987. }
  988. return base_ptr;
  989. }
  990. bool ValidationState_t::ContainsSizedIntOrFloatType(uint32_t id, SpvOp type,
  991. uint32_t width) const {
  992. if (type != SpvOpTypeInt && type != SpvOpTypeFloat) return false;
  993. const auto inst = FindDef(id);
  994. if (!inst) return false;
  995. if (inst->opcode() == type) {
  996. return inst->GetOperandAs<uint32_t>(1u) == width;
  997. }
  998. switch (inst->opcode()) {
  999. case SpvOpTypeArray:
  1000. case SpvOpTypeRuntimeArray:
  1001. case SpvOpTypeVector:
  1002. case SpvOpTypeMatrix:
  1003. case SpvOpTypeImage:
  1004. case SpvOpTypeSampledImage:
  1005. case SpvOpTypeCooperativeMatrixNV:
  1006. return ContainsSizedIntOrFloatType(inst->GetOperandAs<uint32_t>(1u), type,
  1007. width);
  1008. case SpvOpTypePointer:
  1009. if (IsForwardPointer(id)) return false;
  1010. return ContainsSizedIntOrFloatType(inst->GetOperandAs<uint32_t>(2u), type,
  1011. width);
  1012. case SpvOpTypeFunction:
  1013. case SpvOpTypeStruct: {
  1014. for (uint32_t i = 1; i < inst->operands().size(); ++i) {
  1015. if (ContainsSizedIntOrFloatType(inst->GetOperandAs<uint32_t>(i), type,
  1016. width))
  1017. return true;
  1018. }
  1019. return false;
  1020. }
  1021. default:
  1022. return false;
  1023. }
  1024. }
  1025. bool ValidationState_t::ContainsLimitedUseIntOrFloatType(uint32_t id) const {
  1026. if ((!HasCapability(SpvCapabilityInt16) &&
  1027. ContainsSizedIntOrFloatType(id, SpvOpTypeInt, 16)) ||
  1028. (!HasCapability(SpvCapabilityInt8) &&
  1029. ContainsSizedIntOrFloatType(id, SpvOpTypeInt, 8)) ||
  1030. (!HasCapability(SpvCapabilityFloat16) &&
  1031. ContainsSizedIntOrFloatType(id, SpvOpTypeFloat, 16))) {
  1032. return true;
  1033. }
  1034. return false;
  1035. }
  1036. bool ValidationState_t::IsValidStorageClass(
  1037. SpvStorageClass storage_class) const {
  1038. if (spvIsVulkanEnv(context()->target_env)) {
  1039. switch (storage_class) {
  1040. case SpvStorageClassUniformConstant:
  1041. case SpvStorageClassUniform:
  1042. case SpvStorageClassStorageBuffer:
  1043. case SpvStorageClassInput:
  1044. case SpvStorageClassOutput:
  1045. case SpvStorageClassImage:
  1046. case SpvStorageClassWorkgroup:
  1047. case SpvStorageClassPrivate:
  1048. case SpvStorageClassFunction:
  1049. case SpvStorageClassPushConstant:
  1050. case SpvStorageClassPhysicalStorageBuffer:
  1051. case SpvStorageClassRayPayloadNV:
  1052. case SpvStorageClassIncomingRayPayloadNV:
  1053. case SpvStorageClassHitAttributeNV:
  1054. case SpvStorageClassCallableDataNV:
  1055. case SpvStorageClassIncomingCallableDataNV:
  1056. case SpvStorageClassShaderRecordBufferNV:
  1057. return true;
  1058. default:
  1059. return false;
  1060. }
  1061. }
  1062. return true;
  1063. }
  1064. #define VUID_WRAP(vuid) "[" #vuid "] "
  1065. // Currently no 2 VUID share the same id, so no need for |reference|
  1066. std::string ValidationState_t::VkErrorID(uint32_t id,
  1067. const char* /*reference*/) const {
  1068. if (!spvIsVulkanEnv(context_->target_env)) {
  1069. return "";
  1070. }
  1071. // This large switch case is only searched when an error has occured.
  1072. // If an id is changed, the old case must be modified or removed. Each string
  1073. // here is interpreted as being "implemented"
  1074. // Clang format adds spaces between hyphens
  1075. // clang-format off
  1076. switch (id) {
  1077. case 4181:
  1078. return VUID_WRAP(VUID-BaseInstance-BaseInstance-04181);
  1079. case 4182:
  1080. return VUID_WRAP(VUID-BaseInstance-BaseInstance-04182);
  1081. case 4183:
  1082. return VUID_WRAP(VUID-BaseInstance-BaseInstance-04183);
  1083. case 4184:
  1084. return VUID_WRAP(VUID-BaseVertex-BaseVertex-04184);
  1085. case 4185:
  1086. return VUID_WRAP(VUID-BaseVertex-BaseVertex-04185);
  1087. case 4186:
  1088. return VUID_WRAP(VUID-BaseVertex-BaseVertex-04186);
  1089. case 4187:
  1090. return VUID_WRAP(VUID-ClipDistance-ClipDistance-04187);
  1091. case 4188:
  1092. return VUID_WRAP(VUID-ClipDistance-ClipDistance-04188);
  1093. case 4189:
  1094. return VUID_WRAP(VUID-ClipDistance-ClipDistance-04189);
  1095. case 4190:
  1096. return VUID_WRAP(VUID-ClipDistance-ClipDistance-04190);
  1097. case 4191:
  1098. return VUID_WRAP(VUID-ClipDistance-ClipDistance-04191);
  1099. case 4196:
  1100. return VUID_WRAP(VUID-CullDistance-CullDistance-04196);
  1101. case 4197:
  1102. return VUID_WRAP(VUID-CullDistance-CullDistance-04197);
  1103. case 4198:
  1104. return VUID_WRAP(VUID-CullDistance-CullDistance-04198);
  1105. case 4199:
  1106. return VUID_WRAP(VUID-CullDistance-CullDistance-04199);
  1107. case 4200:
  1108. return VUID_WRAP(VUID-CullDistance-CullDistance-04200);
  1109. case 4205:
  1110. return VUID_WRAP(VUID-DeviceIndex-DeviceIndex-04205);
  1111. case 4206:
  1112. return VUID_WRAP(VUID-DeviceIndex-DeviceIndex-04206);
  1113. case 4207:
  1114. return VUID_WRAP(VUID-DrawIndex-DrawIndex-04207);
  1115. case 4208:
  1116. return VUID_WRAP(VUID-DrawIndex-DrawIndex-04208);
  1117. case 4209:
  1118. return VUID_WRAP(VUID-DrawIndex-DrawIndex-04209);
  1119. case 4210:
  1120. return VUID_WRAP(VUID-FragCoord-FragCoord-04210);
  1121. case 4211:
  1122. return VUID_WRAP(VUID-FragCoord-FragCoord-04211);
  1123. case 4212:
  1124. return VUID_WRAP(VUID-FragCoord-FragCoord-04212);
  1125. case 4213:
  1126. return VUID_WRAP(VUID-FragDepth-FragDepth-04213);
  1127. case 4214:
  1128. return VUID_WRAP(VUID-FragDepth-FragDepth-04214);
  1129. case 4215:
  1130. return VUID_WRAP(VUID-FragDepth-FragDepth-04215);
  1131. case 4216:
  1132. return VUID_WRAP(VUID-FragDepth-FragDepth-04216);
  1133. case 4217:
  1134. return VUID_WRAP(VUID-FragInvocationCountEXT-FragInvocationCountEXT-04217);
  1135. case 4218:
  1136. return VUID_WRAP(VUID-FragInvocationCountEXT-FragInvocationCountEXT-04218);
  1137. case 4219:
  1138. return VUID_WRAP(VUID-FragInvocationCountEXT-FragInvocationCountEXT-04219);
  1139. case 4220:
  1140. return VUID_WRAP(VUID-FragSizeEXT-FragSizeEXT-04220);
  1141. case 4221:
  1142. return VUID_WRAP(VUID-FragSizeEXT-FragSizeEXT-04221);
  1143. case 4222:
  1144. return VUID_WRAP(VUID-FragSizeEXT-FragSizeEXT-04222);
  1145. case 4223:
  1146. return VUID_WRAP(VUID-FragStencilRefEXT-FragStencilRefEXT-04223);
  1147. case 4224:
  1148. return VUID_WRAP(VUID-FragStencilRefEXT-FragStencilRefEXT-04224);
  1149. case 4225:
  1150. return VUID_WRAP(VUID-FragStencilRefEXT-FragStencilRefEXT-04225);
  1151. case 4229:
  1152. return VUID_WRAP(VUID-FrontFacing-FrontFacing-04229);
  1153. case 4230:
  1154. return VUID_WRAP(VUID-FrontFacing-FrontFacing-04230);
  1155. case 4231:
  1156. return VUID_WRAP(VUID-FrontFacing-FrontFacing-04231);
  1157. case 4232:
  1158. return VUID_WRAP(VUID-FullyCoveredEXT-FullyCoveredEXT-04232);
  1159. case 4233:
  1160. return VUID_WRAP(VUID-FullyCoveredEXT-FullyCoveredEXT-04233);
  1161. case 4234:
  1162. return VUID_WRAP(VUID-FullyCoveredEXT-FullyCoveredEXT-04234);
  1163. case 4236:
  1164. return VUID_WRAP(VUID-GlobalInvocationId-GlobalInvocationId-04236);
  1165. case 4237:
  1166. return VUID_WRAP(VUID-GlobalInvocationId-GlobalInvocationId-04237);
  1167. case 4238:
  1168. return VUID_WRAP(VUID-GlobalInvocationId-GlobalInvocationId-04238);
  1169. case 4239:
  1170. return VUID_WRAP(VUID-HelperInvocation-HelperInvocation-04239);
  1171. case 4240:
  1172. return VUID_WRAP(VUID-HelperInvocation-HelperInvocation-04240);
  1173. case 4241:
  1174. return VUID_WRAP(VUID-HelperInvocation-HelperInvocation-04241);
  1175. case 4242:
  1176. return VUID_WRAP(VUID-HitKindKHR-HitKindKHR-04242);
  1177. case 4243:
  1178. return VUID_WRAP(VUID-HitKindKHR-HitKindKHR-04243);
  1179. case 4244:
  1180. return VUID_WRAP(VUID-HitKindKHR-HitKindKHR-04244);
  1181. case 4245:
  1182. return VUID_WRAP(VUID-HitTNV-HitTNV-04245);
  1183. case 4246:
  1184. return VUID_WRAP(VUID-HitTNV-HitTNV-04246);
  1185. case 4247:
  1186. return VUID_WRAP(VUID-HitTNV-HitTNV-04247);
  1187. case 4248:
  1188. return VUID_WRAP(VUID-IncomingRayFlagsKHR-IncomingRayFlagsKHR-04248);
  1189. case 4249:
  1190. return VUID_WRAP(VUID-IncomingRayFlagsKHR-IncomingRayFlagsKHR-04249);
  1191. case 4250:
  1192. return VUID_WRAP(VUID-IncomingRayFlagsKHR-IncomingRayFlagsKHR-04250);
  1193. case 4251:
  1194. return VUID_WRAP(VUID-InstanceCustomIndexKHR-InstanceCustomIndexKHR-04251);
  1195. case 4252:
  1196. return VUID_WRAP(VUID-InstanceCustomIndexKHR-InstanceCustomIndexKHR-04252);
  1197. case 4253:
  1198. return VUID_WRAP(VUID-InstanceCustomIndexKHR-InstanceCustomIndexKHR-04253);
  1199. case 4254:
  1200. return VUID_WRAP(VUID-InstanceId-InstanceId-04254);
  1201. case 4255:
  1202. return VUID_WRAP(VUID-InstanceId-InstanceId-04255);
  1203. case 4256:
  1204. return VUID_WRAP(VUID-InstanceId-InstanceId-04256);
  1205. case 4257:
  1206. return VUID_WRAP(VUID-InvocationId-InvocationId-04257);
  1207. case 4258:
  1208. return VUID_WRAP(VUID-InvocationId-InvocationId-04258);
  1209. case 4259:
  1210. return VUID_WRAP(VUID-InvocationId-InvocationId-04259);
  1211. case 4263:
  1212. return VUID_WRAP(VUID-InstanceIndex-InstanceIndex-04263);
  1213. case 4264:
  1214. return VUID_WRAP(VUID-InstanceIndex-InstanceIndex-04264);
  1215. case 4265:
  1216. return VUID_WRAP(VUID-InstanceIndex-InstanceIndex-04265);
  1217. case 4266:
  1218. return VUID_WRAP(VUID-LaunchIdKHR-LaunchIdKHR-04266);
  1219. case 4267:
  1220. return VUID_WRAP(VUID-LaunchIdKHR-LaunchIdKHR-04267);
  1221. case 4268:
  1222. return VUID_WRAP(VUID-LaunchIdKHR-LaunchIdKHR-04268);
  1223. case 4269:
  1224. return VUID_WRAP(VUID-LaunchSizeKHR-LaunchSizeKHR-04269);
  1225. case 4270:
  1226. return VUID_WRAP(VUID-LaunchSizeKHR-LaunchSizeKHR-04270);
  1227. case 4271:
  1228. return VUID_WRAP(VUID-LaunchSizeKHR-LaunchSizeKHR-04271);
  1229. case 4272:
  1230. return VUID_WRAP(VUID-Layer-Layer-04272);
  1231. case 4273:
  1232. return VUID_WRAP(VUID-Layer-Layer-04273);
  1233. case 4274:
  1234. return VUID_WRAP(VUID-Layer-Layer-04274);
  1235. case 4275:
  1236. return VUID_WRAP(VUID-Layer-Layer-04275);
  1237. case 4276:
  1238. return VUID_WRAP(VUID-Layer-Layer-04276);
  1239. case 4281:
  1240. return VUID_WRAP(VUID-LocalInvocationId-LocalInvocationId-04281);
  1241. case 4282:
  1242. return VUID_WRAP(VUID-LocalInvocationId-LocalInvocationId-04282);
  1243. case 4283:
  1244. return VUID_WRAP(VUID-LocalInvocationId-LocalInvocationId-04283);
  1245. case 4293:
  1246. return VUID_WRAP(VUID-NumSubgroups-NumSubgroups-04293);
  1247. case 4294:
  1248. return VUID_WRAP(VUID-NumSubgroups-NumSubgroups-04294);
  1249. case 4295:
  1250. return VUID_WRAP(VUID-NumSubgroups-NumSubgroups-04295);
  1251. case 4296:
  1252. return VUID_WRAP(VUID-NumWorkgroups-NumWorkgroups-04296);
  1253. case 4297:
  1254. return VUID_WRAP(VUID-NumWorkgroups-NumWorkgroups-04297);
  1255. case 4298:
  1256. return VUID_WRAP(VUID-NumWorkgroups-NumWorkgroups-04298);
  1257. case 4299:
  1258. return VUID_WRAP(VUID-ObjectRayDirectionKHR-ObjectRayDirectionKHR-04299);
  1259. case 4300:
  1260. return VUID_WRAP(VUID-ObjectRayDirectionKHR-ObjectRayDirectionKHR-04300);
  1261. case 4301:
  1262. return VUID_WRAP(VUID-ObjectRayDirectionKHR-ObjectRayDirectionKHR-04301);
  1263. case 4302:
  1264. return VUID_WRAP(VUID-ObjectRayOriginKHR-ObjectRayOriginKHR-04302);
  1265. case 4303:
  1266. return VUID_WRAP(VUID-ObjectRayOriginKHR-ObjectRayOriginKHR-04303);
  1267. case 4304:
  1268. return VUID_WRAP(VUID-ObjectRayOriginKHR-ObjectRayOriginKHR-04304);
  1269. case 4305:
  1270. return VUID_WRAP(VUID-ObjectToWorldKHR-ObjectToWorldKHR-04305);
  1271. case 4306:
  1272. return VUID_WRAP(VUID-ObjectToWorldKHR-ObjectToWorldKHR-04306);
  1273. case 4307:
  1274. return VUID_WRAP(VUID-ObjectToWorldKHR-ObjectToWorldKHR-04307);
  1275. case 4308:
  1276. return VUID_WRAP(VUID-PatchVertices-PatchVertices-04308);
  1277. case 4309:
  1278. return VUID_WRAP(VUID-PatchVertices-PatchVertices-04309);
  1279. case 4310:
  1280. return VUID_WRAP(VUID-PatchVertices-PatchVertices-04310);
  1281. case 4311:
  1282. return VUID_WRAP(VUID-PointCoord-PointCoord-04311);
  1283. case 4312:
  1284. return VUID_WRAP(VUID-PointCoord-PointCoord-04312);
  1285. case 4313:
  1286. return VUID_WRAP(VUID-PointCoord-PointCoord-04313);
  1287. case 4314:
  1288. return VUID_WRAP(VUID-PointSize-PointSize-04314);
  1289. case 4315:
  1290. return VUID_WRAP(VUID-PointSize-PointSize-04315);
  1291. case 4316:
  1292. return VUID_WRAP(VUID-PointSize-PointSize-04316);
  1293. case 4317:
  1294. return VUID_WRAP(VUID-PointSize-PointSize-04317);
  1295. case 4318:
  1296. return VUID_WRAP(VUID-Position-Position-04318);
  1297. case 4319:
  1298. return VUID_WRAP(VUID-Position-Position-04319);
  1299. case 4320:
  1300. return VUID_WRAP(VUID-Position-Position-04320);
  1301. case 4321:
  1302. return VUID_WRAP(VUID-Position-Position-04321);
  1303. case 4330:
  1304. return VUID_WRAP(VUID-PrimitiveId-PrimitiveId-04330);
  1305. case 4334:
  1306. return VUID_WRAP(VUID-PrimitiveId-PrimitiveId-04334);
  1307. case 4337:
  1308. return VUID_WRAP(VUID-PrimitiveId-PrimitiveId-04337);
  1309. case 4345:
  1310. return VUID_WRAP(VUID-RayGeometryIndexKHR-RayGeometryIndexKHR-04345);
  1311. case 4346:
  1312. return VUID_WRAP(VUID-RayGeometryIndexKHR-RayGeometryIndexKHR-04346);
  1313. case 4347:
  1314. return VUID_WRAP(VUID-RayGeometryIndexKHR-RayGeometryIndexKHR-04347);
  1315. case 4348:
  1316. return VUID_WRAP(VUID-RayTmaxKHR-RayTmaxKHR-04348);
  1317. case 4349:
  1318. return VUID_WRAP(VUID-RayTmaxKHR-RayTmaxKHR-04349);
  1319. case 4350:
  1320. return VUID_WRAP(VUID-RayTmaxKHR-RayTmaxKHR-04350);
  1321. case 4351:
  1322. return VUID_WRAP(VUID-RayTminKHR-RayTminKHR-04351);
  1323. case 4352:
  1324. return VUID_WRAP(VUID-RayTminKHR-RayTminKHR-04352);
  1325. case 4353:
  1326. return VUID_WRAP(VUID-RayTminKHR-RayTminKHR-04353);
  1327. case 4354:
  1328. return VUID_WRAP(VUID-SampleId-SampleId-04354);
  1329. case 4355:
  1330. return VUID_WRAP(VUID-SampleId-SampleId-04355);
  1331. case 4356:
  1332. return VUID_WRAP(VUID-SampleId-SampleId-04356);
  1333. case 4357:
  1334. return VUID_WRAP(VUID-SampleMask-SampleMask-04357);
  1335. case 4358:
  1336. return VUID_WRAP(VUID-SampleMask-SampleMask-04358);
  1337. case 4359:
  1338. return VUID_WRAP(VUID-SampleMask-SampleMask-04359);
  1339. case 4360:
  1340. return VUID_WRAP(VUID-SamplePosition-SamplePosition-04360);
  1341. case 4361:
  1342. return VUID_WRAP(VUID-SamplePosition-SamplePosition-04361);
  1343. case 4362:
  1344. return VUID_WRAP(VUID-SamplePosition-SamplePosition-04362);
  1345. case 4367:
  1346. return VUID_WRAP(VUID-SubgroupId-SubgroupId-04367);
  1347. case 4368:
  1348. return VUID_WRAP(VUID-SubgroupId-SubgroupId-04368);
  1349. case 4369:
  1350. return VUID_WRAP(VUID-SubgroupId-SubgroupId-04369);
  1351. case 4370:
  1352. return VUID_WRAP(VUID-SubgroupEqMask-SubgroupEqMask-04370);
  1353. case 4371:
  1354. return VUID_WRAP(VUID-SubgroupEqMask-SubgroupEqMask-04371);
  1355. case 4372:
  1356. return VUID_WRAP(VUID-SubgroupGeMask-SubgroupGeMask-04372);
  1357. case 4373:
  1358. return VUID_WRAP(VUID-SubgroupGeMask-SubgroupGeMask-04373);
  1359. case 4374:
  1360. return VUID_WRAP(VUID-SubgroupGtMask-SubgroupGtMask-04374);
  1361. case 4375:
  1362. return VUID_WRAP(VUID-SubgroupGtMask-SubgroupGtMask-04375);
  1363. case 4376:
  1364. return VUID_WRAP(VUID-SubgroupLeMask-SubgroupLeMask-04376);
  1365. case 4377:
  1366. return VUID_WRAP(VUID-SubgroupLeMask-SubgroupLeMask-04377);
  1367. case 4378:
  1368. return VUID_WRAP(VUID-SubgroupLtMask-SubgroupLtMask-04378);
  1369. case 4379:
  1370. return VUID_WRAP(VUID-SubgroupLtMask-SubgroupLtMask-04379);
  1371. case 4380:
  1372. return VUID_WRAP(VUID-SubgroupLocalInvocationId-SubgroupLocalInvocationId-04380);
  1373. case 4381:
  1374. return VUID_WRAP(VUID-SubgroupLocalInvocationId-SubgroupLocalInvocationId-04381);
  1375. case 4382:
  1376. return VUID_WRAP(VUID-SubgroupSize-SubgroupSize-04382);
  1377. case 4383:
  1378. return VUID_WRAP(VUID-SubgroupSize-SubgroupSize-04383);
  1379. case 4387:
  1380. return VUID_WRAP(VUID-TessCoord-TessCoord-04387);
  1381. case 4388:
  1382. return VUID_WRAP(VUID-TessCoord-TessCoord-04388);
  1383. case 4389:
  1384. return VUID_WRAP(VUID-TessCoord-TessCoord-04389);
  1385. case 4390:
  1386. return VUID_WRAP(VUID-TessLevelOuter-TessLevelOuter-04390);
  1387. case 4391:
  1388. return VUID_WRAP(VUID-TessLevelOuter-TessLevelOuter-04391);
  1389. case 4392:
  1390. return VUID_WRAP(VUID-TessLevelOuter-TessLevelOuter-04392);
  1391. case 4393:
  1392. return VUID_WRAP(VUID-TessLevelOuter-TessLevelOuter-04393);
  1393. case 4394:
  1394. return VUID_WRAP(VUID-TessLevelInner-TessLevelInner-04394);
  1395. case 4395:
  1396. return VUID_WRAP(VUID-TessLevelInner-TessLevelInner-04395);
  1397. case 4396:
  1398. return VUID_WRAP(VUID-TessLevelInner-TessLevelInner-04396);
  1399. case 4397:
  1400. return VUID_WRAP(VUID-TessLevelInner-TessLevelInner-04397);
  1401. case 4398:
  1402. return VUID_WRAP(VUID-VertexIndex-VertexIndex-04398);
  1403. case 4399:
  1404. return VUID_WRAP(VUID-VertexIndex-VertexIndex-04399);
  1405. case 4400:
  1406. return VUID_WRAP(VUID-VertexIndex-VertexIndex-04400);
  1407. case 4401:
  1408. return VUID_WRAP(VUID-ViewIndex-ViewIndex-04401);
  1409. case 4402:
  1410. return VUID_WRAP(VUID-ViewIndex-ViewIndex-04402);
  1411. case 4403:
  1412. return VUID_WRAP(VUID-ViewIndex-ViewIndex-04403);
  1413. case 4404:
  1414. return VUID_WRAP(VUID-ViewportIndex-ViewportIndex-04404);
  1415. case 4405:
  1416. return VUID_WRAP(VUID-ViewportIndex-ViewportIndex-04405);
  1417. case 4406:
  1418. return VUID_WRAP(VUID-ViewportIndex-ViewportIndex-04406);
  1419. case 4407:
  1420. return VUID_WRAP(VUID-ViewportIndex-ViewportIndex-04407);
  1421. case 4408:
  1422. return VUID_WRAP(VUID-ViewportIndex-ViewportIndex-04408);
  1423. case 4422:
  1424. return VUID_WRAP(VUID-WorkgroupId-WorkgroupId-04422);
  1425. case 4423:
  1426. return VUID_WRAP(VUID-WorkgroupId-WorkgroupId-04423);
  1427. case 4424:
  1428. return VUID_WRAP(VUID-WorkgroupId-WorkgroupId-04424);
  1429. case 4425:
  1430. return VUID_WRAP(VUID-WorkgroupSize-WorkgroupSize-04425);
  1431. case 4426:
  1432. return VUID_WRAP(VUID-WorkgroupSize-WorkgroupSize-04426);
  1433. case 4427:
  1434. return VUID_WRAP(VUID-WorkgroupSize-WorkgroupSize-04427);
  1435. case 4428:
  1436. return VUID_WRAP(VUID-WorldRayDirectionKHR-WorldRayDirectionKHR-04428);
  1437. case 4429:
  1438. return VUID_WRAP(VUID-WorldRayDirectionKHR-WorldRayDirectionKHR-04429);
  1439. case 4430:
  1440. return VUID_WRAP(VUID-WorldRayDirectionKHR-WorldRayDirectionKHR-04430);
  1441. case 4431:
  1442. return VUID_WRAP(VUID-WorldRayOriginKHR-WorldRayOriginKHR-04431);
  1443. case 4432:
  1444. return VUID_WRAP(VUID-WorldRayOriginKHR-WorldRayOriginKHR-04432);
  1445. case 4433:
  1446. return VUID_WRAP(VUID-WorldRayOriginKHR-WorldRayOriginKHR-04433);
  1447. case 4434:
  1448. return VUID_WRAP(VUID-WorldToObjectKHR-WorldToObjectKHR-04434);
  1449. case 4435:
  1450. return VUID_WRAP(VUID-WorldToObjectKHR-WorldToObjectKHR-04435);
  1451. case 4436:
  1452. return VUID_WRAP(VUID-WorldToObjectKHR-WorldToObjectKHR-04436);
  1453. case 4484:
  1454. return VUID_WRAP(VUID-PrimitiveShadingRateKHR-PrimitiveShadingRateKHR-04484);
  1455. case 4485:
  1456. return VUID_WRAP(VUID-PrimitiveShadingRateKHR-PrimitiveShadingRateKHR-04485);
  1457. case 4486:
  1458. return VUID_WRAP(VUID-PrimitiveShadingRateKHR-PrimitiveShadingRateKHR-04486);
  1459. case 4490:
  1460. return VUID_WRAP(VUID-ShadingRateKHR-ShadingRateKHR-04490);
  1461. case 4491:
  1462. return VUID_WRAP(VUID-ShadingRateKHR-ShadingRateKHR-04491);
  1463. case 4492:
  1464. return VUID_WRAP(VUID-ShadingRateKHR-ShadingRateKHR-04492);
  1465. case 4633:
  1466. return VUID_WRAP(VUID-StandaloneSpirv-None-04633);
  1467. case 4635:
  1468. return VUID_WRAP(VUID-StandaloneSpirv-None-04635);
  1469. case 4638:
  1470. return VUID_WRAP(VUID-StandaloneSpirv-None-04638);
  1471. case 4639:
  1472. return VUID_WRAP(VUID-StandaloneSpirv-None-04639);
  1473. case 4640:
  1474. return VUID_WRAP(VUID-StandaloneSpirv-None-04640);
  1475. case 4642:
  1476. return VUID_WRAP(VUID-StandaloneSpirv-None-04642);
  1477. case 4651:
  1478. return VUID_WRAP(VUID-StandaloneSpirv-OpVariable-04651);
  1479. case 4652:
  1480. return VUID_WRAP(VUID-StandaloneSpirv-OpReadClockKHR-04652);
  1481. case 4653:
  1482. return VUID_WRAP(VUID-StandaloneSpirv-OriginLowerLeft-04653);
  1483. case 4654:
  1484. return VUID_WRAP(VUID-StandaloneSpirv-PixelCenterInteger-04654);
  1485. case 4655:
  1486. return VUID_WRAP(VUID-StandaloneSpirv-UniformConstant-04655);
  1487. case 4656:
  1488. return VUID_WRAP(VUID-StandaloneSpirv-OpTypeImage-04656);
  1489. case 4657:
  1490. return VUID_WRAP(VUID-StandaloneSpirv-OpTypeImage-04657);
  1491. case 4658:
  1492. return VUID_WRAP(VUID-StandaloneSpirv-OpImageTexelPointer-04658);
  1493. case 4659:
  1494. return VUID_WRAP(VUID-StandaloneSpirv-OpImageQuerySizeLod-04659);
  1495. case 4662:
  1496. return VUID_WRAP(VUID-StandaloneSpirv-Offset-04662);
  1497. case 4663:
  1498. return VUID_WRAP(VUID-StandaloneSpirv-Offset-04663);
  1499. case 4664:
  1500. return VUID_WRAP(VUID-StandaloneSpirv-OpImageGather-04664);
  1501. case 4669:
  1502. return VUID_WRAP(VUID-StandaloneSpirv-GLSLShared-04669);
  1503. case 4675:
  1504. return VUID_WRAP(VUID-StandaloneSpirv-FPRoundingMode-04675);
  1505. case 4677:
  1506. return VUID_WRAP(VUID-StandaloneSpirv-Invariant-04677);
  1507. case 4683:
  1508. return VUID_WRAP(VUID-StandaloneSpirv-LocalSize-04683);
  1509. case 4685:
  1510. return VUID_WRAP(VUID-StandaloneSpirv-OpGroupNonUniformBallotBitCount-04685);
  1511. case 4686:
  1512. return VUID_WRAP(VUID-StandaloneSpirv-None-04686);
  1513. case 4710:
  1514. return VUID_WRAP(VUID-StandaloneSpirv-PhysicalStorageBuffer64-04710);
  1515. case 4711:
  1516. return VUID_WRAP(VUID-StandaloneSpirv-OpTypeForwardPointer-04711);
  1517. case 4730:
  1518. return VUID_WRAP(VUID-StandaloneSpirv-OpAtomicStore-04730);
  1519. case 4731:
  1520. return VUID_WRAP(VUID-StandaloneSpirv-OpAtomicLoad-04731);
  1521. case 4732:
  1522. return VUID_WRAP(VUID-StandaloneSpirv-OpMemoryBarrier-04732);
  1523. case 4733:
  1524. return VUID_WRAP(VUID-StandaloneSpirv-OpMemoryBarrier-04733);
  1525. default:
  1526. return ""; // unknown id
  1527. };
  1528. // clang-format on
  1529. }
  1530. } // namespace val
  1531. } // namespace spvtools