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

Function GetLocationsForVariable

source/val/validate_interfaces.cpp:274–534  ·  view source on GitHub ↗

Populates |locations| (and/or |output_index1_locations|) with the use location and component coordinates for |variable|. Indices are calculated as 4 * location + component.

Source from the content-addressed store, hash-verified

272// location and component coordinates for |variable|. Indices are calculated as
273// 4 * location + component.
274spv_result_t GetLocationsForVariable(
275 ValidationState_t& _, const Instruction* entry_point,
276 const Instruction* variable, std::unordered_set<uint32_t>* locations,
277 std::unordered_set<uint32_t>* output_index1_locations) {
278 const bool is_fragment = entry_point->GetOperandAs<spv::ExecutionModel>(0) ==
279 spv::ExecutionModel::Fragment;
280 const auto sc_index = 2u;
281 const bool is_output = variable->GetOperandAs<spv::StorageClass>(sc_index) ==
282 spv::StorageClass::Output;
283 auto ptr_type_id = variable->GetOperandAs<uint32_t>(0);
284 auto ptr_type = _.FindDef(ptr_type_id);
285 auto type_id = ptr_type->GetOperandAs<uint32_t>(2);
286 auto type = _.FindDef(type_id);
287
288 // Check for Location, Component and Index decorations on the variable. The
289 // validator allows duplicate decorations if the location/component/index are
290 // equal. Also track Patch and PerTaskNV decorations.
291 bool has_location = false;
292 uint32_t location = 0;
293 uint32_t component = 0;
294 bool has_index = false;
295 uint32_t index = 0;
296 bool has_patch = false;
297 bool has_per_task_nv = false;
298 bool has_per_vertex_khr = false;
299 // Duplicate Location, Component, Index are checked elsewhere.
300 for (auto& dec : _.id_decorations(variable->id())) {
301 if (dec.dec_type() == spv::Decoration::Location) {
302 has_location = true;
303 location = dec.params()[0];
304 } else if (dec.dec_type() == spv::Decoration::Component) {
305 component = dec.params()[0];
306 } else if (dec.dec_type() == spv::Decoration::Index) {
307 if (!is_output || !is_fragment) {
308 return _.diag(SPV_ERROR_INVALID_DATA, variable)
309 << "Index can only be applied to Fragment output variables";
310 }
311 has_index = true;
312 index = dec.params()[0];
313 } else if (dec.dec_type() == spv::Decoration::BuiltIn) {
314 // Don't check built-ins.
315 return SPV_SUCCESS;
316 } else if (dec.dec_type() == spv::Decoration::Patch) {
317 has_patch = true;
318 } else if (dec.dec_type() == spv::Decoration::PerTaskNV) {
319 has_per_task_nv = true;
320 } else if (dec.dec_type() == spv::Decoration::PerVertexKHR) {
321 if (!is_fragment) {
322 return _.diag(SPV_ERROR_INVALID_DATA, variable)
323 << _.VkErrorID(6777)
324 << "PerVertexKHR can only be applied to Fragment Execution "
325 "Models";
326 }
327 if (type->opcode() != spv::Op::OpTypeArray &&
328 type->opcode() != spv::Op::OpTypeRuntimeArray) {
329 return _.diag(SPV_ERROR_INVALID_DATA, variable)
330 << _.VkErrorID(6778)
331 << "PerVertexKHR must be declared as arrays";

Callers 1

ValidateLocationsFunction · 0.85

Calls 15

NumConsumedLocationsFunction · 0.85
NumConsumedComponentsFunction · 0.85
FindDefMethod · 0.80
dec_typeMethod · 0.80
diagMethod · 0.80
VkErrorIDMethod · 0.80
EvalInt32IfConstMethod · 0.80
struct_member_indexMethod · 0.80
operandsMethod · 0.80
idMethod · 0.45
opcodeMethod · 0.45
HasDecorationMethod · 0.45

Tested by

no test coverage detected