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

Commit 9a7e49d

Browse files
author
Jonah Williams
authored
[Impeller] fix order of operations in SkSL generated texture lookup. (#48488)
Fixes flutter/flutter#139017 When multiplying by the texture size we need to add parens incase the texture argument is actually an expression and not a single value.
1 parent 222beb2 commit 9a7e49d

6 files changed

Lines changed: 75 additions & 9 deletions

File tree

impeller/compiler/compiler_test.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,14 @@ std::unique_ptr<fml::FileMapping> CompilerTest::GetReflectionJson(
6565
return fml::FileMapping::CreateReadOnly(fd);
6666
}
6767

68+
std::unique_ptr<fml::FileMapping> CompilerTest::GetShaderFile(
69+
const char* fixture_name,
70+
TargetPlatform platform) const {
71+
auto filename = SLFileName(fixture_name, platform);
72+
auto fd = fml::OpenFileReadOnly(intermediates_directory_, filename.c_str());
73+
return fml::FileMapping::CreateReadOnly(fd);
74+
}
75+
6876
bool CompilerTest::CanCompileAndReflect(const char* fixture_name,
6977
SourceType source_type,
7078
SourceLanguage source_language,

impeller/compiler/compiler_test.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ class CompilerTest : public ::testing::TestWithParam<TargetPlatform> {
2424
std::unique_ptr<fml::FileMapping> GetReflectionJson(
2525
const char* fixture_name) const;
2626

27+
std::unique_ptr<fml::FileMapping> GetShaderFile(
28+
const char* fixture_name,
29+
TargetPlatform platform) const;
30+
2731
bool CanCompileAndReflect(
2832
const char* fixture_name,
2933
SourceType source_type = SourceType::kUnknown,

impeller/compiler/compiler_unittests.cc

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

5+
#include <cstring>
56
#include "flutter/testing/testing.h"
7+
#include "gtest/gtest.h"
68
#include "impeller/base/validation.h"
79
#include "impeller/compiler/compiler.h"
810
#include "impeller/compiler/compiler_test.h"
@@ -26,18 +28,27 @@ TEST(CompilerTest, ShaderKindMatchingIsSuccessful) {
2628
}
2729

2830
TEST_P(CompilerTest, CanCompile) {
31+
if (GetParam() == TargetPlatform::kSkSL) {
32+
GTEST_SKIP() << "Not supported with SkSL";
33+
}
2934
ASSERT_TRUE(CanCompileAndReflect("sample.vert"));
3035
ASSERT_TRUE(CanCompileAndReflect("sample.vert", SourceType::kVertexShader));
3136
ASSERT_TRUE(CanCompileAndReflect("sample.vert", SourceType::kVertexShader,
3237
SourceLanguage::kGLSL));
3338
}
3439

3540
TEST_P(CompilerTest, CanCompileHLSL) {
41+
if (GetParam() == TargetPlatform::kSkSL) {
42+
GTEST_SKIP() << "Not supported with SkSL";
43+
}
3644
ASSERT_TRUE(CanCompileAndReflect(
3745
"simple.vert.hlsl", SourceType::kVertexShader, SourceLanguage::kHLSL));
3846
}
3947

4048
TEST_P(CompilerTest, CanCompileHLSLWithMultipleStages) {
49+
if (GetParam() == TargetPlatform::kSkSL) {
50+
GTEST_SKIP() << "Not supported with SkSL";
51+
}
4152
ASSERT_TRUE(CanCompileAndReflect("multiple_stages.hlsl",
4253
SourceType::kVertexShader,
4354
SourceLanguage::kHLSL, "VertexShader"));
@@ -47,12 +58,18 @@ TEST_P(CompilerTest, CanCompileHLSLWithMultipleStages) {
4758
}
4859

4960
TEST_P(CompilerTest, CanCompileTessellationControlShader) {
61+
if (GetParam() == TargetPlatform::kSkSL) {
62+
GTEST_SKIP() << "Not supported with SkSL";
63+
}
5064
ASSERT_TRUE(CanCompileAndReflect("sample.tesc"));
5165
ASSERT_TRUE(CanCompileAndReflect("sample.tesc",
5266
SourceType::kTessellationControlShader));
5367
}
5468

5569
TEST_P(CompilerTest, CanCompileTessellationEvaluationShader) {
70+
if (GetParam() == TargetPlatform::kSkSL) {
71+
GTEST_SKIP() << "Not supported with SkSL";
72+
}
5673
ASSERT_TRUE(CanCompileAndReflect("sample.tese"));
5774
ASSERT_TRUE(CanCompileAndReflect("sample.tese",
5875
SourceType::kTessellationEvaluationShader));
@@ -67,12 +84,18 @@ TEST_P(CompilerTest, CanCompileComputeShader) {
6784
}
6885

6986
TEST_P(CompilerTest, MustFailDueToExceedingResourcesLimit) {
87+
if (GetParam() == TargetPlatform::kSkSL) {
88+
GTEST_SKIP() << "Not supported with SkSL";
89+
}
7090
ScopedValidationDisable disable_validation;
7191
ASSERT_FALSE(
7292
CanCompileAndReflect("resources_limit.vert", SourceType::kVertexShader));
7393
}
7494

7595
TEST_P(CompilerTest, MustFailDueToMultipleLocationPerStructMember) {
96+
if (GetParam() == TargetPlatform::kSkSL) {
97+
GTEST_SKIP() << "Not supported with SkSL";
98+
}
7699
ScopedValidationDisable disable_validation;
77100
ASSERT_FALSE(CanCompileAndReflect("struct_def_bug.vert"));
78101
}
@@ -98,6 +121,9 @@ TEST_P(CompilerTest, BindingBaseForFragShader) {
98121
}
99122

100123
TEST_P(CompilerTest, UniformsHaveBindingAndSet) {
124+
if (GetParam() == TargetPlatform::kSkSL) {
125+
GTEST_SKIP() << "Not supported with SkSL";
126+
}
101127
ASSERT_TRUE(CanCompileAndReflect("sample_with_binding.vert",
102128
SourceType::kVertexShader));
103129
ASSERT_TRUE(CanCompileAndReflect("sample.frag", SourceType::kFragmentShader));
@@ -123,14 +149,30 @@ TEST_P(CompilerTest, UniformsHaveBindingAndSet) {
123149
ASSERT_EQ(vert_uniform_binding.binding, 17u);
124150
}
125151

126-
#define INSTANTIATE_TARGET_PLATFORM_TEST_SUITE_P(suite_name) \
127-
INSTANTIATE_TEST_SUITE_P( \
128-
suite_name, CompilerTest, \
129-
::testing::Values( \
130-
TargetPlatform::kOpenGLES, TargetPlatform::kOpenGLDesktop, \
131-
TargetPlatform::kMetalDesktop, TargetPlatform::kMetalIOS), \
132-
[](const ::testing::TestParamInfo<CompilerTest::ParamType>& info) { \
133-
return TargetPlatformToString(info.param); \
152+
TEST_P(CompilerTest, SkSLTextureLookUpOrderOfOperations) {
153+
if (GetParam() != TargetPlatform::kSkSL) {
154+
GTEST_SKIP() << "Only supported on SkSL";
155+
}
156+
ASSERT_TRUE(
157+
CanCompileAndReflect("texture_lookup.frag", SourceType::kFragmentShader));
158+
159+
auto shader = GetShaderFile("texture_lookup.frag", GetParam());
160+
auto string_mapping = reinterpret_cast<const char*>(shader->GetMapping());
161+
162+
EXPECT_TRUE(strcmp(string_mapping,
163+
"textureA.eval(textureA_size * ( vec2(1.0) + "
164+
"flutter_FragCoord.xy));") != -1);
165+
}
166+
167+
#define INSTANTIATE_TARGET_PLATFORM_TEST_SUITE_P(suite_name) \
168+
INSTANTIATE_TEST_SUITE_P( \
169+
suite_name, CompilerTest, \
170+
::testing::Values(TargetPlatform::kOpenGLES, \
171+
TargetPlatform::kOpenGLDesktop, \
172+
TargetPlatform::kMetalDesktop, \
173+
TargetPlatform::kMetalIOS, TargetPlatform::kSkSL), \
174+
[](const ::testing::TestParamInfo<CompilerTest::ParamType>& info) { \
175+
return TargetPlatformToString(info.param); \
134176
});
135177

136178
INSTANTIATE_TARGET_PLATFORM_TEST_SUITE_P(CompilerSuite);

impeller/compiler/spirv_sksl.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,7 @@ std::string CompilerSkSL::to_function_args(const TextureFunctionArguments& args,
466466
return "()";
467467
}
468468

469-
return name + "_size * " + no_shader;
469+
return name + "_size * (" + no_shader + ")";
470470
}
471471

472472
} // namespace compiler

impeller/fixtures/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ test_fixtures("file_fixtures") {
101101
"two_triangles.glb",
102102
"types.h",
103103
"wtf.otf",
104+
"texture_lookup.frag",
104105
]
105106
if (host_os == "mac") {
106107
fixtures += [ "/System/Library/Fonts/Apple Color Emoji.ttc" ]
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
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 sampler2D textureA;
6+
7+
out vec4 frag_color;
8+
9+
void main() {
10+
frag_color = texture(textureA, vec2(1.0) + gl_FragCoord.xy);
11+
}

0 commit comments

Comments
 (0)