Skip to content

Commit

Permalink
Adds --sksl target to impellerc (flutter#131)
Browse files Browse the repository at this point in the history
  • Loading branch information
zanderso authored and dnfield committed Apr 27, 2022
1 parent ca3cd7f commit f1c1b68
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 42 deletions.
49 changes: 43 additions & 6 deletions impeller/compiler/compiler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ CompilerTargetPlatformToCompilerMSLTargetPlatform(
return spirv_cross::CompilerMSL::Options::Platform::iOS;
case Compiler::TargetPlatform::kMacOS:
// Unknown should not happen due to prior validation.
case Compiler::TargetPlatform::kFlutterSPIRV:
case Compiler::TargetPlatform::kUnknown:
return spirv_cross::CompilerMSL::Options::Platform::macOS;
}
Expand Down Expand Up @@ -239,18 +240,29 @@ Compiler::Compiler(const fml::Mapping& source_mapping,
// will be processed later by backend specific compilers. So optimizations
// here are irrelevant and get in the way of generating reflection code.
options.SetGenerateDebugInfo();
options.SetOptimizationLevel(
shaderc_optimization_level::shaderc_optimization_level_zero);

// Expects GLSL 4.60 (Core Profile).
// https://www.khronos.org/registry/OpenGL/specs/gl/GLSLangSpec.4.60.pdf
options.SetSourceLanguage(
shaderc_source_language::shaderc_source_language_glsl);
options.SetForcedVersionProfile(460, shaderc_profile::shaderc_profile_core);
options.SetTargetEnvironment(
shaderc_target_env::shaderc_target_env_vulkan,
shaderc_env_version::shaderc_env_version_vulkan_1_1);
options.SetTargetSpirv(shaderc_spirv_version::shaderc_spirv_version_1_3);
if (source_options.target_platform == TargetPlatform::kFlutterSPIRV) {
options.SetOptimizationLevel(
shaderc_optimization_level::shaderc_optimization_level_size);
options.SetTargetEnvironment(
shaderc_target_env::shaderc_target_env_opengl,
shaderc_env_version::shaderc_env_version_opengl_4_5
);
options.SetTargetSpirv(shaderc_spirv_version::shaderc_spirv_version_1_0);
} else {
options.SetOptimizationLevel(
shaderc_optimization_level::shaderc_optimization_level_zero);
options.SetTargetEnvironment(
shaderc_target_env::shaderc_target_env_vulkan,
shaderc_env_version::shaderc_env_version_vulkan_1_1
);
options.SetTargetSpirv(shaderc_spirv_version::shaderc_spirv_version_1_3);
}

options.SetAutoBindUniforms(true);
options.SetAutoMapLocations(true);
Expand Down Expand Up @@ -295,6 +307,11 @@ Compiler::Compiler(const fml::Mapping& source_mapping,
included_file_names_ = std::move(included_file_names);
}

if (!TargetPlatformNeedsMSL(source_options.target_platform)) {
is_valid_ = true;
return;
}

// MSL Generation.
spirv_cross::Parser parser(spv_result_->cbegin(),
spv_result_->cend() - spv_result_->cbegin());
Expand Down Expand Up @@ -418,6 +435,26 @@ std::string Compiler::EntryPointFromSourceName(const std::string& file_name,
return stream.str();
}

bool Compiler::TargetPlatformNeedsMSL(TargetPlatform platform) {
switch (platform) {
case TargetPlatform::kIPhoneOS:
case TargetPlatform::kMacOS:
return true;
default:
return false;
}
}

bool Compiler::TargetPlatformNeedsReflection(TargetPlatform platform) {
switch (platform) {
case TargetPlatform::kIPhoneOS:
case TargetPlatform::kMacOS:
return true;
default:
return false;
}
}

std::string Compiler::GetSourcePrefix() const {
std::stringstream stream;
stream << options_.file_name << ": ";
Expand Down
5 changes: 5 additions & 0 deletions impeller/compiler/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,18 @@ class Compiler {
kUnknown,
kMacOS,
kIPhoneOS,
kFlutterSPIRV,
};

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

static std::string EntryPointFromSourceName(const std::string& file_name,
SourceType type);

static bool TargetPlatformNeedsMSL(TargetPlatform platform);

static bool TargetPlatformNeedsReflection(TargetPlatform platform);

struct SourceOptions {
SourceType type = SourceType::kUnknown;
TargetPlatform target_platform = TargetPlatform::kUnknown;
Expand Down
13 changes: 10 additions & 3 deletions impeller/compiler/compiler_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,15 @@ class CompilerTest : public ::testing::Test {

~CompilerTest() = default;

bool CanCompileFixture(const char* fixture_name) const {
bool CanCompileFixture(const char* fixture_name,
Compiler::TargetPlatform target_platform) const {
auto fixture = flutter::testing::OpenFixtureAsMapping(fixture_name);
if (!fixture->GetMapping()) {
VALIDATION_LOG << "Could not find shader in fixtures: " << fixture_name;
return false;
}
Compiler::SourceOptions compiler_options(fixture_name);
compiler_options.target_platform = Compiler::TargetPlatform::kMacOS;
compiler_options.target_platform = target_platform;
compiler_options.working_directory = std::make_shared<fml::UniqueFD>(
flutter::testing::OpenFixturesDirectory());
Reflector::Options reflector_options;
Expand Down Expand Up @@ -60,7 +61,13 @@ TEST_F(CompilerTest, ShaderKindMatchingIsSuccessful) {
}

TEST_F(CompilerTest, CanCompileSample) {
ASSERT_TRUE(CanCompileFixture("sample.vert"));
ASSERT_TRUE(CanCompileFixture(
"sample.vert", Compiler::TargetPlatform::kMacOS));
}

TEST_F(CompilerTest, CanTargetFlutterSPIRV) {
ASSERT_TRUE(CanCompileFixture(
"test_texture.frag", Compiler::TargetPlatform::kFlutterSPIRV));
}

} // namespace testing
Expand Down
76 changes: 46 additions & 30 deletions impeller/compiler/impellerc_main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -69,49 +69,65 @@ bool Main(const fml::CommandLine& command_line) {
return false;
}

if (!fml::WriteAtomically(*switches.working_directory,
switches.metal_file_name.c_str(),
*compiler.GetMSLShaderSource())) {
std::cerr << "Could not write file to " << switches.spirv_file_name
<< std::endl;
return false;
}

if (!switches.reflection_json_name.empty()) {
if (Compiler::TargetPlatformNeedsMSL(options.target_platform)) {
if (!fml::WriteAtomically(*switches.working_directory,
switches.reflection_json_name.c_str(),
*compiler.GetReflector()->GetReflectionJSON())) {
std::cerr << "Could not write reflection json to "
<< switches.reflection_json_name << std::endl;
switches.metal_file_name.c_str(),
*compiler.GetMSLShaderSource())) {
std::cerr << "Could not write file to " << switches.spirv_file_name
<< std::endl;
return false;
}
}

if (!switches.reflection_header_name.empty()) {
if (!fml::WriteAtomically(
*switches.working_directory,
switches.reflection_header_name.c_str(),
*compiler.GetReflector()->GetReflectionHeader())) {
std::cerr << "Could not write reflection header to "
<< switches.reflection_header_name << std::endl;
return false;

if (Compiler::TargetPlatformNeedsReflection(options.target_platform)) {
if (!switches.reflection_json_name.empty()) {
if (!fml::WriteAtomically(*switches.working_directory,
switches.reflection_json_name.c_str(),
*compiler.GetReflector()->GetReflectionJSON())) {
std::cerr << "Could not write reflection json to "
<< switches.reflection_json_name << std::endl;
return false;
}
}
}

if (!switches.reflection_cc_name.empty()) {
if (!fml::WriteAtomically(*switches.working_directory,
switches.reflection_cc_name.c_str(),
*compiler.GetReflector()->GetReflectionCC())) {
std::cerr << "Could not write reflection CC to "
<< switches.reflection_cc_name << std::endl;
return false;
if (!switches.reflection_header_name.empty()) {
if (!fml::WriteAtomically(
*switches.working_directory,
switches.reflection_header_name.c_str(),
*compiler.GetReflector()->GetReflectionHeader())) {
std::cerr << "Could not write reflection header to "
<< switches.reflection_header_name << std::endl;
return false;
}
}

if (!switches.reflection_cc_name.empty()) {
if (!fml::WriteAtomically(*switches.working_directory,
switches.reflection_cc_name.c_str(),
*compiler.GetReflector()->GetReflectionCC())) {
std::cerr << "Could not write reflection CC to "
<< switches.reflection_cc_name << std::endl;
return false;
}
}
}

if (!switches.depfile_path.empty()) {
std::string result_file;
switch (switches.target_platform) {
case Compiler::TargetPlatform::kMacOS:
case Compiler::TargetPlatform::kIPhoneOS:
result_file = switches.metal_file_name;
break;
case Compiler::TargetPlatform::kFlutterSPIRV:
case Compiler::TargetPlatform::kUnknown:
result_file = switches.spirv_file_name;
break;
}
if (!fml::WriteAtomically(
*switches.working_directory, switches.depfile_path.c_str(),
*compiler.CreateDepfileContents({switches.metal_file_name}))) {
*compiler.CreateDepfileContents({result_file}))) {
std::cerr << "Could not write depfile to " << switches.depfile_path
<< std::endl;
return false;
Expand Down
3 changes: 2 additions & 1 deletion impeller/compiler/switches.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ namespace compiler {
static const std::map<std::string, Compiler::TargetPlatform> kKnownPlatforms = {
{"macos", Compiler::TargetPlatform::kMacOS},
{"ios", Compiler::TargetPlatform::kIPhoneOS},
{"flutter-spirv", Compiler::TargetPlatform::kFlutterSPIRV},
};

void Switches::PrintHelp(std::ostream& stream) {
Expand Down Expand Up @@ -112,7 +113,7 @@ bool Switches::AreValid(std::ostream& explain) const {
valid = false;
}

if (metal_file_name.empty()) {
if (metal_file_name.empty() && Compiler::TargetPlatformNeedsMSL(target_platform)) {
explain << "Metal file name was empty." << std::endl;
valid = false;
}
Expand Down
5 changes: 3 additions & 2 deletions impeller/fixtures/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,14 @@ impeller_shaders("shader_fixtures") {

test_fixtures("file_fixtures") {
fixtures = [
"sample.vert",
"types.h",
"airplane.jpg",
"bay_bridge.jpg",
"boston.jpg",
"embarcadero.jpg",
"kalimba.jpg",
"sample.vert",
"types.h",
"test_texture.frag",
"//flutter/third_party/txt/third_party/fonts/Roboto-Regular.ttf",
"//flutter/third_party/txt/third_party/fonts/NotoColorEmoji.ttf",
"//flutter/third_party/txt/third_party/fonts/HomemadeApple.ttf",
Expand Down

0 comments on commit f1c1b68

Please sign in to comment.