Fix for fuzzer-discovered error in SPIR-V compilation. Unused InterfaceBlocks were not added to the ProgramUsage map. The ProgramUsageVisitor now makes sure to account for them during its initial scan. Change-Id: If3afac8e954c5b685ddc6b63b0f771d8c0b8f207 Bug: oss-fuzz:33405 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/398016 Auto-Submit: John Stiles <johnstiles@google.com> Commit-Queue: Brian Osman <brianosman@google.com> Reviewed-by: Brian Osman <brianosman@google.com>
diff --git a/gn/sksl_tests.gni b/gn/sksl_tests.gni index 68ef838..5dcd55a 100644 --- a/gn/sksl_tests.gni +++ b/gn/sksl_tests.gni
@@ -237,6 +237,7 @@ "/sksl/spirv/OpaqueTypeInArray.sksl", "/sksl/workarounds/RewriteMatrixVectorMultiply.sksl", "/sksl/errors/UndefinedFunction.sksl", + "/sksl/errors/UnusedInterfaceBlock.sksl", ] sksl_shared_tests = [
diff --git a/resources/sksl/errors/UnusedInterfaceBlock.sksl b/resources/sksl/errors/UnusedInterfaceBlock.sksl new file mode 100644 index 0000000..353cd9e --- /dev/null +++ b/resources/sksl/errors/UnusedInterfaceBlock.sksl
@@ -0,0 +1,2 @@ +in s { int I; }; +void main() {}
diff --git a/src/sksl/SkSLAnalysis.cpp b/src/sksl/SkSLAnalysis.cpp index 52301d2..23384a0 100644 --- a/src/sksl/SkSLAnalysis.cpp +++ b/src/sksl/SkSLAnalysis.cpp
@@ -210,6 +210,9 @@ // they are unread and unwritten. fUsage->fVariableCounts[param]; } + } else if (pe.is<InterfaceBlock>()) { + // Ensure interface-block variables exist in the variable usage map. + fUsage->fVariableCounts[&pe.as<InterfaceBlock>().variable()]; } return INHERITED::visitProgramElement(pe); }
diff --git a/src/sksl/codegen/SkSLSPIRVCodeGenerator.cpp b/src/sksl/codegen/SkSLSPIRVCodeGenerator.cpp index 907187e..c00ef53 100644 --- a/src/sksl/codegen/SkSLSPIRVCodeGenerator.cpp +++ b/src/sksl/codegen/SkSLSPIRVCodeGenerator.cpp
@@ -3521,8 +3521,7 @@ SpvId id = this->writeInterfaceBlock(intf); const Modifiers& modifiers = intf.variable().modifiers(); - if (((modifiers.fFlags & Modifiers::kIn_Flag) || - (modifiers.fFlags & Modifiers::kOut_Flag)) && + if ((modifiers.fFlags & (Modifiers::kIn_Flag | Modifiers::kOut_Flag)) && modifiers.fLayout.fBuiltin == -1 && !is_dead(intf.variable(), fProgram.fUsage.get())) { interfaceVars.insert(id); @@ -3561,8 +3560,7 @@ for (auto entry : fVariableMap) { const Variable* var = entry.first; if (var->storage() == Variable::Storage::kGlobal && - ((var->modifiers().fFlags & Modifiers::kIn_Flag) || - (var->modifiers().fFlags & Modifiers::kOut_Flag)) && + (var->modifiers().fFlags & (Modifiers::kIn_Flag | Modifiers::kOut_Flag)) && !is_dead(*var, fProgram.fUsage.get())) { interfaceVars.insert(entry.second); }
diff --git a/tests/sksl/errors/UnusedInterfaceBlock.asm.frag b/tests/sksl/errors/UnusedInterfaceBlock.asm.frag new file mode 100644 index 0000000..177aabe --- /dev/null +++ b/tests/sksl/errors/UnusedInterfaceBlock.asm.frag
@@ -0,0 +1,32 @@ +### Compilation failed: + +error: SPIR-V validation error: Member index 0 is missing a location assignment + %s = OpTypeStruct %int + +OpCapability Shader +%1 = OpExtInstImport "GLSL.std.450" +OpMemoryModel Logical GLSL450 +OpEntryPoint Fragment %main "main" %3 %sk_Clockwise +OpExecutionMode %main OriginUpperLeft +OpName %s "s" +OpMemberName %s 0 "I" +OpName %sk_Clockwise "sk_Clockwise" +OpName %main "main" +OpMemberDecorate %s 0 Offset 0 +OpDecorate %s Block +OpDecorate %sk_Clockwise BuiltIn FrontFacing +%int = OpTypeInt 32 1 +%s = OpTypeStruct %int +%_ptr_Input_s = OpTypePointer Input %s +%3 = OpVariable %_ptr_Input_s Input +%bool = OpTypeBool +%_ptr_Input_bool = OpTypePointer Input %bool +%sk_Clockwise = OpVariable %_ptr_Input_bool Input +%void = OpTypeVoid +%11 = OpTypeFunction %void +%main = OpFunction %void None %11 +%12 = OpLabel +OpReturn +OpFunctionEnd + +1 error