1 //
2 // Copyright 2017 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // ScalarizeVecAndMatConstructorArgs_test.cpp:
7 // Tests for scalarizing vector and matrix constructor args.
8 //
9
10 #include "GLSLANG/ShaderLang.h"
11 #include "angle_gl.h"
12 #include "gtest/gtest.h"
13 #include "tests/test_utils/compiler_test.h"
14
15 using namespace sh;
16
17 namespace
18 {
19
20 class ScalarizeVecAndMatConstructorArgsTest : public MatchOutputCodeTest
21 {
22 public:
ScalarizeVecAndMatConstructorArgsTest()23 ScalarizeVecAndMatConstructorArgsTest()
24 : MatchOutputCodeTest(GL_FRAGMENT_SHADER,
25 SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS,
26 SH_ESSL_OUTPUT)
27 {}
28 };
29
30 // Verifies scalarizing matrix inside a vector constructor.
TEST_F(ScalarizeVecAndMatConstructorArgsTest,MatrixInVectorConstructor)31 TEST_F(ScalarizeVecAndMatConstructorArgsTest, MatrixInVectorConstructor)
32 {
33 const std::string shaderString =
34 R"(
35 precision mediump float;
36
37 uniform mat2 umat2;
38
39 void main()
40 {
41 gl_FragColor = vec4(umat2);
42 })";
43 compile(shaderString);
44
45 std::vector<const char *> expectedStrings = {
46 "main()", " = _uumat2", "gl_FragColor = vec4(", "[0][0],", "[0][1],", "[1][0],", "[1][1])"};
47
48 EXPECT_TRUE(foundInCodeInOrder(expectedStrings));
49 }
50
51 // Verifies scalarizing a vector insized a matrix constructor.
TEST_F(ScalarizeVecAndMatConstructorArgsTest,VectorInMatrixConstructor)52 TEST_F(ScalarizeVecAndMatConstructorArgsTest, VectorInMatrixConstructor)
53 {
54 const std::string shaderString =
55 R"(
56 precision mediump float;
57
58 uniform vec2 uvec2;
59
60 void main()
61 {
62 mat2 m = mat2(uvec2, uvec2);
63 gl_FragColor = vec4(m * uvec2, m * uvec2);
64 })";
65 compile(shaderString);
66
67 std::vector<const char *> expectedStrings = {
68 "main()", " = _uuvec2", "mat2(", "[0],", "[1],", "[0],", "[1])", "gl_FragColor = vec4("};
69
70 EXPECT_TRUE(foundInCodeInOrder(expectedStrings));
71 }
72
73 // Verifies that scalarizing vector and matrix constructor args inside a sequence operator preserves
74 // correct order of operations.
TEST_F(ScalarizeVecAndMatConstructorArgsTest,SequenceOperator)75 TEST_F(ScalarizeVecAndMatConstructorArgsTest, SequenceOperator)
76 {
77 const std::string shaderString =
78 R"(
79 precision mediump float;
80
81 uniform vec2 u;
82
83 void main()
84 {
85 vec2 v = u;
86 mat2 m = (v[0] += 1.0, mat2(v, v[1], -v[0]));
87 gl_FragColor = vec4(m[0], m[1]);
88 })";
89 compile(shaderString);
90
91 std::vector<const char *> expectedStrings = {"_uv[0] += ", "-_uv[0]"};
92
93 EXPECT_TRUE(foundInCodeInOrder(expectedStrings));
94 }
95
96 // Verifies that scalarizing vector and matrix constructor args inside multiple declarations
97 // preserves the correct order of operations.
TEST_F(ScalarizeVecAndMatConstructorArgsTest,MultiDeclaration)98 TEST_F(ScalarizeVecAndMatConstructorArgsTest, MultiDeclaration)
99 {
100 const std::string shaderString =
101 R"(
102 precision mediump float;
103
104 uniform vec2 u;
105
106 void main()
107 {
108 vec2 v = vec2(u[0]),
109 w = mat2(v, v) * u;
110 gl_FragColor = vec4(v, w);
111 })";
112 compile(shaderString);
113
114 std::vector<const char *> expectedStrings = {"vec2(_uu[0])", "mat2("};
115
116 EXPECT_TRUE(foundInCodeInOrder(expectedStrings));
117 }
118
119 // Verifies that constructors without precision don't cause issues.
TEST_F(ScalarizeVecAndMatConstructorArgsTest,ConstructorWithoutPrecision)120 TEST_F(ScalarizeVecAndMatConstructorArgsTest, ConstructorWithoutPrecision)
121 {
122 const std::string shaderString =
123 R"(
124 precision mediump float;
125
126 uniform float u;
127
128 void main()
129 {
130 mat4 m = mat4(u);
131 mat2(0, bvec3(m));
132 })";
133 compile(shaderString);
134 }
135
136 } // anonymous namespace
137