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

Commit c53fd4b

Browse files
authored
[Impeller] Make IPLR files multi-platform (#49253)
This is part of the work towards supporting OpenGLES and Vulkan for runtime stage shaders. Removes some redundant work we had around SkSL. Now only bundles the shaders we actually ask for from the command line. @bdero, we should figure out if this is the right approach for flutter_gpu. With this change, the IPLR format goes from having a root table of shader related information to a root table of shader information per `sksl`, `metal`, `opengles`, and `vulkan` platforms. This may end up allowing us to revert #47278, but I'm not sure I understand all the implications of that at this point. I have run some but not all tests locally.
1 parent 3837195 commit c53fd4b

36 files changed

+643
-418
lines changed

impeller/aiks/aiks_unittests.cc

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2947,8 +2947,10 @@ TEST_P(AiksTest, CanRenderClippedRuntimeEffects) {
29472947
GTEST_SKIP_("This backend doesn't support runtime effects.");
29482948
}
29492949

2950-
auto runtime_stage =
2950+
auto runtime_stages =
29512951
OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
2952+
auto runtime_stage = runtime_stages[RuntimeStageBackend::kMetal];
2953+
ASSERT_TRUE(runtime_stage);
29522954
ASSERT_TRUE(runtime_stage->IsDirty());
29532955

29542956
struct FragUniforms {
@@ -2980,7 +2982,9 @@ TEST_P(AiksTest, DrawPaintTransformsBounds) {
29802982
GTEST_SKIP_("This backend doesn't support runtime effects.");
29812983
}
29822984

2983-
auto runtime_stage = OpenAssetAsRuntimeStage("gradient.frag.iplr");
2985+
auto runtime_stages = OpenAssetAsRuntimeStage("gradient.frag.iplr");
2986+
auto runtime_stage = runtime_stages[RuntimeStageBackend::kMetal];
2987+
ASSERT_TRUE(runtime_stage);
29842988
ASSERT_TRUE(runtime_stage->IsDirty());
29852989

29862990
struct FragUniforms {

impeller/compiler/impellerc_main.cc

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "flutter/fml/file.h"
1111
#include "flutter/fml/mapping.h"
1212
#include "impeller/compiler/compiler.h"
13+
#include "impeller/compiler/runtime_stage_data.h"
1314
#include "impeller/compiler/shader_bundle.h"
1415
#include "impeller/compiler/source_options.h"
1516
#include "impeller/compiler/switches.h"
@@ -19,9 +20,9 @@
1920
namespace impeller {
2021
namespace compiler {
2122

22-
/// Run the shader compiler to geneate SkSL.
23+
/// Run the shader compiler to geneate SkSL reflection data.
2324
/// If there is an error, prints error text and returns `nullptr`.
24-
static std::shared_ptr<fml::Mapping> CompileSkSL(
25+
static std::shared_ptr<RuntimeStageData::Shader> CompileSkSL(
2526
std::shared_ptr<fml::Mapping> source_file_mapping,
2627
SourceOptions& options,
2728
Reflector::Options& reflector_options) {
@@ -38,7 +39,7 @@ static std::shared_ptr<fml::Mapping> CompileSkSL(
3839
std::cerr << sksl_compiler.GetErrorMessages() << std::endl;
3940
return nullptr;
4041
}
41-
return sksl_compiler.GetSLShaderSource();
42+
return sksl_compiler.GetReflector()->GetRuntimeStageShaderData();
4243
}
4344

4445
/// Outputs artifacts for a single compiler invocation and option configuration.
@@ -52,11 +53,11 @@ static bool OutputArtifacts(Compiler& compiler,
5253
/// 1. Invoke the compiler to generate SkSL if needed.
5354
///
5455

55-
std::shared_ptr<fml::Mapping> sksl_mapping;
56+
std::shared_ptr<RuntimeStageData::Shader> sksl_shader;
5657
if (switches.iplr && TargetPlatformBundlesSkSL(switches.target_platform)) {
57-
sksl_mapping =
58+
sksl_shader =
5859
CompileSkSL(std::move(source_file_mapping), options, reflector_options);
59-
if (!sksl_mapping) {
60+
if (!sksl_shader) {
6061
return false;
6162
}
6263
}
@@ -74,17 +75,42 @@ static bool OutputArtifacts(Compiler& compiler,
7475
std::cerr << "Could not create reflector." << std::endl;
7576
return false;
7677
}
77-
auto stage_data = reflector->GetRuntimeStageData();
78+
auto stage_data = reflector->GetRuntimeStageShaderData();
7879
if (!stage_data) {
7980
std::cerr << "Runtime stage information was nil." << std::endl;
8081
return false;
8182
}
82-
if (sksl_mapping) {
83-
stage_data->SetSkSLData(std::move(sksl_mapping));
83+
RuntimeStageData stages;
84+
if (sksl_shader) {
85+
stages.AddShader(RuntimeStageBackend::kSkSL, sksl_shader);
8486
}
85-
auto stage_data_mapping = options.json_format
86-
? stage_data->CreateJsonMapping()
87-
: stage_data->CreateMapping();
87+
switch (switches.target_platform) {
88+
case TargetPlatform::kUnknown:
89+
case TargetPlatform::kMetalDesktop:
90+
case TargetPlatform::kMetalIOS:
91+
case TargetPlatform::kOpenGLES:
92+
case TargetPlatform::kOpenGLDesktop:
93+
case TargetPlatform::kVulkan:
94+
std::cerr << "TargetPlatform "
95+
<< TargetPlatformToString(switches.target_platform)
96+
<< " not supported for IPLR.";
97+
return false;
98+
case TargetPlatform::kRuntimeStageMetal:
99+
stages.AddShader(RuntimeStageBackend::kMetal, stage_data);
100+
break;
101+
case TargetPlatform::kRuntimeStageGLES:
102+
stages.AddShader(RuntimeStageBackend::kOpenGLES, stage_data);
103+
break;
104+
case TargetPlatform::kRuntimeStageVulkan:
105+
stages.AddShader(RuntimeStageBackend::kVulkan, stage_data);
106+
break;
107+
case TargetPlatform::kSkSL:
108+
// Already handled above.
109+
break;
110+
}
111+
112+
auto stage_data_mapping = options.json_format ? stages.CreateJsonMapping()
113+
: stages.CreateMapping();
88114
if (!stage_data_mapping) {
89115
std::cerr << "Runtime stage data could not be created." << std::endl;
90116
return false;

impeller/compiler/reflector.cc

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,8 @@ Reflector::Reflector(Options options,
127127
return;
128128
}
129129

130-
runtime_stage_data_ = GenerateRuntimeStageData();
131-
if (!runtime_stage_data_) {
130+
runtime_stage_shader_ = GenerateRuntimeStageData();
131+
if (!runtime_stage_shader_) {
132132
return;
133133
}
134134

@@ -162,8 +162,9 @@ std::shared_ptr<fml::Mapping> Reflector::GetReflectionCC() const {
162162
return reflection_cc_;
163163
}
164164

165-
std::shared_ptr<RuntimeStageData> Reflector::GetRuntimeStageData() const {
166-
return runtime_stage_data_;
165+
std::shared_ptr<RuntimeStageData::Shader> Reflector::GetRuntimeStageShaderData()
166+
const {
167+
return runtime_stage_shader_;
167168
}
168169

169170
std::optional<nlohmann::json> Reflector::GenerateTemplateArguments() const {
@@ -317,18 +318,17 @@ std::shared_ptr<fml::Mapping> Reflector::GenerateReflectionCC() const {
317318
return InflateTemplate(kReflectionCCTemplate);
318319
}
319320

320-
std::shared_ptr<RuntimeStageData> Reflector::GenerateRuntimeStageData() const {
321+
std::shared_ptr<RuntimeStageData::Shader> Reflector::GenerateRuntimeStageData()
322+
const {
321323
const auto& entrypoints = compiler_->get_entry_points_and_stages();
322324
if (entrypoints.size() != 1u) {
323325
VALIDATION_LOG << "Single entrypoint not found.";
324326
return nullptr;
325327
}
326-
auto data = std::make_shared<RuntimeStageData>(
327-
options_.entry_point_name, //
328-
entrypoints.front().execution_model, //
329-
options_.target_platform //
330-
);
331-
data->SetShaderData(shader_data_);
328+
auto data = std::make_unique<RuntimeStageData::Shader>();
329+
data->entrypoint = options_.entry_point_name;
330+
data->stage = entrypoints.front().execution_model;
331+
data->shader = shader_data_;
332332

333333
// Sort the IR so that the uniforms are in declaration order.
334334
std::vector<spirv_cross::ID> uniforms =
@@ -346,7 +346,7 @@ std::shared_ptr<RuntimeStageData> Reflector::GenerateRuntimeStageData() const {
346346
uniform_description.columns = spir_type.columns;
347347
uniform_description.bit_width = spir_type.width;
348348
uniform_description.array_elements = GetArrayElements(spir_type);
349-
data->AddUniformDescription(std::move(uniform_description));
349+
data->uniforms.emplace_back(std::move(uniform_description));
350350
}
351351

352352
// We only need to worry about storing vertex attributes.
@@ -373,7 +373,7 @@ std::shared_ptr<RuntimeStageData> Reflector::GenerateRuntimeStageData() const {
373373
input_description.vec_size = type.vecsize;
374374
input_description.columns = type.columns;
375375
input_description.offset = offset.value_or(0u);
376-
data->AddInputDescription(std::move(input_description));
376+
data->inputs.emplace_back(std::move(input_description));
377377
}
378378
}
379379

impeller/compiler/reflector.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ class Reflector {
7272

7373
std::shared_ptr<fml::Mapping> GetReflectionCC() const;
7474

75-
std::shared_ptr<RuntimeStageData> GetRuntimeStageData() const;
75+
std::shared_ptr<RuntimeStageData::Shader> GetRuntimeStageShaderData() const;
7676

7777
private:
7878
struct StructDefinition {
@@ -100,7 +100,7 @@ class Reflector {
100100
std::unique_ptr<const nlohmann::json> template_arguments_;
101101
std::shared_ptr<fml::Mapping> reflection_header_;
102102
std::shared_ptr<fml::Mapping> reflection_cc_;
103-
std::shared_ptr<RuntimeStageData> runtime_stage_data_;
103+
std::shared_ptr<RuntimeStageData::Shader> runtime_stage_shader_;
104104
bool is_valid_ = false;
105105

106106
std::optional<nlohmann::json> GenerateTemplateArguments() const;
@@ -109,7 +109,7 @@ class Reflector {
109109

110110
std::shared_ptr<fml::Mapping> GenerateReflectionCC() const;
111111

112-
std::shared_ptr<RuntimeStageData> GenerateRuntimeStageData() const;
112+
std::shared_ptr<RuntimeStageData::Shader> GenerateRuntimeStageData() const;
113113

114114
std::shared_ptr<fml::Mapping> InflateTemplate(std::string_view tmpl) const;
115115

0 commit comments

Comments
 (0)