Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
compiler_unittests.cc
Go to the documentation of this file.
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#include <cstring>
7#include "gtest/gtest.h"
13
14namespace impeller {
15namespace compiler {
16namespace testing {
17
19 CompilerSuite,
21 ::testing::Values(TargetPlatform::kOpenGLES,
26 [](const ::testing::TestParamInfo<CompilerTest::ParamType>& info) {
27 return TargetPlatformToString(info.param);
28 });
29
31 CompilerSuite,
33 ::testing::Values(TargetPlatform::kRuntimeStageMetal,
38 [](const ::testing::TestParamInfo<CompilerTest::ParamType>& info) {
39 return TargetPlatformToString(info.param);
40 });
41
43 CompilerSuite,
45 ::testing::Values(TargetPlatform::kSkSL),
46 [](const ::testing::TestParamInfo<CompilerTest::ParamType>& info) {
47 return TargetPlatformToString(info.param);
48 });
49
51 CompilerSuite,
53 ::testing::Values(TargetPlatform::kUnknown),
54 [](const ::testing::TestParamInfo<CompilerTest::ParamType>& info) {
55 return TargetPlatformToString(info.param);
56 });
57
58TEST(CompilerTest, Defines) {
59 std::shared_ptr<const fml::Mapping> fixture =
60 flutter::testing::OpenFixtureAsMapping("check_gles_definition.frag");
61
62 SourceOptions options;
65 options.entry_point_name = "main";
67
68 Reflector::Options reflector_options;
70 Compiler compiler = Compiler(fixture, options, reflector_options);
71
72 // Should fail as the shader has a compilation error in it.
73 EXPECT_EQ(compiler.GetSPIRVAssembly(), nullptr);
74
75 // Should succeed as the compilation error is ifdef'd out.
78 Compiler compiler_2 = Compiler(fixture, options, reflector_options);
79 EXPECT_NE(compiler_2.GetSPIRVAssembly(), nullptr);
80}
81
82TEST(CompilerTest, DeprecatedUnflippedDefines) {
83 std::shared_ptr<const fml::Mapping> fixture =
85 "check_gles_unflipped_definition.frag");
86
87 SourceOptions options;
89 options.entry_point_name = "main";
91
92 Reflector::Options reflector_options;
93
94 // Test that IMPELLER_OPENGLES_UNFLIPPED_DEPRECATED is defined on
95 // TargetPlatform::kRuntimeStageGLES.
96 {
99 Compiler compiler = Compiler(fixture, options, reflector_options);
100 // Should fail as the shader has a compilation error in it.
101 EXPECT_EQ(compiler.GetSPIRVAssembly(), nullptr);
102 }
103
104 // Test that IMPELLER_OPENGLES_UNFLIPPED_DEPRECATED is defined on
105 // TargetPlatform::kRuntimeStageGLES3.
106 {
109 Compiler compiler = Compiler(fixture, options, reflector_options);
110 // Should fail as the shader has a compilation error in it.
111 EXPECT_EQ(compiler.GetSPIRVAssembly(), nullptr);
112 }
113
114 // Should succeed as the compilation error is ifdef'd out.
115 {
118 Compiler compiler = Compiler(fixture, options, reflector_options);
119 EXPECT_NE(compiler.GetSPIRVAssembly(), nullptr);
120 }
121}
122
123TEST(CompilerTest, YFlipInjectionForGLESVertexShaders) {
124 // Compiles `fixture_name` for `platform` and returns the generated SL
125 // source. See https://github.com/flutter/flutter/issues/186554.
126 auto compile = [](const char* fixture_name, SourceType type,
127 TargetPlatform platform) -> std::string {
128 std::shared_ptr<fml::Mapping> fixture =
130 FML_CHECK(fixture);
131
132 SourceOptions options(fixture_name, type);
134 options.target_platform = platform;
135 options.working_directory = std::make_shared<fml::UniqueFD>(
137 options.entry_point_name = "main";
138
139 Reflector::Options reflector_options;
140 reflector_options.target_platform = platform;
141 reflector_options.header_file_name = "y_flip_injection.h";
142 reflector_options.shader_name = "shader";
143
144 Compiler compiler(fixture, options, reflector_options);
145 if (!compiler.IsValid()) {
146 return "";
147 }
148 auto sl = compiler.GetSLShaderSource();
149 if (!sl || !sl->GetMapping()) {
150 return "";
151 }
152 return std::string(reinterpret_cast<const char*>(sl->GetMapping()),
153 sl->GetSize());
154 };
155
156 // GL vertex shader: gets both the declaration and the epilogue.
157 const std::string gl_vert = compile("sample.vert", SourceType::kVertexShader,
159 EXPECT_NE(gl_vert.find("uniform float _impeller_y_flip"), std::string::npos)
160 << "GLES vertex shader is missing the y-flip uniform declaration:\n"
161 << gl_vert;
162 EXPECT_NE(gl_vert.find("gl_Position.y *= _impeller_y_flip"),
163 std::string::npos)
164 << "GLES vertex shader is missing the y-flip epilogue:\n"
165 << gl_vert;
166
167 // GL fragment shader: not injected.
168 const std::string gl_frag = compile(
170 EXPECT_EQ(gl_frag.find("_impeller_y_flip"), std::string::npos)
171 << "GLES fragment shader was unexpectedly injected:\n"
172 << gl_frag;
173
174 // Metal vertex shader: not injected.
175 const std::string mtl_vert = compile("sample.vert", SourceType::kVertexShader,
177 EXPECT_EQ(mtl_vert.find("_impeller_y_flip"), std::string::npos)
178 << "Metal vertex shader was unexpectedly injected:\n"
179 << mtl_vert;
180}
181
182TEST(CompilerTest, YFlipInjectionHandlesEarlyReturnsInGLESVertexShader) {
183 // `y_flip_early_return.vert` has an early `return` before main's implicit
184 // exit; the wrap-main injection must flip on both paths.
185 std::shared_ptr<fml::Mapping> fixture =
186 flutter::testing::OpenFixtureAsMapping("y_flip_early_return.vert");
187 FML_CHECK(fixture);
188
189 SourceOptions options("y_flip_early_return.vert", SourceType::kVertexShader);
192 options.working_directory = std::make_shared<fml::UniqueFD>(
194 options.entry_point_name = "main";
195
196 Reflector::Options reflector_options;
197 reflector_options.target_platform = TargetPlatform::kOpenGLES;
198 reflector_options.header_file_name = "y_flip_early_return.h";
199 reflector_options.shader_name = "shader";
200
201 Compiler compiler(fixture, options, reflector_options);
202 ASSERT_TRUE(compiler.IsValid());
203 auto sl = compiler.GetSLShaderSource();
204 ASSERT_TRUE(sl && sl->GetMapping());
205 const std::string gl_vert(reinterpret_cast<const char*>(sl->GetMapping()),
206 sl->GetSize());
207
208 EXPECT_NE(gl_vert.find("void _impeller_user_main("), std::string::npos)
209 << gl_vert;
210 EXPECT_NE(gl_vert.find("_impeller_user_main();"), std::string::npos)
211 << gl_vert;
212 EXPECT_NE(gl_vert.find("gl_Position.y *= _impeller_y_flip"),
213 std::string::npos)
214 << gl_vert;
215
216 // Only the wrapper's `void main(` should remain after the rename.
217 const size_t first_main = gl_vert.find("\nvoid main(");
218 ASSERT_NE(first_main, std::string::npos);
219 EXPECT_EQ(gl_vert.find("\nvoid main(", first_main + 1), std::string::npos)
220 << gl_vert;
221}
222
223TEST(CompilerTest, ShaderKindMatchingIsSuccessful) {
224 ASSERT_EQ(SourceTypeFromFileName("hello.vert"), SourceType::kVertexShader);
225 ASSERT_EQ(SourceTypeFromFileName("hello.frag"), SourceType::kFragmentShader);
226 ASSERT_EQ(SourceTypeFromFileName("hello.comp"), SourceType::kComputeShader);
227 ASSERT_EQ(SourceTypeFromFileName("hello.msl"), SourceType::kUnknown);
228 ASSERT_EQ(SourceTypeFromFileName("hello.glsl"), SourceType::kUnknown);
229}
230
231TEST_P(CompilerTest, CanCompile) {
232 ASSERT_TRUE(CanCompileAndReflect("sample.vert"));
233 ASSERT_TRUE(CanCompileAndReflect("sample.vert", SourceType::kVertexShader));
234 ASSERT_TRUE(CanCompileAndReflect("sample.vert", SourceType::kVertexShader,
236}
237
238TEST_P(CompilerTest, CanCompileHLSL) {
239 ASSERT_TRUE(CanCompileAndReflect(
241}
242
243TEST_P(CompilerTest, CanCompileHLSLWithMultipleStages) {
244 ASSERT_TRUE(CanCompileAndReflect("multiple_stages.hlsl",
246 SourceLanguage::kHLSL, "VertexShader"));
247 ASSERT_TRUE(CanCompileAndReflect("multiple_stages.hlsl",
249 SourceLanguage::kHLSL, "FragmentShader"));
250}
251
252TEST_P(CompilerTest, CanCompileComputeShader) {
253 ASSERT_TRUE(CanCompileAndReflect("sample.comp", SourceType::kComputeShader,
254 SourceLanguage::kGLSL, "main"));
255}
256
257TEST_P(CompilerTest, MustFailDueToExceedingResourcesLimit) {
258 ScopedValidationDisable disable_validation;
259 ASSERT_FALSE(
260 CanCompileAndReflect("resources_limit.vert", SourceType::kVertexShader));
261}
262
263TEST_P(CompilerTest, MustFailDueToMultipleLocationPerStructMember) {
264 ScopedValidationDisable disable_validation;
265 ASSERT_FALSE(CanCompileAndReflect("struct_def_bug.vert"));
266}
267
268TEST_P(CompilerTest, UniformBlockInstanceNameCanonicalizedForGL) {
269 if (!TargetPlatformIsOpenGL(GetParam())) {
270 GTEST_SKIP() << "Only GL targets lower uniform blocks to flat structs.";
271 }
272 // `mat2_test.frag` has `uniform Params { ... } uParams;`. Without
273 // canonicalization, BufferBindingsGLES cannot resolve `uParams.uMat2`.
274 ASSERT_TRUE(
275 CanCompileAndReflect("mat2_test.frag", SourceType::kFragmentShader));
276 auto sl_source = GetCompiler()->GetSLShaderSource();
277 ASSERT_NE(sl_source, nullptr);
278 const std::string source(
279 reinterpret_cast<const char*>(sl_source->GetMapping()),
280 sl_source->GetSize());
281 EXPECT_EQ(source.find("uParams."), std::string::npos) << source;
282 EXPECT_NE(source.find("_Params."), std::string::npos) << source;
283}
284
285TEST_P(CompilerTest, BindingBaseForFragShader) {
286 if (!TargetPlatformIsVulkan(GetParam())) {
287 GTEST_SKIP();
288 }
289
290 ASSERT_TRUE(CanCompileAndReflect("sample.vert", SourceType::kVertexShader));
291 ASSERT_TRUE(CanCompileAndReflect("sample.frag", SourceType::kFragmentShader));
292
293 auto get_binding = [&](const char* fixture) -> uint32_t {
294 auto json_fd = GetReflectionJson(fixture);
295 nlohmann::json shader_json = nlohmann::json::parse(json_fd->GetMapping());
296 return shader_json["buffers"][0]["binding"].get<uint32_t>();
297 };
298
299 auto vert_uniform_binding = get_binding("sample.vert");
300 auto frag_uniform_binding = get_binding("sample.frag");
301
302 ASSERT_GT(frag_uniform_binding, vert_uniform_binding);
303}
304
305namespace {
306struct UniformInfo {
307 std::string uniform_name;
308 uint32_t location;
309 std::string type_name;
310 uint32_t columns;
311 uint32_t vec_size;
312
313 static UniformInfo fromJson(const nlohmann::json& json) {
314 return {
315 .uniform_name = json["name"].get<std::string>(),
316 .location = json["location"].get<uint32_t>(),
317 .type_name = json["type"]["type_name"].get<std::string>(),
318 .columns = json["type"]["columns"].get<uint32_t>(),
319 .vec_size = json["type"]["vec_size"].get<uint32_t>(),
320 };
321 }
322
323 static UniformInfo Sampler(const std::string& name, uint32_t location) {
324 return UniformInfo{
325 .uniform_name = name,
326 .location = location,
327 .type_name = "ShaderType::kSampledImage",
328 .columns = 1u,
329 .vec_size = 1u,
330 };
331 }
332 static UniformInfo Float(const std::string& name, uint32_t location) {
333 return FloatInfo(name, location, 1u, 1u);
334 }
335 static UniformInfo Vec2(const std::string& name, uint32_t location) {
336 return FloatInfo(name, location, 1u, 2u);
337 }
338 static UniformInfo Vec3(const std::string& name, uint32_t location) {
339 return FloatInfo(name, location, 1u, 3u);
340 }
341 static UniformInfo Vec4(const std::string& name, uint32_t location) {
342 return FloatInfo(name, location, 1u, 4u);
343 }
344 static UniformInfo Mat4(const std::string& name, uint32_t location) {
345 return FloatInfo(name, location, 4u, 4u);
346 }
347
348 constexpr bool operator==(const UniformInfo& other) const {
349 return (uniform_name == other.uniform_name && //
350 location == other.location && //
351 type_name == other.type_name && //
352 columns == other.columns && //
353 vec_size == other.vec_size);
354 }
355
356 private:
357 static UniformInfo FloatInfo(const std::string& name,
358 uint32_t location,
359 uint32_t columns,
360 uint32_t vec_size) {
361 return UniformInfo{
362 .uniform_name = name,
363 .location = location,
364 .type_name = "ShaderType::kFloat",
365 .columns = columns,
366 .vec_size = vec_size,
367 };
368 }
369};
370
371inline std::ostream& operator<<(std::ostream& out, const UniformInfo& info) {
372 out << "UniformInfo {" << std::endl
373 << " uniform_name: " << info.uniform_name << std::endl
374 << " location: " << info.location << std::endl
375 << " type_name: " << info.type_name << std::endl
376 << " columns: " << info.columns << std::endl
377 << " vec_size: " << info.vec_size << std::endl
378 << "}";
379 return out;
380}
381} // namespace
382
383TEST_P(CompilerTestRuntime, UniformsAppearInJson) {
384 if (GetParam() == TargetPlatform::kRuntimeStageVulkan) {
385 // TODO(https://github.com/flutter/flutter/issues/182578): Investigate why
386 // this does not pass.
387 GTEST_SKIP() << "Not supported with Vulkan";
388 }
389
390 ASSERT_TRUE(CanCompileAndReflect("sample_with_uniforms.frag",
393
394 auto json_fd = GetReflectionJson("sample_with_uniforms.frag");
395 ASSERT_TRUE(json_fd);
396 nlohmann::json shader_json = nlohmann::json::parse(json_fd->GetMapping());
397 auto sampler_list = shader_json["sampled_images"];
398 auto float_list = shader_json["uniforms"];
399 ASSERT_EQ(sampler_list.size(), 2u);
400 ASSERT_EQ(float_list.size(), 6u);
401
402 {
403 // clang-format off
404 std::array expected_infos = {
405 UniformInfo::Sampler("uFirstSampler", 1u),
406 UniformInfo::Sampler("uSampler", 7u),
407 };
408 // clang-format on
409 ASSERT_EQ(sampler_list.size(), expected_infos.size());
410 for (size_t i = 0; i < expected_infos.size(); i++) {
411 EXPECT_EQ(UniformInfo::fromJson(sampler_list[i]), expected_infos[i])
412 << "index: " << i;
413 }
414 }
415
416 {
417 // clang-format off
418 std::array expected_infos = {
419 UniformInfo::Float("uFirstFloat", 0u),
420 UniformInfo::Float("uFloat", 2u),
421 UniformInfo::Vec2("uVec2", 3u),
422 UniformInfo::Vec3("uVec3", 4u),
423 UniformInfo::Vec4("uVec4", 5u),
424 UniformInfo::Mat4("uMat4", 6u),
425 };
426 // clang-format on
427 ASSERT_EQ(float_list.size(), expected_infos.size());
428 for (size_t i = 0; i < expected_infos.size(); i++) {
429 EXPECT_EQ(UniformInfo::fromJson(float_list[i]), expected_infos[i])
430 << "index: " << i;
431 }
432 }
433}
434
435TEST_P(CompilerTestRuntime, PositionedUniformsAppearInJson) {
436 if (GetParam() == TargetPlatform::kRuntimeStageVulkan) {
437 // TODO(https://github.com/flutter/flutter/issues/182578): Investigate why
438 // this does not pass.
439 GTEST_SKIP() << "Not supported with Vulkan";
440 }
441
442 ASSERT_TRUE(CanCompileAndReflect("sample_with_positioned_uniforms.frag",
445
446 auto json_fd = GetReflectionJson("sample_with_positioned_uniforms.frag");
447 ASSERT_TRUE(json_fd);
448 nlohmann::json shader_json = nlohmann::json::parse(json_fd->GetMapping());
449 auto sampler_list = shader_json["sampled_images"];
450 auto float_list = shader_json["uniforms"];
451 ASSERT_EQ(sampler_list.size(), 3u);
452 ASSERT_EQ(float_list.size(), 7u);
453
454 {
455 // clang-format off
456 std::array expected_infos = {
457 UniformInfo::Sampler("uSamplerNotPositioned1", 1u),
458 UniformInfo::Sampler("uSampler", 0u),
459 UniformInfo::Sampler("uSamplerNotPositioned2", 3u),
460 };
461 // clang-format on
462 ASSERT_EQ(sampler_list.size(), expected_infos.size());
463 for (size_t i = 0; i < expected_infos.size(); i++) {
464 EXPECT_EQ(UniformInfo::fromJson(sampler_list[i]), expected_infos[i])
465 << "index: " << i;
466 }
467 }
468
469 {
470 // clang-format off
471 std::array expected_infos = {
472 UniformInfo::Float("uFloatNotPositioned1", 0u),
473 UniformInfo::Float("uFloat", 6u),
474 UniformInfo::Vec2("uVec2", 5u),
475 UniformInfo::Vec3("uVec3", 3u),
476 UniformInfo::Vec4("uVec4", 2u),
477 UniformInfo::Mat4("uMat4", 1u),
478 UniformInfo::Float("uFloatNotPositioned2", 2u),
479 };
480 // clang-format on
481 ASSERT_EQ(float_list.size(), expected_infos.size());
482 for (size_t i = 0; i < expected_infos.size(); i++) {
483 EXPECT_EQ(UniformInfo::fromJson(float_list[i]), expected_infos[i])
484 << "index: " << i;
485 }
486 }
487}
488
489TEST_P(CompilerTest, UniformsHaveBindingAndSet) {
490 if (GetParam() == TargetPlatform::kSkSL) {
491 GTEST_SKIP() << "Not supported with SkSL";
492 }
493 ASSERT_TRUE(CanCompileAndReflect("sample_with_binding.vert",
495 ASSERT_TRUE(CanCompileAndReflect("sample.frag", SourceType::kFragmentShader));
496
497 struct binding_and_set {
498 uint32_t binding;
499 uint32_t set;
500 };
501
502 auto get_binding = [&](const char* fixture) -> binding_and_set {
503 auto json_fd = GetReflectionJson(fixture);
504 nlohmann::json shader_json = nlohmann::json::parse(json_fd->GetMapping());
505 uint32_t binding = shader_json["buffers"][0]["binding"].get<uint32_t>();
506 uint32_t set = shader_json["buffers"][0]["set"].get<uint32_t>();
507 return {binding, set};
508 };
509
510 auto vert_uniform_binding = get_binding("sample_with_binding.vert");
511 auto frag_uniform_binding = get_binding("sample.frag");
512
513 ASSERT_EQ(frag_uniform_binding.set, 0u);
514 ASSERT_EQ(vert_uniform_binding.set, 3u);
515 ASSERT_EQ(vert_uniform_binding.binding, 17u);
516}
517
518TEST_P(CompilerTestSkSL, SkSLTextureLookUpOrderOfOperations) {
519 ASSERT_TRUE(
520 CanCompileAndReflect("texture_lookup.frag", SourceType::kFragmentShader));
521
522 auto shader = GetShaderFile("texture_lookup.frag", GetParam());
523 std::string_view shader_mapping(
524 reinterpret_cast<const char*>(shader->GetMapping()), shader->GetSize());
525
526 constexpr std::string_view expected =
527 "textureA.eval(textureA_size * ( vec2(1.0) + flutter_FragCoord.xy));";
528
529 EXPECT_NE(shader_mapping.find(expected), std::string::npos);
530}
531
532TEST_P(CompilerTestSkSL, CanCompileStructs) {
533 ASSERT_TRUE(CanCompileAndReflect("struct_internal.frag",
535}
536
537TEST_P(CompilerTestSkSL, FailsToCompileDueToArrayInitializerWithConstants) {
538 auto expected_err =
539 "There was a compiler error: SkSL does not support array initializers: "
540 "array_initializer_with_constants.frag:6";
541
542 EXPECT_EXIT(CanCompileAndReflect("array_initializer_with_constants.frag",
544 ::testing::ExitedWithCode(1), expected_err);
545}
546
547TEST_P(CompilerTestSkSL, FailsToCompileDueToArrayInitializerWithVariables) {
548 auto expected_err =
549 "There was a compiler error: SkSL does not support array initializers: "
550 "array_initializer_with_variables.frag:12";
551
552 EXPECT_EXIT(CanCompileAndReflect("array_initializer_with_variables.frag",
554 ::testing::ExitedWithCode(1), expected_err);
555}
556
557TEST_P(CompilerTestSkSL, FailsToCompileDueToArrayAssignment) {
558 // Does not EXIT because the backend SkSL compiler doesn't detect the invalid
559 // SkSL. Returns false because the Impeller Compiler's post-compile validation
560 // fails.
561 ASSERT_FALSE(CanCompileAndReflect("array_assignment.frag",
563
564 const Compiler* compiler = GetCompiler();
565 ASSERT_TRUE(compiler);
566 // Truncated error message.
567 ASSERT_STREQ(
568 compiler->GetErrorMessages().c_str(),
569 "\"array_assignment.frag\": \n"
570 "Compiled to invalid SkSL:\n"
571 " // This SkSL shader is autogenerated by spirv-cross.\n"
572 " \n"
573 " float4 flutter_FragCoord;\n"
574 " \n"
575 " vec4 frag_color;\n"
576 " \n"
577 "... (truncated 16 lines)\n"
578 "SkSL Error:\n"
579 " error: 12: initializers are not permitted on arrays (or structs "
580 "containing arrays)\n"
581 " float more_nums[2] = nums;\n"
582 " ^^^^\n"
583 " 1 error\n");
584 // Full error message.
585 ASSERT_STREQ(compiler->GetVerboseErrorMessages().c_str(),
586 "\"array_assignment.frag\": \n"
587 "Compiled to invalid SkSL:\n"
588 "// This SkSL shader is autogenerated by spirv-cross.\n"
589 "\n"
590 "float4 flutter_FragCoord;\n"
591 "\n"
592 "vec4 frag_color;\n"
593 "\n"
594 "void FLT_main()\n"
595 "{\n"
596 " float nums[2];\n"
597 " nums[0] = 1.0;\n"
598 " nums[1] = 0.5;\n"
599 " float more_nums[2] = nums;\n"
600 " frag_color = vec4(nums[0], nums[1], 1.0, 1.0);\n"
601 "}\n"
602 "\n"
603 "half4 main(float2 iFragCoord)\n"
604 "{\n"
605 " flutter_FragCoord = float4(iFragCoord, 0, 0);\n"
606 " FLT_main();\n"
607 " return frag_color;\n"
608 "}\n"
609 "\n"
610 "SkSL Error:\n"
611 "error: 12: initializers are not permitted on arrays (or "
612 "structs containing arrays)\n"
613 " float more_nums[2] = nums;\n"
614 " ^^^^\n"
615 "1 error\n"
616 "\n");
617}
618
619TEST_P(CompilerTestSkSL, CompilesWithValidArrayInitialization) {
620 ASSERT_TRUE(
621 CanCompileAndReflect("array_initialization_without_initializer.frag",
623}
624
625TEST_P(CompilerTestRuntime, Mat2Reflection) {
626 if (GetParam() == TargetPlatform::kSkSL) {
627 GTEST_SKIP() << "Not supported with SkSL";
628 }
629
630 ASSERT_TRUE(CanCompileAndReflect(
632
633 std::unique_ptr<fml::FileMapping> json_fd =
634 GetReflectionJson("mat2_test.frag");
635 ASSERT_TRUE(json_fd);
636 nlohmann::json shader_json = nlohmann::json::parse(json_fd->GetMapping());
637 nlohmann::json::value_type buffers = shader_json["buffers"];
638
639 // uParams should be in buffers.
640 ASSERT_GE(buffers.size(), 1u);
641 nlohmann::json::value_type uParams = buffers[0];
642 EXPECT_EQ(uParams["name"], "Params");
643
644 nlohmann::json::value_type members = uParams["type"]["members"];
645 // We expect 1 member (for the mat2) which is a Point (vec2) with array
646 // size 2.
647 ASSERT_EQ(members.size(), 1u);
648
649 nlohmann::json::value_type mat2Member = members[0];
650
651 // Should be Mat2 (vec2)
652 EXPECT_EQ(mat2Member["type"], "Mat2");
653
654 // Size 8 bytes (vec2)
655 EXPECT_EQ(mat2Member["size"], 8u);
656
657 // Byte length should be total array size (stride * count)
658 // Stride 16 * 2 = 32.
659 EXPECT_EQ(mat2Member["byte_length"], 32u);
660
661 // Array elements should be 2 (columns).
662 EXPECT_EQ(mat2Member["array_elements"], 2u);
663
664 // Offset 0
665 EXPECT_EQ(mat2Member["offset"], 0u);
666}
667
668TEST_P(CompilerTestUnknownPlatform, MustFailDueToUnknownPlatform) {
669 ASSERT_FALSE(
670 CanCompileAndReflect("sample.frag", SourceType::kFragmentShader));
671}
672
673} // namespace testing
674} // namespace compiler
675} // namespace impeller
std::string GetVerboseErrorMessages() const
Definition compiler.cc:705
std::shared_ptr< fml::Mapping > GetSPIRVAssembly() const
Definition compiler.cc:683
std::shared_ptr< fml::Mapping > GetSLShaderSource() const
Definition compiler.cc:687
std::string GetErrorMessages() const
Definition compiler.cc:701
uint32_t vec_size
std::string type_name
uint32_t columns
std::string uniform_name
uint32_t location
bool operator==(const FlutterPoint &a, const FlutterPoint &b)
std::ostream & operator<<(std::ostream &out, const FlutterPoint &point)
#define FML_CHECK(condition)
Definition logging.h:104
const char * name
Definition fuchsia.cc:50
fml::UniqueFD OpenFixturesDirectory()
Opens the fixtures directory for the unit-test harness.
Definition testing.cc:22
std::unique_ptr< fml::Mapping > OpenFixtureAsMapping(const std::string &fixture_name)
Opens a fixture of the given file name and returns a mapping to its contents.
Definition testing.cc:58
std::function< ProfileSample(void)> Sampler
Sampler is run during SamplingProfiler::SampleRepeatedly. Each platform should implement its version ...
INSTANTIATE_TEST_SUITE_P(CompilerSuite, CompilerTest, ::testing::Values(TargetPlatform::kOpenGLES, TargetPlatform::kOpenGLDesktop, TargetPlatform::kMetalDesktop, TargetPlatform::kMetalIOS, TargetPlatform::kVulkan), [](const ::testing::TestParamInfo< CompilerTest::ParamType > &info) { return TargetPlatformToString(info.param);})
TEST_P(CompilerTest, CanCompile)
TEST(CompilerTest, Defines)
std::string TargetPlatformToString(TargetPlatform platform)
Definition types.cc:62
SourceType SourceTypeFromFileName(const std::filesystem::path &file_name)
Definition types.cc:17
bool TargetPlatformIsOpenGL(TargetPlatform platform)
Definition types.cc:239
bool TargetPlatformIsVulkan(TargetPlatform platform)
Definition types.cc:277
impeller::ShaderType type
std::shared_ptr< fml::UniqueFD > working_directory