mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-11-23 12:10:06 +00:00
An OpVariable initializer can be a module-scope variable
Fixes https://github.com/KhronosGroup/SPIRV-Tools/issues/482
This commit is contained in:
parent
aadf696fce
commit
d5b0cd34c9
@ -988,7 +988,7 @@ bool idUsage::isValid<SpvOpSpecConstantOp>(const spv_instruction_t *inst) {}
|
||||
|
||||
template <>
|
||||
bool idUsage::isValid<SpvOpVariable>(const spv_instruction_t* inst,
|
||||
const spv_opcode_desc opcodeEntry) {
|
||||
const spv_opcode_desc) {
|
||||
auto resultTypeIndex = 1;
|
||||
auto resultType = module_.FindDef(inst->words[resultTypeIndex]);
|
||||
if (!resultType || SpvOpTypePointer != resultType->opcode()) {
|
||||
@ -997,13 +997,19 @@ bool idUsage::isValid<SpvOpVariable>(const spv_instruction_t* inst,
|
||||
<< "' is not a pointer type.";
|
||||
return false;
|
||||
}
|
||||
if (opcodeEntry->numTypes < inst->words.size()) {
|
||||
auto initialiserIndex = 4;
|
||||
auto initialiser = module_.FindDef(inst->words[initialiserIndex]);
|
||||
if (!initialiser || !spvOpcodeIsConstant(initialiser->opcode())) {
|
||||
const auto initialiserIndex = 4;
|
||||
if (initialiserIndex < inst->words.size()) {
|
||||
const auto initialiser = module_.FindDef(inst->words[initialiserIndex]);
|
||||
const auto storageClassIndex = 3;
|
||||
const auto is_module_scope_var =
|
||||
initialiser && (initialiser->opcode() == SpvOpVariable) &&
|
||||
(initialiser->word(storageClassIndex) != SpvStorageClassFunction);
|
||||
const auto is_constant =
|
||||
initialiser && spvOpcodeIsConstant(initialiser->opcode());
|
||||
if (!initialiser || !(is_constant || is_module_scope_var)) {
|
||||
DIAG(initialiserIndex) << "OpVariable Initializer <id> '"
|
||||
<< inst->words[initialiserIndex]
|
||||
<< "' is not a constant.";
|
||||
<< "' is not a constant or module-scope variable.";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1461,7 +1461,7 @@ TEST_F(ValidateIdWithMessage, OpVariableGood) {
|
||||
CompileSuccessfully(spirv.c_str());
|
||||
EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
|
||||
}
|
||||
TEST_F(ValidateIdWithMessage, OpVariableInitializerGood) {
|
||||
TEST_F(ValidateIdWithMessage, OpVariableInitializerConstantGood) {
|
||||
string spirv = kGLSL450MemoryModel + R"(
|
||||
%1 = OpTypeInt 32 1
|
||||
%2 = OpTypePointer Input %1
|
||||
@ -1470,6 +1470,16 @@ TEST_F(ValidateIdWithMessage, OpVariableInitializerGood) {
|
||||
CompileSuccessfully(spirv.c_str());
|
||||
EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
|
||||
}
|
||||
TEST_F(ValidateIdWithMessage, OpVariableInitializerGlobalVariableGood) {
|
||||
string spirv = kGLSL450MemoryModel + R"(
|
||||
%1 = OpTypeInt 32 1
|
||||
%2 = OpTypePointer Uniform %1
|
||||
%3 = OpVariable %2 Uniform
|
||||
%4 = OpTypePointer Uniform %2 ; pointer to pointer
|
||||
%5 = OpVariable %4 Uniform %3)";
|
||||
CompileSuccessfully(spirv.c_str());
|
||||
EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
|
||||
}
|
||||
// TODO: Positive test OpVariable with OpConstantNull of OpTypePointer
|
||||
TEST_F(ValidateIdWithMessage, OpVariableResultTypeBad) {
|
||||
string spirv = kGLSL450MemoryModel + R"(
|
||||
@ -1478,13 +1488,55 @@ TEST_F(ValidateIdWithMessage, OpVariableResultTypeBad) {
|
||||
CompileSuccessfully(spirv.c_str());
|
||||
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
|
||||
}
|
||||
TEST_F(ValidateIdWithMessage, OpVariableInitializerBad) {
|
||||
TEST_F(ValidateIdWithMessage, OpVariableInitializerIsTypeBad) {
|
||||
string spirv = kGLSL450MemoryModel + R"(
|
||||
%1 = OpTypeInt 32 1
|
||||
%2 = OpTypePointer Input %1
|
||||
%3 = OpVariable %2 Input %2)";
|
||||
CompileSuccessfully(spirv.c_str());
|
||||
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("OpVariable Initializer <id> '2' is not a constant or "
|
||||
"module-scope variable"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateIdWithMessage, OpVariableInitializerIsFunctionVarBad) {
|
||||
string spirv = kGLSL450MemoryModel + R"(
|
||||
%int = OpTypeInt 32 1
|
||||
%ptrint = OpTypePointer Function %int
|
||||
%ptrptrint = OpTypePointer Function %ptrint
|
||||
%void = OpTypeVoid
|
||||
%fnty = OpTypeFunction %void
|
||||
%main = OpFunction %void None %fnty
|
||||
%entry = OpLabel
|
||||
%var = OpVariable %ptrint Function
|
||||
%varinit = OpVariable %ptrptrint Function %var ; Can't initialize function variable.
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
CompileSuccessfully(spirv.c_str());
|
||||
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("OpVariable Initializer <id> '8' is not a constant or "
|
||||
"module-scope variable"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateIdWithMessage, OpVariableInitializerIsModuleVarGood) {
|
||||
string spirv = kGLSL450MemoryModel + R"(
|
||||
%int = OpTypeInt 32 1
|
||||
%ptrint = OpTypePointer Uniform %int
|
||||
%mvar = OpVariable %ptrint Uniform
|
||||
%ptrptrint = OpTypePointer Function %ptrint
|
||||
%void = OpTypeVoid
|
||||
%fnty = OpTypeFunction %void
|
||||
%main = OpFunction %void None %fnty
|
||||
%entry = OpLabel
|
||||
%goodvar = OpVariable %ptrptrint Function %mvar ; This is ok
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
CompileSuccessfully(spirv.c_str());
|
||||
EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
|
||||
}
|
||||
|
||||
TEST_F(ValidateIdWithMessage, OpLoadGood) {
|
||||
|
Loading…
Reference in New Issue
Block a user