| // Copyright 2013 The Flutter Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include "flutter/testing/testing.h" | |
| #include "impeller/base/validation.h" | |
| #include "impeller/compiler/compiler.h" | |
| #include "impeller/compiler/compiler_test.h" | |
| #include "impeller/compiler/source_options.h" | |
| #include "impeller/compiler/types.h" | |
| namespace impeller { | |
| namespace compiler { | |
| namespace testing { | |
| TEST(CompilerTest, ShaderKindMatchingIsSuccessful) { | |
| ASSERT_EQ(SourceTypeFromFileName("hello.vert"), SourceType::kVertexShader); | |
| ASSERT_EQ(SourceTypeFromFileName("hello.frag"), SourceType::kFragmentShader); | |
| ASSERT_EQ(SourceTypeFromFileName("hello.tesc"), | |
| SourceType::kTessellationControlShader); | |
| ASSERT_EQ(SourceTypeFromFileName("hello.tese"), | |
| SourceType::kTessellationEvaluationShader); | |
| ASSERT_EQ(SourceTypeFromFileName("hello.comp"), SourceType::kComputeShader); | |
| ASSERT_EQ(SourceTypeFromFileName("hello.msl"), SourceType::kUnknown); | |
| ASSERT_EQ(SourceTypeFromFileName("hello.glsl"), SourceType::kUnknown); | |
| } | |
| TEST_P(CompilerTest, CanCompile) { | |
| ASSERT_TRUE(CanCompileAndReflect("sample.vert")); | |
| ASSERT_TRUE(CanCompileAndReflect("sample.vert", SourceType::kVertexShader)); | |
| ASSERT_TRUE(CanCompileAndReflect("sample.vert", SourceType::kVertexShader, | |
| SourceLanguage::kGLSL)); | |
| } | |
| TEST_P(CompilerTest, CanCompileHLSL) { | |
| ASSERT_TRUE(CanCompileAndReflect( | |
| "simple.vert.hlsl", SourceType::kVertexShader, SourceLanguage::kHLSL)); | |
| } | |
| TEST_P(CompilerTest, CanCompileHLSLWithMultipleStages) { | |
| ASSERT_TRUE(CanCompileAndReflect("multiple_stages.hlsl", | |
| SourceType::kVertexShader, | |
| SourceLanguage::kHLSL, "VertexShader")); | |
| ASSERT_TRUE(CanCompileAndReflect("multiple_stages.hlsl", | |
| SourceType::kFragmentShader, | |
| SourceLanguage::kHLSL, "FragmentShader")); | |
| } | |
| TEST_P(CompilerTest, CanCompileTessellationControlShader) { | |
| ASSERT_TRUE(CanCompileAndReflect("sample.tesc")); | |
| ASSERT_TRUE(CanCompileAndReflect("sample.tesc", | |
| SourceType::kTessellationControlShader)); | |
| } | |
| TEST_P(CompilerTest, CanCompileTessellationEvaluationShader) { | |
| ASSERT_TRUE(CanCompileAndReflect("sample.tese")); | |
| ASSERT_TRUE(CanCompileAndReflect("sample.tese", | |
| SourceType::kTessellationEvaluationShader)); | |
| } | |
| TEST_P(CompilerTest, CanCompileComputeShader) { | |
| if (!TargetPlatformIsMetal(GetParam())) { | |
| GTEST_SKIP_("Only enabled on Metal backends till ES 3.2 support is added."); | |
| } | |
| ASSERT_TRUE(CanCompileAndReflect("sample.comp")); | |
| ASSERT_TRUE(CanCompileAndReflect("sample.comp", SourceType::kComputeShader)); | |
| } | |
| TEST_P(CompilerTest, MustFailDueToExceedingResourcesLimit) { | |
| ScopedValidationDisable disable_validation; | |
| ASSERT_FALSE( | |
| CanCompileAndReflect("resources_limit.vert", SourceType::kVertexShader)); | |
| } | |
| TEST_P(CompilerTest, MustFailDueToMultipleLocationPerStructMember) { | |
| ScopedValidationDisable disable_validation; | |
| ASSERT_FALSE(CanCompileAndReflect("struct_def_bug.vert")); | |
| } | |
| TEST_P(CompilerTest, BindingBaseForFragShader) { | |
| #ifndef IMPELLER_ENABLE_VULKAN | |
| GTEST_SKIP(); | |
| #endif | |
| ASSERT_TRUE(CanCompileAndReflect("sample.vert", SourceType::kVertexShader)); | |
| ASSERT_TRUE(CanCompileAndReflect("sample.frag", SourceType::kFragmentShader)); | |
| auto get_binding = [&](const char* fixture) -> uint32_t { | |
| auto json_fd = GetReflectionJson(fixture); | |
| nlohmann::json shader_json = nlohmann::json::parse(json_fd->GetMapping()); | |
| return shader_json["buffers"][0]["binding"].get<uint32_t>(); | |
| }; | |
| auto vert_uniform_binding = get_binding("sample.vert"); | |
| auto frag_uniform_binding = get_binding("sample.frag"); | |
| ASSERT_GT(frag_uniform_binding, vert_uniform_binding); | |
| } | |
| TEST_P(CompilerTest, UniformsHaveBindingAndSet) { | |
| ASSERT_TRUE(CanCompileAndReflect("sample_with_binding.vert", | |
| SourceType::kVertexShader)); | |
| ASSERT_TRUE(CanCompileAndReflect("sample.frag", SourceType::kFragmentShader)); | |
| struct binding_and_set { | |
| uint32_t binding; | |
| uint32_t set; | |
| }; | |
| auto get_binding = [&](const char* fixture) -> binding_and_set { | |
| auto json_fd = GetReflectionJson(fixture); | |
| nlohmann::json shader_json = nlohmann::json::parse(json_fd->GetMapping()); | |
| uint32_t binding = shader_json["buffers"][0]["binding"].get<uint32_t>(); | |
| uint32_t set = shader_json["buffers"][0]["set"].get<uint32_t>(); | |
| return {binding, set}; | |
| }; | |
| auto vert_uniform_binding = get_binding("sample_with_binding.vert"); | |
| auto frag_uniform_binding = get_binding("sample.frag"); | |
| ASSERT_EQ(frag_uniform_binding.set, 0u); | |
| ASSERT_EQ(vert_uniform_binding.set, 3u); | |
| ASSERT_EQ(vert_uniform_binding.binding, 17u); | |
| } | |
| #define INSTANTIATE_TARGET_PLATFORM_TEST_SUITE_P(suite_name) \ | |
| INSTANTIATE_TEST_SUITE_P( \ | |
| suite_name, CompilerTest, \ | |
| ::testing::Values( \ | |
| TargetPlatform::kOpenGLES, TargetPlatform::kOpenGLDesktop, \ | |
| TargetPlatform::kMetalDesktop, TargetPlatform::kMetalIOS), \ | |
| [](const ::testing::TestParamInfo<CompilerTest::ParamType>& info) { \ | |
| return TargetPlatformToString(info.param); \ | |
| }); | |
| INSTANTIATE_TARGET_PLATFORM_TEST_SUITE_P(CompilerSuite); | |
| } // namespace testing | |
| } // namespace compiler | |
| } // namespace impeller |