12 #include "flutter/fml/file.h"
13 #include "fml/command_line.h"
43 const std::string optional_prefix =
"[optional] ";
44 const std::string optional_multiple_prefix =
"[optional,multiple] ";
48 stream <<
"ImpellerC is an offline shader processor and reflection engine."
50 stream <<
"---------------------------------------------------------------"
52 stream <<
"Expected invocation is:" << std::endl << std::endl;
53 stream <<
"./impellerc <One platform or multiple runtime stages> "
54 "--input=<source_file> --sl=<sl_output_file> <optional arguments>"
58 stream <<
"Valid platforms are:" << std::endl << std::endl;
61 stream <<
" --" << platform.first;
63 stream <<
" ]" << std::endl << std::endl;
65 stream <<
"Valid runtime stages are:" << std::endl << std::endl;
66 stream <<
"At least one of [";
68 stream <<
" --" << platform.first;
70 stream <<
" ]" << std::endl << std::endl;
72 stream <<
"Optional arguments:" << std::endl << std::endl;
73 stream << optional_prefix
74 <<
"--spirv=<spirv_output_file> (ignored for --shader-bundle)"
76 stream << optional_prefix <<
"--input-type={";
78 stream << source_type.first <<
", ";
80 stream <<
"}" << std::endl;
81 stream << optional_prefix <<
"--source-language=glsl|hlsl (default: glsl)"
83 stream << optional_prefix
84 <<
"--entry-point=<entry_point_name> (default: main; "
87 stream << optional_prefix
88 <<
"--iplr (causes --sl file to be emitted in "
91 stream << optional_prefix
92 <<
"--shader-bundle=<bundle_spec> (causes --sl "
94 "emitted in Flutter GPU's shader bundle format)"
96 stream << optional_prefix <<
"--reflection-json=<reflection_json_file>"
98 stream << optional_prefix <<
"--reflection-header=<reflection_header_file>"
100 stream << optional_prefix <<
"--reflection-cc=<reflection_cc_file>"
102 stream << optional_multiple_prefix <<
"--include=<include_directory>"
104 stream << optional_multiple_prefix <<
"--define=<define>" << std::endl;
105 stream << optional_prefix <<
"--depfile=<depfile_path>" << std::endl;
106 stream << optional_prefix <<
"--gles-language-version=<number>" << std::endl;
107 stream << optional_prefix <<
"--json" << std::endl;
108 stream << optional_prefix
109 <<
"--use-half-textures (force openGL semantics when "
112 stream << optional_prefix <<
"--require-framebuffer-fetch" << std::endl;
120 const fml::CommandLine& command_line) {
123 if (command_line.HasOption(platform.first)) {
130 target = platform.second;
138 const fml::CommandLine& command_line) {
139 std::vector<TargetPlatform> stages;
141 if (command_line.HasOption(platform.first)) {
142 stages.push_back(platform.second);
149 const fml::CommandLine& command_line) {
150 auto source_type_option =
151 command_line.GetOptionValueWithDefault(
"input-type",
"");
156 return source_type_search->second;
160 : working_directory(
std::make_shared<fml::UniqueFD>(fml::OpenDirectory(
163 fml::FilePermission::kRead))),
164 source_file_name(command_line.GetOptionValueWithDefault(
"input",
"")),
166 sl_file_name(command_line.GetOptionValueWithDefault(
"sl",
"")),
167 iplr(command_line.HasOption(
"iplr")),
169 command_line.GetOptionValueWithDefault(
"shader-bundle",
"")),
170 spirv_file_name(command_line.GetOptionValueWithDefault(
"spirv",
"")),
171 reflection_json_name(
172 command_line.GetOptionValueWithDefault(
"reflection-json",
"")),
173 reflection_header_name(
174 command_line.GetOptionValueWithDefault(
"reflection-header",
"")),
176 command_line.GetOptionValueWithDefault(
"reflection-cc",
"")),
177 depfile_path(command_line.GetOptionValueWithDefault(
"depfile",
"")),
178 json_format(command_line.HasOption(
"json")),
179 gles_language_version(
180 stoi(command_line.GetOptionValueWithDefault(
"gles-language-version",
183 command_line.GetOptionValueWithDefault(
"metal-version",
"1.2")),
185 command_line.GetOptionValueWithDefault(
"entry-point",
"main")),
186 use_half_textures(command_line.HasOption(
"use-half-textures")),
187 require_framebuffer_fetch(
188 command_line.HasOption(
"require-framebuffer-fetch")),
192 command_line.GetOptionValueWithDefault(
"source-language",
"glsl"));
200 for (
const auto& include_dir_path : command_line.GetOptionValues(
"include")) {
201 if (!include_dir_path.data()) {
212 std::filesystem::path include_dir_absolute;
213 if (std::filesystem::path(include_dir_path).is_absolute()) {
214 include_dir_absolute = std::filesystem::path(include_dir_path);
216 auto cwd =
Utf8FromPath(std::filesystem::current_path());
217 include_dir_absolute = std::filesystem::absolute(
218 std::filesystem::path(cwd) / include_dir_path);
221 auto dir = std::make_shared<fml::UniqueFD>(fml::OpenDirectoryReadOnly(
223 if (!dir || !dir->is_valid()) {
228 dir_entry.
name = include_dir_path;
229 dir_entry.
dir = std::move(dir);
234 for (
const auto& define : command_line.GetOptionValues(
"define")) {
248 !shader_bundle_mode) {
249 explain <<
"Either a target platform was not specified, or no runtime "
250 "stages were specified."
256 explain <<
"Invalid source language type." << std::endl;
261 explain <<
"Could not open the working directory: \""
262 <<
Utf8FromPath(std::filesystem::current_path()).c_str() <<
"\""
268 explain <<
"Input file name was empty." << std::endl;
273 explain <<
"Target shading language file name was empty." << std::endl;
278 explain <<
"Spirv file name was empty." << std::endl;
282 if (
iplr && shader_bundle_mode) {
283 explain <<
"--iplr and --shader-bundle flag cannot be specified at the "
294 return runtime_stages_;
296 return {target_platform_};
301 !runtime_stages_.empty()) {
302 return runtime_stages_.front();
304 return target_platform_;
308 std::optional<TargetPlatform> target_platform)
const {