validation_state.cpp 75 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189
  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, spv::Op op) {
  30. // See Section 2.4
  31. if (spvOpcodeGeneratesType(op) || spvOpcodeIsConstant(op))
  32. return kLayoutTypes;
  33. switch (op) {
  34. case spv::Op::OpCapability:
  35. return kLayoutCapabilities;
  36. case spv::Op::OpExtension:
  37. return kLayoutExtensions;
  38. case spv::Op::OpExtInstImport:
  39. return kLayoutExtInstImport;
  40. case spv::Op::OpMemoryModel:
  41. return kLayoutMemoryModel;
  42. case spv::Op::OpEntryPoint:
  43. return kLayoutEntryPoint;
  44. case spv::Op::OpExecutionMode:
  45. case spv::Op::OpExecutionModeId:
  46. return kLayoutExecutionMode;
  47. case spv::Op::OpSourceContinued:
  48. case spv::Op::OpSource:
  49. case spv::Op::OpSourceExtension:
  50. case spv::Op::OpString:
  51. return kLayoutDebug1;
  52. case spv::Op::OpName:
  53. case spv::Op::OpMemberName:
  54. return kLayoutDebug2;
  55. case spv::Op::OpModuleProcessed:
  56. return kLayoutDebug3;
  57. case spv::Op::OpDecorate:
  58. case spv::Op::OpMemberDecorate:
  59. case spv::Op::OpGroupDecorate:
  60. case spv::Op::OpGroupMemberDecorate:
  61. case spv::Op::OpDecorationGroup:
  62. case spv::Op::OpDecorateId:
  63. case spv::Op::OpDecorateStringGOOGLE:
  64. case spv::Op::OpMemberDecorateStringGOOGLE:
  65. return kLayoutAnnotations;
  66. case spv::Op::OpTypeForwardPointer:
  67. return kLayoutTypes;
  68. case spv::Op::OpVariable:
  69. if (current_section == kLayoutTypes) return kLayoutTypes;
  70. return kLayoutFunctionDefinitions;
  71. case spv::Op::OpExtInst:
  72. // spv::Op::OpExtInst is only allowed in types section for certain
  73. // extended instruction sets. This will be checked separately.
  74. if (current_section == kLayoutTypes) return kLayoutTypes;
  75. return kLayoutFunctionDefinitions;
  76. case spv::Op::OpLine:
  77. case spv::Op::OpNoLine:
  78. case spv::Op::OpUndef:
  79. if (current_section == kLayoutTypes) return kLayoutTypes;
  80. return kLayoutFunctionDefinitions;
  81. case spv::Op::OpFunction:
  82. case spv::Op::OpFunctionParameter:
  83. case spv::Op::OpFunctionEnd:
  84. if (current_section == kLayoutFunctionDeclarations)
  85. return kLayoutFunctionDeclarations;
  86. return kLayoutFunctionDefinitions;
  87. case spv::Op::OpSamplerImageAddressingModeNV:
  88. return kLayoutSamplerImageAddressMode;
  89. default:
  90. break;
  91. }
  92. return kLayoutFunctionDefinitions;
  93. }
  94. bool IsInstructionInLayoutSection(ModuleLayoutSection layout, spv::Op op) {
  95. return layout == InstructionLayoutSection(layout, op);
  96. }
  97. // Counts the number of instructions and functions in the file.
  98. spv_result_t CountInstructions(void* user_data,
  99. const spv_parsed_instruction_t* inst) {
  100. ValidationState_t& _ = *(reinterpret_cast<ValidationState_t*>(user_data));
  101. if (spv::Op(inst->opcode) == spv::Op::OpFunction) {
  102. _.increment_total_functions();
  103. }
  104. _.increment_total_instructions();
  105. return SPV_SUCCESS;
  106. }
  107. spv_result_t setHeader(void* user_data, spv_endianness_t, uint32_t,
  108. uint32_t version, uint32_t generator, uint32_t id_bound,
  109. uint32_t) {
  110. ValidationState_t& vstate =
  111. *(reinterpret_cast<ValidationState_t*>(user_data));
  112. vstate.setIdBound(id_bound);
  113. vstate.setGenerator(generator);
  114. vstate.setVersion(version);
  115. return SPV_SUCCESS;
  116. }
  117. // Add features based on SPIR-V core version number.
  118. void UpdateFeaturesBasedOnSpirvVersion(ValidationState_t::Feature* features,
  119. uint32_t version) {
  120. assert(features);
  121. if (version >= SPV_SPIRV_VERSION_WORD(1, 4)) {
  122. features->select_between_composites = true;
  123. features->copy_memory_permits_two_memory_accesses = true;
  124. features->uconvert_spec_constant_op = true;
  125. features->nonwritable_var_in_function_or_private = true;
  126. }
  127. }
  128. } // namespace
  129. ValidationState_t::ValidationState_t(const spv_const_context ctx,
  130. const spv_const_validator_options opt,
  131. const uint32_t* words,
  132. const size_t num_words,
  133. const uint32_t max_warnings)
  134. : context_(ctx),
  135. options_(opt),
  136. words_(words),
  137. num_words_(num_words),
  138. unresolved_forward_ids_{},
  139. operand_names_{},
  140. current_layout_section_(kLayoutCapabilities),
  141. module_functions_(),
  142. module_capabilities_(),
  143. module_extensions_(),
  144. ordered_instructions_(),
  145. all_definitions_(),
  146. global_vars_(),
  147. local_vars_(),
  148. struct_nesting_depth_(),
  149. struct_has_nested_blockorbufferblock_struct_(),
  150. grammar_(ctx),
  151. addressing_model_(spv::AddressingModel::Max),
  152. memory_model_(spv::MemoryModel::Max),
  153. pointer_size_and_alignment_(0),
  154. sampler_image_addressing_mode_(0),
  155. in_function_(false),
  156. num_of_warnings_(0),
  157. max_num_of_warnings_(max_warnings) {
  158. assert(opt && "Validator options may not be Null.");
  159. const auto env = context_->target_env;
  160. if (spvIsVulkanEnv(env)) {
  161. // Vulkan 1.1 includes VK_KHR_relaxed_block_layout in core.
  162. if (env != SPV_ENV_VULKAN_1_0) {
  163. features_.env_relaxed_block_layout = true;
  164. }
  165. }
  166. // LocalSizeId is only disallowed prior to Vulkan 1.3 without maintenance4.
  167. switch (env) {
  168. case SPV_ENV_VULKAN_1_0:
  169. case SPV_ENV_VULKAN_1_1:
  170. case SPV_ENV_VULKAN_1_1_SPIRV_1_4:
  171. case SPV_ENV_VULKAN_1_2:
  172. features_.env_allow_localsizeid = false;
  173. break;
  174. default:
  175. features_.env_allow_localsizeid = true;
  176. break;
  177. }
  178. // Only attempt to count if we have words, otherwise let the other validation
  179. // fail and generate an error.
  180. if (num_words > 0) {
  181. // Count the number of instructions in the binary.
  182. // This parse should not produce any error messages. Hijack the context and
  183. // replace the message consumer so that we do not pollute any state in input
  184. // consumer.
  185. spv_context_t hijacked_context = *ctx;
  186. hijacked_context.consumer = [](spv_message_level_t, const char*,
  187. const spv_position_t&, const char*) {};
  188. spvBinaryParse(&hijacked_context, this, words, num_words, setHeader,
  189. CountInstructions,
  190. /* diagnostic = */ nullptr);
  191. preallocateStorage();
  192. }
  193. UpdateFeaturesBasedOnSpirvVersion(&features_, version_);
  194. name_mapper_ = spvtools::GetTrivialNameMapper();
  195. if (options_->use_friendly_names) {
  196. friendly_mapper_ = spvtools::MakeUnique<spvtools::FriendlyNameMapper>(
  197. context_, words_, num_words_);
  198. name_mapper_ = friendly_mapper_->GetNameMapper();
  199. }
  200. }
  201. void ValidationState_t::preallocateStorage() {
  202. ordered_instructions_.reserve(total_instructions_);
  203. module_functions_.reserve(total_functions_);
  204. }
  205. spv_result_t ValidationState_t::ForwardDeclareId(uint32_t id) {
  206. unresolved_forward_ids_.insert(id);
  207. return SPV_SUCCESS;
  208. }
  209. spv_result_t ValidationState_t::RemoveIfForwardDeclared(uint32_t id) {
  210. unresolved_forward_ids_.erase(id);
  211. return SPV_SUCCESS;
  212. }
  213. spv_result_t ValidationState_t::RegisterForwardPointer(uint32_t id) {
  214. forward_pointer_ids_.insert(id);
  215. return SPV_SUCCESS;
  216. }
  217. bool ValidationState_t::IsForwardPointer(uint32_t id) const {
  218. return (forward_pointer_ids_.find(id) != forward_pointer_ids_.end());
  219. }
  220. void ValidationState_t::AssignNameToId(uint32_t id, std::string name) {
  221. operand_names_[id] = name;
  222. }
  223. std::string ValidationState_t::getIdName(uint32_t id) const {
  224. const std::string id_name = name_mapper_(id);
  225. std::stringstream out;
  226. out << "'" << id << "[%" << id_name << "]'";
  227. return out.str();
  228. }
  229. size_t ValidationState_t::unresolved_forward_id_count() const {
  230. return unresolved_forward_ids_.size();
  231. }
  232. std::vector<uint32_t> ValidationState_t::UnresolvedForwardIds() const {
  233. std::vector<uint32_t> out(std::begin(unresolved_forward_ids_),
  234. std::end(unresolved_forward_ids_));
  235. return out;
  236. }
  237. bool ValidationState_t::IsDefinedId(uint32_t id) const {
  238. return all_definitions_.find(id) != std::end(all_definitions_);
  239. }
  240. const Instruction* ValidationState_t::FindDef(uint32_t id) const {
  241. auto it = all_definitions_.find(id);
  242. if (it == all_definitions_.end()) return nullptr;
  243. return it->second;
  244. }
  245. Instruction* ValidationState_t::FindDef(uint32_t id) {
  246. auto it = all_definitions_.find(id);
  247. if (it == all_definitions_.end()) return nullptr;
  248. return it->second;
  249. }
  250. ModuleLayoutSection ValidationState_t::current_layout_section() const {
  251. return current_layout_section_;
  252. }
  253. void ValidationState_t::ProgressToNextLayoutSectionOrder() {
  254. // Guard against going past the last element(kLayoutFunctionDefinitions)
  255. if (current_layout_section_ <= kLayoutFunctionDefinitions) {
  256. current_layout_section_ =
  257. static_cast<ModuleLayoutSection>(current_layout_section_ + 1);
  258. }
  259. }
  260. bool ValidationState_t::IsOpcodeInPreviousLayoutSection(spv::Op op) {
  261. ModuleLayoutSection section =
  262. InstructionLayoutSection(current_layout_section_, op);
  263. return section < current_layout_section_;
  264. }
  265. bool ValidationState_t::IsOpcodeInCurrentLayoutSection(spv::Op op) {
  266. return IsInstructionInLayoutSection(current_layout_section_, op);
  267. }
  268. DiagnosticStream ValidationState_t::diag(spv_result_t error_code,
  269. const Instruction* inst) {
  270. if (error_code == SPV_WARNING) {
  271. if (num_of_warnings_ == max_num_of_warnings_) {
  272. DiagnosticStream({0, 0, 0}, context_->consumer, "", error_code)
  273. << "Other warnings have been suppressed.\n";
  274. }
  275. if (num_of_warnings_ >= max_num_of_warnings_) {
  276. return DiagnosticStream({0, 0, 0}, nullptr, "", error_code);
  277. }
  278. ++num_of_warnings_;
  279. }
  280. std::string disassembly;
  281. if (inst) disassembly = Disassemble(*inst);
  282. return DiagnosticStream({0, 0, inst ? inst->LineNum() : 0},
  283. context_->consumer, disassembly, error_code);
  284. }
  285. std::vector<Function>& ValidationState_t::functions() {
  286. return module_functions_;
  287. }
  288. Function& ValidationState_t::current_function() {
  289. assert(in_function_body());
  290. return module_functions_.back();
  291. }
  292. const Function& ValidationState_t::current_function() const {
  293. assert(in_function_body());
  294. return module_functions_.back();
  295. }
  296. const Function* ValidationState_t::function(uint32_t id) const {
  297. const auto it = id_to_function_.find(id);
  298. if (it == id_to_function_.end()) return nullptr;
  299. return it->second;
  300. }
  301. Function* ValidationState_t::function(uint32_t id) {
  302. auto it = id_to_function_.find(id);
  303. if (it == id_to_function_.end()) return nullptr;
  304. return it->second;
  305. }
  306. bool ValidationState_t::in_function_body() const { return in_function_; }
  307. bool ValidationState_t::in_block() const {
  308. return module_functions_.empty() == false &&
  309. module_functions_.back().current_block() != nullptr;
  310. }
  311. void ValidationState_t::RegisterCapability(spv::Capability cap) {
  312. // Avoid redundant work. Otherwise the recursion could induce work
  313. // quadrdatic in the capability dependency depth. (Ok, not much, but
  314. // it's something.)
  315. if (module_capabilities_.Contains(cap)) return;
  316. module_capabilities_.Add(cap);
  317. spv_operand_desc desc;
  318. if (SPV_SUCCESS == grammar_.lookupOperand(SPV_OPERAND_TYPE_CAPABILITY,
  319. uint32_t(cap), &desc)) {
  320. CapabilitySet(desc->numCapabilities, desc->capabilities)
  321. .ForEach([this](spv::Capability c) { RegisterCapability(c); });
  322. }
  323. switch (cap) {
  324. case spv::Capability::Kernel:
  325. features_.group_ops_reduce_and_scans = true;
  326. break;
  327. case spv::Capability::Int8:
  328. features_.use_int8_type = true;
  329. features_.declare_int8_type = true;
  330. break;
  331. case spv::Capability::StorageBuffer8BitAccess:
  332. case spv::Capability::UniformAndStorageBuffer8BitAccess:
  333. case spv::Capability::StoragePushConstant8:
  334. case spv::Capability::WorkgroupMemoryExplicitLayout8BitAccessKHR:
  335. features_.declare_int8_type = true;
  336. break;
  337. case spv::Capability::Int16:
  338. features_.declare_int16_type = true;
  339. break;
  340. case spv::Capability::Float16:
  341. case spv::Capability::Float16Buffer:
  342. features_.declare_float16_type = true;
  343. break;
  344. case spv::Capability::StorageUniformBufferBlock16:
  345. case spv::Capability::StorageUniform16:
  346. case spv::Capability::StoragePushConstant16:
  347. case spv::Capability::StorageInputOutput16:
  348. case spv::Capability::WorkgroupMemoryExplicitLayout16BitAccessKHR:
  349. features_.declare_int16_type = true;
  350. features_.declare_float16_type = true;
  351. features_.free_fp_rounding_mode = true;
  352. break;
  353. case spv::Capability::VariablePointers:
  354. case spv::Capability::VariablePointersStorageBuffer:
  355. features_.variable_pointers = true;
  356. break;
  357. default:
  358. // TODO(dneto): For now don't validate SPV_NV_ray_tracing, which uses
  359. // capability spv::Capability::RayTracingNV.
  360. // spv::Capability::RayTracingProvisionalKHR would need the same
  361. // treatment. One of the differences going from SPV_KHR_ray_tracing from
  362. // provisional to final spec was the provisional spec uses Locations
  363. // for variables in certain storage classes, just like the
  364. // SPV_NV_ray_tracing extension. So it mimics the NVIDIA extension.
  365. // The final SPV_KHR_ray_tracing uses a different capability token
  366. // number, so it doesn't fall into this case.
  367. break;
  368. }
  369. }
  370. void ValidationState_t::RegisterExtension(Extension ext) {
  371. if (module_extensions_.Contains(ext)) return;
  372. module_extensions_.Add(ext);
  373. switch (ext) {
  374. case kSPV_AMD_gpu_shader_half_float:
  375. case kSPV_AMD_gpu_shader_half_float_fetch:
  376. // SPV_AMD_gpu_shader_half_float enables float16 type.
  377. // https://github.com/KhronosGroup/SPIRV-Tools/issues/1375
  378. features_.declare_float16_type = true;
  379. break;
  380. case kSPV_AMD_gpu_shader_int16:
  381. // This is not yet in the extension, but it's recommended for it.
  382. // See https://github.com/KhronosGroup/glslang/issues/848
  383. features_.uconvert_spec_constant_op = true;
  384. break;
  385. case kSPV_AMD_shader_ballot:
  386. // The grammar doesn't encode the fact that SPV_AMD_shader_ballot
  387. // enables the use of group operations Reduce, InclusiveScan,
  388. // and ExclusiveScan. Enable it manually.
  389. // https://github.com/KhronosGroup/SPIRV-Tools/issues/991
  390. features_.group_ops_reduce_and_scans = true;
  391. break;
  392. default:
  393. break;
  394. }
  395. }
  396. bool ValidationState_t::HasAnyOfCapabilities(
  397. const CapabilitySet& capabilities) const {
  398. return module_capabilities_.HasAnyOf(capabilities);
  399. }
  400. bool ValidationState_t::HasAnyOfExtensions(
  401. const ExtensionSet& extensions) const {
  402. return module_extensions_.HasAnyOf(extensions);
  403. }
  404. void ValidationState_t::set_addressing_model(spv::AddressingModel am) {
  405. addressing_model_ = am;
  406. switch (am) {
  407. case spv::AddressingModel::Physical32:
  408. pointer_size_and_alignment_ = 4;
  409. break;
  410. default:
  411. // fall through
  412. case spv::AddressingModel::Physical64:
  413. case spv::AddressingModel::PhysicalStorageBuffer64:
  414. pointer_size_and_alignment_ = 8;
  415. break;
  416. }
  417. }
  418. spv::AddressingModel ValidationState_t::addressing_model() const {
  419. return addressing_model_;
  420. }
  421. void ValidationState_t::set_memory_model(spv::MemoryModel mm) {
  422. memory_model_ = mm;
  423. }
  424. spv::MemoryModel ValidationState_t::memory_model() const {
  425. return memory_model_;
  426. }
  427. void ValidationState_t::set_samplerimage_variable_address_mode(
  428. uint32_t bit_width) {
  429. sampler_image_addressing_mode_ = bit_width;
  430. }
  431. uint32_t ValidationState_t::samplerimage_variable_address_mode() const {
  432. return sampler_image_addressing_mode_;
  433. }
  434. spv_result_t ValidationState_t::RegisterFunction(
  435. uint32_t id, uint32_t ret_type_id,
  436. spv::FunctionControlMask function_control, uint32_t function_type_id) {
  437. assert(in_function_body() == false &&
  438. "RegisterFunction can only be called when parsing the binary outside "
  439. "of another function");
  440. in_function_ = true;
  441. module_functions_.emplace_back(id, ret_type_id, function_control,
  442. function_type_id);
  443. id_to_function_.emplace(id, &current_function());
  444. // TODO(umar): validate function type and type_id
  445. return SPV_SUCCESS;
  446. }
  447. spv_result_t ValidationState_t::RegisterFunctionEnd() {
  448. assert(in_function_body() == true &&
  449. "RegisterFunctionEnd can only be called when parsing the binary "
  450. "inside of another function");
  451. assert(in_block() == false &&
  452. "RegisterFunctionParameter can only be called when parsing the binary "
  453. "outside of a block");
  454. current_function().RegisterFunctionEnd();
  455. in_function_ = false;
  456. return SPV_SUCCESS;
  457. }
  458. Instruction* ValidationState_t::AddOrderedInstruction(
  459. const spv_parsed_instruction_t* inst) {
  460. ordered_instructions_.emplace_back(inst);
  461. ordered_instructions_.back().SetLineNum(ordered_instructions_.size());
  462. return &ordered_instructions_.back();
  463. }
  464. // Improves diagnostic messages by collecting names of IDs
  465. void ValidationState_t::RegisterDebugInstruction(const Instruction* inst) {
  466. switch (inst->opcode()) {
  467. case spv::Op::OpName: {
  468. const auto target = inst->GetOperandAs<uint32_t>(0);
  469. const std::string str = inst->GetOperandAs<std::string>(1);
  470. AssignNameToId(target, str);
  471. break;
  472. }
  473. case spv::Op::OpMemberName: {
  474. const auto target = inst->GetOperandAs<uint32_t>(0);
  475. const std::string str = inst->GetOperandAs<std::string>(2);
  476. AssignNameToId(target, str);
  477. break;
  478. }
  479. case spv::Op::OpSourceContinued:
  480. case spv::Op::OpSource:
  481. case spv::Op::OpSourceExtension:
  482. case spv::Op::OpString:
  483. case spv::Op::OpLine:
  484. case spv::Op::OpNoLine:
  485. default:
  486. break;
  487. }
  488. }
  489. void ValidationState_t::RegisterInstruction(Instruction* inst) {
  490. if (inst->id()) all_definitions_.insert(std::make_pair(inst->id(), inst));
  491. // Some validation checks are easier by getting all the consumers
  492. for (size_t i = 0; i < inst->operands().size(); ++i) {
  493. const spv_parsed_operand_t& operand = inst->operand(i);
  494. if ((SPV_OPERAND_TYPE_ID == operand.type) ||
  495. (SPV_OPERAND_TYPE_TYPE_ID == operand.type)) {
  496. const uint32_t operand_word = inst->word(operand.offset);
  497. Instruction* operand_inst = FindDef(operand_word);
  498. if (!operand_inst) {
  499. continue;
  500. }
  501. // If the instruction is using an OpTypeSampledImage as an operand, it
  502. // should be recorded. The validator will ensure that all usages of an
  503. // OpTypeSampledImage and its definition are in the same basic block.
  504. if ((SPV_OPERAND_TYPE_ID == operand.type) &&
  505. (spv::Op::OpSampledImage == operand_inst->opcode())) {
  506. RegisterSampledImageConsumer(operand_word, inst);
  507. }
  508. // In order to track storage classes (not Function) used per execution
  509. // model we can't use RegisterExecutionModelLimitation on instructions
  510. // like OpTypePointer which are going to be in the pre-function section.
  511. // Instead just need to register storage class usage for consumers in a
  512. // function block.
  513. if (inst->function()) {
  514. if (operand_inst->opcode() == spv::Op::OpTypePointer) {
  515. RegisterStorageClassConsumer(
  516. operand_inst->GetOperandAs<spv::StorageClass>(1), inst);
  517. } else if (operand_inst->opcode() == spv::Op::OpVariable) {
  518. RegisterStorageClassConsumer(
  519. operand_inst->GetOperandAs<spv::StorageClass>(2), inst);
  520. }
  521. }
  522. }
  523. }
  524. }
  525. std::vector<Instruction*> ValidationState_t::getSampledImageConsumers(
  526. uint32_t sampled_image_id) const {
  527. std::vector<Instruction*> result;
  528. auto iter = sampled_image_consumers_.find(sampled_image_id);
  529. if (iter != sampled_image_consumers_.end()) {
  530. result = iter->second;
  531. }
  532. return result;
  533. }
  534. void ValidationState_t::RegisterSampledImageConsumer(uint32_t sampled_image_id,
  535. Instruction* consumer) {
  536. sampled_image_consumers_[sampled_image_id].push_back(consumer);
  537. }
  538. void ValidationState_t::RegisterStorageClassConsumer(
  539. spv::StorageClass storage_class, Instruction* consumer) {
  540. if (spvIsVulkanEnv(context()->target_env)) {
  541. if (storage_class == spv::StorageClass::Output) {
  542. std::string errorVUID = VkErrorID(4644);
  543. function(consumer->function()->id())
  544. ->RegisterExecutionModelLimitation([errorVUID](
  545. spv::ExecutionModel model,
  546. std::string* message) {
  547. if (model == spv::ExecutionModel::GLCompute ||
  548. model == spv::ExecutionModel::RayGenerationKHR ||
  549. model == spv::ExecutionModel::IntersectionKHR ||
  550. model == spv::ExecutionModel::AnyHitKHR ||
  551. model == spv::ExecutionModel::ClosestHitKHR ||
  552. model == spv::ExecutionModel::MissKHR ||
  553. model == spv::ExecutionModel::CallableKHR) {
  554. if (message) {
  555. *message =
  556. errorVUID +
  557. "in Vulkan environment, Output Storage Class must not be "
  558. "used in GLCompute, RayGenerationKHR, IntersectionKHR, "
  559. "AnyHitKHR, ClosestHitKHR, MissKHR, or CallableKHR "
  560. "execution models";
  561. }
  562. return false;
  563. }
  564. return true;
  565. });
  566. }
  567. if (storage_class == spv::StorageClass::Workgroup) {
  568. std::string errorVUID = VkErrorID(4645);
  569. function(consumer->function()->id())
  570. ->RegisterExecutionModelLimitation([errorVUID](
  571. spv::ExecutionModel model,
  572. std::string* message) {
  573. if (model != spv::ExecutionModel::GLCompute &&
  574. model != spv::ExecutionModel::TaskNV &&
  575. model != spv::ExecutionModel::MeshNV &&
  576. model != spv::ExecutionModel::TaskEXT &&
  577. model != spv::ExecutionModel::MeshEXT) {
  578. if (message) {
  579. *message =
  580. errorVUID +
  581. "in Vulkan environment, Workgroup Storage Class is limited "
  582. "to MeshNV, TaskNV, and GLCompute execution model";
  583. }
  584. return false;
  585. }
  586. return true;
  587. });
  588. }
  589. }
  590. if (storage_class == spv::StorageClass::CallableDataKHR) {
  591. std::string errorVUID = VkErrorID(4704);
  592. function(consumer->function()->id())
  593. ->RegisterExecutionModelLimitation([errorVUID](
  594. spv::ExecutionModel model,
  595. std::string* message) {
  596. if (model != spv::ExecutionModel::RayGenerationKHR &&
  597. model != spv::ExecutionModel::ClosestHitKHR &&
  598. model != spv::ExecutionModel::CallableKHR &&
  599. model != spv::ExecutionModel::MissKHR) {
  600. if (message) {
  601. *message = errorVUID +
  602. "CallableDataKHR Storage Class is limited to "
  603. "RayGenerationKHR, ClosestHitKHR, CallableKHR, and "
  604. "MissKHR execution model";
  605. }
  606. return false;
  607. }
  608. return true;
  609. });
  610. } else if (storage_class == spv::StorageClass::IncomingCallableDataKHR) {
  611. std::string errorVUID = VkErrorID(4705);
  612. function(consumer->function()->id())
  613. ->RegisterExecutionModelLimitation([errorVUID](
  614. spv::ExecutionModel model,
  615. std::string* message) {
  616. if (model != spv::ExecutionModel::CallableKHR) {
  617. if (message) {
  618. *message = errorVUID +
  619. "IncomingCallableDataKHR Storage Class is limited to "
  620. "CallableKHR execution model";
  621. }
  622. return false;
  623. }
  624. return true;
  625. });
  626. } else if (storage_class == spv::StorageClass::RayPayloadKHR) {
  627. std::string errorVUID = VkErrorID(4698);
  628. function(consumer->function()->id())
  629. ->RegisterExecutionModelLimitation([errorVUID](
  630. spv::ExecutionModel model,
  631. std::string* message) {
  632. if (model != spv::ExecutionModel::RayGenerationKHR &&
  633. model != spv::ExecutionModel::ClosestHitKHR &&
  634. model != spv::ExecutionModel::MissKHR) {
  635. if (message) {
  636. *message =
  637. errorVUID +
  638. "RayPayloadKHR Storage Class is limited to RayGenerationKHR, "
  639. "ClosestHitKHR, and MissKHR execution model";
  640. }
  641. return false;
  642. }
  643. return true;
  644. });
  645. } else if (storage_class == spv::StorageClass::HitAttributeKHR) {
  646. std::string errorVUID = VkErrorID(4701);
  647. function(consumer->function()->id())
  648. ->RegisterExecutionModelLimitation(
  649. [errorVUID](spv::ExecutionModel model, std::string* message) {
  650. if (model != spv::ExecutionModel::IntersectionKHR &&
  651. model != spv::ExecutionModel::AnyHitKHR &&
  652. model != spv::ExecutionModel::ClosestHitKHR) {
  653. if (message) {
  654. *message = errorVUID +
  655. "HitAttributeKHR Storage Class is limited to "
  656. "IntersectionKHR, AnyHitKHR, sand ClosestHitKHR "
  657. "execution model";
  658. }
  659. return false;
  660. }
  661. return true;
  662. });
  663. } else if (storage_class == spv::StorageClass::IncomingRayPayloadKHR) {
  664. std::string errorVUID = VkErrorID(4699);
  665. function(consumer->function()->id())
  666. ->RegisterExecutionModelLimitation(
  667. [errorVUID](spv::ExecutionModel model, std::string* message) {
  668. if (model != spv::ExecutionModel::AnyHitKHR &&
  669. model != spv::ExecutionModel::ClosestHitKHR &&
  670. model != spv::ExecutionModel::MissKHR) {
  671. if (message) {
  672. *message =
  673. errorVUID +
  674. "IncomingRayPayloadKHR Storage Class is limited to "
  675. "AnyHitKHR, ClosestHitKHR, and MissKHR execution model";
  676. }
  677. return false;
  678. }
  679. return true;
  680. });
  681. } else if (storage_class == spv::StorageClass::ShaderRecordBufferKHR) {
  682. std::string errorVUID = VkErrorID(7119);
  683. function(consumer->function()->id())
  684. ->RegisterExecutionModelLimitation(
  685. [errorVUID](spv::ExecutionModel model, std::string* message) {
  686. if (model != spv::ExecutionModel::RayGenerationKHR &&
  687. model != spv::ExecutionModel::IntersectionKHR &&
  688. model != spv::ExecutionModel::AnyHitKHR &&
  689. model != spv::ExecutionModel::ClosestHitKHR &&
  690. model != spv::ExecutionModel::CallableKHR &&
  691. model != spv::ExecutionModel::MissKHR) {
  692. if (message) {
  693. *message =
  694. errorVUID +
  695. "ShaderRecordBufferKHR Storage Class is limited to "
  696. "RayGenerationKHR, IntersectionKHR, AnyHitKHR, "
  697. "ClosestHitKHR, CallableKHR, and MissKHR execution model";
  698. }
  699. return false;
  700. }
  701. return true;
  702. });
  703. } else if (storage_class == spv::StorageClass::TaskPayloadWorkgroupEXT) {
  704. function(consumer->function()->id())
  705. ->RegisterExecutionModelLimitation(
  706. [](spv::ExecutionModel model, std::string* message) {
  707. if (model != spv::ExecutionModel::TaskEXT &&
  708. model != spv::ExecutionModel::MeshEXT) {
  709. if (message) {
  710. *message =
  711. "TaskPayloadWorkgroupEXT Storage Class is limited to "
  712. "TaskEXT and MeshKHR execution model";
  713. }
  714. return false;
  715. }
  716. return true;
  717. });
  718. } else if (storage_class == spv::StorageClass::HitObjectAttributeNV) {
  719. function(consumer->function()->id())
  720. ->RegisterExecutionModelLimitation([](spv::ExecutionModel model,
  721. std::string* message) {
  722. if (model != spv::ExecutionModel::RayGenerationKHR &&
  723. model != spv::ExecutionModel::ClosestHitKHR &&
  724. model != spv::ExecutionModel::MissKHR) {
  725. if (message) {
  726. *message =
  727. "HitObjectAttributeNV Storage Class is limited to "
  728. "RayGenerationKHR, ClosestHitKHR or MissKHR execution model";
  729. }
  730. return false;
  731. }
  732. return true;
  733. });
  734. }
  735. }
  736. uint32_t ValidationState_t::getIdBound() const { return id_bound_; }
  737. void ValidationState_t::setIdBound(const uint32_t bound) { id_bound_ = bound; }
  738. bool ValidationState_t::RegisterUniqueTypeDeclaration(const Instruction* inst) {
  739. std::vector<uint32_t> key;
  740. key.push_back(static_cast<uint32_t>(inst->opcode()));
  741. for (size_t index = 0; index < inst->operands().size(); ++index) {
  742. const spv_parsed_operand_t& operand = inst->operand(index);
  743. if (operand.type == SPV_OPERAND_TYPE_RESULT_ID) continue;
  744. const int words_begin = operand.offset;
  745. const int words_end = words_begin + operand.num_words;
  746. assert(words_end <= static_cast<int>(inst->words().size()));
  747. key.insert(key.end(), inst->words().begin() + words_begin,
  748. inst->words().begin() + words_end);
  749. }
  750. return unique_type_declarations_.insert(std::move(key)).second;
  751. }
  752. uint32_t ValidationState_t::GetTypeId(uint32_t id) const {
  753. const Instruction* inst = FindDef(id);
  754. return inst ? inst->type_id() : 0;
  755. }
  756. spv::Op ValidationState_t::GetIdOpcode(uint32_t id) const {
  757. const Instruction* inst = FindDef(id);
  758. return inst ? inst->opcode() : spv::Op::OpNop;
  759. }
  760. uint32_t ValidationState_t::GetComponentType(uint32_t id) const {
  761. const Instruction* inst = FindDef(id);
  762. assert(inst);
  763. switch (inst->opcode()) {
  764. case spv::Op::OpTypeFloat:
  765. case spv::Op::OpTypeInt:
  766. case spv::Op::OpTypeBool:
  767. return id;
  768. case spv::Op::OpTypeVector:
  769. return inst->word(2);
  770. case spv::Op::OpTypeMatrix:
  771. return GetComponentType(inst->word(2));
  772. case spv::Op::OpTypeCooperativeMatrixNV:
  773. return inst->word(2);
  774. default:
  775. break;
  776. }
  777. if (inst->type_id()) return GetComponentType(inst->type_id());
  778. assert(0);
  779. return 0;
  780. }
  781. uint32_t ValidationState_t::GetDimension(uint32_t id) const {
  782. const Instruction* inst = FindDef(id);
  783. assert(inst);
  784. switch (inst->opcode()) {
  785. case spv::Op::OpTypeFloat:
  786. case spv::Op::OpTypeInt:
  787. case spv::Op::OpTypeBool:
  788. return 1;
  789. case spv::Op::OpTypeVector:
  790. case spv::Op::OpTypeMatrix:
  791. return inst->word(3);
  792. case spv::Op::OpTypeCooperativeMatrixNV:
  793. // Actual dimension isn't known, return 0
  794. return 0;
  795. default:
  796. break;
  797. }
  798. if (inst->type_id()) return GetDimension(inst->type_id());
  799. assert(0);
  800. return 0;
  801. }
  802. uint32_t ValidationState_t::GetBitWidth(uint32_t id) const {
  803. const uint32_t component_type_id = GetComponentType(id);
  804. const Instruction* inst = FindDef(component_type_id);
  805. assert(inst);
  806. if (inst->opcode() == spv::Op::OpTypeFloat ||
  807. inst->opcode() == spv::Op::OpTypeInt)
  808. return inst->word(2);
  809. if (inst->opcode() == spv::Op::OpTypeBool) return 1;
  810. assert(0);
  811. return 0;
  812. }
  813. bool ValidationState_t::IsVoidType(uint32_t id) const {
  814. const Instruction* inst = FindDef(id);
  815. return inst && inst->opcode() == spv::Op::OpTypeVoid;
  816. }
  817. bool ValidationState_t::IsFloatScalarType(uint32_t id) const {
  818. const Instruction* inst = FindDef(id);
  819. return inst && inst->opcode() == spv::Op::OpTypeFloat;
  820. }
  821. bool ValidationState_t::IsFloatVectorType(uint32_t id) const {
  822. const Instruction* inst = FindDef(id);
  823. if (!inst) {
  824. return false;
  825. }
  826. if (inst->opcode() == spv::Op::OpTypeVector) {
  827. return IsFloatScalarType(GetComponentType(id));
  828. }
  829. return false;
  830. }
  831. bool ValidationState_t::IsFloatScalarOrVectorType(uint32_t id) const {
  832. const Instruction* inst = FindDef(id);
  833. if (!inst) {
  834. return false;
  835. }
  836. if (inst->opcode() == spv::Op::OpTypeFloat) {
  837. return true;
  838. }
  839. if (inst->opcode() == spv::Op::OpTypeVector) {
  840. return IsFloatScalarType(GetComponentType(id));
  841. }
  842. return false;
  843. }
  844. bool ValidationState_t::IsIntScalarType(uint32_t id) const {
  845. const Instruction* inst = FindDef(id);
  846. return inst && inst->opcode() == spv::Op::OpTypeInt;
  847. }
  848. bool ValidationState_t::IsIntVectorType(uint32_t id) const {
  849. const Instruction* inst = FindDef(id);
  850. if (!inst) {
  851. return false;
  852. }
  853. if (inst->opcode() == spv::Op::OpTypeVector) {
  854. return IsIntScalarType(GetComponentType(id));
  855. }
  856. return false;
  857. }
  858. bool ValidationState_t::IsIntScalarOrVectorType(uint32_t id) const {
  859. const Instruction* inst = FindDef(id);
  860. if (!inst) {
  861. return false;
  862. }
  863. if (inst->opcode() == spv::Op::OpTypeInt) {
  864. return true;
  865. }
  866. if (inst->opcode() == spv::Op::OpTypeVector) {
  867. return IsIntScalarType(GetComponentType(id));
  868. }
  869. return false;
  870. }
  871. bool ValidationState_t::IsUnsignedIntScalarType(uint32_t id) const {
  872. const Instruction* inst = FindDef(id);
  873. return inst && inst->opcode() == spv::Op::OpTypeInt && inst->word(3) == 0;
  874. }
  875. bool ValidationState_t::IsUnsignedIntVectorType(uint32_t id) const {
  876. const Instruction* inst = FindDef(id);
  877. if (!inst) {
  878. return false;
  879. }
  880. if (inst->opcode() == spv::Op::OpTypeVector) {
  881. return IsUnsignedIntScalarType(GetComponentType(id));
  882. }
  883. return false;
  884. }
  885. bool ValidationState_t::IsSignedIntScalarType(uint32_t id) const {
  886. const Instruction* inst = FindDef(id);
  887. return inst && inst->opcode() == spv::Op::OpTypeInt && inst->word(3) == 1;
  888. }
  889. bool ValidationState_t::IsSignedIntVectorType(uint32_t id) const {
  890. const Instruction* inst = FindDef(id);
  891. if (!inst) {
  892. return false;
  893. }
  894. if (inst->opcode() == spv::Op::OpTypeVector) {
  895. return IsSignedIntScalarType(GetComponentType(id));
  896. }
  897. return false;
  898. }
  899. bool ValidationState_t::IsBoolScalarType(uint32_t id) const {
  900. const Instruction* inst = FindDef(id);
  901. return inst && inst->opcode() == spv::Op::OpTypeBool;
  902. }
  903. bool ValidationState_t::IsBoolVectorType(uint32_t id) const {
  904. const Instruction* inst = FindDef(id);
  905. if (!inst) {
  906. return false;
  907. }
  908. if (inst->opcode() == spv::Op::OpTypeVector) {
  909. return IsBoolScalarType(GetComponentType(id));
  910. }
  911. return false;
  912. }
  913. bool ValidationState_t::IsBoolScalarOrVectorType(uint32_t id) const {
  914. const Instruction* inst = FindDef(id);
  915. if (!inst) {
  916. return false;
  917. }
  918. if (inst->opcode() == spv::Op::OpTypeBool) {
  919. return true;
  920. }
  921. if (inst->opcode() == spv::Op::OpTypeVector) {
  922. return IsBoolScalarType(GetComponentType(id));
  923. }
  924. return false;
  925. }
  926. bool ValidationState_t::IsFloatMatrixType(uint32_t id) const {
  927. const Instruction* inst = FindDef(id);
  928. if (!inst) {
  929. return false;
  930. }
  931. if (inst->opcode() == spv::Op::OpTypeMatrix) {
  932. return IsFloatScalarType(GetComponentType(id));
  933. }
  934. return false;
  935. }
  936. bool ValidationState_t::GetMatrixTypeInfo(uint32_t id, uint32_t* num_rows,
  937. uint32_t* num_cols,
  938. uint32_t* column_type,
  939. uint32_t* component_type) const {
  940. if (!id) return false;
  941. const Instruction* mat_inst = FindDef(id);
  942. assert(mat_inst);
  943. if (mat_inst->opcode() != spv::Op::OpTypeMatrix) return false;
  944. const uint32_t vec_type = mat_inst->word(2);
  945. const Instruction* vec_inst = FindDef(vec_type);
  946. assert(vec_inst);
  947. if (vec_inst->opcode() != spv::Op::OpTypeVector) {
  948. assert(0);
  949. return false;
  950. }
  951. *num_cols = mat_inst->word(3);
  952. *num_rows = vec_inst->word(3);
  953. *column_type = mat_inst->word(2);
  954. *component_type = vec_inst->word(2);
  955. return true;
  956. }
  957. bool ValidationState_t::GetStructMemberTypes(
  958. uint32_t struct_type_id, std::vector<uint32_t>* member_types) const {
  959. member_types->clear();
  960. if (!struct_type_id) return false;
  961. const Instruction* inst = FindDef(struct_type_id);
  962. assert(inst);
  963. if (inst->opcode() != spv::Op::OpTypeStruct) return false;
  964. *member_types =
  965. std::vector<uint32_t>(inst->words().cbegin() + 2, inst->words().cend());
  966. if (member_types->empty()) return false;
  967. return true;
  968. }
  969. bool ValidationState_t::IsPointerType(uint32_t id) const {
  970. const Instruction* inst = FindDef(id);
  971. return inst && inst->opcode() == spv::Op::OpTypePointer;
  972. }
  973. bool ValidationState_t::GetPointerTypeInfo(
  974. uint32_t id, uint32_t* data_type, spv::StorageClass* storage_class) const {
  975. *storage_class = spv::StorageClass::Max;
  976. if (!id) return false;
  977. const Instruction* inst = FindDef(id);
  978. assert(inst);
  979. if (inst->opcode() != spv::Op::OpTypePointer) return false;
  980. *storage_class = spv::StorageClass(inst->word(2));
  981. *data_type = inst->word(3);
  982. return true;
  983. }
  984. bool ValidationState_t::IsAccelerationStructureType(uint32_t id) const {
  985. const Instruction* inst = FindDef(id);
  986. return inst && inst->opcode() == spv::Op::OpTypeAccelerationStructureKHR;
  987. }
  988. bool ValidationState_t::IsCooperativeMatrixType(uint32_t id) const {
  989. const Instruction* inst = FindDef(id);
  990. return inst && inst->opcode() == spv::Op::OpTypeCooperativeMatrixNV;
  991. }
  992. bool ValidationState_t::IsFloatCooperativeMatrixType(uint32_t id) const {
  993. if (!IsCooperativeMatrixType(id)) return false;
  994. return IsFloatScalarType(FindDef(id)->word(2));
  995. }
  996. bool ValidationState_t::IsIntCooperativeMatrixType(uint32_t id) const {
  997. if (!IsCooperativeMatrixType(id)) return false;
  998. return IsIntScalarType(FindDef(id)->word(2));
  999. }
  1000. bool ValidationState_t::IsUnsignedIntCooperativeMatrixType(uint32_t id) const {
  1001. if (!IsCooperativeMatrixType(id)) return false;
  1002. return IsUnsignedIntScalarType(FindDef(id)->word(2));
  1003. }
  1004. // Either a 32 bit 2-component uint vector or a 64 bit uint scalar
  1005. bool ValidationState_t::IsUnsigned64BitHandle(uint32_t id) const {
  1006. return ((IsUnsignedIntScalarType(id) && GetBitWidth(id) == 64) ||
  1007. (IsUnsignedIntVectorType(id) && GetDimension(id) == 2 &&
  1008. GetBitWidth(id) == 32));
  1009. }
  1010. spv_result_t ValidationState_t::CooperativeMatrixShapesMatch(
  1011. const Instruction* inst, uint32_t m1, uint32_t m2) {
  1012. const auto m1_type = FindDef(m1);
  1013. const auto m2_type = FindDef(m2);
  1014. if (m1_type->opcode() != spv::Op::OpTypeCooperativeMatrixNV ||
  1015. m2_type->opcode() != spv::Op::OpTypeCooperativeMatrixNV) {
  1016. return diag(SPV_ERROR_INVALID_DATA, inst)
  1017. << "Expected cooperative matrix types";
  1018. }
  1019. uint32_t m1_scope_id = m1_type->GetOperandAs<uint32_t>(2);
  1020. uint32_t m1_rows_id = m1_type->GetOperandAs<uint32_t>(3);
  1021. uint32_t m1_cols_id = m1_type->GetOperandAs<uint32_t>(4);
  1022. uint32_t m2_scope_id = m2_type->GetOperandAs<uint32_t>(2);
  1023. uint32_t m2_rows_id = m2_type->GetOperandAs<uint32_t>(3);
  1024. uint32_t m2_cols_id = m2_type->GetOperandAs<uint32_t>(4);
  1025. bool m1_is_int32 = false, m1_is_const_int32 = false, m2_is_int32 = false,
  1026. m2_is_const_int32 = false;
  1027. uint32_t m1_value = 0, m2_value = 0;
  1028. std::tie(m1_is_int32, m1_is_const_int32, m1_value) =
  1029. EvalInt32IfConst(m1_scope_id);
  1030. std::tie(m2_is_int32, m2_is_const_int32, m2_value) =
  1031. EvalInt32IfConst(m2_scope_id);
  1032. if (m1_is_const_int32 && m2_is_const_int32 && m1_value != m2_value) {
  1033. return diag(SPV_ERROR_INVALID_DATA, inst)
  1034. << "Expected scopes of Matrix and Result Type to be "
  1035. << "identical";
  1036. }
  1037. std::tie(m1_is_int32, m1_is_const_int32, m1_value) =
  1038. EvalInt32IfConst(m1_rows_id);
  1039. std::tie(m2_is_int32, m2_is_const_int32, m2_value) =
  1040. EvalInt32IfConst(m2_rows_id);
  1041. if (m1_is_const_int32 && m2_is_const_int32 && m1_value != m2_value) {
  1042. return diag(SPV_ERROR_INVALID_DATA, inst)
  1043. << "Expected rows of Matrix type and Result Type to be "
  1044. << "identical";
  1045. }
  1046. std::tie(m1_is_int32, m1_is_const_int32, m1_value) =
  1047. EvalInt32IfConst(m1_cols_id);
  1048. std::tie(m2_is_int32, m2_is_const_int32, m2_value) =
  1049. EvalInt32IfConst(m2_cols_id);
  1050. if (m1_is_const_int32 && m2_is_const_int32 && m1_value != m2_value) {
  1051. return diag(SPV_ERROR_INVALID_DATA, inst)
  1052. << "Expected columns of Matrix type and Result Type to be "
  1053. << "identical";
  1054. }
  1055. return SPV_SUCCESS;
  1056. }
  1057. uint32_t ValidationState_t::GetOperandTypeId(const Instruction* inst,
  1058. size_t operand_index) const {
  1059. return GetTypeId(inst->GetOperandAs<uint32_t>(operand_index));
  1060. }
  1061. bool ValidationState_t::GetConstantValUint64(uint32_t id, uint64_t* val) const {
  1062. const Instruction* inst = FindDef(id);
  1063. if (!inst) {
  1064. assert(0 && "Instruction not found");
  1065. return false;
  1066. }
  1067. if (inst->opcode() != spv::Op::OpConstant &&
  1068. inst->opcode() != spv::Op::OpSpecConstant)
  1069. return false;
  1070. if (!IsIntScalarType(inst->type_id())) return false;
  1071. if (inst->words().size() == 4) {
  1072. *val = inst->word(3);
  1073. } else {
  1074. assert(inst->words().size() == 5);
  1075. *val = inst->word(3);
  1076. *val |= uint64_t(inst->word(4)) << 32;
  1077. }
  1078. return true;
  1079. }
  1080. std::tuple<bool, bool, uint32_t> ValidationState_t::EvalInt32IfConst(
  1081. uint32_t id) const {
  1082. const Instruction* const inst = FindDef(id);
  1083. assert(inst);
  1084. const uint32_t type = inst->type_id();
  1085. if (type == 0 || !IsIntScalarType(type) || GetBitWidth(type) != 32) {
  1086. return std::make_tuple(false, false, 0);
  1087. }
  1088. // Spec constant values cannot be evaluated so don't consider constant for
  1089. // the purpose of this method.
  1090. if (!spvOpcodeIsConstant(inst->opcode()) ||
  1091. spvOpcodeIsSpecConstant(inst->opcode())) {
  1092. return std::make_tuple(true, false, 0);
  1093. }
  1094. if (inst->opcode() == spv::Op::OpConstantNull) {
  1095. return std::make_tuple(true, true, 0);
  1096. }
  1097. assert(inst->words().size() == 4);
  1098. return std::make_tuple(true, true, inst->word(3));
  1099. }
  1100. void ValidationState_t::ComputeFunctionToEntryPointMapping() {
  1101. for (const uint32_t entry_point : entry_points()) {
  1102. std::stack<uint32_t> call_stack;
  1103. std::set<uint32_t> visited;
  1104. call_stack.push(entry_point);
  1105. while (!call_stack.empty()) {
  1106. const uint32_t called_func_id = call_stack.top();
  1107. call_stack.pop();
  1108. if (!visited.insert(called_func_id).second) continue;
  1109. function_to_entry_points_[called_func_id].push_back(entry_point);
  1110. const Function* called_func = function(called_func_id);
  1111. if (called_func) {
  1112. // Other checks should error out on this invalid SPIR-V.
  1113. for (const uint32_t new_call : called_func->function_call_targets()) {
  1114. call_stack.push(new_call);
  1115. }
  1116. }
  1117. }
  1118. }
  1119. }
  1120. void ValidationState_t::ComputeRecursiveEntryPoints() {
  1121. for (const Function& func : functions()) {
  1122. std::stack<uint32_t> call_stack;
  1123. std::set<uint32_t> visited;
  1124. for (const uint32_t new_call : func.function_call_targets()) {
  1125. call_stack.push(new_call);
  1126. }
  1127. while (!call_stack.empty()) {
  1128. const uint32_t called_func_id = call_stack.top();
  1129. call_stack.pop();
  1130. if (!visited.insert(called_func_id).second) continue;
  1131. if (called_func_id == func.id()) {
  1132. for (const uint32_t entry_point :
  1133. function_to_entry_points_[called_func_id])
  1134. recursive_entry_points_.insert(entry_point);
  1135. break;
  1136. }
  1137. const Function* called_func = function(called_func_id);
  1138. if (called_func) {
  1139. // Other checks should error out on this invalid SPIR-V.
  1140. for (const uint32_t new_call : called_func->function_call_targets()) {
  1141. call_stack.push(new_call);
  1142. }
  1143. }
  1144. }
  1145. }
  1146. }
  1147. const std::vector<uint32_t>& ValidationState_t::FunctionEntryPoints(
  1148. uint32_t func) const {
  1149. auto iter = function_to_entry_points_.find(func);
  1150. if (iter == function_to_entry_points_.end()) {
  1151. return empty_ids_;
  1152. } else {
  1153. return iter->second;
  1154. }
  1155. }
  1156. std::set<uint32_t> ValidationState_t::EntryPointReferences(uint32_t id) const {
  1157. std::set<uint32_t> referenced_entry_points;
  1158. const auto inst = FindDef(id);
  1159. if (!inst) return referenced_entry_points;
  1160. std::vector<const Instruction*> stack;
  1161. stack.push_back(inst);
  1162. while (!stack.empty()) {
  1163. const auto current_inst = stack.back();
  1164. stack.pop_back();
  1165. if (const auto func = current_inst->function()) {
  1166. // Instruction lives in a function, we can stop searching.
  1167. const auto function_entry_points = FunctionEntryPoints(func->id());
  1168. referenced_entry_points.insert(function_entry_points.begin(),
  1169. function_entry_points.end());
  1170. } else {
  1171. // Instruction is in the global scope, keep searching its uses.
  1172. for (auto pair : current_inst->uses()) {
  1173. const auto next_inst = pair.first;
  1174. stack.push_back(next_inst);
  1175. }
  1176. }
  1177. }
  1178. return referenced_entry_points;
  1179. }
  1180. std::string ValidationState_t::Disassemble(const Instruction& inst) const {
  1181. const spv_parsed_instruction_t& c_inst(inst.c_inst());
  1182. return Disassemble(c_inst.words, c_inst.num_words);
  1183. }
  1184. std::string ValidationState_t::Disassemble(const uint32_t* words,
  1185. uint16_t num_words) const {
  1186. uint32_t disassembly_options = SPV_BINARY_TO_TEXT_OPTION_NO_HEADER |
  1187. SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES;
  1188. return spvInstructionBinaryToText(context()->target_env, words, num_words,
  1189. words_, num_words_, disassembly_options);
  1190. }
  1191. bool ValidationState_t::LogicallyMatch(const Instruction* lhs,
  1192. const Instruction* rhs,
  1193. bool check_decorations) {
  1194. if (lhs->opcode() != rhs->opcode()) {
  1195. return false;
  1196. }
  1197. if (check_decorations) {
  1198. const auto& dec_a = id_decorations(lhs->id());
  1199. const auto& dec_b = id_decorations(rhs->id());
  1200. for (const auto& dec : dec_b) {
  1201. if (std::find(dec_a.begin(), dec_a.end(), dec) == dec_a.end()) {
  1202. return false;
  1203. }
  1204. }
  1205. }
  1206. if (lhs->opcode() == spv::Op::OpTypeArray) {
  1207. // Size operands must match.
  1208. if (lhs->GetOperandAs<uint32_t>(2u) != rhs->GetOperandAs<uint32_t>(2u)) {
  1209. return false;
  1210. }
  1211. // Elements must match or logically match.
  1212. const auto lhs_ele_id = lhs->GetOperandAs<uint32_t>(1u);
  1213. const auto rhs_ele_id = rhs->GetOperandAs<uint32_t>(1u);
  1214. if (lhs_ele_id == rhs_ele_id) {
  1215. return true;
  1216. }
  1217. const auto lhs_ele = FindDef(lhs_ele_id);
  1218. const auto rhs_ele = FindDef(rhs_ele_id);
  1219. if (!lhs_ele || !rhs_ele) {
  1220. return false;
  1221. }
  1222. return LogicallyMatch(lhs_ele, rhs_ele, check_decorations);
  1223. } else if (lhs->opcode() == spv::Op::OpTypeStruct) {
  1224. // Number of elements must match.
  1225. if (lhs->operands().size() != rhs->operands().size()) {
  1226. return false;
  1227. }
  1228. for (size_t i = 1u; i < lhs->operands().size(); ++i) {
  1229. const auto lhs_ele_id = lhs->GetOperandAs<uint32_t>(i);
  1230. const auto rhs_ele_id = rhs->GetOperandAs<uint32_t>(i);
  1231. // Elements must match or logically match.
  1232. if (lhs_ele_id == rhs_ele_id) {
  1233. continue;
  1234. }
  1235. const auto lhs_ele = FindDef(lhs_ele_id);
  1236. const auto rhs_ele = FindDef(rhs_ele_id);
  1237. if (!lhs_ele || !rhs_ele) {
  1238. return false;
  1239. }
  1240. if (!LogicallyMatch(lhs_ele, rhs_ele, check_decorations)) {
  1241. return false;
  1242. }
  1243. }
  1244. // All checks passed.
  1245. return true;
  1246. }
  1247. // No other opcodes are acceptable at this point. Arrays and structs are
  1248. // caught above and if they're elements are not arrays or structs they are
  1249. // required to match exactly.
  1250. return false;
  1251. }
  1252. const Instruction* ValidationState_t::TracePointer(
  1253. const Instruction* inst) const {
  1254. auto base_ptr = inst;
  1255. while (base_ptr->opcode() == spv::Op::OpAccessChain ||
  1256. base_ptr->opcode() == spv::Op::OpInBoundsAccessChain ||
  1257. base_ptr->opcode() == spv::Op::OpPtrAccessChain ||
  1258. base_ptr->opcode() == spv::Op::OpInBoundsPtrAccessChain ||
  1259. base_ptr->opcode() == spv::Op::OpCopyObject) {
  1260. base_ptr = FindDef(base_ptr->GetOperandAs<uint32_t>(2u));
  1261. }
  1262. return base_ptr;
  1263. }
  1264. bool ValidationState_t::ContainsType(
  1265. uint32_t id, const std::function<bool(const Instruction*)>& f,
  1266. bool traverse_all_types) const {
  1267. const auto inst = FindDef(id);
  1268. if (!inst) return false;
  1269. if (f(inst)) return true;
  1270. switch (inst->opcode()) {
  1271. case spv::Op::OpTypeArray:
  1272. case spv::Op::OpTypeRuntimeArray:
  1273. case spv::Op::OpTypeVector:
  1274. case spv::Op::OpTypeMatrix:
  1275. case spv::Op::OpTypeImage:
  1276. case spv::Op::OpTypeSampledImage:
  1277. case spv::Op::OpTypeCooperativeMatrixNV:
  1278. return ContainsType(inst->GetOperandAs<uint32_t>(1u), f,
  1279. traverse_all_types);
  1280. case spv::Op::OpTypePointer:
  1281. if (IsForwardPointer(id)) return false;
  1282. if (traverse_all_types) {
  1283. return ContainsType(inst->GetOperandAs<uint32_t>(2u), f,
  1284. traverse_all_types);
  1285. }
  1286. break;
  1287. case spv::Op::OpTypeFunction:
  1288. case spv::Op::OpTypeStruct:
  1289. if (inst->opcode() == spv::Op::OpTypeFunction && !traverse_all_types) {
  1290. return false;
  1291. }
  1292. for (uint32_t i = 1; i < inst->operands().size(); ++i) {
  1293. if (ContainsType(inst->GetOperandAs<uint32_t>(i), f,
  1294. traverse_all_types)) {
  1295. return true;
  1296. }
  1297. }
  1298. break;
  1299. default:
  1300. break;
  1301. }
  1302. return false;
  1303. }
  1304. bool ValidationState_t::ContainsSizedIntOrFloatType(uint32_t id, spv::Op type,
  1305. uint32_t width) const {
  1306. if (type != spv::Op::OpTypeInt && type != spv::Op::OpTypeFloat) return false;
  1307. const auto f = [type, width](const Instruction* inst) {
  1308. if (inst->opcode() == type) {
  1309. return inst->GetOperandAs<uint32_t>(1u) == width;
  1310. }
  1311. return false;
  1312. };
  1313. return ContainsType(id, f);
  1314. }
  1315. bool ValidationState_t::ContainsLimitedUseIntOrFloatType(uint32_t id) const {
  1316. if ((!HasCapability(spv::Capability::Int16) &&
  1317. ContainsSizedIntOrFloatType(id, spv::Op::OpTypeInt, 16)) ||
  1318. (!HasCapability(spv::Capability::Int8) &&
  1319. ContainsSizedIntOrFloatType(id, spv::Op::OpTypeInt, 8)) ||
  1320. (!HasCapability(spv::Capability::Float16) &&
  1321. ContainsSizedIntOrFloatType(id, spv::Op::OpTypeFloat, 16))) {
  1322. return true;
  1323. }
  1324. return false;
  1325. }
  1326. bool ValidationState_t::ContainsRuntimeArray(uint32_t id) const {
  1327. const auto f = [](const Instruction* inst) {
  1328. return inst->opcode() == spv::Op::OpTypeRuntimeArray;
  1329. };
  1330. return ContainsType(id, f, /* traverse_all_types = */ false);
  1331. }
  1332. bool ValidationState_t::IsValidStorageClass(
  1333. spv::StorageClass storage_class) const {
  1334. if (spvIsVulkanEnv(context()->target_env)) {
  1335. switch (storage_class) {
  1336. case spv::StorageClass::UniformConstant:
  1337. case spv::StorageClass::Uniform:
  1338. case spv::StorageClass::StorageBuffer:
  1339. case spv::StorageClass::Input:
  1340. case spv::StorageClass::Output:
  1341. case spv::StorageClass::Image:
  1342. case spv::StorageClass::Workgroup:
  1343. case spv::StorageClass::Private:
  1344. case spv::StorageClass::Function:
  1345. case spv::StorageClass::PushConstant:
  1346. case spv::StorageClass::PhysicalStorageBuffer:
  1347. case spv::StorageClass::RayPayloadKHR:
  1348. case spv::StorageClass::IncomingRayPayloadKHR:
  1349. case spv::StorageClass::HitAttributeKHR:
  1350. case spv::StorageClass::CallableDataKHR:
  1351. case spv::StorageClass::IncomingCallableDataKHR:
  1352. case spv::StorageClass::ShaderRecordBufferKHR:
  1353. case spv::StorageClass::TaskPayloadWorkgroupEXT:
  1354. case spv::StorageClass::HitObjectAttributeNV:
  1355. return true;
  1356. default:
  1357. return false;
  1358. }
  1359. }
  1360. return true;
  1361. }
  1362. #define VUID_WRAP(vuid) "[" #vuid "] "
  1363. // Currently no 2 VUID share the same id, so no need for |reference|
  1364. std::string ValidationState_t::VkErrorID(uint32_t id,
  1365. const char* /*reference*/) const {
  1366. if (!spvIsVulkanEnv(context_->target_env)) {
  1367. return "";
  1368. }
  1369. // This large switch case is only searched when an error has occurred.
  1370. // If an id is changed, the old case must be modified or removed. Each string
  1371. // here is interpreted as being "implemented"
  1372. // Clang format adds spaces between hyphens
  1373. // clang-format off
  1374. switch (id) {
  1375. case 4154:
  1376. return VUID_WRAP(VUID-BaryCoordKHR-BaryCoordKHR-04154);
  1377. case 4155:
  1378. return VUID_WRAP(VUID-BaryCoordKHR-BaryCoordKHR-04155);
  1379. case 4156:
  1380. return VUID_WRAP(VUID-BaryCoordKHR-BaryCoordKHR-04156);
  1381. case 4160:
  1382. return VUID_WRAP(VUID-BaryCoordNoPerspKHR-BaryCoordNoPerspKHR-04160);
  1383. case 4161:
  1384. return VUID_WRAP(VUID-BaryCoordNoPerspKHR-BaryCoordNoPerspKHR-04161);
  1385. case 4162:
  1386. return VUID_WRAP(VUID-BaryCoordNoPerspKHR-BaryCoordNoPerspKHR-04162);
  1387. case 4181:
  1388. return VUID_WRAP(VUID-BaseInstance-BaseInstance-04181);
  1389. case 4182:
  1390. return VUID_WRAP(VUID-BaseInstance-BaseInstance-04182);
  1391. case 4183:
  1392. return VUID_WRAP(VUID-BaseInstance-BaseInstance-04183);
  1393. case 4184:
  1394. return VUID_WRAP(VUID-BaseVertex-BaseVertex-04184);
  1395. case 4185:
  1396. return VUID_WRAP(VUID-BaseVertex-BaseVertex-04185);
  1397. case 4186:
  1398. return VUID_WRAP(VUID-BaseVertex-BaseVertex-04186);
  1399. case 4187:
  1400. return VUID_WRAP(VUID-ClipDistance-ClipDistance-04187);
  1401. case 4188:
  1402. return VUID_WRAP(VUID-ClipDistance-ClipDistance-04188);
  1403. case 4189:
  1404. return VUID_WRAP(VUID-ClipDistance-ClipDistance-04189);
  1405. case 4190:
  1406. return VUID_WRAP(VUID-ClipDistance-ClipDistance-04190);
  1407. case 4191:
  1408. return VUID_WRAP(VUID-ClipDistance-ClipDistance-04191);
  1409. case 4196:
  1410. return VUID_WRAP(VUID-CullDistance-CullDistance-04196);
  1411. case 4197:
  1412. return VUID_WRAP(VUID-CullDistance-CullDistance-04197);
  1413. case 4198:
  1414. return VUID_WRAP(VUID-CullDistance-CullDistance-04198);
  1415. case 4199:
  1416. return VUID_WRAP(VUID-CullDistance-CullDistance-04199);
  1417. case 4200:
  1418. return VUID_WRAP(VUID-CullDistance-CullDistance-04200);
  1419. case 6735:
  1420. return VUID_WRAP(VUID-CullMaskKHR-CullMaskKHR-06735); // Execution Model
  1421. case 6736:
  1422. return VUID_WRAP(VUID-CullMaskKHR-CullMaskKHR-06736); // input storage
  1423. case 6737:
  1424. return VUID_WRAP(VUID-CullMaskKHR-CullMaskKHR-06737); // 32 int scalar
  1425. case 4205:
  1426. return VUID_WRAP(VUID-DeviceIndex-DeviceIndex-04205);
  1427. case 4206:
  1428. return VUID_WRAP(VUID-DeviceIndex-DeviceIndex-04206);
  1429. case 4207:
  1430. return VUID_WRAP(VUID-DrawIndex-DrawIndex-04207);
  1431. case 4208:
  1432. return VUID_WRAP(VUID-DrawIndex-DrawIndex-04208);
  1433. case 4209:
  1434. return VUID_WRAP(VUID-DrawIndex-DrawIndex-04209);
  1435. case 4210:
  1436. return VUID_WRAP(VUID-FragCoord-FragCoord-04210);
  1437. case 4211:
  1438. return VUID_WRAP(VUID-FragCoord-FragCoord-04211);
  1439. case 4212:
  1440. return VUID_WRAP(VUID-FragCoord-FragCoord-04212);
  1441. case 4213:
  1442. return VUID_WRAP(VUID-FragDepth-FragDepth-04213);
  1443. case 4214:
  1444. return VUID_WRAP(VUID-FragDepth-FragDepth-04214);
  1445. case 4215:
  1446. return VUID_WRAP(VUID-FragDepth-FragDepth-04215);
  1447. case 4216:
  1448. return VUID_WRAP(VUID-FragDepth-FragDepth-04216);
  1449. case 4217:
  1450. return VUID_WRAP(VUID-FragInvocationCountEXT-FragInvocationCountEXT-04217);
  1451. case 4218:
  1452. return VUID_WRAP(VUID-FragInvocationCountEXT-FragInvocationCountEXT-04218);
  1453. case 4219:
  1454. return VUID_WRAP(VUID-FragInvocationCountEXT-FragInvocationCountEXT-04219);
  1455. case 4220:
  1456. return VUID_WRAP(VUID-FragSizeEXT-FragSizeEXT-04220);
  1457. case 4221:
  1458. return VUID_WRAP(VUID-FragSizeEXT-FragSizeEXT-04221);
  1459. case 4222:
  1460. return VUID_WRAP(VUID-FragSizeEXT-FragSizeEXT-04222);
  1461. case 4223:
  1462. return VUID_WRAP(VUID-FragStencilRefEXT-FragStencilRefEXT-04223);
  1463. case 4224:
  1464. return VUID_WRAP(VUID-FragStencilRefEXT-FragStencilRefEXT-04224);
  1465. case 4225:
  1466. return VUID_WRAP(VUID-FragStencilRefEXT-FragStencilRefEXT-04225);
  1467. case 4229:
  1468. return VUID_WRAP(VUID-FrontFacing-FrontFacing-04229);
  1469. case 4230:
  1470. return VUID_WRAP(VUID-FrontFacing-FrontFacing-04230);
  1471. case 4231:
  1472. return VUID_WRAP(VUID-FrontFacing-FrontFacing-04231);
  1473. case 4232:
  1474. return VUID_WRAP(VUID-FullyCoveredEXT-FullyCoveredEXT-04232);
  1475. case 4233:
  1476. return VUID_WRAP(VUID-FullyCoveredEXT-FullyCoveredEXT-04233);
  1477. case 4234:
  1478. return VUID_WRAP(VUID-FullyCoveredEXT-FullyCoveredEXT-04234);
  1479. case 4236:
  1480. return VUID_WRAP(VUID-GlobalInvocationId-GlobalInvocationId-04236);
  1481. case 4237:
  1482. return VUID_WRAP(VUID-GlobalInvocationId-GlobalInvocationId-04237);
  1483. case 4238:
  1484. return VUID_WRAP(VUID-GlobalInvocationId-GlobalInvocationId-04238);
  1485. case 4239:
  1486. return VUID_WRAP(VUID-HelperInvocation-HelperInvocation-04239);
  1487. case 4240:
  1488. return VUID_WRAP(VUID-HelperInvocation-HelperInvocation-04240);
  1489. case 4241:
  1490. return VUID_WRAP(VUID-HelperInvocation-HelperInvocation-04241);
  1491. case 4242:
  1492. return VUID_WRAP(VUID-HitKindKHR-HitKindKHR-04242);
  1493. case 4243:
  1494. return VUID_WRAP(VUID-HitKindKHR-HitKindKHR-04243);
  1495. case 4244:
  1496. return VUID_WRAP(VUID-HitKindKHR-HitKindKHR-04244);
  1497. case 4245:
  1498. return VUID_WRAP(VUID-HitTNV-HitTNV-04245);
  1499. case 4246:
  1500. return VUID_WRAP(VUID-HitTNV-HitTNV-04246);
  1501. case 4247:
  1502. return VUID_WRAP(VUID-HitTNV-HitTNV-04247);
  1503. case 4248:
  1504. return VUID_WRAP(VUID-IncomingRayFlagsKHR-IncomingRayFlagsKHR-04248);
  1505. case 4249:
  1506. return VUID_WRAP(VUID-IncomingRayFlagsKHR-IncomingRayFlagsKHR-04249);
  1507. case 4250:
  1508. return VUID_WRAP(VUID-IncomingRayFlagsKHR-IncomingRayFlagsKHR-04250);
  1509. case 4251:
  1510. return VUID_WRAP(VUID-InstanceCustomIndexKHR-InstanceCustomIndexKHR-04251);
  1511. case 4252:
  1512. return VUID_WRAP(VUID-InstanceCustomIndexKHR-InstanceCustomIndexKHR-04252);
  1513. case 4253:
  1514. return VUID_WRAP(VUID-InstanceCustomIndexKHR-InstanceCustomIndexKHR-04253);
  1515. case 4254:
  1516. return VUID_WRAP(VUID-InstanceId-InstanceId-04254);
  1517. case 4255:
  1518. return VUID_WRAP(VUID-InstanceId-InstanceId-04255);
  1519. case 4256:
  1520. return VUID_WRAP(VUID-InstanceId-InstanceId-04256);
  1521. case 4257:
  1522. return VUID_WRAP(VUID-InvocationId-InvocationId-04257);
  1523. case 4258:
  1524. return VUID_WRAP(VUID-InvocationId-InvocationId-04258);
  1525. case 4259:
  1526. return VUID_WRAP(VUID-InvocationId-InvocationId-04259);
  1527. case 4263:
  1528. return VUID_WRAP(VUID-InstanceIndex-InstanceIndex-04263);
  1529. case 4264:
  1530. return VUID_WRAP(VUID-InstanceIndex-InstanceIndex-04264);
  1531. case 4265:
  1532. return VUID_WRAP(VUID-InstanceIndex-InstanceIndex-04265);
  1533. case 4266:
  1534. return VUID_WRAP(VUID-LaunchIdKHR-LaunchIdKHR-04266);
  1535. case 4267:
  1536. return VUID_WRAP(VUID-LaunchIdKHR-LaunchIdKHR-04267);
  1537. case 4268:
  1538. return VUID_WRAP(VUID-LaunchIdKHR-LaunchIdKHR-04268);
  1539. case 4269:
  1540. return VUID_WRAP(VUID-LaunchSizeKHR-LaunchSizeKHR-04269);
  1541. case 4270:
  1542. return VUID_WRAP(VUID-LaunchSizeKHR-LaunchSizeKHR-04270);
  1543. case 4271:
  1544. return VUID_WRAP(VUID-LaunchSizeKHR-LaunchSizeKHR-04271);
  1545. case 4272:
  1546. return VUID_WRAP(VUID-Layer-Layer-04272);
  1547. case 4273:
  1548. return VUID_WRAP(VUID-Layer-Layer-04273);
  1549. case 4274:
  1550. return VUID_WRAP(VUID-Layer-Layer-04274);
  1551. case 4275:
  1552. return VUID_WRAP(VUID-Layer-Layer-04275);
  1553. case 4276:
  1554. return VUID_WRAP(VUID-Layer-Layer-04276);
  1555. case 4281:
  1556. return VUID_WRAP(VUID-LocalInvocationId-LocalInvocationId-04281);
  1557. case 4282:
  1558. return VUID_WRAP(VUID-LocalInvocationId-LocalInvocationId-04282);
  1559. case 4283:
  1560. return VUID_WRAP(VUID-LocalInvocationId-LocalInvocationId-04283);
  1561. case 4293:
  1562. return VUID_WRAP(VUID-NumSubgroups-NumSubgroups-04293);
  1563. case 4294:
  1564. return VUID_WRAP(VUID-NumSubgroups-NumSubgroups-04294);
  1565. case 4295:
  1566. return VUID_WRAP(VUID-NumSubgroups-NumSubgroups-04295);
  1567. case 4296:
  1568. return VUID_WRAP(VUID-NumWorkgroups-NumWorkgroups-04296);
  1569. case 4297:
  1570. return VUID_WRAP(VUID-NumWorkgroups-NumWorkgroups-04297);
  1571. case 4298:
  1572. return VUID_WRAP(VUID-NumWorkgroups-NumWorkgroups-04298);
  1573. case 4299:
  1574. return VUID_WRAP(VUID-ObjectRayDirectionKHR-ObjectRayDirectionKHR-04299);
  1575. case 4300:
  1576. return VUID_WRAP(VUID-ObjectRayDirectionKHR-ObjectRayDirectionKHR-04300);
  1577. case 4301:
  1578. return VUID_WRAP(VUID-ObjectRayDirectionKHR-ObjectRayDirectionKHR-04301);
  1579. case 4302:
  1580. return VUID_WRAP(VUID-ObjectRayOriginKHR-ObjectRayOriginKHR-04302);
  1581. case 4303:
  1582. return VUID_WRAP(VUID-ObjectRayOriginKHR-ObjectRayOriginKHR-04303);
  1583. case 4304:
  1584. return VUID_WRAP(VUID-ObjectRayOriginKHR-ObjectRayOriginKHR-04304);
  1585. case 4305:
  1586. return VUID_WRAP(VUID-ObjectToWorldKHR-ObjectToWorldKHR-04305);
  1587. case 4306:
  1588. return VUID_WRAP(VUID-ObjectToWorldKHR-ObjectToWorldKHR-04306);
  1589. case 4307:
  1590. return VUID_WRAP(VUID-ObjectToWorldKHR-ObjectToWorldKHR-04307);
  1591. case 4308:
  1592. return VUID_WRAP(VUID-PatchVertices-PatchVertices-04308);
  1593. case 4309:
  1594. return VUID_WRAP(VUID-PatchVertices-PatchVertices-04309);
  1595. case 4310:
  1596. return VUID_WRAP(VUID-PatchVertices-PatchVertices-04310);
  1597. case 4311:
  1598. return VUID_WRAP(VUID-PointCoord-PointCoord-04311);
  1599. case 4312:
  1600. return VUID_WRAP(VUID-PointCoord-PointCoord-04312);
  1601. case 4313:
  1602. return VUID_WRAP(VUID-PointCoord-PointCoord-04313);
  1603. case 4314:
  1604. return VUID_WRAP(VUID-PointSize-PointSize-04314);
  1605. case 4315:
  1606. return VUID_WRAP(VUID-PointSize-PointSize-04315);
  1607. case 4316:
  1608. return VUID_WRAP(VUID-PointSize-PointSize-04316);
  1609. case 4317:
  1610. return VUID_WRAP(VUID-PointSize-PointSize-04317);
  1611. case 4318:
  1612. return VUID_WRAP(VUID-Position-Position-04318);
  1613. case 4319:
  1614. return VUID_WRAP(VUID-Position-Position-04319);
  1615. case 4320:
  1616. return VUID_WRAP(VUID-Position-Position-04320);
  1617. case 4321:
  1618. return VUID_WRAP(VUID-Position-Position-04321);
  1619. case 4330:
  1620. return VUID_WRAP(VUID-PrimitiveId-PrimitiveId-04330);
  1621. case 4334:
  1622. return VUID_WRAP(VUID-PrimitiveId-PrimitiveId-04334);
  1623. case 4337:
  1624. return VUID_WRAP(VUID-PrimitiveId-PrimitiveId-04337);
  1625. case 4345:
  1626. return VUID_WRAP(VUID-RayGeometryIndexKHR-RayGeometryIndexKHR-04345);
  1627. case 4346:
  1628. return VUID_WRAP(VUID-RayGeometryIndexKHR-RayGeometryIndexKHR-04346);
  1629. case 4347:
  1630. return VUID_WRAP(VUID-RayGeometryIndexKHR-RayGeometryIndexKHR-04347);
  1631. case 4348:
  1632. return VUID_WRAP(VUID-RayTmaxKHR-RayTmaxKHR-04348);
  1633. case 4349:
  1634. return VUID_WRAP(VUID-RayTmaxKHR-RayTmaxKHR-04349);
  1635. case 4350:
  1636. return VUID_WRAP(VUID-RayTmaxKHR-RayTmaxKHR-04350);
  1637. case 4351:
  1638. return VUID_WRAP(VUID-RayTminKHR-RayTminKHR-04351);
  1639. case 4352:
  1640. return VUID_WRAP(VUID-RayTminKHR-RayTminKHR-04352);
  1641. case 4353:
  1642. return VUID_WRAP(VUID-RayTminKHR-RayTminKHR-04353);
  1643. case 4354:
  1644. return VUID_WRAP(VUID-SampleId-SampleId-04354);
  1645. case 4355:
  1646. return VUID_WRAP(VUID-SampleId-SampleId-04355);
  1647. case 4356:
  1648. return VUID_WRAP(VUID-SampleId-SampleId-04356);
  1649. case 4357:
  1650. return VUID_WRAP(VUID-SampleMask-SampleMask-04357);
  1651. case 4358:
  1652. return VUID_WRAP(VUID-SampleMask-SampleMask-04358);
  1653. case 4359:
  1654. return VUID_WRAP(VUID-SampleMask-SampleMask-04359);
  1655. case 4360:
  1656. return VUID_WRAP(VUID-SamplePosition-SamplePosition-04360);
  1657. case 4361:
  1658. return VUID_WRAP(VUID-SamplePosition-SamplePosition-04361);
  1659. case 4362:
  1660. return VUID_WRAP(VUID-SamplePosition-SamplePosition-04362);
  1661. case 4367:
  1662. return VUID_WRAP(VUID-SubgroupId-SubgroupId-04367);
  1663. case 4368:
  1664. return VUID_WRAP(VUID-SubgroupId-SubgroupId-04368);
  1665. case 4369:
  1666. return VUID_WRAP(VUID-SubgroupId-SubgroupId-04369);
  1667. case 4370:
  1668. return VUID_WRAP(VUID-SubgroupEqMask-SubgroupEqMask-04370);
  1669. case 4371:
  1670. return VUID_WRAP(VUID-SubgroupEqMask-SubgroupEqMask-04371);
  1671. case 4372:
  1672. return VUID_WRAP(VUID-SubgroupGeMask-SubgroupGeMask-04372);
  1673. case 4373:
  1674. return VUID_WRAP(VUID-SubgroupGeMask-SubgroupGeMask-04373);
  1675. case 4374:
  1676. return VUID_WRAP(VUID-SubgroupGtMask-SubgroupGtMask-04374);
  1677. case 4375:
  1678. return VUID_WRAP(VUID-SubgroupGtMask-SubgroupGtMask-04375);
  1679. case 4376:
  1680. return VUID_WRAP(VUID-SubgroupLeMask-SubgroupLeMask-04376);
  1681. case 4377:
  1682. return VUID_WRAP(VUID-SubgroupLeMask-SubgroupLeMask-04377);
  1683. case 4378:
  1684. return VUID_WRAP(VUID-SubgroupLtMask-SubgroupLtMask-04378);
  1685. case 4379:
  1686. return VUID_WRAP(VUID-SubgroupLtMask-SubgroupLtMask-04379);
  1687. case 4380:
  1688. return VUID_WRAP(VUID-SubgroupLocalInvocationId-SubgroupLocalInvocationId-04380);
  1689. case 4381:
  1690. return VUID_WRAP(VUID-SubgroupLocalInvocationId-SubgroupLocalInvocationId-04381);
  1691. case 4382:
  1692. return VUID_WRAP(VUID-SubgroupSize-SubgroupSize-04382);
  1693. case 4383:
  1694. return VUID_WRAP(VUID-SubgroupSize-SubgroupSize-04383);
  1695. case 4387:
  1696. return VUID_WRAP(VUID-TessCoord-TessCoord-04387);
  1697. case 4388:
  1698. return VUID_WRAP(VUID-TessCoord-TessCoord-04388);
  1699. case 4389:
  1700. return VUID_WRAP(VUID-TessCoord-TessCoord-04389);
  1701. case 4390:
  1702. return VUID_WRAP(VUID-TessLevelOuter-TessLevelOuter-04390);
  1703. case 4391:
  1704. return VUID_WRAP(VUID-TessLevelOuter-TessLevelOuter-04391);
  1705. case 4392:
  1706. return VUID_WRAP(VUID-TessLevelOuter-TessLevelOuter-04392);
  1707. case 4393:
  1708. return VUID_WRAP(VUID-TessLevelOuter-TessLevelOuter-04393);
  1709. case 4394:
  1710. return VUID_WRAP(VUID-TessLevelInner-TessLevelInner-04394);
  1711. case 4395:
  1712. return VUID_WRAP(VUID-TessLevelInner-TessLevelInner-04395);
  1713. case 4396:
  1714. return VUID_WRAP(VUID-TessLevelInner-TessLevelInner-04396);
  1715. case 4397:
  1716. return VUID_WRAP(VUID-TessLevelInner-TessLevelInner-04397);
  1717. case 4398:
  1718. return VUID_WRAP(VUID-VertexIndex-VertexIndex-04398);
  1719. case 4399:
  1720. return VUID_WRAP(VUID-VertexIndex-VertexIndex-04399);
  1721. case 4400:
  1722. return VUID_WRAP(VUID-VertexIndex-VertexIndex-04400);
  1723. case 4401:
  1724. return VUID_WRAP(VUID-ViewIndex-ViewIndex-04401);
  1725. case 4402:
  1726. return VUID_WRAP(VUID-ViewIndex-ViewIndex-04402);
  1727. case 4403:
  1728. return VUID_WRAP(VUID-ViewIndex-ViewIndex-04403);
  1729. case 4404:
  1730. return VUID_WRAP(VUID-ViewportIndex-ViewportIndex-04404);
  1731. case 4405:
  1732. return VUID_WRAP(VUID-ViewportIndex-ViewportIndex-04405);
  1733. case 4406:
  1734. return VUID_WRAP(VUID-ViewportIndex-ViewportIndex-04406);
  1735. case 4407:
  1736. return VUID_WRAP(VUID-ViewportIndex-ViewportIndex-04407);
  1737. case 4408:
  1738. return VUID_WRAP(VUID-ViewportIndex-ViewportIndex-04408);
  1739. case 4422:
  1740. return VUID_WRAP(VUID-WorkgroupId-WorkgroupId-04422);
  1741. case 4423:
  1742. return VUID_WRAP(VUID-WorkgroupId-WorkgroupId-04423);
  1743. case 4424:
  1744. return VUID_WRAP(VUID-WorkgroupId-WorkgroupId-04424);
  1745. case 4425:
  1746. return VUID_WRAP(VUID-WorkgroupSize-WorkgroupSize-04425);
  1747. case 4426:
  1748. return VUID_WRAP(VUID-WorkgroupSize-WorkgroupSize-04426);
  1749. case 4427:
  1750. return VUID_WRAP(VUID-WorkgroupSize-WorkgroupSize-04427);
  1751. case 4428:
  1752. return VUID_WRAP(VUID-WorldRayDirectionKHR-WorldRayDirectionKHR-04428);
  1753. case 4429:
  1754. return VUID_WRAP(VUID-WorldRayDirectionKHR-WorldRayDirectionKHR-04429);
  1755. case 4430:
  1756. return VUID_WRAP(VUID-WorldRayDirectionKHR-WorldRayDirectionKHR-04430);
  1757. case 4431:
  1758. return VUID_WRAP(VUID-WorldRayOriginKHR-WorldRayOriginKHR-04431);
  1759. case 4432:
  1760. return VUID_WRAP(VUID-WorldRayOriginKHR-WorldRayOriginKHR-04432);
  1761. case 4433:
  1762. return VUID_WRAP(VUID-WorldRayOriginKHR-WorldRayOriginKHR-04433);
  1763. case 4434:
  1764. return VUID_WRAP(VUID-WorldToObjectKHR-WorldToObjectKHR-04434);
  1765. case 4435:
  1766. return VUID_WRAP(VUID-WorldToObjectKHR-WorldToObjectKHR-04435);
  1767. case 4436:
  1768. return VUID_WRAP(VUID-WorldToObjectKHR-WorldToObjectKHR-04436);
  1769. case 4484:
  1770. return VUID_WRAP(VUID-PrimitiveShadingRateKHR-PrimitiveShadingRateKHR-04484);
  1771. case 4485:
  1772. return VUID_WRAP(VUID-PrimitiveShadingRateKHR-PrimitiveShadingRateKHR-04485);
  1773. case 4486:
  1774. return VUID_WRAP(VUID-PrimitiveShadingRateKHR-PrimitiveShadingRateKHR-04486);
  1775. case 4490:
  1776. return VUID_WRAP(VUID-ShadingRateKHR-ShadingRateKHR-04490);
  1777. case 4491:
  1778. return VUID_WRAP(VUID-ShadingRateKHR-ShadingRateKHR-04491);
  1779. case 4492:
  1780. return VUID_WRAP(VUID-ShadingRateKHR-ShadingRateKHR-04492);
  1781. case 4633:
  1782. return VUID_WRAP(VUID-StandaloneSpirv-None-04633);
  1783. case 4634:
  1784. return VUID_WRAP(VUID-StandaloneSpirv-None-04634);
  1785. case 4635:
  1786. return VUID_WRAP(VUID-StandaloneSpirv-None-04635);
  1787. case 4636:
  1788. return VUID_WRAP(VUID-StandaloneSpirv-None-04636);
  1789. case 4637:
  1790. return VUID_WRAP(VUID-StandaloneSpirv-None-04637);
  1791. case 4638:
  1792. return VUID_WRAP(VUID-StandaloneSpirv-None-04638);
  1793. case 7321:
  1794. return VUID_WRAP(VUID-StandaloneSpirv-None-07321);
  1795. case 4640:
  1796. return VUID_WRAP(VUID-StandaloneSpirv-None-04640);
  1797. case 4641:
  1798. return VUID_WRAP(VUID-StandaloneSpirv-None-04641);
  1799. case 4642:
  1800. return VUID_WRAP(VUID-StandaloneSpirv-None-04642);
  1801. case 4643:
  1802. return VUID_WRAP(VUID-StandaloneSpirv-None-04643);
  1803. case 4644:
  1804. return VUID_WRAP(VUID-StandaloneSpirv-None-04644);
  1805. case 4645:
  1806. return VUID_WRAP(VUID-StandaloneSpirv-None-04645);
  1807. case 4651:
  1808. return VUID_WRAP(VUID-StandaloneSpirv-OpVariable-04651);
  1809. case 4652:
  1810. return VUID_WRAP(VUID-StandaloneSpirv-OpReadClockKHR-04652);
  1811. case 4653:
  1812. return VUID_WRAP(VUID-StandaloneSpirv-OriginLowerLeft-04653);
  1813. case 4654:
  1814. return VUID_WRAP(VUID-StandaloneSpirv-PixelCenterInteger-04654);
  1815. case 4655:
  1816. return VUID_WRAP(VUID-StandaloneSpirv-UniformConstant-04655);
  1817. case 4656:
  1818. return VUID_WRAP(VUID-StandaloneSpirv-OpTypeImage-04656);
  1819. case 4657:
  1820. return VUID_WRAP(VUID-StandaloneSpirv-OpTypeImage-04657);
  1821. case 4658:
  1822. return VUID_WRAP(VUID-StandaloneSpirv-OpImageTexelPointer-04658);
  1823. case 4659:
  1824. return VUID_WRAP(VUID-StandaloneSpirv-OpImageQuerySizeLod-04659);
  1825. case 4662:
  1826. return VUID_WRAP(VUID-StandaloneSpirv-Offset-04662);
  1827. case 4663:
  1828. return VUID_WRAP(VUID-StandaloneSpirv-Offset-04663);
  1829. case 4664:
  1830. return VUID_WRAP(VUID-StandaloneSpirv-OpImageGather-04664);
  1831. case 4667:
  1832. return VUID_WRAP(VUID-StandaloneSpirv-None-04667);
  1833. case 4669:
  1834. return VUID_WRAP(VUID-StandaloneSpirv-GLSLShared-04669);
  1835. case 4670:
  1836. return VUID_WRAP(VUID-StandaloneSpirv-Flat-04670);
  1837. case 4675:
  1838. return VUID_WRAP(VUID-StandaloneSpirv-FPRoundingMode-04675);
  1839. case 4677:
  1840. return VUID_WRAP(VUID-StandaloneSpirv-Invariant-04677);
  1841. case 4680:
  1842. return VUID_WRAP(VUID-StandaloneSpirv-OpTypeRuntimeArray-04680);
  1843. case 4682:
  1844. return VUID_WRAP(VUID-StandaloneSpirv-OpControlBarrier-04682);
  1845. case 6426:
  1846. return VUID_WRAP(VUID-StandaloneSpirv-LocalSize-06426); // formally 04683
  1847. case 4685:
  1848. return VUID_WRAP(VUID-StandaloneSpirv-OpGroupNonUniformBallotBitCount-04685);
  1849. case 4686:
  1850. return VUID_WRAP(VUID-StandaloneSpirv-None-04686);
  1851. case 4698:
  1852. return VUID_WRAP(VUID-StandaloneSpirv-RayPayloadKHR-04698);
  1853. case 4699:
  1854. return VUID_WRAP(VUID-StandaloneSpirv-IncomingRayPayloadKHR-04699);
  1855. case 4701:
  1856. return VUID_WRAP(VUID-StandaloneSpirv-HitAttributeKHR-04701);
  1857. case 4703:
  1858. return VUID_WRAP(VUID-StandaloneSpirv-HitAttributeKHR-04703);
  1859. case 4704:
  1860. return VUID_WRAP(VUID-StandaloneSpirv-CallableDataKHR-04704);
  1861. case 4705:
  1862. return VUID_WRAP(VUID-StandaloneSpirv-IncomingCallableDataKHR-04705);
  1863. case 7119:
  1864. return VUID_WRAP(VUID-StandaloneSpirv-ShaderRecordBufferKHR-07119);
  1865. case 4708:
  1866. return VUID_WRAP(VUID-StandaloneSpirv-PhysicalStorageBuffer64-04708);
  1867. case 4710:
  1868. return VUID_WRAP(VUID-StandaloneSpirv-PhysicalStorageBuffer64-04710);
  1869. case 4711:
  1870. return VUID_WRAP(VUID-StandaloneSpirv-OpTypeForwardPointer-04711);
  1871. case 4730:
  1872. return VUID_WRAP(VUID-StandaloneSpirv-OpAtomicStore-04730);
  1873. case 4731:
  1874. return VUID_WRAP(VUID-StandaloneSpirv-OpAtomicLoad-04731);
  1875. case 4732:
  1876. return VUID_WRAP(VUID-StandaloneSpirv-OpMemoryBarrier-04732);
  1877. case 4733:
  1878. return VUID_WRAP(VUID-StandaloneSpirv-OpMemoryBarrier-04733);
  1879. case 4734:
  1880. return VUID_WRAP(VUID-StandaloneSpirv-OpVariable-04734);
  1881. case 4744:
  1882. return VUID_WRAP(VUID-StandaloneSpirv-Flat-04744);
  1883. case 4777:
  1884. return VUID_WRAP(VUID-StandaloneSpirv-OpImage-04777);
  1885. case 4780:
  1886. return VUID_WRAP(VUID-StandaloneSpirv-Result-04780);
  1887. case 4781:
  1888. return VUID_WRAP(VUID-StandaloneSpirv-Base-04781);
  1889. case 4915:
  1890. return VUID_WRAP(VUID-StandaloneSpirv-Location-04915);
  1891. case 4916:
  1892. return VUID_WRAP(VUID-StandaloneSpirv-Location-04916);
  1893. case 4917:
  1894. return VUID_WRAP(VUID-StandaloneSpirv-Location-04917);
  1895. case 4918:
  1896. return VUID_WRAP(VUID-StandaloneSpirv-Location-04918);
  1897. case 4919:
  1898. return VUID_WRAP(VUID-StandaloneSpirv-Location-04919);
  1899. case 4920:
  1900. return VUID_WRAP(VUID-StandaloneSpirv-Component-04920);
  1901. case 4921:
  1902. return VUID_WRAP(VUID-StandaloneSpirv-Component-04921);
  1903. case 4922:
  1904. return VUID_WRAP(VUID-StandaloneSpirv-Component-04922);
  1905. case 4923:
  1906. return VUID_WRAP(VUID-StandaloneSpirv-Component-04923);
  1907. case 4924:
  1908. return VUID_WRAP(VUID-StandaloneSpirv-Component-04924);
  1909. case 6201:
  1910. return VUID_WRAP(VUID-StandaloneSpirv-Flat-06201);
  1911. case 6202:
  1912. return VUID_WRAP(VUID-StandaloneSpirv-Flat-06202);
  1913. case 6214:
  1914. return VUID_WRAP(VUID-StandaloneSpirv-OpTypeImage-06214);
  1915. case 6491:
  1916. return VUID_WRAP(VUID-StandaloneSpirv-DescriptorSet-06491);
  1917. case 6671:
  1918. return VUID_WRAP(VUID-StandaloneSpirv-OpTypeSampledImage-06671);
  1919. case 6672:
  1920. return VUID_WRAP(VUID-StandaloneSpirv-Location-06672);
  1921. case 6674:
  1922. return VUID_WRAP(VUID-StandaloneSpirv-OpEntryPoint-06674);
  1923. case 6675:
  1924. return VUID_WRAP(VUID-StandaloneSpirv-PushConstant-06675);
  1925. case 6676:
  1926. return VUID_WRAP(VUID-StandaloneSpirv-Uniform-06676);
  1927. case 6677:
  1928. return VUID_WRAP(VUID-StandaloneSpirv-UniformConstant-06677);
  1929. case 6678:
  1930. return VUID_WRAP(VUID-StandaloneSpirv-InputAttachmentIndex-06678);
  1931. case 6777:
  1932. return VUID_WRAP(VUID-StandaloneSpirv-PerVertexKHR-06777);
  1933. case 6778:
  1934. return VUID_WRAP(VUID-StandaloneSpirv-Input-06778);
  1935. case 6807:
  1936. return VUID_WRAP(VUID-StandaloneSpirv-Uniform-06807);
  1937. case 6808:
  1938. return VUID_WRAP(VUID-StandaloneSpirv-PushConstant-06808);
  1939. case 6925:
  1940. return VUID_WRAP(VUID-StandaloneSpirv-Uniform-06925);
  1941. case 6997:
  1942. return VUID_WRAP(VUID-StandaloneSpirv-SubgroupVoteKHR-06997);
  1943. case 7102:
  1944. return VUID_WRAP(VUID-StandaloneSpirv-MeshEXT-07102);
  1945. case 7320:
  1946. return VUID_WRAP(VUID-StandaloneSpirv-ExecutionModel-07320);
  1947. case 7290:
  1948. return VUID_WRAP(VUID-StandaloneSpirv-Input-07290);
  1949. case 7650:
  1950. return VUID_WRAP(VUID-StandaloneSpirv-Base-07650);
  1951. case 7651:
  1952. return VUID_WRAP(VUID-StandaloneSpirv-Base-07651);
  1953. case 7652:
  1954. return VUID_WRAP(VUID-StandaloneSpirv-Base-07652);
  1955. case 7703:
  1956. return VUID_WRAP(VUID-StandaloneSpirv-Component-07703);
  1957. default:
  1958. return ""; // unknown id
  1959. }
  1960. // clang-format on
  1961. }
  1962. } // namespace val
  1963. } // namespace spvtools