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

[impeller] Add compiler and reflector support for tessellation and compute shaders. #33565

Merged
merged 2 commits into from
May 23, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions impeller/compiler/compiler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ Compiler::Compiler(const fml::Mapping& source_mapping,
return;
}

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

if (!sl_string_) {
COMPILER_ERROR << "Could not generate MSL from SPIRV";
COMPILER_ERROR << "Could not generate SL from SPIRV";
return;
}

Expand Down
4 changes: 2 additions & 2 deletions impeller/compiler/compiler_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -146,14 +146,14 @@ bool CompilerTest::CanCompileAndReflect(const char* fixture_name) const {

if (!fml::WriteAtomically(intermediates_directory_,
ReflectionCCName(fixture_name).c_str(),
*reflection_header)) {
*reflection_source)) {
VALIDATION_LOG << "Could not write reflection CC intermediates.";
return false;
}

if (!fml::WriteAtomically(intermediates_directory_,
ReflectionJSONName(fixture_name).c_str(),
*reflection_header)) {
*reflection_json)) {
VALIDATION_LOG << "Could not write reflection json intermediates.";
return false;
}
Expand Down
20 changes: 20 additions & 0 deletions impeller/compiler/compiler_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ namespace testing {
TEST(CompilerTest, ShaderKindMatchingIsSuccessful) {
ASSERT_EQ(SourceTypeFromFileName("hello.vert"), SourceType::kVertexShader);
ASSERT_EQ(SourceTypeFromFileName("hello.frag"), SourceType::kFragmentShader);
ASSERT_EQ(SourceTypeFromFileName("hello.tesc"),
SourceType::kTessellationControlShader);
ASSERT_EQ(SourceTypeFromFileName("hello.tese"),
SourceType::kTessellationEvaluationShader);
ASSERT_EQ(SourceTypeFromFileName("hello.comp"), SourceType::kComputeShader);
ASSERT_EQ(SourceTypeFromFileName("hello.msl"), SourceType::kUnknown);
ASSERT_EQ(SourceTypeFromFileName("hello.glsl"), SourceType::kUnknown);
}
Expand All @@ -24,6 +29,21 @@ TEST_P(CompilerTest, CanCompile) {
ASSERT_TRUE(CanCompileAndReflect("sample.vert"));
}

TEST_P(CompilerTest, CanCompileTessellationControlShader) {
ASSERT_TRUE(CanCompileAndReflect("sample.tesc"));
}

TEST_P(CompilerTest, CanCompileTessellationEvaluationShader) {
ASSERT_TRUE(CanCompileAndReflect("sample.tese"));
}

TEST_P(CompilerTest, CanCompileComputeShader) {
if (!TargetPlatformIsMetal(GetParam())) {
GTEST_SKIP_("Only enabled on Metal backends till ES 3.2 support is added.");
}
ASSERT_TRUE(CanCompileAndReflect("sample.comp"));
}

TEST_P(CompilerTest, MustFailDueToMultipleLocationPerStructMember) {
if (GetParam() == TargetPlatform::kFlutterSPIRV) {
// This is a failure of reflection which this target doesn't perform.
Expand Down
18 changes: 18 additions & 0 deletions impeller/compiler/reflector.cc
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ static std::string ExecutionModelToString(spv::ExecutionModel model) {
return "vertex";
case spv::ExecutionModel::ExecutionModelFragment:
return "fragment";
case spv::ExecutionModel::ExecutionModelTessellationControl:
return "tessellation_control";
case spv::ExecutionModel::ExecutionModelTessellationEvaluation:
return "tessellation_evaluation";
case spv::ExecutionModel::ExecutionModelGLCompute:
return "compute";
default:
return "unsupported";
}
Expand All @@ -85,6 +91,18 @@ static std::string StringToShaderStage(std::string str) {
return "ShaderStage::kFragment";
}

if (str == "tessellation_control") {
return "ShaderStage::kTessellationControl";
}

if (str == "tessellation_evaluation") {
return "ShaderStage::kTessellationEvaluation";
}

if (str == "compute") {
return "ShaderStage::kCompute";
}

return "ShaderStage::kUnknown";
}

Expand Down
65 changes: 65 additions & 0 deletions impeller/compiler/types.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,18 @@ SourceType SourceTypeFromFileName(const std::string& file_name) {
return SourceType::kFragmentShader;
}

if (StringEndWith(file_name, ".tesc")) {
return SourceType::kTessellationControlShader;
}

if (StringEndWith(file_name, ".tese")) {
return SourceType::kTessellationEvaluationShader;
}

if (StringEndWith(file_name, ".comp")) {
return SourceType::kComputeShader;
}

return SourceType::kUnknown;
}

Expand Down Expand Up @@ -70,6 +82,15 @@ std::string EntryPointFunctionNameFromSourceName(const std::string& file_name,
case SourceType::kFragmentShader:
stream << "fragment";
break;
case SourceType::kTessellationControlShader:
stream << "tess_control";
break;
case SourceType::kTessellationEvaluationShader:
stream << "tess_eval";
break;
case SourceType::kComputeShader:
stream << "compute";
break;
}
stream << "_main";
return stream.str();
Expand Down Expand Up @@ -134,6 +155,12 @@ shaderc_shader_kind ToShaderCShaderKind(SourceType type) {
return shaderc_shader_kind::shaderc_vertex_shader;
case SourceType::kFragmentShader:
return shaderc_shader_kind::shaderc_fragment_shader;
case SourceType::kTessellationControlShader:
return shaderc_shader_kind::shaderc_tess_control_shader;
case SourceType::kTessellationEvaluationShader:
return shaderc_shader_kind::shaderc_tess_evaluation_shader;
case SourceType::kComputeShader:
return shaderc_shader_kind::shaderc_compute_shader;
case SourceType::kUnknown:
break;
}
Expand All @@ -146,6 +173,12 @@ spv::ExecutionModel ToExecutionModel(SourceType type) {
return spv::ExecutionModel::ExecutionModelVertex;
case SourceType::kFragmentShader:
return spv::ExecutionModel::ExecutionModelFragment;
case SourceType::kTessellationControlShader:
return spv::ExecutionModel::ExecutionModelTessellationControl;
case SourceType::kTessellationEvaluationShader:
return spv::ExecutionModel::ExecutionModelTessellationEvaluation;
case SourceType::kComputeShader:
return spv::ExecutionModel::ExecutionModelGLCompute;
case SourceType::kUnknown:
break;
}
Expand Down Expand Up @@ -176,6 +209,12 @@ std::string SourceTypeToString(SourceType type) {
return "vert";
case SourceType::kFragmentShader:
return "frag";
case SourceType::kTessellationControlShader:
return "tesc";
case SourceType::kTessellationEvaluationShader:
return "tese";
case SourceType::kComputeShader:
return "comp";
}
FML_UNREACHABLE();
}
Expand Down Expand Up @@ -204,5 +243,31 @@ std::string ToUtf8(const std::string& string) {
return string;
}

bool TargetPlatformIsOpenGL(TargetPlatform platform) {
switch (platform) {
case TargetPlatform::kOpenGLES:
case TargetPlatform::kOpenGLDesktop:
return true;
case TargetPlatform::kMetalDesktop:
case TargetPlatform::kMetalIOS:
case TargetPlatform::kUnknown:
case TargetPlatform::kFlutterSPIRV:
return false;
}
}

bool TargetPlatformIsMetal(TargetPlatform platform) {
switch (platform) {
case TargetPlatform::kMetalDesktop:
case TargetPlatform::kMetalIOS:
return true;
case TargetPlatform::kUnknown:
case TargetPlatform::kFlutterSPIRV:
case TargetPlatform::kOpenGLES:
case TargetPlatform::kOpenGLDesktop:
return false;
}
}

} // namespace compiler
} // namespace impeller
7 changes: 7 additions & 0 deletions impeller/compiler/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ enum class SourceType {
kUnknown,
kVertexShader,
kFragmentShader,
kTessellationControlShader,
kTessellationEvaluationShader,
kComputeShader,
};

enum class TargetPlatform {
Expand All @@ -31,6 +34,10 @@ enum class TargetPlatform {
kOpenGLDesktop,
};

bool TargetPlatformIsMetal(TargetPlatform platform);

bool TargetPlatformIsOpenGL(TargetPlatform platform);

SourceType SourceTypeFromFileName(const std::string& file_name);

std::string SourceTypeToString(SourceType type);
Expand Down
3 changes: 3 additions & 0 deletions impeller/fixtures/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ test_fixtures("file_fixtures") {
"embarcadero.jpg",
"kalimba.jpg",
"sample.vert",
"sample.tesc",
"sample.tese",
"sample.comp",
"struct_def_bug.vert",
"table_mountain_nx.png",
"table_mountain_ny.png",
Expand Down
5 changes: 5 additions & 0 deletions impeller/fixtures/sample.comp
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
layout (local_size_x = 16, local_size_y = 16) in;

void main(void) {
// Do nothing.
}
5 changes: 5 additions & 0 deletions impeller/fixtures/sample.tesc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
layout(vertices = 4) out;

void main() {
gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
}
14 changes: 14 additions & 0 deletions impeller/fixtures/sample.tese
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
layout (quads, equal_spacing, ccw) in;

void main() {
float u = gl_TessCoord.x;
float omu = 1 - u;
float v = gl_TessCoord.y;
float omv = 1 - v;

gl_Position =
omu * omv * gl_in[0].gl_Position +
u * omv * gl_in[1].gl_Position +
u * v * gl_in[2].gl_Position +
omu * v * gl_in[3].gl_Position;
}
9 changes: 9 additions & 0 deletions impeller/renderer/backend/gles/pipeline_library_gles.cc
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,15 @@ static void LogShaderCompilationFailure(const ProcTableGLES& gl,
case ShaderStage::kFragment:
stream << "fragment";
break;
case ShaderStage::kTessellationControl:
stream << "tessellation control";
break;
case ShaderStage::kTessellationEvaluation:
stream << "tessellation evaluation";
break;
case ShaderStage::kCompute:
stream << "compute";
break;
}
stream << " shader for '" << name << "' with error:" << std::endl;
stream << GetShaderInfoLog(gl, shader) << std::endl;
Expand Down
9 changes: 9 additions & 0 deletions impeller/renderer/backend/gles/shader_library_gles.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@ static std::string GLESShaderNameToShaderKeyName(const std::string& name,
case ShaderStage::kFragment:
stream << "_fragment_";
break;
case ShaderStage::kTessellationControl:
stream << "_tessellation_control_";
break;
case ShaderStage::kTessellationEvaluation:
stream << "_tessellation_evaluation_";
break;
case ShaderStage::kCompute:
stream << "_compute_";
break;
}
stream << "main";
return stream.str();
Expand Down
9 changes: 9 additions & 0 deletions impeller/renderer/command.cc
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ bool Command::BindResource(ShaderStage stage,
case ShaderStage::kFragment:
fragment_bindings.buffers[slot.binding] = {&metadata, view};
return true;
case ShaderStage::kTessellationControl:
case ShaderStage::kTessellationEvaluation:
case ShaderStage::kCompute:
case ShaderStage::kUnknown:
return false;
}
Expand All @@ -74,6 +77,9 @@ bool Command::BindResource(ShaderStage stage,
case ShaderStage::kFragment:
fragment_bindings.textures[slot.texture_index] = {&metadata, texture};
return true;
case ShaderStage::kTessellationControl:
case ShaderStage::kTessellationEvaluation:
case ShaderStage::kCompute:
case ShaderStage::kUnknown:
return false;
}
Expand Down Expand Up @@ -101,6 +107,9 @@ bool Command::BindResource(ShaderStage stage,
fragment_bindings.samplers[slot.sampler_index] = {&metadata, sampler};
return true;
case ShaderStage::kUnknown:
case ShaderStage::kTessellationControl:
case ShaderStage::kTessellationEvaluation:
case ShaderStage::kCompute:
return false;
}

Expand Down
3 changes: 3 additions & 0 deletions impeller/renderer/shader_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ enum class ShaderStage {
kUnknown,
kVertex,
kFragment,
kTessellationControl,
kTessellationEvaluation,
kCompute,
};

enum class ShaderType {
Expand Down