77#include " bench/Benchmark.h"
88#include " bench/ResultsWriter.h"
99#include " bench/SkSLBench.h"
10+ #include " include/core/SkCanvas.h"
11+ #include " src/gpu/GrCaps.h"
12+ #include " src/gpu/GrRecordingContextPriv.h"
13+ #include " src/gpu/mock/GrMockCaps.h"
1014#include " src/sksl/SkSLCompiler.h"
15+ #include " src/sksl/SkSLIRGenerator.h"
16+ #include " src/sksl/SkSLParser.h"
1117
1218class SkSLCompilerStartupBench : public Benchmark {
1319protected:
@@ -28,12 +34,37 @@ class SkSLCompilerStartupBench : public Benchmark {
2834
2935DEF_BENCH (return new SkSLCompilerStartupBench();)
3036
31- class SkSLBench : public Benchmark {
37+ enum class Output {
38+ kNone ,
39+ kGLSL ,
40+ kMetal ,
41+ kSPIRV
42+ };
43+
44+ class SkSLCompileBench : public Benchmark {
3245public:
33- SkSLBench (SkSL::String name, const char * src)
34- : fName (" sksl_" + name)
46+ static const char * output_string (Output output) {
47+ switch (output) {
48+ case Output::kNone : return " " ;
49+ case Output::kGLSL : return " glsl_" ;
50+ case Output::kMetal : return " metal_" ;
51+ case Output::kSPIRV : return " spirv_" ;
52+ }
53+ SkUNREACHABLE;
54+ }
55+
56+ SkSLCompileBench (SkSL::String name, const char * src, bool optimize, Output output)
57+ : fName (SkSL::String(" sksl_" ) + (optimize ? " " : " unoptimized_" ) + output_string(output) +
58+ name)
3559 , fSrc (src)
36- , fCompiler (/* caps=*/ nullptr ) {}
60+ , fCaps (GrContextOptions(), GrMockOptions())
61+ , fCompiler (fCaps .shaderCaps())
62+ , fOutput (output) {
63+ fSettings .fOptimize = optimize;
64+ // The test programs we compile don't follow Vulkan rules and thus produce invalid
65+ // SPIR-V. This is harmless, so long as we don't try to validate them.
66+ fSettings .fValidateSPIRV = false ;
67+ }
3768
3869protected:
3970 const char * onGetName () override {
@@ -44,15 +75,67 @@ class SkSLBench : public Benchmark {
4475 return backend == kNonRendering_Backend ;
4576 }
4677
47- void onDraw (int loops, SkCanvas*) override {
78+ void onDraw (int loops, SkCanvas* canvas ) override {
4879 for (int i = 0 ; i < loops; i++) {
4980 std::unique_ptr<SkSL::Program> program = fCompiler .convertProgram (
5081 SkSL::Program::kFragment_Kind ,
5182 fSrc ,
5283 fSettings );
5384 if (fCompiler .errorCount ()) {
54- printf (" %s\n " , fCompiler .errorText ().c_str ());
55- SK_ABORT (" shader compilation failed" );
85+ SK_ABORT (" shader compilation failed: %s\n " , fCompiler .errorText ().c_str ());
86+ }
87+ SkSL::String result;
88+ switch (fOutput ) {
89+ case Output::kNone : break ;
90+ case Output::kGLSL : SkAssertResult (fCompiler .toGLSL (*program, &result)); break ;
91+ case Output::kMetal : SkAssertResult (fCompiler .toMetal (*program, &result)); break ;
92+ case Output::kSPIRV : SkAssertResult (fCompiler .toSPIRV (*program, &result)); break ;
93+ }
94+ }
95+ }
96+
97+ private:
98+ SkSL::String fName ;
99+ SkSL::String fSrc ;
100+ GrMockCaps fCaps ;
101+ SkSL::Compiler fCompiler ;
102+ SkSL::Program::Settings fSettings ;
103+ Output fOutput ;
104+
105+ using INHERITED = Benchmark;
106+ };
107+
108+ class SkSLParseBench : public Benchmark {
109+ public:
110+ SkSLParseBench (SkSL::String name, const char * src)
111+ : fName (" sksl_parse_" + name)
112+ , fSrc (src)
113+ , fCompiler (/* caps=*/ nullptr ) {}
114+
115+ protected:
116+ const char * onGetName () override {
117+ return fName .c_str ();
118+ }
119+
120+ bool isSuitableFor (Backend backend) override {
121+ return backend == kNonRendering_Backend ;
122+ }
123+
124+ void onDelayedSetup () override {
125+ SkSL::ParsedModule module = fCompiler .moduleForProgramKind (
126+ SkSL::Program::Kind::kFragment_Kind );
127+ fCompiler .irGenerator ().setSymbolTable (module .fSymbols );
128+ }
129+
130+ void onDraw (int loops, SkCanvas*) override {
131+ for (int i = 0 ; i < loops; i++) {
132+ fCompiler .irGenerator ().pushSymbolTable ();
133+ SkSL::Parser parser (fSrc .c_str (), fSrc .length (), *fCompiler .irGenerator ().symbolTable (),
134+ fCompiler );
135+ parser.compilationUnit ();
136+ fCompiler .irGenerator ().popSymbolTable ();
137+ if (fCompiler .errorCount ()) {
138+ SK_ABORT (" shader compilation failed: %s\n " , fCompiler .errorText ().c_str ());
56139 }
57140 }
58141 }
@@ -68,22 +151,33 @@ class SkSLBench : public Benchmark {
68151
69152// /////////////////////////////////////////////////////////////////////////////
70153
71- DEF_BENCH (return new SkSLBench(" large" , R"(
72- uniform half urange_Stage1;
73- uniform half4 uleftBorderColor_Stage1_c0_c0;
74- uniform half4 urightBorderColor_Stage1_c0_c0;
75- uniform float3x3 umatrix_Stage1_c0_c0_c0;
76- uniform half2 ufocalParams_Stage1_c0_c0_c0_c0;
77- uniform float4 uscale0_1_Stage1_c0_c0_c1;
78- uniform float4 uscale2_3_Stage1_c0_c0_c1;
79- uniform float4 uscale4_5_Stage1_c0_c0_c1;
80- uniform float4 uscale6_7_Stage1_c0_c0_c1;
81- uniform float4 ubias0_1_Stage1_c0_c0_c1;
82- uniform float4 ubias2_3_Stage1_c0_c0_c1;
83- uniform float4 ubias4_5_Stage1_c0_c0_c1;
84- uniform float4 ubias6_7_Stage1_c0_c0_c1;
85- uniform half4 uthresholds1_7_Stage1_c0_c0_c1;
86- uniform half4 uthresholds9_13_Stage1_c0_c0_c1;
154+ #define COMPILER_BENCH (name, text ) \
155+ static constexpr char name ## _SRC[] = text; \
156+ DEF_BENCH (return new SkSLParseBench(#name, name ## _SRC);) \
157+ DEF_BENCH (return new SkSLCompileBench(#name, name ## _SRC, /* optimize=*/ false , Output::kNone );) \
158+ DEF_BENCH (return new SkSLCompileBench(#name, name ## _SRC, /* optimize=*/ true , Output::kNone );) \
159+ DEF_BENCH (return new SkSLCompileBench(#name, name ## _SRC, /* optimize=*/ true , Output::kGLSL );) \
160+ DEF_BENCH (return new SkSLCompileBench(#name, name ## _SRC, /* optimize=*/ true , Output::kMetal );) \
161+ DEF_BENCH (return new SkSLCompileBench(#name, name ## _SRC, /* optimize=*/ true , Output::kSPIRV );)
162+
163+ // Metal requires a layout set and binding for all of its uniforms. We just care that these shaders
164+ // compile, not that they actually work, so we just fill them with zeroes.
165+ COMPILER_BENCH (large, R"(
166+ layout(set=0, binding=0) uniform half urange_Stage1;
167+ layout(set=0, binding=0) uniform half4 uleftBorderColor_Stage1_c0_c0;
168+ layout(set=0, binding=0) uniform half4 urightBorderColor_Stage1_c0_c0;
169+ layout(set=0, binding=0) uniform float3x3 umatrix_Stage1_c0_c0_c0;
170+ layout(set=0, binding=0) uniform half2 ufocalParams_Stage1_c0_c0_c0_c0;
171+ layout(set=0, binding=0) uniform float4 uscale0_1_Stage1_c0_c0_c1;
172+ layout(set=0, binding=0) uniform float4 uscale2_3_Stage1_c0_c0_c1;
173+ layout(set=0, binding=0) uniform float4 uscale4_5_Stage1_c0_c0_c1;
174+ layout(set=0, binding=0) uniform float4 uscale6_7_Stage1_c0_c0_c1;
175+ layout(set=0, binding=0) uniform float4 ubias0_1_Stage1_c0_c0_c1;
176+ layout(set=0, binding=0) uniform float4 ubias2_3_Stage1_c0_c0_c1;
177+ layout(set=0, binding=0) uniform float4 ubias4_5_Stage1_c0_c0_c1;
178+ layout(set=0, binding=0) uniform float4 ubias6_7_Stage1_c0_c0_c1;
179+ layout(set=0, binding=0) uniform half4 uthresholds1_7_Stage1_c0_c0_c1;
180+ layout(set=0, binding=0) uniform half4 uthresholds9_13_Stage1_c0_c0_c1;
87181flat in half4 vcolor_Stage0;
88182in float vcoverage_Stage0;
89183flat in float4 vgeomSubset_Stage0;
@@ -347,12 +441,12 @@ void main()
347441 sk_FragColor = output_Stage1 * outputCoverage_Stage0;
348442 }
349443}
350- )" );)
444+ )" );
351445
352- DEF_BENCH ( return new SkSLBench( " medium" , R"(
353- uniform half2 uDstTextureUpperLeft_Stage1;
354- uniform half2 uDstTextureCoordScale_Stage1;
355- uniform sampler2D uDstTextureSampler_Stage1;
446+ COMPILER_BENCH ( medium, R"(
447+ layout(set=0, binding=0) uniform half2 uDstTextureUpperLeft_Stage1;
448+ layout(set=0, binding=0) uniform half2 uDstTextureCoordScale_Stage1;
449+ layout(set=0, binding=0) uniform sampler2D uDstTextureSampler_Stage1;
356450 noperspective in half4 vQuadEdge_Stage0;
357451 noperspective in half4 vinColor_Stage0;
358452 out half4 sk_FragColor;
@@ -414,11 +508,11 @@ DEF_BENCH(return new SkSLBench("medium", R"(
414508 (half4(1.0) - outputCoverage_Stage0) * _dstColor;
415509 }
416510 }
417- )" ); )
511+ )" );
418512
419- DEF_BENCH ( return new SkSLBench( " small" , R"(
420- uniform float3x3 umatrix_Stage1_c0_c0;
421- uniform sampler2D uTextureSampler_0_Stage1;
513+ COMPILER_BENCH ( small, R"(
514+ layout(set=0, binding=0) uniform float3x3 umatrix_Stage1_c0_c0;
515+ layout(set=0, binding=0) uniform sampler2D uTextureSampler_0_Stage1;
422516 noperspective in float2 vTransformedCoords_0_Stage0;
423517 out half4 sk_FragColor;
424518 half4 TextureEffect_Stage1_c0_c0_c0(half4 _input)
@@ -453,9 +547,9 @@ DEF_BENCH(return new SkSLBench("small", R"(
453547 sk_FragColor = output_Stage1 * outputCoverage_Stage0;
454548 }
455549 }
456- )" ); )
550+ )" );
457551
458- DEF_BENCH ( return new SkSLBench( " tiny" , " void main() { sk_FragColor = half4(1); }" ); )
552+ COMPILER_BENCH ( tiny, " void main() { sk_FragColor = half4(1); }" );
459553
460554#if defined(SK_BUILD_FOR_UNIX)
461555
0 commit comments