Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/KhronosGroup/SPIRV-Tools.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/val/validate_memory.cpp')
-rw-r--r--source/val/validate_memory.cpp46
1 files changed, 45 insertions, 1 deletions
diff --git a/source/val/validate_memory.cpp b/source/val/validate_memory.cpp
index 074bdb88a..8a66beef7 100644
--- a/source/val/validate_memory.cpp
+++ b/source/val/validate_memory.cpp
@@ -1410,7 +1410,51 @@ spv_result_t ValidatePtrAccessChain(ValidationState_t& _,
<< "VariablePointers or VariablePointersStorageBuffer";
}
}
- return ValidateAccessChain(_, inst);
+
+ // Need to call first, will make sure Base is a valid ID
+ if (auto error = ValidateAccessChain(_, inst)) return error;
+
+ const auto base_id = inst->GetOperandAs<uint32_t>(2);
+ const auto base = _.FindDef(base_id);
+ const auto base_type = _.FindDef(base->type_id());
+ const auto base_type_storage_class = base_type->word(2);
+
+ if (_.HasCapability(SpvCapabilityShader) &&
+ (base_type_storage_class == SpvStorageClassUniform ||
+ base_type_storage_class == SpvStorageClassStorageBuffer ||
+ base_type_storage_class == SpvStorageClassPhysicalStorageBuffer ||
+ base_type_storage_class == SpvStorageClassPushConstant ||
+ (_.HasCapability(SpvCapabilityWorkgroupMemoryExplicitLayoutKHR) &&
+ base_type_storage_class == SpvStorageClassWorkgroup)) &&
+ !_.HasDecoration(base_type->id(), SpvDecorationArrayStride)) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "OpPtrAccessChain must have a Base whose type is decorated "
+ "with ArrayStride";
+ }
+
+ if (spvIsVulkanEnv(_.context()->target_env)) {
+ if (base_type_storage_class == SpvStorageClassWorkgroup) {
+ if (!_.HasCapability(SpvCapabilityVariablePointers)) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "OpPtrAccessChain Base operand pointing to Workgroup "
+ "storage class must use VariablePointers capability";
+ }
+ } else if (base_type_storage_class == SpvStorageClassStorageBuffer) {
+ if (!_.features().variable_pointers) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "OpPtrAccessChain Base operand pointing to StorageBuffer "
+ "storage class must use VariablePointers or "
+ "VariablePointersStorageBuffer capability";
+ }
+ } else if (base_type_storage_class !=
+ SpvStorageClassPhysicalStorageBuffer) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "OpPtrAccessChain Base operand must point to Workgroup, "
+ "StorageBuffer, or PhysicalStorageBuffer storage class";
+ }
+ }
+
+ return SPV_SUCCESS;
}
spv_result_t ValidateArrayLength(ValidationState_t& state,