1 | // Copyright 2013 The Flutter Authors. All rights reserved. |
---|---|
2 | // Use of this source code is governed by a BSD-style license that can be |
3 | // found in the LICENSE file. |
4 | |
5 | #include "impeller/compiler/types.h" |
6 | |
7 | #include <filesystem> |
8 | #include <sstream> |
9 | |
10 | #include "flutter/fml/logging.h" |
11 | #include "impeller/compiler/utilities.h" |
12 | |
13 | namespace impeller { |
14 | namespace compiler { |
15 | |
16 | static bool StringEndWith(const std::string& string, |
17 | const std::string& suffix) { |
18 | if (suffix.size() > string.size()) { |
19 | return false; |
20 | } |
21 | |
22 | if (suffix.empty() || suffix.empty()) { |
23 | return false; |
24 | } |
25 | |
26 | return string.rfind(str: suffix) == (string.size() - suffix.size()); |
27 | } |
28 | |
29 | SourceType SourceTypeFromFileName(const std::string& file_name) { |
30 | if (StringEndWith(string: file_name, suffix: ".vert")) { |
31 | return SourceType::kVertexShader; |
32 | } |
33 | |
34 | if (StringEndWith(string: file_name, suffix: ".frag")) { |
35 | return SourceType::kFragmentShader; |
36 | } |
37 | |
38 | if (StringEndWith(string: file_name, suffix: ".tesc")) { |
39 | return SourceType::kTessellationControlShader; |
40 | } |
41 | |
42 | if (StringEndWith(string: file_name, suffix: ".tese")) { |
43 | return SourceType::kTessellationEvaluationShader; |
44 | } |
45 | |
46 | if (StringEndWith(string: file_name, suffix: ".comp")) { |
47 | return SourceType::kComputeShader; |
48 | } |
49 | |
50 | return SourceType::kUnknown; |
51 | } |
52 | |
53 | std::string TargetPlatformToString(TargetPlatform platform) { |
54 | switch (platform) { |
55 | case TargetPlatform::kUnknown: |
56 | return "Unknown"; |
57 | case TargetPlatform::kMetalDesktop: |
58 | return "MetalDesktop"; |
59 | case TargetPlatform::kMetalIOS: |
60 | return "MetaliOS"; |
61 | case TargetPlatform::kOpenGLES: |
62 | return "OpenGLES"; |
63 | case TargetPlatform::kOpenGLDesktop: |
64 | return "OpenGLDesktop"; |
65 | case TargetPlatform::kVulkan: |
66 | return "Vulkan"; |
67 | case TargetPlatform::kRuntimeStageMetal: |
68 | return "RuntimeStageMetal"; |
69 | case TargetPlatform::kRuntimeStageGLES: |
70 | return "RuntimeStageGLES"; |
71 | case TargetPlatform::kRuntimeStageVulkan: |
72 | return "RuntimeStageVulkan"; |
73 | case TargetPlatform::kSkSL: |
74 | return "SkSL"; |
75 | } |
76 | FML_UNREACHABLE(); |
77 | } |
78 | |
79 | std::string SourceLanguageToString(SourceLanguage source_language) { |
80 | switch (source_language) { |
81 | case SourceLanguage::kUnknown: |
82 | return "Unknown"; |
83 | case SourceLanguage::kGLSL: |
84 | return "GLSL"; |
85 | case SourceLanguage::kHLSL: |
86 | return "HLSL"; |
87 | } |
88 | } |
89 | |
90 | std::string EntryPointFunctionNameFromSourceName( |
91 | const std::string& file_name, |
92 | SourceType type, |
93 | SourceLanguage source_language, |
94 | const std::string& entry_point_name) { |
95 | if (source_language == SourceLanguage::kHLSL) { |
96 | return entry_point_name; |
97 | } |
98 | |
99 | std::stringstream stream; |
100 | std::filesystem::path file_path(file_name); |
101 | stream << ConvertToEntrypointName(string: Utf8FromPath(path: file_path.stem())) << "_"; |
102 | switch (type) { |
103 | case SourceType::kUnknown: |
104 | stream << "unknown"; |
105 | break; |
106 | case SourceType::kVertexShader: |
107 | stream << "vertex"; |
108 | break; |
109 | case SourceType::kFragmentShader: |
110 | stream << "fragment"; |
111 | break; |
112 | case SourceType::kTessellationControlShader: |
113 | stream << "tess_control"; |
114 | break; |
115 | case SourceType::kTessellationEvaluationShader: |
116 | stream << "tess_eval"; |
117 | break; |
118 | case SourceType::kComputeShader: |
119 | stream << "compute"; |
120 | break; |
121 | } |
122 | stream << "_main"; |
123 | return stream.str(); |
124 | } |
125 | |
126 | bool TargetPlatformNeedsReflection(TargetPlatform platform) { |
127 | switch (platform) { |
128 | case TargetPlatform::kMetalIOS: |
129 | case TargetPlatform::kMetalDesktop: |
130 | case TargetPlatform::kOpenGLES: |
131 | case TargetPlatform::kOpenGLDesktop: |
132 | case TargetPlatform::kRuntimeStageMetal: |
133 | case TargetPlatform::kRuntimeStageGLES: |
134 | case TargetPlatform::kRuntimeStageVulkan: |
135 | case TargetPlatform::kVulkan: |
136 | return true; |
137 | case TargetPlatform::kUnknown: |
138 | case TargetPlatform::kSkSL: |
139 | return false; |
140 | } |
141 | FML_UNREACHABLE(); |
142 | } |
143 | |
144 | std::string ShaderCErrorToString(shaderc_compilation_status status) { |
145 | using Status = shaderc_compilation_status; |
146 | switch (status) { |
147 | case Status::shaderc_compilation_status_success: |
148 | return "Success"; |
149 | case Status::shaderc_compilation_status_invalid_stage: |
150 | return "Invalid shader stage specified"; |
151 | case Status::shaderc_compilation_status_compilation_error: |
152 | return "Compilation error"; |
153 | case Status::shaderc_compilation_status_internal_error: |
154 | return "Internal error"; |
155 | case Status::shaderc_compilation_status_null_result_object: |
156 | return "Internal error. Null result object"; |
157 | case Status::shaderc_compilation_status_invalid_assembly: |
158 | return "Invalid assembly"; |
159 | case Status::shaderc_compilation_status_validation_error: |
160 | return "Validation error"; |
161 | case Status::shaderc_compilation_status_transformation_error: |
162 | return "Transformation error"; |
163 | case Status::shaderc_compilation_status_configuration_error: |
164 | return "Configuration error"; |
165 | } |
166 | return "Unknown internal error"; |
167 | } |
168 | |
169 | shaderc_shader_kind ToShaderCShaderKind(SourceType type) { |
170 | switch (type) { |
171 | case SourceType::kVertexShader: |
172 | return shaderc_shader_kind::shaderc_vertex_shader; |
173 | case SourceType::kFragmentShader: |
174 | return shaderc_shader_kind::shaderc_fragment_shader; |
175 | case SourceType::kTessellationControlShader: |
176 | return shaderc_shader_kind::shaderc_tess_control_shader; |
177 | case SourceType::kTessellationEvaluationShader: |
178 | return shaderc_shader_kind::shaderc_tess_evaluation_shader; |
179 | case SourceType::kComputeShader: |
180 | return shaderc_shader_kind::shaderc_compute_shader; |
181 | case SourceType::kUnknown: |
182 | break; |
183 | } |
184 | return shaderc_shader_kind::shaderc_glsl_infer_from_source; |
185 | } |
186 | |
187 | spv::ExecutionModel ToExecutionModel(SourceType type) { |
188 | switch (type) { |
189 | case SourceType::kVertexShader: |
190 | return spv::ExecutionModel::ExecutionModelVertex; |
191 | case SourceType::kFragmentShader: |
192 | return spv::ExecutionModel::ExecutionModelFragment; |
193 | case SourceType::kTessellationControlShader: |
194 | return spv::ExecutionModel::ExecutionModelTessellationControl; |
195 | case SourceType::kTessellationEvaluationShader: |
196 | return spv::ExecutionModel::ExecutionModelTessellationEvaluation; |
197 | case SourceType::kComputeShader: |
198 | return spv::ExecutionModel::ExecutionModelGLCompute; |
199 | case SourceType::kUnknown: |
200 | break; |
201 | } |
202 | return spv::ExecutionModel::ExecutionModelMax; |
203 | } |
204 | |
205 | spirv_cross::CompilerMSL::Options::Platform TargetPlatformToMSLPlatform( |
206 | TargetPlatform platform) { |
207 | switch (platform) { |
208 | case TargetPlatform::kMetalIOS: |
209 | case TargetPlatform::kRuntimeStageMetal: |
210 | return spirv_cross::CompilerMSL::Options::Platform::iOS; |
211 | case TargetPlatform::kMetalDesktop: |
212 | return spirv_cross::CompilerMSL::Options::Platform::macOS; |
213 | case TargetPlatform::kSkSL: |
214 | case TargetPlatform::kOpenGLES: |
215 | case TargetPlatform::kOpenGLDesktop: |
216 | case TargetPlatform::kRuntimeStageGLES: |
217 | case TargetPlatform::kRuntimeStageVulkan: |
218 | case TargetPlatform::kVulkan: |
219 | case TargetPlatform::kUnknown: |
220 | return spirv_cross::CompilerMSL::Options::Platform::macOS; |
221 | } |
222 | FML_UNREACHABLE(); |
223 | } |
224 | |
225 | std::string SourceTypeToString(SourceType type) { |
226 | switch (type) { |
227 | case SourceType::kUnknown: |
228 | return "unknown"; |
229 | case SourceType::kVertexShader: |
230 | return "vert"; |
231 | case SourceType::kFragmentShader: |
232 | return "frag"; |
233 | case SourceType::kTessellationControlShader: |
234 | return "tesc"; |
235 | case SourceType::kTessellationEvaluationShader: |
236 | return "tese"; |
237 | case SourceType::kComputeShader: |
238 | return "comp"; |
239 | } |
240 | FML_UNREACHABLE(); |
241 | } |
242 | |
243 | std::string TargetPlatformSLExtension(TargetPlatform platform) { |
244 | switch (platform) { |
245 | case TargetPlatform::kUnknown: |
246 | return "unknown"; |
247 | case TargetPlatform::kMetalDesktop: |
248 | case TargetPlatform::kMetalIOS: |
249 | case TargetPlatform::kRuntimeStageMetal: |
250 | return "metal"; |
251 | case TargetPlatform::kSkSL: |
252 | case TargetPlatform::kOpenGLES: |
253 | case TargetPlatform::kOpenGLDesktop: |
254 | case TargetPlatform::kRuntimeStageGLES: |
255 | return "glsl"; |
256 | case TargetPlatform::kVulkan: |
257 | case TargetPlatform::kRuntimeStageVulkan: |
258 | return "vk.spirv"; |
259 | } |
260 | FML_UNREACHABLE(); |
261 | } |
262 | |
263 | bool TargetPlatformIsOpenGL(TargetPlatform platform) { |
264 | switch (platform) { |
265 | case TargetPlatform::kOpenGLES: |
266 | case TargetPlatform::kOpenGLDesktop: |
267 | case TargetPlatform::kRuntimeStageGLES: |
268 | return true; |
269 | case TargetPlatform::kMetalDesktop: |
270 | case TargetPlatform::kRuntimeStageMetal: |
271 | case TargetPlatform::kRuntimeStageVulkan: |
272 | case TargetPlatform::kMetalIOS: |
273 | case TargetPlatform::kUnknown: |
274 | case TargetPlatform::kSkSL: |
275 | case TargetPlatform::kVulkan: |
276 | return false; |
277 | } |
278 | FML_UNREACHABLE(); |
279 | } |
280 | |
281 | bool TargetPlatformIsMetal(TargetPlatform platform) { |
282 | switch (platform) { |
283 | case TargetPlatform::kMetalDesktop: |
284 | case TargetPlatform::kMetalIOS: |
285 | case TargetPlatform::kRuntimeStageMetal: |
286 | return true; |
287 | case TargetPlatform::kUnknown: |
288 | case TargetPlatform::kSkSL: |
289 | case TargetPlatform::kOpenGLES: |
290 | case TargetPlatform::kOpenGLDesktop: |
291 | case TargetPlatform::kRuntimeStageGLES: |
292 | case TargetPlatform::kRuntimeStageVulkan: |
293 | case TargetPlatform::kVulkan: |
294 | return false; |
295 | } |
296 | FML_UNREACHABLE(); |
297 | } |
298 | |
299 | bool TargetPlatformIsVulkan(TargetPlatform platform) { |
300 | switch (platform) { |
301 | case TargetPlatform::kRuntimeStageVulkan: |
302 | case TargetPlatform::kVulkan: |
303 | return true; |
304 | case TargetPlatform::kMetalDesktop: |
305 | case TargetPlatform::kMetalIOS: |
306 | case TargetPlatform::kRuntimeStageMetal: |
307 | case TargetPlatform::kUnknown: |
308 | case TargetPlatform::kSkSL: |
309 | case TargetPlatform::kOpenGLES: |
310 | case TargetPlatform::kOpenGLDesktop: |
311 | case TargetPlatform::kRuntimeStageGLES: |
312 | return false; |
313 | } |
314 | FML_UNREACHABLE(); |
315 | } |
316 | |
317 | bool TargetPlatformBundlesSkSL(TargetPlatform platform) { |
318 | switch (platform) { |
319 | case TargetPlatform::kSkSL: |
320 | case TargetPlatform::kRuntimeStageMetal: |
321 | case TargetPlatform::kRuntimeStageGLES: |
322 | case TargetPlatform::kRuntimeStageVulkan: |
323 | return true; |
324 | case TargetPlatform::kMetalDesktop: |
325 | case TargetPlatform::kMetalIOS: |
326 | case TargetPlatform::kUnknown: |
327 | case TargetPlatform::kOpenGLES: |
328 | case TargetPlatform::kOpenGLDesktop: |
329 | case TargetPlatform::kVulkan: |
330 | return false; |
331 | } |
332 | FML_UNREACHABLE(); |
333 | } |
334 | |
335 | } // namespace compiler |
336 | } // namespace impeller |
337 |
Definitions
- StringEndWith
- SourceTypeFromFileName
- TargetPlatformToString
- SourceLanguageToString
- EntryPointFunctionNameFromSourceName
- TargetPlatformNeedsReflection
- ShaderCErrorToString
- ToShaderCShaderKind
- ToExecutionModel
- TargetPlatformToMSLPlatform
- SourceTypeToString
- TargetPlatformSLExtension
- TargetPlatformIsOpenGL
- TargetPlatformIsMetal
- TargetPlatformIsVulkan
Learn more about Flutter for embedded and desktop on industrialflutter.com