1//
2// Copyright (c) 2002-2012 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#include "gtest/gtest.h"
7#include "angle_gl.h"
8#include "common/utilities.h"
9#include "common/angleutils.h"
10#include "compiler/translator/VariablePacker.h"
11
12static sh::GLenum types[] = {
13  GL_FLOAT_MAT4,            // 0
14  GL_FLOAT_MAT2,            // 1
15  GL_FLOAT_VEC4,            // 2
16  GL_INT_VEC4,              // 3
17  GL_BOOL_VEC4,             // 4
18  GL_FLOAT_MAT3,            // 5
19  GL_FLOAT_VEC3,            // 6
20  GL_INT_VEC3,              // 7
21  GL_BOOL_VEC3,             // 8
22  GL_FLOAT_VEC2,            // 9
23  GL_INT_VEC2,              // 10
24  GL_BOOL_VEC2,             // 11
25  GL_FLOAT,                 // 12
26  GL_INT,                   // 13
27  GL_BOOL,                  // 14
28  GL_SAMPLER_2D,            // 15
29  GL_SAMPLER_CUBE,          // 16
30  GL_SAMPLER_EXTERNAL_OES,  // 17
31  GL_SAMPLER_2D_RECT_ARB,   // 18
32  GL_UNSIGNED_INT,          // 19
33  GL_UNSIGNED_INT_VEC2,     // 20
34  GL_UNSIGNED_INT_VEC3,     // 21
35  GL_UNSIGNED_INT_VEC4,     // 22
36  GL_FLOAT_MAT2x3,          // 23
37  GL_FLOAT_MAT2x4,          // 24
38  GL_FLOAT_MAT3x2,          // 25
39  GL_FLOAT_MAT3x4,          // 26
40  GL_FLOAT_MAT4x2,          // 27
41  GL_FLOAT_MAT4x3,          // 28
42  GL_SAMPLER_3D,            // 29
43  GL_SAMPLER_2D_ARRAY,      // 30
44  GL_SAMPLER_2D_SHADOW,     // 31
45  GL_SAMPLER_CUBE_SHADOW,   // 32
46  GL_SAMPLER_2D_ARRAY_SHADOW, // 33
47  GL_INT_SAMPLER_2D,        // 34
48  GL_INT_SAMPLER_CUBE,      // 35
49  GL_INT_SAMPLER_3D,        // 36
50  GL_INT_SAMPLER_2D_ARRAY,  // 37
51  GL_UNSIGNED_INT_SAMPLER_2D, // 38
52  GL_UNSIGNED_INT_SAMPLER_CUBE, // 39
53  GL_UNSIGNED_INT_SAMPLER_3D, // 40
54  GL_UNSIGNED_INT_SAMPLER_2D_ARRAY, // 41
55};
56
57static sh::GLenum nonSqMatTypes[] = {
58  GL_FLOAT_MAT2x3,
59  GL_FLOAT_MAT2x4,
60  GL_FLOAT_MAT3x2,
61  GL_FLOAT_MAT3x4,
62  GL_FLOAT_MAT4x2,
63  GL_FLOAT_MAT4x3
64};
65
66TEST(VariablePacking, Pack) {
67  VariablePacker packer;
68  std::vector<sh::ShaderVariable> vars;
69  const int kMaxRows = 16;
70  // test no vars.
71  EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars));
72
73  for (size_t tt = 0; tt < ArraySize(types); ++tt) {
74    sh::GLenum type = types[tt];
75    int num_rows = VariablePacker::GetNumRows(type);
76    int num_components_per_row = VariablePacker::GetNumComponentsPerRow(type);
77    // Check 1 of the type.
78    vars.clear();
79    vars.push_back(sh::ShaderVariable(type, 0));
80    EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars));
81
82    // Check exactly the right amount of 1 type as an array.
83    int num_vars = kMaxRows / num_rows;
84    vars.clear();
85    vars.push_back(sh::ShaderVariable(type, num_vars == 1 ? 0 : num_vars));
86    EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars));
87
88    // test too many
89    vars.clear();
90    vars.push_back(sh::ShaderVariable(type, num_vars == 0 ? 0 : (num_vars + 1)));
91    EXPECT_FALSE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars));
92
93    // Check exactly the right amount of 1 type as individual vars.
94    num_vars = kMaxRows / num_rows *
95        ((num_components_per_row > 2) ? 1 : (4 / num_components_per_row));
96    vars.clear();
97    for (int ii = 0; ii < num_vars; ++ii) {
98      vars.push_back(sh::ShaderVariable(type, 0));
99    }
100    EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars));
101
102    // Check 1 too many.
103    vars.push_back(sh::ShaderVariable(type, 0));
104    EXPECT_FALSE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars));
105  }
106
107  // Test example from GLSL ES 3.0 spec chapter 11.
108  vars.clear();
109  vars.push_back(sh::ShaderVariable(GL_FLOAT_VEC4, 0));
110  vars.push_back(sh::ShaderVariable(GL_FLOAT_MAT3, 0));
111  vars.push_back(sh::ShaderVariable(GL_FLOAT_MAT3, 0));
112  vars.push_back(sh::ShaderVariable(GL_FLOAT_VEC2, 6));
113  vars.push_back(sh::ShaderVariable(GL_FLOAT_VEC2, 4));
114  vars.push_back(sh::ShaderVariable(GL_FLOAT_VEC2, 0));
115  vars.push_back(sh::ShaderVariable(GL_FLOAT, 3));
116  vars.push_back(sh::ShaderVariable(GL_FLOAT, 2));
117  vars.push_back(sh::ShaderVariable(GL_FLOAT, 0));
118  EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars));
119}
120
121TEST(VariablePacking, PackSizes) {
122  for (size_t tt = 0; tt < ArraySize(types); ++tt) {
123    GLenum type = types[tt];
124
125    int expectedComponents = gl::VariableComponentCount(type);
126    int expectedRows = gl::VariableRowCount(type);
127
128    if (type == GL_FLOAT_MAT2) {
129      expectedComponents = 4;
130    } else if (gl::IsMatrixType(type)) {
131      int squareSize = std::max(gl::VariableRowCount(type),
132          gl::VariableColumnCount(type));
133      expectedComponents = squareSize;
134      expectedRows = squareSize;
135    }
136
137    EXPECT_EQ(expectedComponents,
138      VariablePacker::GetNumComponentsPerRow(type));
139    EXPECT_EQ(expectedRows, VariablePacker::GetNumRows(type));
140  }
141}
142
143// Check special assumptions about packing non-square mats
144TEST(VariablePacking, NonSquareMats) {
145
146  for (size_t mt = 0; mt < ArraySize(nonSqMatTypes); ++mt) {
147
148    GLenum type = nonSqMatTypes[mt];
149
150    int rows = gl::VariableRowCount(type);
151    int cols = gl::VariableColumnCount(type);
152    int squareSize = std::max(rows, cols);
153
154    std::vector<sh::ShaderVariable> vars;
155    vars.push_back(sh::ShaderVariable(type, 0));
156
157    // Fill columns
158    for (int row = 0; row < squareSize; row++) {
159      for (int col = squareSize; col < 4; ++col) {
160        vars.push_back(sh::ShaderVariable(GL_FLOAT, 0));
161      }
162    }
163
164    VariablePacker packer;
165
166    EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(squareSize, vars));
167
168    // and one scalar and packing should fail
169    vars.push_back(sh::ShaderVariable(GL_FLOAT, 0));
170    EXPECT_FALSE(packer.CheckVariablesWithinPackingLimits(squareSize, vars));
171  }
172}
173