Report an error if sk_LastFragColor is referenced without fbFetchSupport

Adjusted default caps in skslc to be consistent with runtime behavior,
and added optional settings mode to enable the feature. Tests for both
scenarios. (The error test crashed prior to the fix).

Bug: oss-fuzz:38726
Change-Id: I5270d4837ac982085d7baf5abd4b361f7bfb8562
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/449062
Reviewed-by: John Stiles <johnstiles@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
This commit is contained in:
Brian Osman 2021-09-15 10:28:27 -04:00 committed by SkCQ
parent 398ef4487b
commit a81e7e2e71
11 changed files with 37 additions and 5 deletions

View File

@ -69,6 +69,7 @@ sksl_error_tests = [
"/sksl/errors/InvalidOutParams.sksl",
"/sksl/errors/InvalidToken.sksl",
"/sksl/errors/InvalidUnary.sksl",
"/sksl/errors/LastFragColorWithoutCaps.sksl",
"/sksl/errors/LayoutInFunctions.sksl",
"/sksl/errors/LayoutRepeatedQualifiers.sksl",
"/sksl/errors/MatrixToVectorCast3x3.sksl",
@ -161,6 +162,7 @@ sksl_error_tests = [
sksl_glsl_tests = [
"/sksl/glsl/ForceHighPrecision.sksl",
"/sksl/glsl/IncompleteShortIntPrecision.sksl",
"/sksl/glsl/LastFragColor.sksl",
"/sksl/glsl/LayoutQualifiers.sksl",
"/sksl/glsl/ShortIntPrecision.sksl",
"/sksl/glsl/TextureSharpenVersion110.sksl",

View File

@ -0,0 +1,3 @@
void main() {
sk_FragColor = sk_LastFragColor;
}

View File

@ -0,0 +1,5 @@
/*#pragma settings FramebufferFetchSupport*/
void main() {
sk_FragColor = sk_LastFragColor;
}

View File

@ -139,6 +139,10 @@ static bool detect_shader_settings(const SkSL::String& text,
static auto s_emulateAbsIntCaps = Factory::EmulateAbsIntFunction();
*caps = s_emulateAbsIntCaps.get();
}
if (settingsText.consumeSuffix(" FramebufferFetchSupport")) {
static auto s_fbFetchSupport = Factory::FramebufferFetchSupport();
*caps = s_fbFetchSupport.get();
}
if (settingsText.consumeSuffix(" IncompleteShortIntPrecision")) {
static auto s_incompleteShortIntCaps = Factory::IncompleteShortIntPrecision();
*caps = s_incompleteShortIntCaps.get();

View File

@ -89,7 +89,7 @@ public:
return fGLSLGeneration > k110_GrGLSLGeneration;
}
bool fFBFetchSupport = true;
bool fFBFetchSupport = false;
bool fbFetchSupport() const {
return fFBFetchSupport;
}
@ -346,6 +346,13 @@ public:
return result;
}
static ShaderCapsPointer FramebufferFetchSupport() {
ShaderCapsPointer result = MakeShaderCaps();
result->fFBFetchSupport = true;
result->fFBFetchColorName = "gl_LastFragData[0]";
return result;
}
static ShaderCapsPointer IncompleteShortIntPrecision() {
ShaderCapsPointer result = MakeShaderCaps();
result->fVersionDeclString = "#version 310es";

View File

@ -777,7 +777,12 @@ void GLSLCodeGenerator::writeVariableReference(const VariableReference& ref) {
this->write("gl_InstanceID");
break;
case SK_LASTFRAGCOLOR_BUILTIN:
this->write(this->caps().fbFetchColorName());
if (this->caps().fbFetchSupport()) {
this->write(this->caps().fbFetchColorName());
} else {
fContext.fErrors->error(ref.fOffset,
"sk_LastFragColor requires framebuffer fetch support");
}
break;
default:
this->write(ref.variable()->name());

View File

@ -0,0 +1,4 @@
### Compilation failed:
error: 2: sk_LastFragColor requires framebuffer fetch support
1 error

View File

@ -0,0 +1,5 @@
out vec4 sk_FragColor;
void main() {
sk_FragColor = gl_LastFragData[0];
}

View File

@ -42,7 +42,6 @@ OpStore %x %int_0
OpStore %y %int_0
OpStore %z %int_0
OpStore %x %int_1
OpStore %y %int_1
OpStore %z %int_1
%20 = OpLoad %int %x
%21 = OpConvertSToF %float %20

View File

@ -5,7 +5,6 @@ void main() {
int y = 0;
int z = 0;
x = 1;
y = 1;
z = 1;
sk_FragColor.xyz = vec3(float(x), float(y), float(z));
}

View File

@ -13,7 +13,6 @@ fragment Outputs fragmentMain(Inputs _in [[stage_in]], bool _frontFacing [[front
int y = 0;
int z = 0;
x = 1;
y = 1;
z = 1;
_out.sk_FragColor.xyz = float3(float(x), float(y), float(z));
return _out;