MCPcopy Create free account
hub / github.com/KhronosGroup/SPIRV-Tools / ValidateLocations

Function ValidateLocations

source/val/validate_interfaces.cpp:536–634  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

534}
535
536spv_result_t ValidateLocations(ValidationState_t& _,
537 const Instruction* entry_point) {
538 // According to Vulkan 14.1 only the following execution models have
539 // locations assigned.
540 // TODO(dneto): SPV_NV_ray_tracing also uses locations on interface variables,
541 // in other shader stages. Similarly, the *provisional* version of
542 // SPV_KHR_ray_tracing did as well, but not the final version.
543 switch (entry_point->GetOperandAs<spv::ExecutionModel>(0)) {
544 case spv::ExecutionModel::Vertex:
545 case spv::ExecutionModel::TessellationControl:
546 case spv::ExecutionModel::TessellationEvaluation:
547 case spv::ExecutionModel::Geometry:
548 case spv::ExecutionModel::Fragment:
549 break;
550 default:
551 return SPV_SUCCESS;
552 }
553
554 const bool is_geometry = entry_point->GetOperandAs<spv::ExecutionModel>(0) ==
555 spv::ExecutionModel::Geometry;
556 const bool has_geometry_streams =
557 is_geometry && _.HasCapability(spv::Capability::GeometryStreams);
558
559 // Locations are stored as a combined location and component values.
560 std::unordered_set<uint32_t> input_locations;
561 std::unordered_set<uint32_t> output_locations_index0;
562 std::unordered_set<uint32_t> output_locations_index1;
563 std::unordered_set<uint32_t> patch_locations_index0;
564 std::unordered_set<uint32_t> patch_locations_index1;
565 std::unordered_map<uint32_t, std::unordered_set<uint32_t>>
566 output_locations_per_stream;
567 std::unordered_map<uint32_t, std::unordered_set<uint32_t>>
568 output_index1_locations_per_stream;
569 std::unordered_set<uint32_t> seen;
570 for (uint32_t i = 3; i < entry_point->operands().size(); ++i) {
571 auto interface_id = entry_point->GetOperandAs<uint32_t>(i);
572 auto interface_var = _.FindDef(interface_id);
573 const auto sc_index = 2u;
574 auto storage_class =
575 interface_var->GetOperandAs<spv::StorageClass>(sc_index);
576 if (storage_class != spv::StorageClass::Input &&
577 storage_class != spv::StorageClass::Output) {
578 continue;
579 }
580 if (!seen.insert(interface_id).second) {
581 // Pre-1.4 an interface variable could be listed multiple times in an
582 // entry point. Validation for 1.4 or later is done elsewhere.
583 continue;
584 }
585
586 // The two Tessellation stages have a "Patch" variable that interface with
587 // the Location mechanism, but are not suppose to be tied to the "normal"
588 // input/output Location.
589 // TODO - SPIR-V allows the Patch decoration to be applied to struct
590 // members, but is not allowed in GLSL/HLSL
591 bool has_patch = false;
592 for (auto& dec : _.id_decorations(interface_var->id())) {
593 if (dec.dec_type() == spv::Decoration::Patch) {

Callers 1

ValidateInterfacesFunction · 0.85

Calls 8

GetLocationsForVariableFunction · 0.85
operandsMethod · 0.80
FindDefMethod · 0.80
dec_typeMethod · 0.80
HasCapabilityMethod · 0.45
sizeMethod · 0.45
insertMethod · 0.45
idMethod · 0.45

Tested by

no test coverage detected