void spvValidatorOptionsSetRelaxStoreStruct(spv_validator_options options,
bool val);
+// Records whether or not the validator should relax the rules on pointer usage
+// in logical addressing mode.
+//
+// When relaxed, it will allow the following usage cases of pointers:
+// 1) OpVariable allocating an object whose type is a pointer type
+// 2) OpReturnValue returning a pointer value
+void spvValidatorOptionsSetRelaxLogicalPointer(spv_validator_options options,
+ bool val);
+
// Encodes the given SPIR-V assembly text to its binary representation. The
// length parameter specifies the number of bytes for text. Encoded binary will
// be stored into *binary. Any error will be written into *diagnostic if
spvValidatorOptionsSetRelaxStoreStruct(options_, val);
}
+ // Records whether or not the validator should relax the rules on pointer
+ // usage in logical addressing mode.
+ //
+ // When relaxed, it will allow the following usage cases of pointers:
+ // 1) OpVariable allocating an object whose type is a pointer type
+ // 2) OpReturnValue returning a pointer value
+ void SetRelaxLogicalPointer(bool val) {
+ spvValidatorOptionsSetRelaxLogicalPointer(options_, val);
+ }
+
private:
spv_validator_options options_;
};
bool val) {
options->relax_struct_store = val;
}
+
+void spvValidatorOptionsSetRelaxLogicalPointer(spv_validator_options options,
+ bool val) {
+ options->relax_logcial_pointer = val;
+}
// Manages command line options passed to the SPIR-V Validator. New struct
// members may be added for any new option.
struct spv_validator_options_t {
- spv_validator_options_t() : universal_limits_(), relax_struct_store(false) {}
+ spv_validator_options_t()
+ : universal_limits_(),
+ relax_struct_store(false),
+ relax_logcial_pointer(false) {}
validator_universal_limits_t universal_limits_;
bool relax_struct_store;
+ bool relax_logcial_pointer;
};
#endif // LIBSPIRV_SPIRV_VALIDATOR_OPTIONS_H_
<< "' is missing or void.";
return false;
}
+
const bool uses_variable_pointer =
module_.features().variable_pointers ||
module_.features().variable_pointers_storage_buffer;
+
if (addressingModel == SpvAddressingModelLogical &&
- SpvOpTypePointer == valueType->opcode() && !uses_variable_pointer) {
+ SpvOpTypePointer == valueType->opcode() && !uses_variable_pointer &&
+ !module_.options()->relax_logcial_pointer) {
DIAG(valueIndex)
<< "OpReturnValue value's type <id> '" << value->type_id()
<< "' is a pointer, which is invalid in the Logical addressing model.";
return false;
}
+
// NOTE: Find OpFunction
const spv_instruction_t* function = inst - 1;
while (firstInst != function) {
"<id> '16's layout."));
}
+TEST_F(ValidateIdWithMessage, OpStoreTypeRelaxedLogicalPointerReturnPointer) {
+ const string spirv = R"(
+ OpCapability Shader
+ OpCapability Linkage
+ OpMemoryModel Logical GLSL450
+%1 = OpTypeInt 32 1
+%2 = OpTypePointer Function %1
+%3 = OpTypeFunction %2 %2
+%4 = OpFunction %2 None %3
+%5 = OpFunctionParameter %2
+%6 = OpLabel
+ OpReturnValue %5
+ OpFunctionEnd)";
+
+ spvValidatorOptionsSetRelaxLogicalPointer(options_, true);
+ CompileSuccessfully(spirv.c_str());
+ EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
+}
+
+TEST_F(ValidateIdWithMessage, OpStoreTypeRelaxedLogicalPointerAllocPointer) {
+ const string spirv = R"(
+ OpCapability Shader
+ OpCapability Linkage
+ OpMemoryModel Logical GLSL450
+ %1 = OpTypeVoid
+ %2 = OpTypeInt 32 1
+ %3 = OpTypeFunction %1 ; void(void)
+ %4 = OpTypePointer Uniform %2 ; int*
+ %5 = OpTypePointer Private %4 ; int** (Private)
+ %6 = OpTypePointer Function %4 ; int** (Function)
+ %7 = OpVariable %5 Private
+ %8 = OpFunction %1 None %3
+ %9 = OpLabel
+%10 = OpVariable %6 Function
+ OpReturn
+ OpFunctionEnd)";
+
+ spvValidatorOptionsSetRelaxLogicalPointer(options_, true);
+ CompileSuccessfully(spirv.c_str());
+ EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
+}
+
TEST_F(ValidateIdWithMessage, OpStoreVoid) {
string spirv = kGLSL450MemoryModel + R"(
%1 = OpTypeVoid
--max-function-args <maximum number arguments allowed per function>
--max-control-flow-nesting-depth <maximum Control Flow nesting depth allowed>
--max-access-chain-indexes <maximum number of indexes allowed to use for Access Chain instructions>
+ --relax-logcial-pointer Allow allocating an object of a pointer type and returning
+ a pointer value from a function in logical addressing mode
--relax-struct-store Allow store from one struct type to a
different type with compatible layout and
members.
continue_processing = false;
return_code = 1;
}
+ } else if (0 == strcmp(cur_arg, "--relax-logical-pointer")) {
+ options.SetRelaxLogicalPointer(true);
} else if (0 == strcmp(cur_arg, "--relax-struct-store")) {
options.SetRelaxStructStore(true);
} else if (0 == cur_arg[1]) {