Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 72664be

Browse files
johnstiles-googleSkia Commit-Bot
authored and
Skia Commit-Bot
committed
Add support for #pragma settings comments in SkSL.
This will allow us to write skslc-based golden tests that deviate from the standalone skslc settings. This CL provides six options; more will be added as necessary. - Default (caps) - UsesPrecisionModifiers (caps) - Version110 (caps) - Version450Core (caps) - ForceHighPrecision (settings flag bit) - Sharpen (settings flag bit) Change-Id: I9b779e039b2f0c0ccf43dca226fb4844aff3526b Reviewed-on: https://skia-review.googlesource.com/c/skia/+/317237 Commit-Queue: John Stiles <[email protected]> Auto-Submit: John Stiles <[email protected]> Reviewed-by: Brian Osman <[email protected]>
1 parent 3ee25e9 commit 72664be

27 files changed

+276
-253
lines changed

gn/sksl_tests.gni

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ sksl_glsl_tests_sources = [
3131
"$_tests/sksl/glsl/DependentInitializers.sksl",
3232
"$_tests/sksl/glsl/Discard.sksl",
3333
"$_tests/sksl/glsl/FloatFolding.sksl",
34+
"$_tests/sksl/glsl/ForceHighPrecision.sksl",
3435
"$_tests/sksl/glsl/FrExp.sksl",
3536
"$_tests/sksl/glsl/Functions.sksl",
3637
"$_tests/sksl/glsl/Height.sksl",
@@ -72,9 +73,18 @@ sksl_glsl_tests_sources = [
7273
"$_tests/sksl/glsl/TernaryAsLValueEntirelyFoldable.sksl",
7374
"$_tests/sksl/glsl/TernaryAsLValueFoldableTest.sksl",
7475
"$_tests/sksl/glsl/TernaryAsLValueUnfoldable.sksl",
76+
"$_tests/sksl/glsl/Texture.sksl",
77+
"$_tests/sksl/glsl/TextureSharpen.sksl",
78+
"$_tests/sksl/glsl/TextureSharpenVersion110.sksl",
79+
"$_tests/sksl/glsl/TextureVersion110.sksl",
80+
"$_tests/sksl/glsl/TypePrecisionDisabled.sksl",
81+
"$_tests/sksl/glsl/TypePrecisionEnabled.sksl",
7582
"$_tests/sksl/glsl/UnusedVariables.sksl",
83+
"$_tests/sksl/glsl/UsesPrecisionModifiers.sksl",
7684
"$_tests/sksl/glsl/VectorConstructors.sksl",
7785
"$_tests/sksl/glsl/VectorFolding.sksl",
86+
"$_tests/sksl/glsl/Version110.sksl",
87+
"$_tests/sksl/glsl/Version450Core.sksl",
7888
"$_tests/sksl/glsl/VertexID.vert",
7989
"$_tests/sksl/glsl/Width.sksl",
8090
"$_tests/sksl/inliner/DoWhileBodyMustBeInlinedIntoAScope.sksl",

src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ void GrGLSLFragmentShaderBuilder::enableSecondaryOutput() {
263263

264264
// If the primary output is declared, we must declare also the secondary output
265265
// and vice versa, since it is not allowed to use a built-in gl_FragColor and a custom
266-
// output. The condition also co-incides with the condition in whici GLES SL 2.0
266+
// output. The condition also co-incides with the condition in which GLES SL 2.0
267267
// requires the built-in gl_SecondaryFragColorEXT, where as 3.0 requires a custom output.
268268
if (caps.mustDeclareFragmentShaderOutput()) {
269269
fOutputs.emplace_back(DeclaredSecondaryColorOutputName(), kHalf4_GrSLType,

src/sksl/SkSLMain.cpp

Lines changed: 59 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,62 @@ static SkSL::String base_name(const char* fpPath, const char* prefix, const char
3333
return result;
3434
}
3535

36+
// Given a string containing an SkSL program, searches for a #pragma settings comment, like so:
37+
// /*#pragma settings Default Sharpen*/
38+
// The passed-in Settings object will be updated accordingly. Any number of options can be provided.
39+
static void detect_shader_settings(const SkSL::String& text, SkSL::Program::Settings* settings) {
40+
// Find a matching comment and isolate the name portion.
41+
static constexpr char kPragmaSettings[] = "/*#pragma settings ";
42+
const char* settingsPtr = strstr(text.c_str(), kPragmaSettings);
43+
if (settingsPtr != nullptr) {
44+
// Subtract one here in order to preserve the leading space, which is necessary to allow
45+
// consumeSuffix to find the first item.
46+
settingsPtr += strlen(kPragmaSettings) - 1;
47+
48+
const char* settingsEnd = strstr(settingsPtr, "*/");
49+
if (settingsEnd != nullptr) {
50+
SkSL::String settingsText{settingsPtr, size_t(settingsEnd - settingsPtr)};
51+
52+
// Apply settings as requested. Since they can come in any order, repeat until we've
53+
// consumed them all.
54+
for (;;) {
55+
const size_t startingLength = settingsText.length();
56+
57+
if (settingsText.consumeSuffix(" Default")) {
58+
static auto s_defaultCaps = SkSL::ShaderCapsFactory::Default();
59+
settings->fCaps = s_defaultCaps.get();
60+
}
61+
if (settingsText.consumeSuffix(" UsesPrecisionModifiers")) {
62+
static auto s_precisionCaps = SkSL::ShaderCapsFactory::UsesPrecisionModifiers();
63+
settings->fCaps = s_precisionCaps.get();
64+
}
65+
if (settingsText.consumeSuffix(" Version110")) {
66+
static auto s_version110Caps = SkSL::ShaderCapsFactory::Version110();
67+
settings->fCaps = s_version110Caps.get();
68+
}
69+
if (settingsText.consumeSuffix(" Version450Core")) {
70+
static auto s_version450CoreCaps = SkSL::ShaderCapsFactory::Version450Core();
71+
settings->fCaps = s_version450CoreCaps.get();
72+
}
73+
if (settingsText.consumeSuffix(" ForceHighPrecision")) {
74+
settings->fForceHighPrecision = true;
75+
}
76+
if (settingsText.consumeSuffix(" Sharpen")) {
77+
settings->fSharpenTextures = true;
78+
}
79+
80+
if (settingsText.empty()) {
81+
break;
82+
}
83+
if (settingsText.length() == startingLength) {
84+
printf("Unrecognized #pragma settings: %s\n", settingsText.c_str());
85+
exit(3);
86+
}
87+
}
88+
}
89+
}
90+
}
91+
3692
/**
3793
* Very simple standalone executable to facilitate testing.
3894
*/
@@ -60,17 +116,15 @@ int main(int argc, const char** argv) {
60116
}
61117

62118
std::ifstream in(argv[1]);
63-
std::string stdText((std::istreambuf_iterator<char>(in)),
64-
std::istreambuf_iterator<char>());
65-
SkSL::String text(stdText.c_str());
119+
SkSL::String text((std::istreambuf_iterator<char>(in)),
120+
std::istreambuf_iterator<char>());
66121
if (in.rdstate()) {
67122
printf("error reading '%s'\n", argv[1]);
68123
exit(2);
69124
}
70125

71-
SkSL::ShaderCapsPointer caps = SkSL::ShaderCapsFactory::Standalone();
72126
SkSL::Program::Settings settings;
73-
settings.fCaps = caps.get();
127+
detect_shader_settings(text, &settings);
74128
SkSL::String name(argv[2]);
75129
if (name.endsWith(".spirv")) {
76130
SkSL::FileOutputStream out(argv[2]);

src/sksl/SkSLString.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,18 @@ bool String::endsWith(const char suffix[]) const {
6161
return !strncmp(this->data() + this->size() - suffixLength, suffix, suffixLength);
6262
}
6363

64+
bool String::consumeSuffix(const char suffix[]) {
65+
size_t suffixLength = strlen(suffix);
66+
if (this->length() < suffixLength) {
67+
return false;
68+
}
69+
if (0 != strncmp(this->data() + this->size() - suffixLength, suffix, suffixLength)) {
70+
return false;
71+
}
72+
this->resize(this->length() - suffixLength);
73+
return true;
74+
}
75+
6476
String String::operator+(const char* s) const {
6577
String result(*this);
6678
result.append(s);

src/sksl/SkSLString.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,9 @@ class SK_API String : public std::string {
6565
void appendf(const char* fmt, ...);
6666
void vappendf(const char* fmt, va_list va);
6767

68-
bool startsWith(const char* prefix) const;
69-
bool endsWith(const char* suffix) const;
68+
bool startsWith(const char prefix[]) const;
69+
bool endsWith(const char suffix[]) const;
70+
bool consumeSuffix(const char suffix[]);
7071

7172
String operator+(const char* s) const;
7273
String operator+(const String& s) const;

src/sksl/SkSLUtil.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,8 @@ class StandaloneShaderCaps {
8585
return fUsesPrecisionModifiers;
8686
}
8787

88-
bool fMustDeclareFragmentShaderOutput = true;
8988
bool mustDeclareFragmentShaderOutput() const {
90-
return fMustDeclareFragmentShaderOutput;
89+
return fGLSLGeneration > k110_GrGLSLGeneration;
9190
}
9291

9392
bool fFBFetchSupport = true;

0 commit comments

Comments
 (0)