diff --git a/.references/spirv-tools b/.references/spirv-tools index 28d0b10..bcb136c 100644 --- a/.references/spirv-tools +++ b/.references/spirv-tools @@ -1 +1 @@ -fbe4f3a +77a096c diff --git a/spirv-tools/source/val/validate.cpp b/spirv-tools/source/val/validate.cpp index 27bb5cb..1141968 100644 --- a/spirv-tools/source/val/validate.cpp +++ b/spirv-tools/source/val/validate.cpp @@ -390,7 +390,7 @@ spv_result_t ValidateBinaryUsingContextAndValidationState( if (auto error = AtomicsPass(*vstate, &instruction)) return error; if (auto error = PrimitivesPass(*vstate, &instruction)) return error; if (auto error = BarriersPass(*vstate, &instruction)) return error; - // Group + if (auto error = GroupPass(*vstate, &instruction)) return error; // Device-Side Enqueue // Pipe if (auto error = NonUniformPass(*vstate, &instruction)) return error; diff --git a/spirv-tools/source/val/validate.h b/spirv-tools/source/val/validate.h index b21972e..1c2328e 100644 --- a/spirv-tools/source/val/validate.h +++ b/spirv-tools/source/val/validate.h @@ -180,6 +180,9 @@ spv_result_t AtomicsPass(ValidationState_t& _, const Instruction* inst); /// Validates correctness of barrier instructions. spv_result_t BarriersPass(ValidationState_t& _, const Instruction* inst); +/// Validates correctness of Group (Kernel) instructions. +spv_result_t GroupPass(ValidationState_t& _, const Instruction* inst); + /// Validates correctness of literal numbers. spv_result_t LiteralsPass(ValidationState_t& _, const Instruction* inst); diff --git a/spirv-tools/source/val/validate_group.cpp b/spirv-tools/source/val/validate_group.cpp new file mode 100644 index 0000000..872bf86 --- /dev/null +++ b/spirv-tools/source/val/validate_group.cpp @@ -0,0 +1,119 @@ +// Copyright (c) 2026 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include + +#include "source/val/instruction.h" +#include "source/val/validate.h" +#include "source/val/validate_scopes.h" +#include "source/val/validation_state.h" + +namespace spvtools { +namespace val { +namespace { + +spv_result_t ValidateGroupAnyAll(ValidationState_t& _, + const Instruction* inst) { + if (!_.IsBoolScalarType(inst->type_id())) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Result must be a boolean scalar type"; + } + + if (!_.IsBoolScalarType(_.GetOperandTypeId(inst, 3))) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Predicate must be a boolean scalar type"; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateGroupBroadcast(ValidationState_t& _, + const Instruction* inst) { + const uint32_t type_id = inst->type_id(); + if (!_.IsFloatScalarOrVectorType(type_id) && + !_.IsIntScalarOrVectorType(type_id) && + !_.IsBoolScalarOrVectorType(type_id)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Result must be a scalar or vector of integer, floating-point, " + "or boolean type"; + } + + const uint32_t value_type_id = _.GetOperandTypeId(inst, 3); + if (value_type_id != type_id) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "The type of Value must match the Result type"; + } + return SPV_SUCCESS; +} + +spv_result_t ValidateGroupFloat(ValidationState_t& _, const Instruction* inst) { + const uint32_t type_id = inst->type_id(); + if (!_.IsFloatScalarOrVectorType(type_id)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Result must be a scalar or vector of float type"; + } + + const uint32_t x_type_id = _.GetOperandTypeId(inst, 4); + if (x_type_id != type_id) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "The type of X must match the Result type"; + } + return SPV_SUCCESS; +} + +spv_result_t ValidateGroupInt(ValidationState_t& _, const Instruction* inst) { + const uint32_t type_id = inst->type_id(); + if (!_.IsIntScalarOrVectorType(type_id)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Result must be a scalar or vector of integer type"; + } + + const uint32_t x_type_id = _.GetOperandTypeId(inst, 4); + if (x_type_id != type_id) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "The type of X must match the Result type"; + } + return SPV_SUCCESS; +} + +} // namespace + +spv_result_t GroupPass(ValidationState_t& _, const Instruction* inst) { + const spv::Op opcode = inst->opcode(); + + switch (opcode) { + case spv::Op::OpGroupAny: + case spv::Op::OpGroupAll: + return ValidateGroupAnyAll(_, inst); + case spv::Op::OpGroupBroadcast: + return ValidateGroupBroadcast(_, inst); + case spv::Op::OpGroupFAdd: + case spv::Op::OpGroupFMax: + case spv::Op::OpGroupFMin: + return ValidateGroupFloat(_, inst); + case spv::Op::OpGroupIAdd: + case spv::Op::OpGroupUMin: + case spv::Op::OpGroupSMin: + case spv::Op::OpGroupUMax: + case spv::Op::OpGroupSMax: + return ValidateGroupInt(_, inst); + default: + break; + } + + return SPV_SUCCESS; +} + +} // namespace val +} // namespace spvtools diff --git a/spirv-tools/source/val/validate_image.cpp b/spirv-tools/source/val/validate_image.cpp index d3ce76f..30334d9 100644 --- a/spirv-tools/source/val/validate_image.cpp +++ b/spirv-tools/source/val/validate_image.cpp @@ -1055,8 +1055,7 @@ spv_result_t ValidateImageCoordinate(ValidationState_t& _, opcode == spv::Op::OpImageSampleProjDrefExplicitLod || opcode == spv::Op::OpImageGather || opcode == spv::Op::OpImageDrefGather || - (opcode == spv::Op::OpImageQueryLod && - !_.HasCapability(spv::Capability::Kernel)) || + opcode == spv::Op::OpImageQueryLod || opcode == spv::Op::OpImageSparseSampleImplicitLod || opcode == spv::Op::OpImageSparseSampleDrefImplicitLod || opcode == spv::Op::OpImageSparseSampleDrefExplicitLod || @@ -1072,8 +1071,6 @@ spv_result_t ValidateImageCoordinate(ValidationState_t& _, opcode == spv::Op::OpImageSparseSampleExplicitLod || opcode == spv::Op::OpImageRead || opcode == spv::Op::OpImageWrite || - (opcode == spv::Op::OpImageQueryLod && - _.HasCapability(spv::Capability::Kernel)) || opcode == spv::Op::OpImageSparseRead; assert(float_only || int_only || int_or_float); diff --git a/spirv-tools/spirv-tools/build-version.inc b/spirv-tools/spirv-tools/build-version.inc index 66368ca..7155848 100644 --- a/spirv-tools/spirv-tools/build-version.inc +++ b/spirv-tools/spirv-tools/build-version.inc @@ -1 +1 @@ -"v2026.1", "SPIRV-Tools v2026.1 v2026.1.rc1-0-gfbe4f3ad" +"v2026.1", "SPIRV-Tools v2026.1 v2026.1.rc1-2-g77a096c9"