Skip to content

Commit 44c93ad

Browse files
authored
spirv-val: accept NonReadable/NonWritable on tensor variables in UniformConstant (KhronosGroup#6184)
* spirv-val: accept NonReadable/NonWritable on tensor variables in UniformConstant Signed-off-by: Kevin Petit <[email protected]> Change-Id: I9925002d576f767a833c303e8191b75aa349f0b8 * review comments Change-Id: I7df3f9bfb130d9ddb964aa7637120a5eb07bd839 * deal with unused variable Change-Id: I05844f8de07027429d97b837d9910e033b9739d9 * attempt to fix CI Change-Id: I2b7f32a0b43b92071550fa05a580429e10d478a1 * attempt to fix CI Change-Id: I10523fce45506590ced8dcd1d5662a83e207314b * attempt to fix CI Change-Id: Ieaffedea8d64f21c29e789e132b3b6533eccb678 * revert CI changes --------- Signed-off-by: Kevin Petit <[email protected]>
1 parent bc7c60e commit 44c93ad

File tree

4 files changed

+172
-78
lines changed

4 files changed

+172
-78
lines changed

source/val/validate_decorations.cpp

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1767,14 +1767,19 @@ spv_result_t CheckFPRoundingModeForShaders(ValidationState_t& vstate,
17671767
return SPV_SUCCESS;
17681768
}
17691769

1770-
// Returns SPV_SUCCESS if validation rules are satisfied for the NonWritable
1770+
// Returns SPV_SUCCESS if validation rules are satisfied for the NonReadable or
1771+
// NonWritable
17711772
// decoration. Otherwise emits a diagnostic and returns something other than
17721773
// SPV_SUCCESS. The |inst| parameter is the object being decorated. This must
17731774
// be called after TypePass and AnnotateCheckDecorationsOfBuffers are called.
1774-
spv_result_t CheckNonWritableDecoration(ValidationState_t& vstate,
1775-
const Instruction& inst,
1776-
const Decoration& decoration) {
1775+
spv_result_t CheckNonReadableWritableDecorations(ValidationState_t& vstate,
1776+
const Instruction& inst,
1777+
const Decoration& decoration) {
17771778
assert(inst.id() && "Parser ensures the target of the decoration has an ID");
1779+
const bool is_non_writable =
1780+
decoration.dec_type() == spv::Decoration::NonWritable;
1781+
assert(is_non_writable ||
1782+
decoration.dec_type() == spv::Decoration::NonReadable);
17781783

17791784
if (decoration.struct_member_index() == Decoration::kInvalidMember) {
17801785
// The target must be a memory object declaration.
@@ -1786,7 +1791,10 @@ spv_result_t CheckNonWritableDecoration(ValidationState_t& vstate,
17861791
opcode != spv::Op::OpFunctionParameter &&
17871792
opcode != spv::Op::OpRawAccessChainNV) {
17881793
return vstate.diag(SPV_ERROR_INVALID_ID, &inst)
1789-
<< "Target of NonWritable decoration must be a memory object "
1794+
<< "Target of "
1795+
<< (is_non_writable ? "NonWritable" : "NonReadable")
1796+
<< " decoration must be a "
1797+
"memory object "
17901798
"declaration (a variable or a function parameter)";
17911799
}
17921800
const auto var_storage_class =
@@ -1797,20 +1805,27 @@ spv_result_t CheckNonWritableDecoration(ValidationState_t& vstate,
17971805
: spv::StorageClass::Max;
17981806
if ((var_storage_class == spv::StorageClass::Function ||
17991807
var_storage_class == spv::StorageClass::Private) &&
1800-
vstate.features().nonwritable_var_in_function_or_private) {
1808+
vstate.features().nonwritable_var_in_function_or_private &&
1809+
is_non_writable) {
18011810
// New permitted feature in SPIR-V 1.4.
18021811
} else if (var_storage_class == spv::StorageClass::TileAttachmentQCOM) {
18031812
} else if (
18041813
// It may point to a UBO, SSBO, storage image, or raw access chain.
18051814
vstate.IsPointerToUniformBlock(type_id) ||
18061815
vstate.IsPointerToStorageBuffer(type_id) ||
18071816
vstate.IsPointerToStorageImage(type_id) ||
1817+
vstate.IsPointerToTensor(type_id) ||
18081818
opcode == spv::Op::OpRawAccessChainNV) {
18091819
} else {
18101820
return vstate.diag(SPV_ERROR_INVALID_ID, &inst)
1811-
<< "Target of NonWritable decoration is invalid: must point to a "
1812-
"storage image, uniform block, "
1813-
<< (vstate.features().nonwritable_var_in_function_or_private
1821+
<< "Target of "
1822+
<< (is_non_writable ? "NonWritable" : "NonReadable")
1823+
<< " decoration is invalid: "
1824+
"must point to a "
1825+
"storage image, tensor variable in UniformConstant storage "
1826+
"class, uniform block, "
1827+
<< (vstate.features().nonwritable_var_in_function_or_private &&
1828+
is_non_writable
18141829
? "storage buffer, or variable in Private or Function "
18151830
"storage class"
18161831
: "or storage buffer");
@@ -2098,8 +2113,10 @@ spv_result_t CheckDecorationsFromDecoration(ValidationState_t& vstate) {
20982113
PASS_OR_BAIL(
20992114
CheckFPRoundingModeForShaders(vstate, *inst, decoration));
21002115
break;
2116+
case spv::Decoration::NonReadable:
21012117
case spv::Decoration::NonWritable:
2102-
PASS_OR_BAIL(CheckNonWritableDecoration(vstate, *inst, decoration));
2118+
PASS_OR_BAIL(
2119+
CheckNonReadableWritableDecorations(vstate, *inst, decoration));
21032120
break;
21042121
case spv::Decoration::Uniform:
21052122
case spv::Decoration::UniformId:

source/val/validate_type.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,9 @@ spv_result_t ValidateTypePointer(ValidationState_t& _,
562562
// a storage image.
563563
if (sampled == 2) _.RegisterPointerToStorageImage(inst->id());
564564
}
565+
if (type->opcode() == spv::Op::OpTypeTensorARM) {
566+
_.RegisterPointerToTensor(inst->id());
567+
}
565568
}
566569

567570
if (!_.IsValidStorageClass(storage_class)) {

source/val/validation_state.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -772,6 +772,16 @@ class ValidationState_t {
772772
pointer_to_storage_image_.insert(type_id);
773773
}
774774

775+
// Is the ID the type of a pointer to a tensor? That is, the pointee
776+
// type is a tensor type.
777+
bool IsPointerToTensor(uint32_t type_id) const {
778+
return pointer_to_tensor_.find(type_id) != pointer_to_tensor_.cend();
779+
}
780+
// Save the ID of a pointer to a tensor.
781+
void RegisterPointerToTensor(uint32_t type_id) {
782+
pointer_to_tensor_.insert(type_id);
783+
}
784+
775785
// Tries to evaluate a any scalar integer OpConstant as uint64.
776786
// OpConstantNull is defined as zero for scalar int (will return true)
777787
// OpSpecConstant* return false since their values cannot be relied upon
@@ -1036,6 +1046,9 @@ class ValidationState_t {
10361046
// The IDs of types of pointers to storage images. This is populated in the
10371047
// TypePass.
10381048
std::unordered_set<uint32_t> pointer_to_storage_image_;
1049+
// The IDs of types of pointers to tensors. This is populated in the
1050+
// TypePass.
1051+
std::unordered_set<uint32_t> pointer_to_tensor_;
10391052

10401053
/// Maps ids to friendly names.
10411054
std::unique_ptr<spvtools::FriendlyNameMapper> friendly_mapper_;

0 commit comments

Comments
 (0)