6 #include "flutter/testing/testing.h"
7 #include "gtest/gtest.h"
26 [](const ::testing::TestParamInfo<CompilerTest::ParamType>& info) {
38 [](const ::testing::TestParamInfo<CompilerTest::ParamType>& info) {
46 [](const ::testing::TestParamInfo<CompilerTest::ParamType>& info) {
54 [](const ::testing::TestParamInfo<CompilerTest::ParamType>& info) {
59 std::shared_ptr<const fml::Mapping> fixture =
60 flutter::testing::OpenFixtureAsMapping(
"check_gles_definition.frag");
91 ASSERT_TRUE(CanCompileAndReflect(
"sample.vert"));
98 ASSERT_TRUE(CanCompileAndReflect(
103 ASSERT_TRUE(CanCompileAndReflect(
"multiple_stages.hlsl",
106 ASSERT_TRUE(CanCompileAndReflect(
"multiple_stages.hlsl",
114 <<
"Only enabled on Metal backends till ES 3.2 support is added.";
116 ASSERT_TRUE(CanCompileAndReflect(
"sample.comp"));
128 ASSERT_FALSE(CanCompileAndReflect(
"struct_def_bug.vert"));
139 auto get_binding = [&](
const char* fixture) -> uint32_t {
140 auto json_fd = GetReflectionJson(fixture);
141 nlohmann::json shader_json = nlohmann::json::parse(json_fd->GetMapping());
142 return shader_json[
"buffers"][0][
"binding"].get<uint32_t>();
145 auto vert_uniform_binding = get_binding(
"sample.vert");
146 auto frag_uniform_binding = get_binding(
"sample.frag");
148 ASSERT_GT(frag_uniform_binding, vert_uniform_binding);
159 static UniformInfo fromJson(
const nlohmann::json& json) {
161 .uniform_name = json[
"name"].get<std::string>(),
162 .
location = json[
"location"].get<uint32_t>(),
163 .type_name = json[
"type"][
"type_name"].get<std::string>(),
164 .
columns = json[
"type"][
"columns"].get<uint32_t>(),
165 .vec_size = json[
"type"][
"vec_size"].get<uint32_t>(),
169 static UniformInfo Sampler(
const std::string& name, uint32_t
location) {
171 .uniform_name = name,
173 .type_name =
"ShaderType::kSampledImage",
178 static UniformInfo Float(
const std::string& name, uint32_t
location) {
179 return FloatInfo(name,
location, 1u, 1u);
181 static UniformInfo Vec2(
const std::string& name, uint32_t
location) {
182 return FloatInfo(name,
location, 1u, 2u);
184 static UniformInfo Vec3(
const std::string& name, uint32_t
location) {
185 return FloatInfo(name,
location, 1u, 3u);
187 static UniformInfo Vec4(
const std::string& name, uint32_t
location) {
188 return FloatInfo(name,
location, 1u, 4u);
190 static UniformInfo Mat4(
const std::string& name, uint32_t
location) {
191 return FloatInfo(name,
location, 4u, 4u);
194 constexpr
bool operator==(
const UniformInfo& other)
const {
203 static UniformInfo FloatInfo(
const std::string& name,
208 .uniform_name = name,
210 .type_name =
"ShaderType::kFloat",
217 inline std::ostream&
operator<<(std::ostream& out,
const UniformInfo& info) {
218 out <<
"UniformInfo {" << std::endl
219 <<
" uniform_name: " << info.uniform_name << std::endl
220 <<
" location: " << info.location << std::endl
221 <<
" type_name: " << info.type_name << std::endl
222 <<
" columns: " << info.columns << std::endl
223 <<
" vec_size: " << info.vec_size << std::endl
233 GTEST_SKIP() <<
"Not supported with Vulkan";
236 ASSERT_TRUE(CanCompileAndReflect(
"sample_with_uniforms.frag",
240 auto json_fd = GetReflectionJson(
"sample_with_uniforms.frag");
241 ASSERT_TRUE(json_fd);
242 nlohmann::json shader_json = nlohmann::json::parse(json_fd->GetMapping());
243 auto sampler_list = shader_json[
"sampled_images"];
244 auto float_list = shader_json[
"uniforms"];
245 ASSERT_EQ(sampler_list.size(), 2u);
246 ASSERT_EQ(float_list.size(), 6u);
250 std::array expected_infos = {
251 UniformInfo::Sampler(
"uFirstSampler", 1u),
252 UniformInfo::Sampler(
"uSampler", 7u),
255 ASSERT_EQ(sampler_list.size(), expected_infos.size());
256 for (
size_t i = 0; i < expected_infos.size(); i++) {
257 EXPECT_EQ(UniformInfo::fromJson(sampler_list[i]), expected_infos[i])
264 std::array expected_infos = {
265 UniformInfo::Float(
"uFirstFloat", 0u),
266 UniformInfo::Float(
"uFloat", 2u),
267 UniformInfo::Vec2(
"uVec2", 3u),
268 UniformInfo::Vec3(
"uVec3", 4u),
269 UniformInfo::Vec4(
"uVec4", 5u),
270 UniformInfo::Mat4(
"uMat4", 6u),
273 ASSERT_EQ(float_list.size(), expected_infos.size());
274 for (
size_t i = 0; i < expected_infos.size(); i++) {
275 EXPECT_EQ(UniformInfo::fromJson(float_list[i]), expected_infos[i])
285 GTEST_SKIP() <<
"Not supported with Vulkan";
288 ASSERT_TRUE(CanCompileAndReflect(
"sample_with_positioned_uniforms.frag",
292 auto json_fd = GetReflectionJson(
"sample_with_positioned_uniforms.frag");
293 ASSERT_TRUE(json_fd);
294 nlohmann::json shader_json = nlohmann::json::parse(json_fd->GetMapping());
295 auto sampler_list = shader_json[
"sampled_images"];
296 auto float_list = shader_json[
"uniforms"];
297 ASSERT_EQ(sampler_list.size(), 3u);
298 ASSERT_EQ(float_list.size(), 7u);
302 std::array expected_infos = {
303 UniformInfo::Sampler(
"uSamplerNotPositioned1", 1u),
304 UniformInfo::Sampler(
"uSampler", 0u),
305 UniformInfo::Sampler(
"uSamplerNotPositioned2", 3u),
308 ASSERT_EQ(sampler_list.size(), expected_infos.size());
309 for (
size_t i = 0; i < expected_infos.size(); i++) {
310 EXPECT_EQ(UniformInfo::fromJson(sampler_list[i]), expected_infos[i])
317 std::array expected_infos = {
318 UniformInfo::Float(
"uFloatNotPositioned1", 0u),
319 UniformInfo::Float(
"uFloat", 6u),
320 UniformInfo::Vec2(
"uVec2", 5u),
321 UniformInfo::Vec3(
"uVec3", 3u),
322 UniformInfo::Vec4(
"uVec4", 2u),
323 UniformInfo::Mat4(
"uMat4", 1u),
324 UniformInfo::Float(
"uFloatNotPositioned2", 2u),
327 ASSERT_EQ(float_list.size(), expected_infos.size());
328 for (
size_t i = 0; i < expected_infos.size(); i++) {
329 EXPECT_EQ(UniformInfo::fromJson(float_list[i]), expected_infos[i])
337 GTEST_SKIP() <<
"Not supported with SkSL";
339 ASSERT_TRUE(CanCompileAndReflect(
"sample_with_binding.vert",
343 struct binding_and_set {
348 auto get_binding = [&](
const char* fixture) -> binding_and_set {
349 auto json_fd = GetReflectionJson(fixture);
350 nlohmann::json shader_json = nlohmann::json::parse(json_fd->GetMapping());
351 uint32_t binding = shader_json[
"buffers"][0][
"binding"].get<uint32_t>();
352 uint32_t set = shader_json[
"buffers"][0][
"set"].get<uint32_t>();
353 return {binding, set};
356 auto vert_uniform_binding = get_binding(
"sample_with_binding.vert");
357 auto frag_uniform_binding = get_binding(
"sample.frag");
359 ASSERT_EQ(frag_uniform_binding.set, 0u);
360 ASSERT_EQ(vert_uniform_binding.set, 3u);
361 ASSERT_EQ(vert_uniform_binding.binding, 17u);
368 auto shader = GetShaderFile(
"texture_lookup.frag", GetParam());
369 std::string_view shader_mapping(
370 reinterpret_cast<const char*
>(shader->GetMapping()), shader->GetSize());
372 constexpr std::string_view expected =
373 "textureA.eval(textureA_size * ( vec2(1.0) + flutter_FragCoord.xy));";
375 EXPECT_NE(shader_mapping.find(expected), std::string::npos);
379 ASSERT_TRUE(CanCompileAndReflect(
"struct_internal.frag",
385 "There was a compiler error: SkSL does not support array initializers: "
386 "array_initializer_with_constants.frag:6";
388 EXPECT_EXIT(CanCompileAndReflect(
"array_initializer_with_constants.frag",
390 ::testing::ExitedWithCode(1), expected_err);
395 "There was a compiler error: SkSL does not support array initializers: "
396 "array_initializer_with_variables.frag:12";
398 EXPECT_EXIT(CanCompileAndReflect(
"array_initializer_with_variables.frag",
400 ::testing::ExitedWithCode(1), expected_err);
407 ASSERT_FALSE(CanCompileAndReflect(
"array_assignment.frag",
410 const Compiler* compiler = GetCompiler();
411 ASSERT_TRUE(compiler);
415 "\"array_assignment.frag\": \n"
416 "Compiled to invalid SkSL:\n"
417 " // This SkSL shader is autogenerated by spirv-cross.\n"
419 " float4 flutter_FragCoord;\n"
421 " vec4 frag_color;\n"
423 "... (truncated 16 lines)\n"
425 " error: 12: initializers are not permitted on arrays (or structs "
426 "containing arrays)\n"
427 " float more_nums[2] = nums;\n"
432 "\"array_assignment.frag\": \n"
433 "Compiled to invalid SkSL:\n"
434 "// This SkSL shader is autogenerated by spirv-cross.\n"
436 "float4 flutter_FragCoord;\n"
445 " float more_nums[2] = nums;\n"
446 " frag_color = vec4(nums[0], nums[1], 1.0, 1.0);\n"
449 "half4 main(float2 iFragCoord)\n"
451 " flutter_FragCoord = float4(iFragCoord, 0, 0);\n"
453 " return frag_color;\n"
457 "error: 12: initializers are not permitted on arrays (or "
458 "structs containing arrays)\n"
459 " float more_nums[2] = nums;\n"
467 CanCompileAndReflect(
"array_initialization_without_initializer.frag",
473 GTEST_SKIP() <<
"Not supported with SkSL";
476 ASSERT_TRUE(CanCompileAndReflect(
479 std::unique_ptr<fml::FileMapping> json_fd =
480 GetReflectionJson(
"mat2_test.frag");
481 ASSERT_TRUE(json_fd);
482 nlohmann::json shader_json = nlohmann::json::parse(json_fd->GetMapping());
483 nlohmann::json::value_type buffers = shader_json[
"buffers"];
486 ASSERT_GE(buffers.size(), 1u);
487 nlohmann::json::value_type uParams = buffers[0];
488 EXPECT_EQ(uParams[
"name"],
"Params");
490 nlohmann::json::value_type members = uParams[
"type"][
"members"];
493 ASSERT_EQ(members.size(), 1u);
495 nlohmann::json::value_type mat2Member = members[0];
498 EXPECT_EQ(mat2Member[
"type"],
"Mat2");
501 EXPECT_EQ(mat2Member[
"size"], 8u);
505 EXPECT_EQ(mat2Member[
"byte_length"], 32u);
508 EXPECT_EQ(mat2Member[
"array_elements"], 2u);
511 EXPECT_EQ(mat2Member[
"offset"], 0u);
std::string GetVerboseErrorMessages() const
std::shared_ptr< fml::Mapping > GetSPIRVAssembly() const
std::string GetErrorMessages() const
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)
SourceType SourceTypeFromFileName(const std::filesystem::path &file_name)
bool TargetPlatformIsMetal(TargetPlatform platform)
bool TargetPlatformIsVulkan(TargetPlatform platform)
std::ostream & operator<<(std::ostream &out, const impeller::Arc &a)
TargetPlatform target_platform
SourceLanguage source_language
std::string entry_point_name
TargetPlatform target_platform