mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-10-18 19:20:05 +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 <>
|
template <>
|
||||||
bool idUsage::isValid<SpvOpVariable>(const spv_instruction_t* inst,
|
bool idUsage::isValid<SpvOpVariable>(const spv_instruction_t* inst,
|
||||||
const spv_opcode_desc opcodeEntry) {
|
const spv_opcode_desc) {
|
||||||
auto resultTypeIndex = 1;
|
auto resultTypeIndex = 1;
|
||||||
auto resultType = module_.FindDef(inst->words[resultTypeIndex]);
|
auto resultType = module_.FindDef(inst->words[resultTypeIndex]);
|
||||||
if (!resultType || SpvOpTypePointer != resultType->opcode()) {
|
if (!resultType || SpvOpTypePointer != resultType->opcode()) {
|
||||||
@ -997,13 +997,19 @@ bool idUsage::isValid<SpvOpVariable>(const spv_instruction_t* inst,
|
|||||||
<< "' is not a pointer type.";
|
<< "' is not a pointer type.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (opcodeEntry->numTypes < inst->words.size()) {
|
const auto initialiserIndex = 4;
|
||||||
auto initialiserIndex = 4;
|
if (initialiserIndex < inst->words.size()) {
|
||||||
auto initialiser = module_.FindDef(inst->words[initialiserIndex]);
|
const auto initialiser = module_.FindDef(inst->words[initialiserIndex]);
|
||||||
if (!initialiser || !spvOpcodeIsConstant(initialiser->opcode())) {
|
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> '"
|
DIAG(initialiserIndex) << "OpVariable Initializer <id> '"
|
||||||
<< inst->words[initialiserIndex]
|
<< inst->words[initialiserIndex]
|
||||||
<< "' is not a constant.";
|
<< "' is not a constant or module-scope variable.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1461,7 +1461,7 @@ TEST_F(ValidateIdWithMessage, OpVariableGood) {
|
|||||||
CompileSuccessfully(spirv.c_str());
|
CompileSuccessfully(spirv.c_str());
|
||||||
EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
|
EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
|
||||||
}
|
}
|
||||||
TEST_F(ValidateIdWithMessage, OpVariableInitializerGood) {
|
TEST_F(ValidateIdWithMessage, OpVariableInitializerConstantGood) {
|
||||||
string spirv = kGLSL450MemoryModel + R"(
|
string spirv = kGLSL450MemoryModel + R"(
|
||||||
%1 = OpTypeInt 32 1
|
%1 = OpTypeInt 32 1
|
||||||
%2 = OpTypePointer Input %1
|
%2 = OpTypePointer Input %1
|
||||||
@ -1470,6 +1470,16 @@ TEST_F(ValidateIdWithMessage, OpVariableInitializerGood) {
|
|||||||
CompileSuccessfully(spirv.c_str());
|
CompileSuccessfully(spirv.c_str());
|
||||||
EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
|
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
|
// TODO: Positive test OpVariable with OpConstantNull of OpTypePointer
|
||||||
TEST_F(ValidateIdWithMessage, OpVariableResultTypeBad) {
|
TEST_F(ValidateIdWithMessage, OpVariableResultTypeBad) {
|
||||||
string spirv = kGLSL450MemoryModel + R"(
|
string spirv = kGLSL450MemoryModel + R"(
|
||||||
@ -1478,13 +1488,55 @@ TEST_F(ValidateIdWithMessage, OpVariableResultTypeBad) {
|
|||||||
CompileSuccessfully(spirv.c_str());
|
CompileSuccessfully(spirv.c_str());
|
||||||
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
|
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
|
||||||
}
|
}
|
||||||
TEST_F(ValidateIdWithMessage, OpVariableInitializerBad) {
|
TEST_F(ValidateIdWithMessage, OpVariableInitializerIsTypeBad) {
|
||||||
string spirv = kGLSL450MemoryModel + R"(
|
string spirv = kGLSL450MemoryModel + R"(
|
||||||
%1 = OpTypeInt 32 1
|
%1 = OpTypeInt 32 1
|
||||||
%2 = OpTypePointer Input %1
|
%2 = OpTypePointer Input %1
|
||||||
%3 = OpVariable %2 Input %2)";
|
%3 = OpVariable %2 Input %2)";
|
||||||
CompileSuccessfully(spirv.c_str());
|
CompileSuccessfully(spirv.c_str());
|
||||||
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
|
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) {
|
TEST_F(ValidateIdWithMessage, OpLoadGood) {
|
||||||
|
Loading…
Reference in New Issue
Block a user