Skip to content

Commit 13c8033

Browse files
authored
[impeller] Add compiler and reflector support for tessellation and compute shaders. (flutter#33565)
1 parent 5c8ac8d commit 13c8033

15 files changed

+174
-4
lines changed

ci/licenses_golden/licenses_flutter

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,9 @@ FILE: ../../../flutter/impeller/fixtures/impeller.vert
565565
FILE: ../../../flutter/impeller/fixtures/instanced_draw.frag
566566
FILE: ../../../flutter/impeller/fixtures/instanced_draw.vert
567567
FILE: ../../../flutter/impeller/fixtures/kalimba.jpg
568+
FILE: ../../../flutter/impeller/fixtures/sample.comp
569+
FILE: ../../../flutter/impeller/fixtures/sample.tesc
570+
FILE: ../../../flutter/impeller/fixtures/sample.tese
568571
FILE: ../../../flutter/impeller/fixtures/sample.vert
569572
FILE: ../../../flutter/impeller/fixtures/struct_def_bug.vert
570573
FILE: ../../../flutter/impeller/fixtures/table_mountain_nx.png

impeller/compiler/compiler.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ Compiler::Compiler(const fml::Mapping& source_mapping,
204204
return;
205205
}
206206

207-
// MSL Generation.
207+
// SL Generation.
208208
spirv_cross::Parser parser(spv_result_->cbegin(),
209209
spv_result_->cend() - spv_result_->cbegin());
210210
// The parser and compiler must be run separately because the parser contains
@@ -225,7 +225,7 @@ Compiler::Compiler(const fml::Mapping& source_mapping,
225225
std::make_shared<std::string>(sl_compiler.GetCompiler()->compile());
226226

227227
if (!sl_string_) {
228-
COMPILER_ERROR << "Could not generate MSL from SPIRV";
228+
COMPILER_ERROR << "Could not generate SL from SPIRV";
229229
return;
230230
}
231231

impeller/compiler/compiler_test.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,14 +146,14 @@ bool CompilerTest::CanCompileAndReflect(const char* fixture_name) const {
146146

147147
if (!fml::WriteAtomically(intermediates_directory_,
148148
ReflectionCCName(fixture_name).c_str(),
149-
*reflection_header)) {
149+
*reflection_source)) {
150150
VALIDATION_LOG << "Could not write reflection CC intermediates.";
151151
return false;
152152
}
153153

154154
if (!fml::WriteAtomically(intermediates_directory_,
155155
ReflectionJSONName(fixture_name).c_str(),
156-
*reflection_header)) {
156+
*reflection_json)) {
157157
VALIDATION_LOG << "Could not write reflection json intermediates.";
158158
return false;
159159
}

impeller/compiler/compiler_unittests.cc

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ namespace testing {
1616
TEST(CompilerTest, ShaderKindMatchingIsSuccessful) {
1717
ASSERT_EQ(SourceTypeFromFileName("hello.vert"), SourceType::kVertexShader);
1818
ASSERT_EQ(SourceTypeFromFileName("hello.frag"), SourceType::kFragmentShader);
19+
ASSERT_EQ(SourceTypeFromFileName("hello.tesc"),
20+
SourceType::kTessellationControlShader);
21+
ASSERT_EQ(SourceTypeFromFileName("hello.tese"),
22+
SourceType::kTessellationEvaluationShader);
23+
ASSERT_EQ(SourceTypeFromFileName("hello.comp"), SourceType::kComputeShader);
1924
ASSERT_EQ(SourceTypeFromFileName("hello.msl"), SourceType::kUnknown);
2025
ASSERT_EQ(SourceTypeFromFileName("hello.glsl"), SourceType::kUnknown);
2126
}
@@ -24,6 +29,21 @@ TEST_P(CompilerTest, CanCompile) {
2429
ASSERT_TRUE(CanCompileAndReflect("sample.vert"));
2530
}
2631

32+
TEST_P(CompilerTest, CanCompileTessellationControlShader) {
33+
ASSERT_TRUE(CanCompileAndReflect("sample.tesc"));
34+
}
35+
36+
TEST_P(CompilerTest, CanCompileTessellationEvaluationShader) {
37+
ASSERT_TRUE(CanCompileAndReflect("sample.tese"));
38+
}
39+
40+
TEST_P(CompilerTest, CanCompileComputeShader) {
41+
if (!TargetPlatformIsMetal(GetParam())) {
42+
GTEST_SKIP_("Only enabled on Metal backends till ES 3.2 support is added.");
43+
}
44+
ASSERT_TRUE(CanCompileAndReflect("sample.comp"));
45+
}
46+
2747
TEST_P(CompilerTest, MustFailDueToMultipleLocationPerStructMember) {
2848
if (GetParam() == TargetPlatform::kFlutterSPIRV) {
2949
// This is a failure of reflection which this target doesn't perform.

impeller/compiler/reflector.cc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,12 @@ static std::string ExecutionModelToString(spv::ExecutionModel model) {
7171
return "vertex";
7272
case spv::ExecutionModel::ExecutionModelFragment:
7373
return "fragment";
74+
case spv::ExecutionModel::ExecutionModelTessellationControl:
75+
return "tessellation_control";
76+
case spv::ExecutionModel::ExecutionModelTessellationEvaluation:
77+
return "tessellation_evaluation";
78+
case spv::ExecutionModel::ExecutionModelGLCompute:
79+
return "compute";
7480
default:
7581
return "unsupported";
7682
}
@@ -85,6 +91,18 @@ static std::string StringToShaderStage(std::string str) {
8591
return "ShaderStage::kFragment";
8692
}
8793

94+
if (str == "tessellation_control") {
95+
return "ShaderStage::kTessellationControl";
96+
}
97+
98+
if (str == "tessellation_evaluation") {
99+
return "ShaderStage::kTessellationEvaluation";
100+
}
101+
102+
if (str == "compute") {
103+
return "ShaderStage::kCompute";
104+
}
105+
88106
return "ShaderStage::kUnknown";
89107
}
90108

impeller/compiler/types.cc

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,18 @@ SourceType SourceTypeFromFileName(const std::string& file_name) {
3434
return SourceType::kFragmentShader;
3535
}
3636

37+
if (StringEndWith(file_name, ".tesc")) {
38+
return SourceType::kTessellationControlShader;
39+
}
40+
41+
if (StringEndWith(file_name, ".tese")) {
42+
return SourceType::kTessellationEvaluationShader;
43+
}
44+
45+
if (StringEndWith(file_name, ".comp")) {
46+
return SourceType::kComputeShader;
47+
}
48+
3749
return SourceType::kUnknown;
3850
}
3951

@@ -70,6 +82,15 @@ std::string EntryPointFunctionNameFromSourceName(const std::string& file_name,
7082
case SourceType::kFragmentShader:
7183
stream << "fragment";
7284
break;
85+
case SourceType::kTessellationControlShader:
86+
stream << "tess_control";
87+
break;
88+
case SourceType::kTessellationEvaluationShader:
89+
stream << "tess_eval";
90+
break;
91+
case SourceType::kComputeShader:
92+
stream << "compute";
93+
break;
7394
}
7495
stream << "_main";
7596
return stream.str();
@@ -134,6 +155,12 @@ shaderc_shader_kind ToShaderCShaderKind(SourceType type) {
134155
return shaderc_shader_kind::shaderc_vertex_shader;
135156
case SourceType::kFragmentShader:
136157
return shaderc_shader_kind::shaderc_fragment_shader;
158+
case SourceType::kTessellationControlShader:
159+
return shaderc_shader_kind::shaderc_tess_control_shader;
160+
case SourceType::kTessellationEvaluationShader:
161+
return shaderc_shader_kind::shaderc_tess_evaluation_shader;
162+
case SourceType::kComputeShader:
163+
return shaderc_shader_kind::shaderc_compute_shader;
137164
case SourceType::kUnknown:
138165
break;
139166
}
@@ -146,6 +173,12 @@ spv::ExecutionModel ToExecutionModel(SourceType type) {
146173
return spv::ExecutionModel::ExecutionModelVertex;
147174
case SourceType::kFragmentShader:
148175
return spv::ExecutionModel::ExecutionModelFragment;
176+
case SourceType::kTessellationControlShader:
177+
return spv::ExecutionModel::ExecutionModelTessellationControl;
178+
case SourceType::kTessellationEvaluationShader:
179+
return spv::ExecutionModel::ExecutionModelTessellationEvaluation;
180+
case SourceType::kComputeShader:
181+
return spv::ExecutionModel::ExecutionModelGLCompute;
149182
case SourceType::kUnknown:
150183
break;
151184
}
@@ -176,6 +209,12 @@ std::string SourceTypeToString(SourceType type) {
176209
return "vert";
177210
case SourceType::kFragmentShader:
178211
return "frag";
212+
case SourceType::kTessellationControlShader:
213+
return "tesc";
214+
case SourceType::kTessellationEvaluationShader:
215+
return "tese";
216+
case SourceType::kComputeShader:
217+
return "comp";
179218
}
180219
FML_UNREACHABLE();
181220
}
@@ -204,5 +243,31 @@ std::string ToUtf8(const std::string& string) {
204243
return string;
205244
}
206245

246+
bool TargetPlatformIsOpenGL(TargetPlatform platform) {
247+
switch (platform) {
248+
case TargetPlatform::kOpenGLES:
249+
case TargetPlatform::kOpenGLDesktop:
250+
return true;
251+
case TargetPlatform::kMetalDesktop:
252+
case TargetPlatform::kMetalIOS:
253+
case TargetPlatform::kUnknown:
254+
case TargetPlatform::kFlutterSPIRV:
255+
return false;
256+
}
257+
}
258+
259+
bool TargetPlatformIsMetal(TargetPlatform platform) {
260+
switch (platform) {
261+
case TargetPlatform::kMetalDesktop:
262+
case TargetPlatform::kMetalIOS:
263+
return true;
264+
case TargetPlatform::kUnknown:
265+
case TargetPlatform::kFlutterSPIRV:
266+
case TargetPlatform::kOpenGLES:
267+
case TargetPlatform::kOpenGLDesktop:
268+
return false;
269+
}
270+
}
271+
207272
} // namespace compiler
208273
} // namespace impeller

impeller/compiler/types.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ enum class SourceType {
2020
kUnknown,
2121
kVertexShader,
2222
kFragmentShader,
23+
kTessellationControlShader,
24+
kTessellationEvaluationShader,
25+
kComputeShader,
2326
};
2427

2528
enum class TargetPlatform {
@@ -31,6 +34,10 @@ enum class TargetPlatform {
3134
kOpenGLDesktop,
3235
};
3336

37+
bool TargetPlatformIsMetal(TargetPlatform platform);
38+
39+
bool TargetPlatformIsOpenGL(TargetPlatform platform);
40+
3441
SourceType SourceTypeFromFileName(const std::string& file_name);
3542

3643
std::string SourceTypeToString(SourceType type);

impeller/fixtures/BUILD.gn

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ test_fixtures("file_fixtures") {
3030
"embarcadero.jpg",
3131
"kalimba.jpg",
3232
"sample.vert",
33+
"sample.tesc",
34+
"sample.tese",
35+
"sample.comp",
3336
"struct_def_bug.vert",
3437
"table_mountain_nx.png",
3538
"table_mountain_ny.png",

impeller/fixtures/sample.comp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
layout (local_size_x = 16, local_size_y = 16) in;
2+
3+
void main(void) {
4+
// Do nothing.
5+
}

impeller/fixtures/sample.tesc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
layout(vertices = 4) out;
2+
3+
void main() {
4+
gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
5+
}

impeller/fixtures/sample.tese

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
layout (quads, equal_spacing, ccw) in;
2+
3+
void main() {
4+
float u = gl_TessCoord.x;
5+
float omu = 1 - u;
6+
float v = gl_TessCoord.y;
7+
float omv = 1 - v;
8+
9+
gl_Position =
10+
omu * omv * gl_in[0].gl_Position +
11+
u * omv * gl_in[1].gl_Position +
12+
u * v * gl_in[2].gl_Position +
13+
omu * v * gl_in[3].gl_Position;
14+
}

impeller/renderer/backend/gles/pipeline_library_gles.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,15 @@ static void LogShaderCompilationFailure(const ProcTableGLES& gl,
4848
case ShaderStage::kFragment:
4949
stream << "fragment";
5050
break;
51+
case ShaderStage::kTessellationControl:
52+
stream << "tessellation control";
53+
break;
54+
case ShaderStage::kTessellationEvaluation:
55+
stream << "tessellation evaluation";
56+
break;
57+
case ShaderStage::kCompute:
58+
stream << "compute";
59+
break;
5160
}
5261
stream << " shader for '" << name << "' with error:" << std::endl;
5362
stream << GetShaderInfoLog(gl, shader) << std::endl;

impeller/renderer/backend/gles/shader_library_gles.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,15 @@ static std::string GLESShaderNameToShaderKeyName(const std::string& name,
3737
case ShaderStage::kFragment:
3838
stream << "_fragment_";
3939
break;
40+
case ShaderStage::kTessellationControl:
41+
stream << "_tessellation_control_";
42+
break;
43+
case ShaderStage::kTessellationEvaluation:
44+
stream << "_tessellation_evaluation_";
45+
break;
46+
case ShaderStage::kCompute:
47+
stream << "_compute_";
48+
break;
4049
}
4150
stream << "main";
4251
return stream.str();

impeller/renderer/command.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ bool Command::BindResource(ShaderStage stage,
4848
case ShaderStage::kFragment:
4949
fragment_bindings.buffers[slot.binding] = {&metadata, view};
5050
return true;
51+
case ShaderStage::kTessellationControl:
52+
case ShaderStage::kTessellationEvaluation:
53+
case ShaderStage::kCompute:
5154
case ShaderStage::kUnknown:
5255
return false;
5356
}
@@ -74,6 +77,9 @@ bool Command::BindResource(ShaderStage stage,
7477
case ShaderStage::kFragment:
7578
fragment_bindings.textures[slot.texture_index] = {&metadata, texture};
7679
return true;
80+
case ShaderStage::kTessellationControl:
81+
case ShaderStage::kTessellationEvaluation:
82+
case ShaderStage::kCompute:
7783
case ShaderStage::kUnknown:
7884
return false;
7985
}
@@ -101,6 +107,9 @@ bool Command::BindResource(ShaderStage stage,
101107
fragment_bindings.samplers[slot.sampler_index] = {&metadata, sampler};
102108
return true;
103109
case ShaderStage::kUnknown:
110+
case ShaderStage::kTessellationControl:
111+
case ShaderStage::kTessellationEvaluation:
112+
case ShaderStage::kCompute:
104113
return false;
105114
}
106115

impeller/renderer/shader_types.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ enum class ShaderStage {
1717
kUnknown,
1818
kVertex,
1919
kFragment,
20+
kTessellationControl,
21+
kTessellationEvaluation,
22+
kCompute,
2023
};
2124

2225
enum class ShaderType {

0 commit comments

Comments
 (0)