Fix fuzzer-discovered error with sk_SecondaryFragColor in SPIR-V.

sk_SecondaryFragColor corresponds to an ES2-only concept
(gl_SecondaryFragColorEXT) and does not have any SPIR-V equivalent.

Two fixes were needed:
- sk_SecondaryFragColor shouldn't be in SPIR-V code at all. Report it as
  an error when it appears.
- We don't stop compilation when this error is reported, so we need to
  fix up the assertion that the fuzzer initially discovered.
  Specifically, the fuzzer found that the `sk_SecondaryFragColor`
  variable never got a SPIR-V ID assigned to it in fVariableMap, so the
  compiler would assert when assembling an expression containing that
  variable. Now, we make sure to populate fVariableMap with an (unused)
  ID in `writeGlobalVar` to avoid this crash.

Change-Id: Ib86919dfc9a325b2b82a7f4b2054b747dad7c32f
Bug: oss-fuzz:44096
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/501976
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
This commit is contained in:
John Stiles 2022-01-28 17:15:44 -05:00 committed by SkCQ
parent e267a5bb7a
commit 343258fa0c
5 changed files with 21 additions and 5 deletions

View File

@ -128,6 +128,7 @@ sksl_error_tests = [
"/sksl/errors/Ossfuzz40479.sksl", "/sksl/errors/Ossfuzz40479.sksl",
"/sksl/errors/Ossfuzz40660.sksl", "/sksl/errors/Ossfuzz40660.sksl",
"/sksl/errors/Ossfuzz44045.sksl", "/sksl/errors/Ossfuzz44045.sksl",
"/sksl/errors/Ossfuzz44096.sksl",
"/sksl/errors/OverflowFloatLiteral.sksl", "/sksl/errors/OverflowFloatLiteral.sksl",
"/sksl/errors/OverflowInlinedLiteral.sksl", "/sksl/errors/OverflowInlinedLiteral.sksl",
"/sksl/errors/OverflowIntLiteral.sksl", "/sksl/errors/OverflowIntLiteral.sksl",
@ -279,6 +280,7 @@ sksl_spirv_tests = [
"/sksl/errors/LayoutInStruct.sksl", "/sksl/errors/LayoutInStruct.sksl",
"/sksl/errors/Ossfuzz36850.sksl", "/sksl/errors/Ossfuzz36850.sksl",
"/sksl/errors/Ossfuzz37469.sksl", "/sksl/errors/Ossfuzz37469.sksl",
"/sksl/errors/Ossfuzz44096.sksl",
"/sksl/errors/UndefinedFunction.sksl", "/sksl/errors/UndefinedFunction.sksl",
"/sksl/errors/UnusedInterfaceBlock.sksl", "/sksl/errors/UnusedInterfaceBlock.sksl",
] ]

View File

@ -0,0 +1 @@
void main() { half x; ++x * sk_SecondaryFragColor; }

View File

@ -3083,9 +3083,6 @@ void SPIRVCodeGenerator::writeGlobalVar(ProgramKind kind, const VarDeclaration&
SkASSERT(!fProgram.fConfig->fSettings.fFragColorIsInOut); SkASSERT(!fProgram.fConfig->fSettings.fFragColorIsInOut);
return; return;
} }
if (var.modifiers().fLayout.fBuiltin == SK_SECONDARYFRAGCOLOR_BUILTIN) {
return;
}
if (this->isDead(var)) { if (this->isDead(var)) {
return; return;
} }
@ -3095,13 +3092,20 @@ void SPIRVCodeGenerator::writeGlobalVar(ProgramKind kind, const VarDeclaration&
fTopLevelUniforms.push_back(&varDecl); fTopLevelUniforms.push_back(&varDecl);
return; return;
} }
// Add this global to the variable map.
const Type& type = var.type(); const Type& type = var.type();
SpvId id = this->nextId(&type);
fVariableMap[&var] = id;
if (var.modifiers().fLayout.fBuiltin == SK_SECONDARYFRAGCOLOR_BUILTIN) {
// sk_SecondaryFragColor corresponds to gl_SecondaryFragColorEXT, which isn't supposed to
// appear in a SPIR-V program (it's only valid in ES2). Report an error.
fContext.fErrors->error(varDecl.fLine, "sk_SecondaryFragColor is not allowed in SPIR-V");
return;
}
Layout layout = var.modifiers().fLayout; Layout layout = var.modifiers().fLayout;
if (layout.fSet < 0 && storageClass == SpvStorageClassUniformConstant) { if (layout.fSet < 0 && storageClass == SpvStorageClassUniformConstant) {
layout.fSet = fProgram.fConfig->fSettings.fDefaultUniformSet; layout.fSet = fProgram.fConfig->fSettings.fDefaultUniformSet;
} }
SpvId id = this->nextId(&type);
fVariableMap[&var] = id;
SpvId typeId = this->getPointerType(type, storageClass); SpvId typeId = this->getPointerType(type, storageClass);
this->writeInstruction(SpvOpVariable, typeId, id, storageClass, fConstantBuffer); this->writeInstruction(SpvOpVariable, typeId, id, storageClass, fConstantBuffer);
this->writeInstruction(SpvOpName, id, var.name(), fNameBuffer); this->writeInstruction(SpvOpName, id, var.name(), fNameBuffer);

View File

@ -0,0 +1,4 @@
### Compilation failed:
error: 9: sk_SecondaryFragColor is not allowed in SPIR-V
1 error

View File

@ -0,0 +1,5 @@
void main() {
float x;
++x * gl_SecondaryFragColorEXT;
}