| Flutter Impeller |

Public Member Functions | List of all members
impeller::compiler::Compiler Class Reference

`#include <compiler.h>`

## Public Member Functions
| Compiler (const std::shared_ptr< const fml::Mapping > &source_mapping, const SourceOptions &options, Reflector::Options reflector_options)
| ~Compiler ()
bool | IsValid () const
std::shared_ptr< fml::Mapping > | GetSPIRVAssembly () const
std::shared_ptr< fml::Mapping > | GetSLShaderSource () const
std::string | GetErrorMessages () const
const std::vector< std::string > & | GetIncludedFileNames () const
std::unique_ptr< fml::Mapping > | CreateDepfileContents (std::initializer_list< std::string > targets) const
const Reflector * | GetReflector () const

## Detailed Description

Definition at line 24 of file compiler.h.

## Constructor & Destructor Documentation

## ◆ Compiler()

impeller::compiler::Compiler::Compiler | ( | const std::shared_ptr< const fml::Mapping > & | source_mapping,
|  | const SourceOptions & | options,
|  | Reflector::Options | reflector_options
| ) |  |

Definition at line 260 of file compiler.cc.

263 : options_(source_options) {
264 if (!source_mapping || source_mapping->GetMapping() == nullptr) {
265 COMPILER_ERROR(error_stream_)
266 << "Could not read shader source or shader source was empty.";
267 return;
268 }
269
270 if (source_options.target_platform == TargetPlatform::kUnknown) {
271 COMPILER_ERROR(error_stream_) << "Target platform not specified.";
272 return;
273 }
274
275 SPIRVCompilerOptions spirv_options;
276
277 // Make sure reflection is as effective as possible. The generated shaders
278 // will be processed later by backend specific compilers.
279 spirv_options.generate_debug_info = true;
280
281 switch (options_.source_language) {
282 case SourceLanguage::kGLSL:
283 // Expects GLSL 4.60 (Core Profile).
284 // https://www.khronos.org/registry/OpenGL/specs/gl/GLSLangSpec.4.60.pdf
285 spirv_options.source_langauge =
286 shaderc_source_language::shaderc_source_language_glsl;
287 spirv_options.source_profile = SPIRVCompilerSourceProfile{
288 shaderc_profile::shaderc_profile_core, //
289 460, //
290 };
291 break;
292 case SourceLanguage::kHLSL:
293 spirv_options.source_langauge =
294 shaderc_source_language::shaderc_source_language_hlsl;
295 break;
296 case SourceLanguage::kUnknown:
297 COMPILER_ERROR(error_stream_) << "Source language invalid.";
298 return;
299 }
300
301 switch (source_options.target_platform) {
302 case TargetPlatform::kMetalDesktop:
303 case TargetPlatform::kMetalIOS: {
304 SPIRVCompilerTargetEnv target;
305
306 if (source_options.use_half_textures) {
307 target.env = shaderc_target_env::shaderc_target_env_opengl;
308 target.version = shaderc_env_version::shaderc_env_version_opengl_4_5;
309 target.spirv_version = shaderc_spirv_version::shaderc_spirv_version_1_0;
310 } else {
311 target.env = shaderc_target_env::shaderc_target_env_vulkan;
312 target.version = shaderc_env_version::shaderc_env_version_vulkan_1_1;
313 target.spirv_version = shaderc_spirv_version::shaderc_spirv_version_1_3;
314 }
315
316 spirv_options.target = target;
317 } break;
318 case TargetPlatform::kOpenGLES:
319 case TargetPlatform::kOpenGLDesktop:
320 case TargetPlatform::kVulkan:
321 case TargetPlatform::kRuntimeStageVulkan: {
322 SPIRVCompilerTargetEnv target;
323
324 target.env = shaderc_target_env::shaderc_target_env_vulkan;
325 target.version = shaderc_env_version::shaderc_env_version_vulkan_1_1;
326 target.spirv_version = shaderc_spirv_version::shaderc_spirv_version_1_3;
327
328 if (source_options.target_platform ==
329 TargetPlatform::kRuntimeStageVulkan) {
330 spirv_options.macro_definitions.push_back("IMPELLER_GRAPHICS_BACKEND");
331 spirv_options.relaxed_vulkan_rules = true;
332 }
333 spirv_options.target = target;
334 } break;
335 case TargetPlatform::kRuntimeStageMetal:
336 case TargetPlatform::kRuntimeStageGLES:
337 case TargetPlatform::kRuntimeStageGLES3: {
338 SPIRVCompilerTargetEnv target;
339
340 target.env = shaderc_target_env::shaderc_target_env_opengl;
341 target.version = shaderc_env_version::shaderc_env_version_opengl_4_5;
342 target.spirv_version = shaderc_spirv_version::shaderc_spirv_version_1_0;
343
344 spirv_options.target = target;
345 spirv_options.macro_definitions.push_back("IMPELLER_GRAPHICS_BACKEND");
346 } break;
347 case TargetPlatform::kSkSL: {
348 SPIRVCompilerTargetEnv target;
349
350 target.env = shaderc_target_env::shaderc_target_env_opengl;
351 target.version = shaderc_env_version::shaderc_env_version_opengl_4_5;
352 target.spirv_version = shaderc_spirv_version::shaderc_spirv_version_1_0;
353
354 // When any optimization level above 'zero' is enabled, the phi merges at
355 // loop continue blocks are rendered using syntax that is supported in
356 // GLSL, but not in SkSL.
357 // https://bugs.chromium.org/p/skia/issues/detail?id=13518.
358 spirv_options.optimization_level =
359 shaderc_optimization_level::shaderc_optimization_level_zero;
360 spirv_options.target = target;
361 spirv_options.macro_definitions.push_back("SKIA_GRAPHICS_BACKEND");
362 } break;
363 case TargetPlatform::kUnknown:
364 COMPILER_ERROR(error_stream_) << "Target platform invalid.";
365 return;
366 }
367
368 // Implicit definition that indicates that this compilation is for the device
369 // (instead of the host).
370 spirv_options.macro_definitions.push_back("IMPELLER_DEVICE");
371 for (const auto& define : source_options.defines) {
372 spirv_options.macro_definitions.push_back(define);
373 }
374
375 std::vector<std::string> included_file_names;
376 spirv_options.includer = std::make_shared<Includer>(
377 options_.working_directory, options_.include_dirs,
378 [&included_file_names](auto included_name) {
379 included_file_names.emplace_back(std::move(included_name));
380 });
381
382 // SPIRV Generation.
383 SPIRVCompiler spv_compiler(source_options, source_mapping);
384
385 spirv_assembly_ = spv_compiler.CompileToSPV(
386 error_stream_, spirv_options.BuildShadercOptions());
387
388 if (!spirv_assembly_) {
389 return;
390 } else {
391 included_file_names_ = std::move(included_file_names);
392 }
393
394 // SL Generation.
395 spirv_cross::Parser parser(
396 reinterpret_cast<const uint32_t*>(spirv_assembly_->GetMapping()),
397 spirv_assembly_->GetSize() / sizeof(uint32_t));
398 // The parser and compiler must be run separately because the parser contains
399 // meta information (like type member names) that are useful for reflection.
400 parser.parse();
401
402 const auto parsed_ir =
403 std::make_shared<spirv_cross::ParsedIR>(parser.get_parsed_ir());
404
405 auto sl_compiler = CreateCompiler(*parsed_ir, options_);
406
407 if (!sl_compiler) {
408 COMPILER_ERROR(error_stream_)
409 << "Could not create compiler for target platform.";
410 return;
411 }
412
413 // We need to invoke the compiler even if we don't use the SL mapping later
414 // for Vulkan. The reflector needs information that is only valid after a
415 // successful compilation call.
416 auto sl_compilation_result =
417 CreateMappingWithString(sl_compiler.GetCompiler()->compile());
418
419 // If the target is Vulkan, our shading language is SPIRV which we already
420 // have. We just need to strip it of debug information. If it isn't, we need
421 // to invoke the appropriate compiler to compile the SPIRV to the target SL.
422 if (source_options.target_platform == TargetPlatform::kVulkan ||
423 source_options.target_platform == TargetPlatform::kRuntimeStageVulkan) {
424 auto stripped_spirv_options = spirv_options;
425 stripped_spirv_options.generate_debug_info = false;
426 sl_mapping_ = spv_compiler.CompileToSPV(
427 error_stream_, stripped_spirv_options.BuildShadercOptions());
428 } else {
429 sl_mapping_ = sl_compilation_result;
430 }
431
432 if (!sl_mapping_) {
433 COMPILER_ERROR(error_stream_) << "Could not generate SL from SPIRV";
434 return;
435 }
436
437 reflector_ = std::make_unique<Reflector>(std::move(reflector_options), //
438 parsed_ir, //
439 GetSLShaderSource(), //
440 sl_compiler //
441 );
442
443 if (!reflector_->IsValid()) {
444 COMPILER_ERROR(error_stream_)
445 << "Could not complete reflection on generated shader.";
446 return;
447 }
448
449 is_valid_ = true;
450 }
impeller::compiler::Compiler::GetSLShaderSource
std::shared_ptr< fml::Mapping > GetSLShaderSource() const
Definition: compiler.cc:458
COMPILER_ERROR
#define COMPILER_ERROR(stream)
Definition: logger.h:39
impeller::compiler::SourceLanguage::kUnknown
@ kUnknown
impeller::compiler::SourceLanguage::kGLSL
@ kGLSL
impeller::compiler::SourceLanguage::kHLSL
@ kHLSL
impeller::compiler::CreateCompiler
static CompilerBackend CreateCompiler(const spirv_cross::ParsedIR &ir, const SourceOptions &source_options)
Definition: compiler.cc:225
impeller::compiler::TargetPlatform::kRuntimeStageMetal
@ kRuntimeStageMetal
impeller::compiler::TargetPlatform::kOpenGLES
@ kOpenGLES
impeller::compiler::TargetPlatform::kUnknown
@ kUnknown
impeller::compiler::TargetPlatform::kRuntimeStageVulkan
@ kRuntimeStageVulkan
impeller::compiler::TargetPlatform::kRuntimeStageGLES3
@ kRuntimeStageGLES3
impeller::compiler::TargetPlatform::kVulkan
@ kVulkan
impeller::compiler::TargetPlatform::kMetalDesktop
@ kMetalDesktop
impeller::compiler::TargetPlatform::kMetalIOS
@ kMetalIOS
impeller::compiler::TargetPlatform::kSkSL
@ kSkSL
impeller::compiler::TargetPlatform::kOpenGLDesktop
@ kOpenGLDesktop
impeller::compiler::TargetPlatform::kRuntimeStageGLES
@ kRuntimeStageGLES
impeller::CreateMappingWithString
std::shared_ptr< fml::Mapping > CreateMappingWithString(std::string string)
Creates a mapping with string data.
Definition: allocation.cc:111
impeller::compiler::SourceOptions::source_language
SourceLanguage source_language
Definition: source_options.h:23
impeller::compiler::SourceOptions::include_dirs
std::vector< IncludeDir > include_dirs
Definition: source_options.h:25
impeller::compiler::SourceOptions::working_directory
std::shared_ptr< fml::UniqueFD > working_directory
Definition: source_options.h:24

References impeller::compiler::SPIRVCompilerOptions::BuildShadercOptions(), COMPILER_ERROR, impeller::compiler::SPIRVCompiler::CompileToSPV(), impeller::compiler::CreateCompiler(), impeller::CreateMappingWithString(), impeller::compiler::SourceOptions::defines, impeller::compiler::SPIRVCompilerTargetEnv::env, impeller::compiler::SPIRVCompilerOptions::generate_debug_info, GetSLShaderSource(), impeller::compiler::SourceOptions::include_dirs, impeller::compiler::SPIRVCompilerOptions::includer, impeller::compiler::kGLSL, impeller::compiler::kHLSL, impeller::compiler::kMetalDesktop, impeller::compiler::kMetalIOS, impeller::compiler::kOpenGLDesktop, impeller::compiler::kOpenGLES, impeller::compiler::kRuntimeStageGLES, impeller::compiler::kRuntimeStageGLES3, impeller::compiler::kRuntimeStageMetal, impeller::compiler::kRuntimeStageVulkan, impeller::compiler::kSkSL, impeller::compiler::kUnknown, impeller::compiler::kVulkan, impeller::compiler::SPIRVCompilerOptions::macro_definitions, impeller::compiler::SPIRVCompilerOptions::optimization_level, impeller::compiler::SPIRVCompilerOptions::relaxed_vulkan_rules, impeller::compiler::SPIRVCompilerOptions::source_langauge, impeller::compiler::SourceOptions::source_language, impeller::compiler::SPIRVCompilerOptions::source_profile, impeller::compiler::SPIRVCompilerTargetEnv::spirv_version, impeller::compiler::SPIRVCompilerOptions::target, impeller::compiler::SourceOptions::target_platform, impeller::compiler::SourceOptions::use_half_textures, impeller::compiler::SPIRVCompilerTargetEnv::version, and impeller::compiler::SourceOptions::working_directory.

## ◆ ~Compiler()

impeller::compiler::Compiler::~Compiler | ( |  | ) |
| default

## Member Function Documentation

## ◆ CreateDepfileContents()

std::unique_ptr< fml::Mapping > impeller::compiler::Compiler::CreateDepfileContents | ( | std::initializer_list< std::string > | targets | ) | const

Definition at line 500 of file compiler.cc.

501 {
502 // https://github.com/ninja-build/ninja/blob/master/src/depfile_parser.cc#L28
503 const auto targets = JoinStrings(targets_names, " ");
504 const auto dependencies = GetDependencyNames(" ");
505
506 std::stringstream stream;
507 stream << targets << ": " << dependencies << "\n";
508
509 auto contents = std::make_shared<std::string>(stream.str());
510 return std::make_unique<fml::NonOwnedMapping>(
511 reinterpret_cast<const uint8_t*>(contents->data()), contents->size(),
512 [contents](auto, auto) {});
513 }
impeller::compiler::JoinStrings
static std::string JoinStrings(std::vector< std::string > items, const std::string &separator)
Definition: compiler.cc:480

References impeller::compiler::JoinStrings().

Referenced by impeller::compiler::OutputDepfile().

## ◆ GetErrorMessages()

std::string impeller::compiler::Compiler::GetErrorMessages | ( |  | ) | const

Definition at line 472 of file compiler.cc.

472 {
473 return error_stream_.str();
474 }

Referenced by impeller::compiler::testing::CompilerTest::CanCompileAndReflect(), impeller::compiler::CompileSkSL(), impeller::compiler::GenerateShaderBackendFB(), impeller::compiler::Main(), and impeller::compiler::OutputIPLR().

## ◆ GetIncludedFileNames()

const std::vector< std::string > & impeller::compiler::Compiler::GetIncludedFileNames | ( |  | ) | const

Definition at line 476 of file compiler.cc.

476 {
477 return included_file_names_;
478 }

## ◆ GetReflector()

const Reflector * impeller::compiler::Compiler::GetReflector | ( |  | ) | const

Definition at line 515 of file compiler.cc.

515 {
516 return reflector_.get();
517 }

Referenced by impeller::compiler::testing::CompilerTest::CanCompileAndReflect(), impeller::compiler::CompileSkSL(), impeller::compiler::GenerateShaderBackendFB(), impeller::compiler::OutputIPLR(), and impeller::compiler::OutputReflectionData().

## ◆ GetSLShaderSource()

std::shared_ptr< fml::Mapping > impeller::compiler::Compiler::GetSLShaderSource | ( |  | ) | const

Definition at line 458 of file compiler.cc.

458 {
459 return sl_mapping_;
460 }

Referenced by impeller::compiler::testing::CompilerTest::CanCompileAndReflect(), Compiler(), and impeller::compiler::OutputSLFile().

## ◆ GetSPIRVAssembly()

std::shared_ptr< fml::Mapping > impeller::compiler::Compiler::GetSPIRVAssembly | ( |  | ) | const

Definition at line 454 of file compiler.cc.

454 {
455 return spirv_assembly_;
456 }

Referenced by impeller::compiler::testing::CompilerTest::CanCompileAndReflect(), and impeller::compiler::Main().

## ◆ IsValid()

bool impeller::compiler::Compiler::IsValid | ( |  | ) | const

Definition at line 462 of file compiler.cc.

462 {
463 return is_valid_;
464 }

Referenced by impeller::compiler::testing::CompilerTest::CanCompileAndReflect(), impeller::compiler::CompileSkSL(), impeller::compiler::GenerateShaderBackendFB(), impeller::compiler::Main(), and impeller::compiler::OutputIPLR().

The documentation for this class was generated from the following files:

- impeller/compiler/compiler.h
- impeller/compiler/compiler.cc