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

Commit e153419

Browse files
committed
[Flutter GPU] Pack multiple backends in shader bundles.
1 parent a2091ea commit e153419

File tree

14 files changed

+160
-78
lines changed

14 files changed

+160
-78
lines changed

impeller/compiler/shader_bundle.cc

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,12 @@ std::optional<ShaderBundleConfig> ParseShaderBundleConfig(
8080
return bundle;
8181
}
8282

83-
static std::unique_ptr<fb::ShaderT> GenerateShaderFB(
83+
static std::unique_ptr<fb::RuntimeStageT> GenerateShaderBackendFB(
84+
TargetPlatform target_platform,
8485
SourceOptions& options,
8586
const std::string& shader_name,
8687
const ShaderConfig& shader_config) {
87-
auto result = std::make_unique<fb::ShaderT>();
88-
result->name = shader_name;
88+
auto result = std::make_unique<fb::RuntimeStageT>();
8989

9090
std::shared_ptr<fml::FileMapping> source_file_mapping =
9191
fml::FileMapping::CreateReadOnly(shader_config.source_file_name);
@@ -96,6 +96,8 @@ static std::unique_ptr<fb::ShaderT> GenerateShaderFB(
9696
}
9797

9898
/// Override options.
99+
options.target_platform = target_platform;
100+
options.file_name = shader_name; // This is just used for error messages.
99101
options.type = shader_config.type;
100102
options.source_language = shader_config.language;
101103
options.entry_point_name = EntryPointFunctionNameFromSourceName(
@@ -129,8 +131,8 @@ static std::unique_ptr<fb::ShaderT> GenerateShaderFB(
129131
return nullptr;
130132
}
131133

132-
result->shader = stage_data->CreateFlatbuffer();
133-
if (!result->shader) {
134+
result = stage_data->CreateFlatbuffer();
135+
if (!result) {
134136
std::cerr << "Failed to create flatbuffer for bundled shader \""
135137
<< shader_name << "\"." << std::endl;
136138
return nullptr;
@@ -139,6 +141,29 @@ static std::unique_ptr<fb::ShaderT> GenerateShaderFB(
139141
return result;
140142
}
141143

144+
static std::unique_ptr<fb::ShaderT> GenerateShaderFB(
145+
SourceOptions& options,
146+
const std::string& shader_name,
147+
const ShaderConfig& shader_config) {
148+
auto result = std::make_unique<fb::ShaderT>();
149+
result->name = shader_name;
150+
result->metal_ios = GenerateShaderBackendFB(
151+
TargetPlatform::kMetalIOS, options, shader_name, shader_config);
152+
result->metal_desktop = GenerateShaderBackendFB(
153+
TargetPlatform::kMetalDesktop, options, shader_name, shader_config);
154+
result->opengl_es = GenerateShaderBackendFB(
155+
TargetPlatform::kOpenGLES, options, shader_name, shader_config);
156+
result->opengl_desktop = GenerateShaderBackendFB(
157+
TargetPlatform::kOpenGLDesktop, options, shader_name, shader_config);
158+
result->vulkan = GenerateShaderBackendFB(TargetPlatform::kVulkan, options,
159+
shader_name, shader_config);
160+
if (!(result->metal_ios && result->metal_desktop && result->opengl_es &&
161+
result->opengl_desktop && result->vulkan)) {
162+
return nullptr;
163+
}
164+
return result;
165+
}
166+
142167
std::optional<fb::ShaderBundleT> GenerateShaderBundleFlatbuffer(
143168
const std::string& bundle_config_json,
144169
SourceOptions& options) {

impeller/compiler/shader_bundle_unittests.cc

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -156,14 +156,14 @@ TEST(ShaderBundleTest, GenerateShaderBundleFlatbufferProducesCorrectResult) {
156156
/// Verify vertex shader.
157157
///
158158

159-
EXPECT_STREQ(vertex->shader->entrypoint.c_str(),
159+
EXPECT_STREQ(vertex->metal_desktop->entrypoint.c_str(),
160160
"flutter_gpu_unlit_vertex_main");
161-
EXPECT_EQ(vertex->shader->stage, fb::Stage::kVertex);
162-
EXPECT_EQ(vertex->shader->target_platform, fb::TargetPlatform::kMetal);
161+
EXPECT_EQ(vertex->metal_desktop->stage, fb::Stage::kVertex);
162+
EXPECT_EQ(vertex->metal_desktop->target_platform, fb::TargetPlatform::kMetal);
163163

164164
// Inputs.
165-
ASSERT_EQ(vertex->shader->inputs.size(), 1u);
166-
const auto& v_in_position = vertex->shader->inputs[0];
165+
ASSERT_EQ(vertex->metal_desktop->inputs.size(), 1u);
166+
const auto& v_in_position = vertex->metal_desktop->inputs[0];
167167
EXPECT_STREQ(v_in_position->name.c_str(), "position");
168168
EXPECT_EQ(v_in_position->location, 0u);
169169
EXPECT_EQ(v_in_position->set, 0u);
@@ -175,16 +175,16 @@ TEST(ShaderBundleTest, GenerateShaderBundleFlatbufferProducesCorrectResult) {
175175
EXPECT_EQ(v_in_position->offset, 0u);
176176

177177
// Uniforms.
178-
ASSERT_EQ(vertex->shader->uniforms.size(), 2u);
179-
const auto* v_mvp = FindByName(vertex->shader->uniforms, "mvp");
178+
ASSERT_EQ(vertex->metal_desktop->uniforms.size(), 2u);
179+
const auto* v_mvp = FindByName(vertex->metal_desktop->uniforms, "mvp");
180180
ASSERT_NE(v_mvp, nullptr);
181181
EXPECT_EQ(v_mvp->location, 0u);
182182
EXPECT_EQ(v_mvp->type, fb::UniformDataType::kFloat);
183183
EXPECT_EQ(v_mvp->bit_width, 32u);
184184
EXPECT_EQ(v_mvp->rows, 4u);
185185
EXPECT_EQ(v_mvp->columns, 4u);
186186
EXPECT_EQ(v_mvp->array_elements, 0u);
187-
const auto* v_color = FindByName(vertex->shader->uniforms, "color");
187+
const auto* v_color = FindByName(vertex->metal_desktop->uniforms, "color");
188188
ASSERT_NE(v_color, nullptr);
189189
EXPECT_EQ(v_color->location, 1u);
190190
EXPECT_EQ(v_color->type, fb::UniformDataType::kFloat);
@@ -197,16 +197,17 @@ TEST(ShaderBundleTest, GenerateShaderBundleFlatbufferProducesCorrectResult) {
197197
/// Verify fragment shader.
198198
///
199199

200-
EXPECT_STREQ(fragment->shader->entrypoint.c_str(),
200+
EXPECT_STREQ(fragment->metal_desktop->entrypoint.c_str(),
201201
"flutter_gpu_unlit_fragment_main");
202-
EXPECT_EQ(fragment->shader->stage, fb::Stage::kFragment);
203-
EXPECT_EQ(fragment->shader->target_platform, fb::TargetPlatform::kMetal);
202+
EXPECT_EQ(fragment->metal_desktop->stage, fb::Stage::kFragment);
203+
EXPECT_EQ(fragment->metal_desktop->target_platform,
204+
fb::TargetPlatform::kMetal);
204205

205206
// Inputs (not recorded for fragment shaders).
206-
ASSERT_EQ(fragment->shader->inputs.size(), 0u);
207+
ASSERT_EQ(fragment->metal_desktop->inputs.size(), 0u);
207208

208209
// Uniforms.
209-
ASSERT_EQ(fragment->shader->inputs.size(), 0u);
210+
ASSERT_EQ(fragment->metal_desktop->inputs.size(), 0u);
210211
}
211212

212213
} // namespace testing

impeller/compiler/switches.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ bool Switches::AreValid(std::ostream& explain) const {
200200
const bool shader_bundle_mode = !shader_bundle.empty();
201201

202202
bool valid = true;
203-
if (target_platform == TargetPlatform::kUnknown) {
203+
if (target_platform == TargetPlatform::kUnknown && !shader_bundle_mode) {
204204
explain << "The target platform (only one) was not specified." << std::endl;
205205
valid = false;
206206
}

impeller/fixtures/BUILD.gn

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,6 @@ impellerc("flutter_gpu_shaders") {
125125
"flutter_gpu_texture.frag",
126126
"flutter_gpu_texture.vert",
127127
]
128-
shader_target_flag = "--runtime-stage-metal"
129128
shader_bundle = "{\"UnlitFragment\": {\"type\": \"fragment\", \"file\": \"../../flutter/impeller/fixtures/flutter_gpu_unlit.frag\"}, \"UnlitVertex\": {\"type\": \"vertex\", \"file\": \"../../flutter/impeller/fixtures/flutter_gpu_unlit.vert\"}, \"TextureFragment\": {\"type\": \"fragment\", \"file\": \"../../flutter/impeller/fixtures/flutter_gpu_texture.frag\"}, \"TextureVertex\": {\"type\": \"vertex\", \"file\": \"../../flutter/impeller/fixtures/flutter_gpu_texture.vert\"}}"
130129
shader_bundle_output = "playground.shaderbundle"
131130
}

impeller/fixtures/flutter_gpu_texture.vert

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
uniform mat4 mvp;
5+
uniform VertInfo {
6+
mat4 mvp;
7+
}
8+
vert_info;
69

710
in vec3 position;
811
in vec2 texture_coords;
@@ -13,5 +16,5 @@ out vec4 v_color;
1316
void main() {
1417
v_texture_coords = texture_coords;
1518
v_color = color;
16-
gl_Position = mvp * vec4(position, 1.0);
19+
gl_Position = vert_info.mvp * vec4(position, 1.0);
1720
}

impeller/fixtures/flutter_gpu_unlit.vert

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,16 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
#version 320 es
6-
7-
layout(location = 0) uniform mat4 mvp;
8-
layout(location = 1) uniform vec4 color;
5+
uniform VertInfo {
6+
mat4 mvp;
7+
vec4 color;
8+
}
9+
vert_info;
910

1011
in vec2 position;
1112
out vec4 v_color;
1213

1314
void main() {
14-
v_color = color;
15-
gl_Position = mvp * vec4(position, 0.0, 1.0);
15+
v_color = vert_info.color;
16+
gl_Position = vert_info.mvp * vec4(position, 0.0, 1.0);
1617
}

impeller/renderer/renderer_dart_unittests.cc

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,31 +9,27 @@
99
#include "flutter/common/settings.h"
1010
#include "flutter/common/task_runners.h"
1111
#include "flutter/lib/gpu/context.h"
12-
#include "flutter/lib/gpu/shader.h"
1312
#include "flutter/lib/gpu/shader_library.h"
1413
#include "flutter/runtime/dart_isolate.h"
1514
#include "flutter/runtime/dart_vm_lifecycle.h"
1615
#include "flutter/testing/dart_fixture.h"
1716
#include "flutter/testing/dart_isolate_runner.h"
1817
#include "flutter/testing/testing.h"
1918
#include "fml/memory/ref_ptr.h"
20-
#include "impeller/core/shader_types.h"
2119
#include "impeller/playground/playground_test.h"
2220
#include "impeller/renderer/render_pass.h"
23-
#include "impeller/renderer/vertex_descriptor.h"
24-
#include "impeller/runtime_stage/runtime_stage.h"
2521

2622
#include "gtest/gtest.h"
2723
#include "third_party/imgui/imgui.h"
2824

2925
namespace impeller {
3026
namespace testing {
3127

32-
static void InstantiateTestShaderLibrary() {
28+
static void InstantiateTestShaderLibrary(Context::BackendType backend_type) {
3329
auto fixture =
3430
flutter::testing::OpenFixtureAsMapping("playground.shaderbundle");
35-
auto library =
36-
flutter::gpu::ShaderLibrary::MakeFromFlatbuffer(std::move(fixture));
31+
auto library = flutter::gpu::ShaderLibrary::MakeFromFlatbuffer(
32+
backend_type, std::move(fixture));
3733
flutter::gpu::ShaderLibrary::SetOverride(library);
3834
}
3935

@@ -57,7 +53,7 @@ class RendererDartTest : public PlaygroundTest,
5753
assert(GetContext() != nullptr);
5854
flutter::gpu::Context::SetOverrideContext(GetContext());
5955

60-
InstantiateTestShaderLibrary();
56+
InstantiateTestShaderLibrary(GetContext()->GetBackendType());
6157

6258
return isolate_.get();
6359
}

impeller/shader_bundle/BUILD.gn

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ flatbuffers("shader_bundle_flatbuffers") {
1010
public_configs = [ "//flutter/impeller/runtime_stage:runtime_stage_config" ]
1111
public_deps = [
1212
"//flutter/impeller/runtime_stage:runtime_stage_flatbuffers",
13-
"//flutter/impeller/runtime_stage:runtime_stage_types_flatbuffers",
1413
"//flutter/third_party/flatbuffers",
1514
]
1615
}

impeller/shader_bundle/shader_bundle.fbs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@ namespace impeller.fb;
88

99
table Shader {
1010
name: string;
11-
shader: RuntimeStage;
11+
metal_ios: RuntimeStage;
12+
metal_desktop: RuntimeStage;
13+
opengl_es: RuntimeStage;
14+
opengl_desktop: RuntimeStage;
15+
vulkan: RuntimeStage;
1216
}
1317

1418
table ShaderBundle {

impeller/tools/impeller.gni

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,7 @@ template("_impellerc") {
288288
# --opengl-desktop
289289
# --vulkan
290290
# --runtime-stage-metal
291+
# Not required for --shader_bundle mode.
291292
# Required: sl_file_extension The file extension to use for output files.
292293
# Not required for --shader_bundle mode.
293294
# Optional: iplr Causes --sl output to be in iplr/runtime
@@ -305,7 +306,7 @@ template("_impellerc") {
305306
# flatbuffer.
306307
template("impellerc") {
307308
assert(defined(invoker.shaders), "Impeller shaders must be specified.")
308-
assert(defined(invoker.shader_target_flag),
309+
assert(defined(invoker.shader_target_flag) || defined(invoker.shader_bundle),
309310
"The flag to impellerc for target selection must be specified.")
310311
assert(defined(invoker.sl_file_extension) || defined(invoker.shader_bundle),
311312
"The extension of the SL file must be specified (metal, glsl, etc..).")
@@ -315,7 +316,7 @@ template("impellerc") {
315316
"When shader_bundle is specified, shader_output_bundle must also be specified.")
316317
}
317318

318-
sksl = invoker.shader_target_flag == "--sksl"
319+
sksl = defined(invoker.iplr) && invoker.shader_target_flag == "--sksl"
319320
iplr = false
320321
if (defined(invoker.iplr) && invoker.iplr) {
321322
iplr = invoker.iplr
@@ -347,13 +348,8 @@ template("impellerc") {
347348
generated_dir = "$target_gen_dir"
348349
}
349350

350-
shader_target_flag = invoker.shader_target_flag
351-
352351
shader_lib_dir = rebase_path("//flutter/impeller/compiler/shader_lib")
353-
args = [
354-
"--include=$shader_lib_dir",
355-
"$shader_target_flag",
356-
]
352+
args = [ "--include=$shader_lib_dir" ]
357353

358354
# When we're in single invocation mode, we can't use source enumeration.
359355
if (!single_invocation) {
@@ -365,6 +361,10 @@ template("impellerc") {
365361
"--include={{source_dir}}",
366362
"--depfile=$depfile_intermediate_path",
367363
]
364+
365+
if (defined(invoker.shader_target_flag)) {
366+
args += [ "${invoker.shader_target_flag}" ]
367+
}
368368
}
369369

370370
if (defined(invoker.gles_language_version)) {

0 commit comments

Comments
 (0)