xref: /aosp_15_r20/external/angle/src/tests/compiler_tests/VariablePacker_test.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2002 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 
7 #include "gtest/gtest.h"
8 
9 #include "angle_gl.h"
10 #include "common/angleutils.h"
11 #include "common/utilities.h"
12 #include "compiler/translator/VariablePacker.h"
13 
14 namespace
15 {
16 
17 static sh::GLenum types[] = {
18     GL_FLOAT_MAT4,                     // 0
19     GL_FLOAT_MAT2,                     // 1
20     GL_FLOAT_VEC4,                     // 2
21     GL_INT_VEC4,                       // 3
22     GL_BOOL_VEC4,                      // 4
23     GL_FLOAT_MAT3,                     // 5
24     GL_FLOAT_VEC3,                     // 6
25     GL_INT_VEC3,                       // 7
26     GL_BOOL_VEC3,                      // 8
27     GL_FLOAT_VEC2,                     // 9
28     GL_INT_VEC2,                       // 10
29     GL_BOOL_VEC2,                      // 11
30     GL_FLOAT,                          // 12
31     GL_INT,                            // 13
32     GL_BOOL,                           // 14
33     GL_SAMPLER_2D,                     // 15
34     GL_SAMPLER_CUBE,                   // 16
35     GL_SAMPLER_EXTERNAL_OES,           // 17
36     GL_SAMPLER_2D_RECT_ANGLE,          // 18
37     GL_UNSIGNED_INT,                   // 19
38     GL_UNSIGNED_INT_VEC2,              // 20
39     GL_UNSIGNED_INT_VEC3,              // 21
40     GL_UNSIGNED_INT_VEC4,              // 22
41     GL_FLOAT_MAT2x3,                   // 23
42     GL_FLOAT_MAT2x4,                   // 24
43     GL_FLOAT_MAT3x2,                   // 25
44     GL_FLOAT_MAT3x4,                   // 26
45     GL_FLOAT_MAT4x2,                   // 27
46     GL_FLOAT_MAT4x3,                   // 28
47     GL_SAMPLER_3D,                     // 29
48     GL_SAMPLER_2D_ARRAY,               // 30
49     GL_SAMPLER_2D_SHADOW,              // 31
50     GL_SAMPLER_CUBE_SHADOW,            // 32
51     GL_SAMPLER_2D_ARRAY_SHADOW,        // 33
52     GL_INT_SAMPLER_2D,                 // 34
53     GL_INT_SAMPLER_CUBE,               // 35
54     GL_INT_SAMPLER_3D,                 // 36
55     GL_INT_SAMPLER_2D_ARRAY,           // 37
56     GL_UNSIGNED_INT_SAMPLER_2D,        // 38
57     GL_UNSIGNED_INT_SAMPLER_CUBE,      // 39
58     GL_UNSIGNED_INT_SAMPLER_3D,        // 40
59     GL_UNSIGNED_INT_SAMPLER_2D_ARRAY,  // 41
60 };
61 
62 static sh::GLenum nonSqMatTypes[] = {GL_FLOAT_MAT2x3, GL_FLOAT_MAT2x4, GL_FLOAT_MAT3x2,
63                                      GL_FLOAT_MAT3x4, GL_FLOAT_MAT4x2, GL_FLOAT_MAT4x3};
64 
65 // Creates either a single variable or an array variable depending on numVars.
CreateShaderVariable(sh::GLenum type,int numVars)66 sh::ShaderVariable CreateShaderVariable(sh::GLenum type, int numVars)
67 {
68     ASSERT(numVars != 0);
69     if (numVars == 1)
70     {
71         return sh::ShaderVariable(type);
72     }
73     return sh::ShaderVariable(type, numVars);
74 }
75 
76 }  // anonymous namespace
77 
TEST(VariablePacking,Pack)78 TEST(VariablePacking, Pack)
79 {
80     std::vector<sh::ShaderVariable> vars;
81     const int kMaxRows = 16;
82     // test no vars.
83     EXPECT_TRUE(CheckVariablesInPackingLimits(kMaxRows, vars));
84 
85     for (size_t tt = 0; tt < ArraySize(types); ++tt)
86     {
87         sh::GLenum type            = types[tt];
88         int num_rows               = sh::GetTypePackingRows(type);
89         int num_components_per_row = sh::GetTypePackingComponentsPerRow(type);
90         // Check 1 of the type.
91         vars.clear();
92         vars.push_back(sh::ShaderVariable(type));
93         EXPECT_TRUE(CheckVariablesInPackingLimits(kMaxRows, vars));
94 
95         // Check exactly the right amount of 1 type as an array.
96         int num_vars = kMaxRows / num_rows;
97         vars.clear();
98         vars.push_back(CreateShaderVariable(type, num_vars));
99         EXPECT_TRUE(CheckVariablesInPackingLimits(kMaxRows, vars));
100 
101         // test too many
102         vars.clear();
103         vars.push_back(CreateShaderVariable(type, num_vars + 1));
104         EXPECT_FALSE(CheckVariablesInPackingLimits(kMaxRows, vars));
105 
106         // Check exactly the right amount of 1 type as individual vars.
107         num_vars =
108             kMaxRows / num_rows * ((num_components_per_row > 2) ? 1 : (4 / num_components_per_row));
109         vars.clear();
110         for (int ii = 0; ii < num_vars; ++ii)
111         {
112             vars.push_back(sh::ShaderVariable(type));
113         }
114         EXPECT_TRUE(CheckVariablesInPackingLimits(kMaxRows, vars));
115 
116         // Check 1 too many.
117         vars.push_back(sh::ShaderVariable(type));
118         EXPECT_FALSE(CheckVariablesInPackingLimits(kMaxRows, vars));
119     }
120 
121     // Test example from GLSL ES 3.0 spec chapter 11.
122     vars.clear();
123     vars.push_back(sh::ShaderVariable(GL_FLOAT_VEC4));
124     vars.push_back(sh::ShaderVariable(GL_FLOAT_MAT3));
125     vars.push_back(sh::ShaderVariable(GL_FLOAT_MAT3));
126     vars.push_back(sh::ShaderVariable(GL_FLOAT_VEC2, 6));
127     vars.push_back(sh::ShaderVariable(GL_FLOAT_VEC2, 4));
128     vars.push_back(sh::ShaderVariable(GL_FLOAT_VEC2));
129     vars.push_back(sh::ShaderVariable(GL_FLOAT, 3));
130     vars.push_back(sh::ShaderVariable(GL_FLOAT, 2));
131     vars.push_back(sh::ShaderVariable(GL_FLOAT));
132     EXPECT_TRUE(CheckVariablesInPackingLimits(kMaxRows, vars));
133 }
134 
TEST(VariablePacking,PackSizes)135 TEST(VariablePacking, PackSizes)
136 {
137     for (size_t tt = 0; tt < ArraySize(types); ++tt)
138     {
139         sh::GLenum type = types[tt];
140 
141         int expectedComponents = gl::VariableComponentCount(type);
142         int expectedRows       = gl::VariableRowCount(type);
143 
144         if (type == GL_FLOAT_MAT2)
145         {
146             expectedComponents = 4;
147         }
148         else if (gl::IsMatrixType(type))
149         {
150             int squareSize = std::max(gl::VariableRowCount(type), gl::VariableColumnCount(type));
151             expectedComponents = squareSize;
152             expectedRows       = squareSize;
153         }
154 
155         EXPECT_EQ(expectedComponents, sh::GetTypePackingComponentsPerRow(type));
156         EXPECT_EQ(expectedRows, sh::GetTypePackingRows(type));
157     }
158 }
159 
160 // Check special assumptions about packing non-square mats
TEST(VariablePacking,NonSquareMats)161 TEST(VariablePacking, NonSquareMats)
162 {
163 
164     for (size_t mt = 0; mt < ArraySize(nonSqMatTypes); ++mt)
165     {
166 
167         sh::GLenum type = nonSqMatTypes[mt];
168 
169         int rows       = gl::VariableRowCount(type);
170         int cols       = gl::VariableColumnCount(type);
171         int squareSize = std::max(rows, cols);
172 
173         std::vector<sh::ShaderVariable> vars;
174         vars.push_back(sh::ShaderVariable(type));
175 
176         // Fill columns
177         for (int row = 0; row < squareSize; row++)
178         {
179             for (int col = squareSize; col < 4; ++col)
180             {
181                 vars.push_back(sh::ShaderVariable(GL_FLOAT));
182             }
183         }
184 
185         EXPECT_TRUE(CheckVariablesInPackingLimits(squareSize, vars));
186 
187         // and one scalar and packing should fail
188         vars.push_back(sh::ShaderVariable(GL_FLOAT));
189         EXPECT_FALSE(CheckVariablesInPackingLimits(squareSize, vars));
190     }
191 }
192 
193 // Scalar type variables can be packed sharing rows with other variables.
TEST(VariablePacking,ReuseRows)194 TEST(VariablePacking, ReuseRows)
195 {
196     std::vector<sh::ShaderVariable> vars;
197     const int kMaxRows = 512;
198 
199     // uniform bool u0[129];
200     // uniform bool u1[129];
201     // uniform bool u2[129];
202     // uniform bool u3[129];
203     {
204         int num_arrays             = 4;
205         int num_elements_per_array = kMaxRows / num_arrays + 1;
206         for (int ii = 0; ii < num_arrays; ++ii)
207         {
208             vars.push_back(sh::ShaderVariable(GL_BOOL, num_elements_per_array));
209         }
210         EXPECT_TRUE(CheckVariablesInPackingLimits(kMaxRows, vars));
211     }
212 
213     vars.clear();
214     // uniform vec2 u0[257];
215     // uniform float u1[257];
216     // uniform int u1[257];
217     {
218         int num_elements_per_array = kMaxRows / 2 + 1;
219         vars.push_back(sh::ShaderVariable(GL_FLOAT_VEC2, num_elements_per_array));
220         vars.push_back(sh::ShaderVariable(GL_FLOAT, num_elements_per_array));
221         vars.push_back(sh::ShaderVariable(GL_INT, num_elements_per_array));
222         EXPECT_TRUE(CheckVariablesInPackingLimits(kMaxRows, vars));
223     }
224 }
225 
226 // Check the packer supports and flattens structures.
TEST(VariablePacking,Struct)227 TEST(VariablePacking, Struct)
228 {
229     std::vector<sh::ShaderVariable> fields;
230     const int kMaxRows = 16;
231 
232     // Test example from GLSL ES 3.0 spec chapter 11, but with structs
233     std::vector<sh::ShaderVariable> vars;
234     vars.push_back(sh::ShaderVariable(GL_NONE));
235 
236     sh::ShaderVariable &parentStruct = vars[0];
237     parentStruct.fields.push_back(sh::ShaderVariable(GL_FLOAT_VEC4));
238     parentStruct.fields.push_back(sh::ShaderVariable(GL_FLOAT_MAT3));
239 
240     parentStruct.fields.push_back(sh::ShaderVariable(GL_NONE));
241     sh::ShaderVariable &innerStruct = parentStruct.fields.back();
242     innerStruct.fields.push_back(sh::ShaderVariable(GL_FLOAT_MAT3));
243     innerStruct.fields.push_back(sh::ShaderVariable(GL_FLOAT_VEC2, 6));
244     innerStruct.fields.push_back(sh::ShaderVariable(GL_FLOAT_VEC2, 4));
245 
246     parentStruct.fields.push_back(sh::ShaderVariable(GL_FLOAT_VEC2));
247     parentStruct.fields.push_back(sh::ShaderVariable(GL_FLOAT, 3));
248     parentStruct.fields.push_back(sh::ShaderVariable(GL_FLOAT, 2));
249     parentStruct.fields.push_back(sh::ShaderVariable(GL_FLOAT));
250 
251     EXPECT_TRUE(CheckVariablesInPackingLimits(kMaxRows, vars));
252 }
253