|
@@ -315,11 +315,12 @@ spv_result_t CheckMemoryAccess(ValidationState_t& _, const Instruction* inst,
|
|
|
SpvStorageClass dst_sc, src_sc;
|
|
SpvStorageClass dst_sc, src_sc;
|
|
|
std::tie(dst_sc, src_sc) = GetStorageClass(_, inst);
|
|
std::tie(dst_sc, src_sc) = GetStorageClass(_, inst);
|
|
|
if (inst->operands().size() <= index) {
|
|
if (inst->operands().size() <= index) {
|
|
|
- if (src_sc == SpvStorageClassPhysicalStorageBufferEXT ||
|
|
|
|
|
- dst_sc == SpvStorageClassPhysicalStorageBufferEXT) {
|
|
|
|
|
|
|
+ // Cases where lack of some operand is invalid
|
|
|
|
|
+ if (src_sc == SpvStorageClassPhysicalStorageBuffer ||
|
|
|
|
|
+ dst_sc == SpvStorageClassPhysicalStorageBuffer) {
|
|
|
return _.diag(SPV_ERROR_INVALID_ID, inst)
|
|
return _.diag(SPV_ERROR_INVALID_ID, inst)
|
|
|
- << "Memory accesses with PhysicalStorageBufferEXT must use "
|
|
|
|
|
- "Aligned.";
|
|
|
|
|
|
|
+ << _.VkErrorID(4708)
|
|
|
|
|
+ << "Memory accesses with PhysicalStorageBuffer must use Aligned.";
|
|
|
}
|
|
}
|
|
|
return SPV_SUCCESS;
|
|
return SPV_SUCCESS;
|
|
|
}
|
|
}
|
|
@@ -368,7 +369,7 @@ spv_result_t CheckMemoryAccess(ValidationState_t& _, const Instruction* inst,
|
|
|
dst_sc != SpvStorageClassCrossWorkgroup &&
|
|
dst_sc != SpvStorageClassCrossWorkgroup &&
|
|
|
dst_sc != SpvStorageClassGeneric && dst_sc != SpvStorageClassImage &&
|
|
dst_sc != SpvStorageClassGeneric && dst_sc != SpvStorageClassImage &&
|
|
|
dst_sc != SpvStorageClassStorageBuffer &&
|
|
dst_sc != SpvStorageClassStorageBuffer &&
|
|
|
- dst_sc != SpvStorageClassPhysicalStorageBufferEXT) {
|
|
|
|
|
|
|
+ dst_sc != SpvStorageClassPhysicalStorageBuffer) {
|
|
|
return _.diag(SPV_ERROR_INVALID_ID, inst)
|
|
return _.diag(SPV_ERROR_INVALID_ID, inst)
|
|
|
<< "NonPrivatePointerKHR requires a pointer in Uniform, "
|
|
<< "NonPrivatePointerKHR requires a pointer in Uniform, "
|
|
|
<< "Workgroup, CrossWorkgroup, Generic, Image or StorageBuffer "
|
|
<< "Workgroup, CrossWorkgroup, Generic, Image or StorageBuffer "
|
|
@@ -379,7 +380,7 @@ spv_result_t CheckMemoryAccess(ValidationState_t& _, const Instruction* inst,
|
|
|
src_sc != SpvStorageClassCrossWorkgroup &&
|
|
src_sc != SpvStorageClassCrossWorkgroup &&
|
|
|
src_sc != SpvStorageClassGeneric && src_sc != SpvStorageClassImage &&
|
|
src_sc != SpvStorageClassGeneric && src_sc != SpvStorageClassImage &&
|
|
|
src_sc != SpvStorageClassStorageBuffer &&
|
|
src_sc != SpvStorageClassStorageBuffer &&
|
|
|
- src_sc != SpvStorageClassPhysicalStorageBufferEXT) {
|
|
|
|
|
|
|
+ src_sc != SpvStorageClassPhysicalStorageBuffer) {
|
|
|
return _.diag(SPV_ERROR_INVALID_ID, inst)
|
|
return _.diag(SPV_ERROR_INVALID_ID, inst)
|
|
|
<< "NonPrivatePointerKHR requires a pointer in Uniform, "
|
|
<< "NonPrivatePointerKHR requires a pointer in Uniform, "
|
|
|
<< "Workgroup, CrossWorkgroup, Generic, Image or StorageBuffer "
|
|
<< "Workgroup, CrossWorkgroup, Generic, Image or StorageBuffer "
|
|
@@ -388,11 +389,11 @@ spv_result_t CheckMemoryAccess(ValidationState_t& _, const Instruction* inst,
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (!(mask & SpvMemoryAccessAlignedMask)) {
|
|
if (!(mask & SpvMemoryAccessAlignedMask)) {
|
|
|
- if (src_sc == SpvStorageClassPhysicalStorageBufferEXT ||
|
|
|
|
|
- dst_sc == SpvStorageClassPhysicalStorageBufferEXT) {
|
|
|
|
|
|
|
+ if (src_sc == SpvStorageClassPhysicalStorageBuffer ||
|
|
|
|
|
+ dst_sc == SpvStorageClassPhysicalStorageBuffer) {
|
|
|
return _.diag(SPV_ERROR_INVALID_ID, inst)
|
|
return _.diag(SPV_ERROR_INVALID_ID, inst)
|
|
|
- << "Memory accesses with PhysicalStorageBufferEXT must use "
|
|
|
|
|
- "Aligned.";
|
|
|
|
|
|
|
+ << _.VkErrorID(4708)
|
|
|
|
|
+ << "Memory accesses with PhysicalStorageBuffer must use Aligned.";
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -628,9 +629,9 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (storage_class == SpvStorageClassPhysicalStorageBufferEXT) {
|
|
|
|
|
|
|
+ if (storage_class == SpvStorageClassPhysicalStorageBuffer) {
|
|
|
return _.diag(SPV_ERROR_INVALID_ID, inst)
|
|
return _.diag(SPV_ERROR_INVALID_ID, inst)
|
|
|
- << "PhysicalStorageBufferEXT must not be used with OpVariable.";
|
|
|
|
|
|
|
+ << "PhysicalStorageBuffer must not be used with OpVariable.";
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
auto pointee_base = pointee;
|
|
auto pointee_base = pointee;
|
|
@@ -639,23 +640,23 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) {
|
|
|
}
|
|
}
|
|
|
if (pointee_base->opcode() == SpvOpTypePointer) {
|
|
if (pointee_base->opcode() == SpvOpTypePointer) {
|
|
|
if (pointee_base->GetOperandAs<uint32_t>(1u) ==
|
|
if (pointee_base->GetOperandAs<uint32_t>(1u) ==
|
|
|
- SpvStorageClassPhysicalStorageBufferEXT) {
|
|
|
|
|
- // check for AliasedPointerEXT/RestrictPointerEXT
|
|
|
|
|
|
|
+ SpvStorageClassPhysicalStorageBuffer) {
|
|
|
|
|
+ // check for AliasedPointer/RestrictPointer
|
|
|
bool foundAliased =
|
|
bool foundAliased =
|
|
|
- _.HasDecoration(inst->id(), SpvDecorationAliasedPointerEXT);
|
|
|
|
|
|
|
+ _.HasDecoration(inst->id(), SpvDecorationAliasedPointer);
|
|
|
bool foundRestrict =
|
|
bool foundRestrict =
|
|
|
- _.HasDecoration(inst->id(), SpvDecorationRestrictPointerEXT);
|
|
|
|
|
|
|
+ _.HasDecoration(inst->id(), SpvDecorationRestrictPointer);
|
|
|
if (!foundAliased && !foundRestrict) {
|
|
if (!foundAliased && !foundRestrict) {
|
|
|
return _.diag(SPV_ERROR_INVALID_ID, inst)
|
|
return _.diag(SPV_ERROR_INVALID_ID, inst)
|
|
|
<< "OpVariable " << inst->id()
|
|
<< "OpVariable " << inst->id()
|
|
|
- << ": expected AliasedPointerEXT or RestrictPointerEXT for "
|
|
|
|
|
- << "PhysicalStorageBufferEXT pointer.";
|
|
|
|
|
|
|
+ << ": expected AliasedPointer or RestrictPointer for "
|
|
|
|
|
+ << "PhysicalStorageBuffer pointer.";
|
|
|
}
|
|
}
|
|
|
if (foundAliased && foundRestrict) {
|
|
if (foundAliased && foundRestrict) {
|
|
|
return _.diag(SPV_ERROR_INVALID_ID, inst)
|
|
return _.diag(SPV_ERROR_INVALID_ID, inst)
|
|
|
<< "OpVariable " << inst->id()
|
|
<< "OpVariable " << inst->id()
|
|
|
- << ": can't specify both AliasedPointerEXT and "
|
|
|
|
|
- << "RestrictPointerEXT for PhysicalStorageBufferEXT pointer.";
|
|
|
|
|
|
|
+ << ": can't specify both AliasedPointer and "
|
|
|
|
|
+ << "RestrictPointer for PhysicalStorageBuffer pointer.";
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -753,7 +754,7 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) {
|
|
|
SPV_OPERAND_TYPE_STORAGE_CLASS, storage_class);
|
|
SPV_OPERAND_TYPE_STORAGE_CLASS, storage_class);
|
|
|
switch (storage_class) {
|
|
switch (storage_class) {
|
|
|
case SpvStorageClassStorageBuffer:
|
|
case SpvStorageClassStorageBuffer:
|
|
|
- case SpvStorageClassPhysicalStorageBufferEXT:
|
|
|
|
|
|
|
+ case SpvStorageClassPhysicalStorageBuffer:
|
|
|
if (!_.HasCapability(SpvCapabilityStorageBuffer16BitAccess)) {
|
|
if (!_.HasCapability(SpvCapabilityStorageBuffer16BitAccess)) {
|
|
|
storage_class_ok = false;
|
|
storage_class_ok = false;
|
|
|
}
|
|
}
|
|
@@ -815,7 +816,7 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) {
|
|
|
SPV_OPERAND_TYPE_STORAGE_CLASS, storage_class);
|
|
SPV_OPERAND_TYPE_STORAGE_CLASS, storage_class);
|
|
|
switch (storage_class) {
|
|
switch (storage_class) {
|
|
|
case SpvStorageClassStorageBuffer:
|
|
case SpvStorageClassStorageBuffer:
|
|
|
- case SpvStorageClassPhysicalStorageBufferEXT:
|
|
|
|
|
|
|
+ case SpvStorageClassPhysicalStorageBuffer:
|
|
|
if (!_.HasCapability(SpvCapabilityStorageBuffer8BitAccess)) {
|
|
if (!_.HasCapability(SpvCapabilityStorageBuffer8BitAccess)) {
|
|
|
storage_class_ok = false;
|
|
storage_class_ok = false;
|
|
|
}
|
|
}
|
|
@@ -869,17 +870,14 @@ spv_result_t ValidateLoad(ValidationState_t& _, const Instruction* inst) {
|
|
|
<< "' is not defined.";
|
|
<< "' is not defined.";
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- const bool uses_variable_pointers =
|
|
|
|
|
- _.features().variable_pointers ||
|
|
|
|
|
- _.features().variable_pointers_storage_buffer;
|
|
|
|
|
const auto pointer_index = 2;
|
|
const auto pointer_index = 2;
|
|
|
const auto pointer_id = inst->GetOperandAs<uint32_t>(pointer_index);
|
|
const auto pointer_id = inst->GetOperandAs<uint32_t>(pointer_index);
|
|
|
const auto pointer = _.FindDef(pointer_id);
|
|
const auto pointer = _.FindDef(pointer_id);
|
|
|
if (!pointer ||
|
|
if (!pointer ||
|
|
|
((_.addressing_model() == SpvAddressingModelLogical) &&
|
|
((_.addressing_model() == SpvAddressingModelLogical) &&
|
|
|
- ((!uses_variable_pointers &&
|
|
|
|
|
|
|
+ ((!_.features().variable_pointers &&
|
|
|
!spvOpcodeReturnsLogicalPointer(pointer->opcode())) ||
|
|
!spvOpcodeReturnsLogicalPointer(pointer->opcode())) ||
|
|
|
- (uses_variable_pointers &&
|
|
|
|
|
|
|
+ (_.features().variable_pointers &&
|
|
|
!spvOpcodeReturnsLogicalVariablePointer(pointer->opcode()))))) {
|
|
!spvOpcodeReturnsLogicalVariablePointer(pointer->opcode()))))) {
|
|
|
return _.diag(SPV_ERROR_INVALID_ID, inst)
|
|
return _.diag(SPV_ERROR_INVALID_ID, inst)
|
|
|
<< "OpLoad Pointer <id> '" << _.getIdName(pointer_id)
|
|
<< "OpLoad Pointer <id> '" << _.getIdName(pointer_id)
|
|
@@ -925,17 +923,14 @@ spv_result_t ValidateLoad(ValidationState_t& _, const Instruction* inst) {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
spv_result_t ValidateStore(ValidationState_t& _, const Instruction* inst) {
|
|
spv_result_t ValidateStore(ValidationState_t& _, const Instruction* inst) {
|
|
|
- const bool uses_variable_pointer =
|
|
|
|
|
- _.features().variable_pointers ||
|
|
|
|
|
- _.features().variable_pointers_storage_buffer;
|
|
|
|
|
const auto pointer_index = 0;
|
|
const auto pointer_index = 0;
|
|
|
const auto pointer_id = inst->GetOperandAs<uint32_t>(pointer_index);
|
|
const auto pointer_id = inst->GetOperandAs<uint32_t>(pointer_index);
|
|
|
const auto pointer = _.FindDef(pointer_id);
|
|
const auto pointer = _.FindDef(pointer_id);
|
|
|
if (!pointer ||
|
|
if (!pointer ||
|
|
|
(_.addressing_model() == SpvAddressingModelLogical &&
|
|
(_.addressing_model() == SpvAddressingModelLogical &&
|
|
|
- ((!uses_variable_pointer &&
|
|
|
|
|
|
|
+ ((!_.features().variable_pointers &&
|
|
|
!spvOpcodeReturnsLogicalPointer(pointer->opcode())) ||
|
|
!spvOpcodeReturnsLogicalPointer(pointer->opcode())) ||
|
|
|
- (uses_variable_pointer &&
|
|
|
|
|
|
|
+ (_.features().variable_pointers &&
|
|
|
!spvOpcodeReturnsLogicalVariablePointer(pointer->opcode()))))) {
|
|
!spvOpcodeReturnsLogicalVariablePointer(pointer->opcode()))))) {
|
|
|
return _.diag(SPV_ERROR_INVALID_ID, inst)
|
|
return _.diag(SPV_ERROR_INVALID_ID, inst)
|
|
|
<< "OpStore Pointer <id> '" << _.getIdName(pointer_id)
|
|
<< "OpStore Pointer <id> '" << _.getIdName(pointer_id)
|
|
@@ -1146,8 +1141,6 @@ spv_result_t ValidateCopyMemory(ValidationState_t& _, const Instruction* inst) {
|
|
|
<< "'s type does not match Source <id> '"
|
|
<< "'s type does not match Source <id> '"
|
|
|
<< _.getIdName(source_type->id()) << "'s type.";
|
|
<< _.getIdName(source_type->id()) << "'s type.";
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- if (auto error = CheckMemoryAccess(_, inst, 2)) return error;
|
|
|
|
|
} else {
|
|
} else {
|
|
|
const auto size_id = inst->GetOperandAs<uint32_t>(2);
|
|
const auto size_id = inst->GetOperandAs<uint32_t>(2);
|
|
|
const auto size = _.FindDef(size_id);
|
|
const auto size = _.FindDef(size_id);
|
|
@@ -1190,8 +1183,6 @@ spv_result_t ValidateCopyMemory(ValidationState_t& _, const Instruction* inst) {
|
|
|
// Cannot infer any other opcodes.
|
|
// Cannot infer any other opcodes.
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- if (auto error = CheckMemoryAccess(_, inst, 3)) return error;
|
|
|
|
|
}
|
|
}
|
|
|
if (auto error = ValidateCopyMemoryMemoryAccess(_, inst)) return error;
|
|
if (auto error = ValidateCopyMemoryMemoryAccess(_, inst)) return error;
|
|
|
|
|
|
|
@@ -1365,8 +1356,7 @@ spv_result_t ValidateAccessChain(ValidationState_t& _,
|
|
|
spv_result_t ValidatePtrAccessChain(ValidationState_t& _,
|
|
spv_result_t ValidatePtrAccessChain(ValidationState_t& _,
|
|
|
const Instruction* inst) {
|
|
const Instruction* inst) {
|
|
|
if (_.addressing_model() == SpvAddressingModelLogical) {
|
|
if (_.addressing_model() == SpvAddressingModelLogical) {
|
|
|
- if (!_.features().variable_pointers &&
|
|
|
|
|
- !_.features().variable_pointers_storage_buffer) {
|
|
|
|
|
|
|
+ if (!_.features().variable_pointers) {
|
|
|
return _.diag(SPV_ERROR_INVALID_DATA, inst)
|
|
return _.diag(SPV_ERROR_INVALID_DATA, inst)
|
|
|
<< "Generating variable pointers requires capability "
|
|
<< "Generating variable pointers requires capability "
|
|
|
<< "VariablePointers or VariablePointersStorageBuffer";
|
|
<< "VariablePointers or VariablePointersStorageBuffer";
|
|
@@ -1484,18 +1474,15 @@ spv_result_t ValidateCooperativeMatrixLoadStoreNV(ValidationState_t& _,
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- const bool uses_variable_pointers =
|
|
|
|
|
- _.features().variable_pointers ||
|
|
|
|
|
- _.features().variable_pointers_storage_buffer;
|
|
|
|
|
const auto pointer_index =
|
|
const auto pointer_index =
|
|
|
(inst->opcode() == SpvOpCooperativeMatrixLoadNV) ? 2u : 0u;
|
|
(inst->opcode() == SpvOpCooperativeMatrixLoadNV) ? 2u : 0u;
|
|
|
const auto pointer_id = inst->GetOperandAs<uint32_t>(pointer_index);
|
|
const auto pointer_id = inst->GetOperandAs<uint32_t>(pointer_index);
|
|
|
const auto pointer = _.FindDef(pointer_id);
|
|
const auto pointer = _.FindDef(pointer_id);
|
|
|
if (!pointer ||
|
|
if (!pointer ||
|
|
|
((_.addressing_model() == SpvAddressingModelLogical) &&
|
|
((_.addressing_model() == SpvAddressingModelLogical) &&
|
|
|
- ((!uses_variable_pointers &&
|
|
|
|
|
|
|
+ ((!_.features().variable_pointers &&
|
|
|
!spvOpcodeReturnsLogicalPointer(pointer->opcode())) ||
|
|
!spvOpcodeReturnsLogicalPointer(pointer->opcode())) ||
|
|
|
- (uses_variable_pointers &&
|
|
|
|
|
|
|
+ (_.features().variable_pointers &&
|
|
|
!spvOpcodeReturnsLogicalVariablePointer(pointer->opcode()))))) {
|
|
!spvOpcodeReturnsLogicalVariablePointer(pointer->opcode()))))) {
|
|
|
return _.diag(SPV_ERROR_INVALID_ID, inst)
|
|
return _.diag(SPV_ERROR_INVALID_ID, inst)
|
|
|
<< opname << " Pointer <id> '" << _.getIdName(pointer_id)
|
|
<< opname << " Pointer <id> '" << _.getIdName(pointer_id)
|
|
@@ -1516,7 +1503,7 @@ spv_result_t ValidateCooperativeMatrixLoadStoreNV(ValidationState_t& _,
|
|
|
|
|
|
|
|
if (storage_class != SpvStorageClassWorkgroup &&
|
|
if (storage_class != SpvStorageClassWorkgroup &&
|
|
|
storage_class != SpvStorageClassStorageBuffer &&
|
|
storage_class != SpvStorageClassStorageBuffer &&
|
|
|
- storage_class != SpvStorageClassPhysicalStorageBufferEXT) {
|
|
|
|
|
|
|
+ storage_class != SpvStorageClassPhysicalStorageBuffer) {
|
|
|
return _.diag(SPV_ERROR_INVALID_ID, inst)
|
|
return _.diag(SPV_ERROR_INVALID_ID, inst)
|
|
|
<< opname << " storage class for pointer type <id> '"
|
|
<< opname << " storage class for pointer type <id> '"
|
|
|
<< _.getIdName(pointer_type_id)
|
|
<< _.getIdName(pointer_type_id)
|
|
@@ -1567,10 +1554,10 @@ spv_result_t ValidateCooperativeMatrixLoadStoreNV(ValidationState_t& _,
|
|
|
spv_result_t ValidatePtrComparison(ValidationState_t& _,
|
|
spv_result_t ValidatePtrComparison(ValidationState_t& _,
|
|
|
const Instruction* inst) {
|
|
const Instruction* inst) {
|
|
|
if (_.addressing_model() == SpvAddressingModelLogical &&
|
|
if (_.addressing_model() == SpvAddressingModelLogical &&
|
|
|
- !_.features().variable_pointers_storage_buffer) {
|
|
|
|
|
|
|
+ !_.features().variable_pointers) {
|
|
|
return _.diag(SPV_ERROR_INVALID_ID, inst)
|
|
return _.diag(SPV_ERROR_INVALID_ID, inst)
|
|
|
- << "Instruction cannot be used without a variable pointers "
|
|
|
|
|
- "capability";
|
|
|
|
|
|
|
+ << "Instruction cannot for logical addressing model be used without "
|
|
|
|
|
+ "a variable pointers capability";
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
const auto result_type = _.FindDef(inst->type_id());
|
|
const auto result_type = _.FindDef(inst->type_id());
|
|
@@ -1605,7 +1592,8 @@ spv_result_t ValidatePtrComparison(ValidationState_t& _,
|
|
|
<< "Invalid pointer storage class";
|
|
<< "Invalid pointer storage class";
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (sc == SpvStorageClassWorkgroup && !_.features().variable_pointers) {
|
|
|
|
|
|
|
+ if (sc == SpvStorageClassWorkgroup &&
|
|
|
|
|
+ !_.HasCapability(SpvCapabilityVariablePointers)) {
|
|
|
return _.diag(SPV_ERROR_INVALID_ID, inst)
|
|
return _.diag(SPV_ERROR_INVALID_ID, inst)
|
|
|
<< "Workgroup storage class pointer requires VariablePointers "
|
|
<< "Workgroup storage class pointer requires VariablePointers "
|
|
|
"capability to be specified";
|
|
"capability to be specified";
|