validation_state.cpp 61 KB

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