mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-11-23 04:00:05 +00:00
Validator pass for image instructions
Includes validation rules for OpImageXXX and ImageOperand. Doesn't include OpTypeImage and OpImageSparseXXX. Disabled an invalid test.
This commit is contained in:
parent
e28edd458b
commit
f407ae2b50
@ -41,6 +41,7 @@ SPVTOOLS_SRC_FILES := \
|
||||
source/validate_datarules.cpp \
|
||||
source/validate_decorations.cpp \
|
||||
source/validate_id.cpp \
|
||||
source/validate_image.cpp \
|
||||
source/validate_instruction.cpp \
|
||||
source/validate_layout.cpp \
|
||||
source/validate_logicals.cpp \
|
||||
|
@ -261,6 +261,7 @@ set(SPIRV_SOURCES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/validate_datarules.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/validate_decorations.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/validate_id.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/validate_image.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/validate_instruction.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/validate_layout.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/validate_logicals.cpp
|
||||
|
@ -438,8 +438,12 @@ bool ValidationState_t::RegisterUniqueTypeDeclaration(
|
||||
|
||||
uint32_t ValidationState_t::GetTypeId(uint32_t id) const {
|
||||
const Instruction* inst = FindDef(id);
|
||||
assert(inst);
|
||||
return inst->type_id();
|
||||
return inst ? inst->type_id() : 0;
|
||||
}
|
||||
|
||||
SpvOp ValidationState_t::GetIdOpcode(uint32_t id) const {
|
||||
const Instruction* inst = FindDef(id);
|
||||
return inst ? inst->opcode() : SpvOpNop;
|
||||
}
|
||||
|
||||
uint32_t ValidationState_t::GetComponentType(uint32_t id) const {
|
||||
@ -523,6 +527,21 @@ bool ValidationState_t::IsFloatVectorType(uint32_t id) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ValidationState_t::IsFloatScalarOrVectorType(uint32_t id) const {
|
||||
const Instruction* inst = FindDef(id);
|
||||
assert(inst);
|
||||
|
||||
if (inst->opcode() == SpvOpTypeFloat) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (inst->opcode() == SpvOpTypeVector) {
|
||||
return IsFloatScalarType(GetComponentType(id));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ValidationState_t::IsIntScalarType(uint32_t id) const {
|
||||
const Instruction* inst = FindDef(id);
|
||||
assert(inst);
|
||||
@ -540,6 +559,21 @@ bool ValidationState_t::IsIntVectorType(uint32_t id) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ValidationState_t::IsIntScalarOrVectorType(uint32_t id) const {
|
||||
const Instruction* inst = FindDef(id);
|
||||
assert(inst);
|
||||
|
||||
if (inst->opcode() == SpvOpTypeInt) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (inst->opcode() == SpvOpTypeVector) {
|
||||
return IsIntScalarType(GetComponentType(id));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ValidationState_t::IsUnsignedIntScalarType(uint32_t id) const {
|
||||
const Instruction* inst = FindDef(id);
|
||||
assert(inst);
|
||||
@ -591,6 +625,21 @@ bool ValidationState_t::IsBoolVectorType(uint32_t id) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ValidationState_t::IsBoolScalarOrVectorType(uint32_t id) const {
|
||||
const Instruction* inst = FindDef(id);
|
||||
assert(inst);
|
||||
|
||||
if (inst->opcode() == SpvOpTypeBool) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (inst->opcode() == SpvOpTypeVector) {
|
||||
return IsBoolScalarType(GetComponentType(id));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ValidationState_t::IsFloatMatrixType(uint32_t id) const {
|
||||
const Instruction* inst = FindDef(id);
|
||||
assert(inst);
|
||||
@ -673,4 +722,27 @@ uint32_t ValidationState_t::GetOperandTypeId(
|
||||
return GetTypeId(inst->words[operand.offset]);
|
||||
}
|
||||
|
||||
bool ValidationState_t::GetConstantValUint64(uint32_t id, uint64_t* val) const {
|
||||
const Instruction* inst = FindDef(id);
|
||||
if (!inst) {
|
||||
assert(0 && "Instruction not found");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (inst->opcode() != SpvOpConstant && inst->opcode() != SpvOpSpecConstant)
|
||||
return false;
|
||||
|
||||
if (!IsIntScalarType(inst->type_id()))
|
||||
return false;
|
||||
|
||||
if (inst->words().size() == 4) {
|
||||
*val = inst->word(3);
|
||||
} else {
|
||||
assert(inst->words().size() == 5);
|
||||
*val = inst->word(3);
|
||||
*val |= uint64_t(inst->word(4)) << 32;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace libspirv
|
||||
|
@ -371,20 +371,31 @@ class ValidationState_t {
|
||||
// Only works for types not for objects.
|
||||
bool IsFloatScalarType(uint32_t id) const;
|
||||
bool IsFloatVectorType(uint32_t id) const;
|
||||
bool IsFloatScalarOrVectorType(uint32_t id) const;
|
||||
bool IsFloatMatrixType(uint32_t id) const;
|
||||
bool IsIntScalarType(uint32_t id) const;
|
||||
bool IsIntVectorType(uint32_t id) const;
|
||||
bool IsIntScalarOrVectorType(uint32_t id) const;
|
||||
bool IsUnsignedIntScalarType(uint32_t id) const;
|
||||
bool IsUnsignedIntVectorType(uint32_t id) const;
|
||||
bool IsSignedIntScalarType(uint32_t id) const;
|
||||
bool IsSignedIntVectorType(uint32_t id) const;
|
||||
bool IsBoolScalarType(uint32_t id) const;
|
||||
bool IsBoolVectorType(uint32_t id) const;
|
||||
bool IsBoolScalarOrVectorType(uint32_t id) const;
|
||||
bool IsPointerType(uint32_t id) const;
|
||||
|
||||
// Gets value from OpConstant and OpSpecConstant as uint64.
|
||||
// Returns false on failure (no instruction, wrong instruction, not int).
|
||||
bool GetConstantValUint64(uint32_t id, uint64_t* val) const;
|
||||
|
||||
// Returns type_id if id has type or zero otherwise.
|
||||
uint32_t GetTypeId(uint32_t id) const;
|
||||
|
||||
// Returns opcode of the instruction which issued the id or OpNop if the
|
||||
// instruction is not registered.
|
||||
SpvOp GetIdOpcode(uint32_t id) const;
|
||||
|
||||
// Returns type_id for given id operand if it has a type or zero otherwise.
|
||||
// |operand_index| is expected to be pointing towards an operand which is an
|
||||
// id.
|
||||
|
@ -183,6 +183,7 @@ spv_result_t ProcessInstruction(void* user_data,
|
||||
if (auto error = ConversionPass(_, inst)) return error;
|
||||
if (auto error = LogicalsPass(_, inst)) return error;
|
||||
if (auto error = BitwisePass(_, inst)) return error;
|
||||
if (auto error = ImagePass(_, inst)) return error;
|
||||
|
||||
return SPV_SUCCESS;
|
||||
}
|
||||
|
@ -127,6 +127,10 @@ spv_result_t LogicalsPass(ValidationState_t& _,
|
||||
spv_result_t BitwisePass(ValidationState_t& _,
|
||||
const spv_parsed_instruction_t* inst);
|
||||
|
||||
/// Validates correctness of image instructions.
|
||||
spv_result_t ImagePass(ValidationState_t& _,
|
||||
const spv_parsed_instruction_t* inst);
|
||||
|
||||
// Validates that capability declarations use operands allowed in the current
|
||||
// context.
|
||||
spv_result_t CapabilityPass(ValidationState_t& _,
|
||||
|
1389
source/validate_image.cpp
Normal file
1389
source/validate_image.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -98,6 +98,12 @@ add_spvtools_unittest(TARGET val_bitwise
|
||||
LIBS ${SPIRV_TOOLS}
|
||||
)
|
||||
|
||||
add_spvtools_unittest(TARGET val_image
|
||||
SRCS val_image_test.cpp
|
||||
${VAL_TEST_COMMON_SRCS}
|
||||
LIBS ${SPIRV_TOOLS}
|
||||
)
|
||||
|
||||
add_spvtools_unittest(TARGET val_limits
|
||||
SRCS val_limits_test.cpp
|
||||
${VAL_TEST_COMMON_SRCS}
|
||||
|
@ -1402,6 +1402,10 @@ make_pair(string(kOpenCLMemoryModel) +
|
||||
MatrixDependencies()))),);
|
||||
// clang-format on
|
||||
|
||||
#if 0
|
||||
// TODO(atgoo@github.com) The following test is not valid as it generates
|
||||
// invalid combinations of images, instructions and image operands.
|
||||
//
|
||||
// Creates assembly containing an OpImageFetch instruction using operands for
|
||||
// the image-operands part. The assembly defines constants %fzero and %izero
|
||||
// that can be used for operands where IDs are required. The assembly is valid,
|
||||
@ -1448,6 +1452,7 @@ INSTANTIATE_TEST_CASE_P(
|
||||
vector<string>{"MinLod"}),
|
||||
make_pair(ImageOperandsTemplate("Lod|Sample %fzero %izero"),
|
||||
AllCapabilities()))), );
|
||||
#endif
|
||||
|
||||
// TODO(umar): Instruction capability checks
|
||||
|
||||
|
3040
test/val/val_image_test.cpp
Normal file
3040
test/val/val_image_test.cpp
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user