Skip to content

Commit 86fdc79

Browse files
chinmaygardednfield
authored andcommitted
Make it an error for a stage input to take more than one slot. (#161)
Earlier, no PerVertexData struct would be generated. The shader is useless without reflection information. Fixes flutter/flutter#102521.
1 parent 3ebfe9e commit 86fdc79

File tree

4 files changed

+54
-2
lines changed

4 files changed

+54
-2
lines changed

impeller/compiler/compiler_unittests.cc

+8
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@ TEST_P(CompilerTest, CanCompile) {
2424
ASSERT_TRUE(CanCompileAndReflect("sample.vert"));
2525
}
2626

27+
TEST_P(CompilerTest, MustFailDueToMultipleLocationPerStructMember) {
28+
if (GetParam() == TargetPlatform::kFlutterSPIRV) {
29+
// This is a failure of reflection which this target doesn't perform.
30+
GTEST_SKIP();
31+
}
32+
ASSERT_FALSE(CanCompileAndReflect("struct_def_bug.vert"));
33+
}
34+
2735
#define INSTANTIATE_TARGET_PLATFORM_TEST_SUITE_P(suite_name) \
2836
INSTANTIATE_TEST_SUITE_P( \
2937
suite_name, CompilerTest, \

impeller/compiler/reflector.cc

+11-2
Original file line numberDiff line numberDiff line change
@@ -232,11 +232,16 @@ std::optional<nlohmann::json> Reflector::GenerateTemplateArguments() const {
232232
auto& struct_definitions = root["struct_definitions"] =
233233
nlohmann::json::array_t{};
234234
if (entrypoints.front().execution_model ==
235-
spv::ExecutionModel::ExecutionModelVertex) {
235+
spv::ExecutionModel::ExecutionModelVertex &&
236+
!shader_resources.stage_inputs.empty()) {
236237
if (auto struc =
237238
ReflectPerVertexStructDefinition(shader_resources.stage_inputs);
238239
struc.has_value()) {
239240
struct_definitions.emplace_back(EmitStructDefinition(struc.value()));
241+
} else {
242+
// If there are stage inputs, it is an error to not generate a per
243+
// vertex data struct for a vertex like shader stage.
244+
return std::nullopt;
240245
}
241246
}
242247

@@ -662,7 +667,10 @@ Reflector::ReflectPerVertexStructDefinition(
662667

663668
for (size_t i = 0; i < locations.size(); i++) {
664669
if (locations.count(i) != 1) {
665-
// Locations are not contiguous. Bail.
670+
// Locations are not contiguous. This usually happens when a single stage
671+
// input takes multiple input slots. No reflection information can be
672+
// generated for such cases anyway. So bail! It is up to the shader author
673+
// to make sure one stage input maps to a single input slot.
666674
return std::nullopt;
667675
}
668676
}
@@ -677,6 +685,7 @@ Reflector::ReflectPerVertexStructDefinition(
677685
}
678686
}
679687
// This really cannot happen with all the validation above.
688+
FML_UNREACHABLE();
680689
return nullptr;
681690
};
682691

impeller/fixtures/BUILD.gn

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ test_fixtures("file_fixtures") {
2727
"embarcadero.jpg",
2828
"kalimba.jpg",
2929
"sample.vert",
30+
"struct_def_bug.vert",
3031
"types.h",
3132
"test_texture.frag",
3233
"//flutter/third_party/txt/third_party/fonts/Roboto-Regular.ttf",

impeller/fixtures/struct_def_bug.vert

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
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+
uniform FrameInfo {
6+
mat4 mvp;
7+
vec2 atlas_size;
8+
vec4 text_color;
9+
} frame_info;
10+
11+
in vec2 unit_vertex;
12+
in mat4 glyph_position; // <--- Causes multiple slots to be used and is a failure.
13+
in vec2 glyph_size;
14+
in vec2 atlas_position;
15+
in vec2 atlas_glyph_size;
16+
17+
out vec2 v_unit_vertex;
18+
out vec2 v_atlas_position;
19+
out vec2 v_atlas_glyph_size;
20+
out vec2 v_atlas_size;
21+
out vec4 v_text_color;
22+
23+
void main() {
24+
gl_Position = frame_info.mvp
25+
* glyph_position
26+
* vec4(unit_vertex.x * glyph_size.x,
27+
unit_vertex.y * glyph_size.y, 0.0, 1.0);
28+
29+
v_unit_vertex = unit_vertex;
30+
v_atlas_position = atlas_position;
31+
v_atlas_glyph_size = atlas_glyph_size;
32+
v_atlas_size = frame_info.atlas_size;
33+
v_text_color = frame_info.text_color;
34+
}

0 commit comments

Comments
 (0)