18d8047995445882c73091578b889226323f38053gman@chromium.org//
28d8047995445882c73091578b889226323f38053gman@chromium.org// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
38d8047995445882c73091578b889226323f38053gman@chromium.org// Use of this source code is governed by a BSD-style license that can be
48d8047995445882c73091578b889226323f38053gman@chromium.org// found in the LICENSE file.
58d8047995445882c73091578b889226323f38053gman@chromium.org//
68d8047995445882c73091578b889226323f38053gman@chromium.org#include "gtest/gtest.h"
7183bde5527317fa2208401e5e6b803ef51a0fdcbJamie Madill#include "angle_gl.h"
8aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill#include "common/utilities.h"
9aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill#include "common/angleutils.h"
10183bde5527317fa2208401e5e6b803ef51a0fdcbJamie Madill#include "compiler/translator/VariablePacker.h"
118d8047995445882c73091578b889226323f38053gman@chromium.org
12aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madillstatic sh::GLenum types[] = {
13aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill  GL_FLOAT_MAT4,            // 0
14aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill  GL_FLOAT_MAT2,            // 1
15aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill  GL_FLOAT_VEC4,            // 2
16aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill  GL_INT_VEC4,              // 3
17aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill  GL_BOOL_VEC4,             // 4
18aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill  GL_FLOAT_MAT3,            // 5
19aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill  GL_FLOAT_VEC3,            // 6
20aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill  GL_INT_VEC3,              // 7
21aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill  GL_BOOL_VEC3,             // 8
22aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill  GL_FLOAT_VEC2,            // 9
23aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill  GL_INT_VEC2,              // 10
24aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill  GL_BOOL_VEC2,             // 11
25aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill  GL_FLOAT,                 // 12
26aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill  GL_INT,                   // 13
27aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill  GL_BOOL,                  // 14
28aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill  GL_SAMPLER_2D,            // 15
29aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill  GL_SAMPLER_CUBE,          // 16
30aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill  GL_SAMPLER_EXTERNAL_OES,  // 17
31aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill  GL_SAMPLER_2D_RECT_ARB,   // 18
3247149b1305f8ebb32ab223f96ece5a9094b340e7Jamie Madill  GL_UNSIGNED_INT,          // 19
3347149b1305f8ebb32ab223f96ece5a9094b340e7Jamie Madill  GL_UNSIGNED_INT_VEC2,     // 20
3447149b1305f8ebb32ab223f96ece5a9094b340e7Jamie Madill  GL_UNSIGNED_INT_VEC3,     // 21
3547149b1305f8ebb32ab223f96ece5a9094b340e7Jamie Madill  GL_UNSIGNED_INT_VEC4,     // 22
3647149b1305f8ebb32ab223f96ece5a9094b340e7Jamie Madill  GL_FLOAT_MAT2x3,          // 23
3747149b1305f8ebb32ab223f96ece5a9094b340e7Jamie Madill  GL_FLOAT_MAT2x4,          // 24
3847149b1305f8ebb32ab223f96ece5a9094b340e7Jamie Madill  GL_FLOAT_MAT3x2,          // 25
3947149b1305f8ebb32ab223f96ece5a9094b340e7Jamie Madill  GL_FLOAT_MAT3x4,          // 26
4047149b1305f8ebb32ab223f96ece5a9094b340e7Jamie Madill  GL_FLOAT_MAT4x2,          // 27
4147149b1305f8ebb32ab223f96ece5a9094b340e7Jamie Madill  GL_FLOAT_MAT4x3,          // 28
4247149b1305f8ebb32ab223f96ece5a9094b340e7Jamie Madill  GL_SAMPLER_3D,            // 29
4347149b1305f8ebb32ab223f96ece5a9094b340e7Jamie Madill  GL_SAMPLER_2D_ARRAY,      // 30
4447149b1305f8ebb32ab223f96ece5a9094b340e7Jamie Madill  GL_SAMPLER_2D_SHADOW,     // 31
4547149b1305f8ebb32ab223f96ece5a9094b340e7Jamie Madill  GL_SAMPLER_CUBE_SHADOW,   // 32
4647149b1305f8ebb32ab223f96ece5a9094b340e7Jamie Madill  GL_SAMPLER_2D_ARRAY_SHADOW, // 33
4747149b1305f8ebb32ab223f96ece5a9094b340e7Jamie Madill  GL_INT_SAMPLER_2D,        // 34
4847149b1305f8ebb32ab223f96ece5a9094b340e7Jamie Madill  GL_INT_SAMPLER_CUBE,      // 35
4947149b1305f8ebb32ab223f96ece5a9094b340e7Jamie Madill  GL_INT_SAMPLER_3D,        // 36
5047149b1305f8ebb32ab223f96ece5a9094b340e7Jamie Madill  GL_INT_SAMPLER_2D_ARRAY,  // 37
5147149b1305f8ebb32ab223f96ece5a9094b340e7Jamie Madill  GL_UNSIGNED_INT_SAMPLER_2D, // 38
5247149b1305f8ebb32ab223f96ece5a9094b340e7Jamie Madill  GL_UNSIGNED_INT_SAMPLER_CUBE, // 39
5347149b1305f8ebb32ab223f96ece5a9094b340e7Jamie Madill  GL_UNSIGNED_INT_SAMPLER_3D, // 40
5447149b1305f8ebb32ab223f96ece5a9094b340e7Jamie Madill  GL_UNSIGNED_INT_SAMPLER_2D_ARRAY, // 41
55aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill};
56aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill
57aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madillstatic sh::GLenum nonSqMatTypes[] = {
58aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill  GL_FLOAT_MAT2x3,
59aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill  GL_FLOAT_MAT2x4,
60aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill  GL_FLOAT_MAT3x2,
61aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill  GL_FLOAT_MAT3x4,
62aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill  GL_FLOAT_MAT4x2,
63aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill  GL_FLOAT_MAT4x3
64aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill};
65aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill
668d8047995445882c73091578b889226323f38053gman@chromium.orgTEST(VariablePacking, Pack) {
678d8047995445882c73091578b889226323f38053gman@chromium.org  VariablePacker packer;
68a718c1e00264edf434aeddf7beb14f4fae0f07a0Jamie Madill  std::vector<sh::ShaderVariable> vars;
698d8047995445882c73091578b889226323f38053gman@chromium.org  const int kMaxRows = 16;
708d8047995445882c73091578b889226323f38053gman@chromium.org  // test no vars.
718d8047995445882c73091578b889226323f38053gman@chromium.org  EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars));
728d8047995445882c73091578b889226323f38053gman@chromium.org
73aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill  for (size_t tt = 0; tt < ArraySize(types); ++tt) {
74183bde5527317fa2208401e5e6b803ef51a0fdcbJamie Madill    sh::GLenum type = types[tt];
758d8047995445882c73091578b889226323f38053gman@chromium.org    int num_rows = VariablePacker::GetNumRows(type);
768d8047995445882c73091578b889226323f38053gman@chromium.org    int num_components_per_row = VariablePacker::GetNumComponentsPerRow(type);
778d8047995445882c73091578b889226323f38053gman@chromium.org    // Check 1 of the type.
788d8047995445882c73091578b889226323f38053gman@chromium.org    vars.clear();
79a3fe2b4e1fce3d0637e2626c6154d19707313a85Jamie Madill    vars.push_back(sh::ShaderVariable(type, 0));
808d8047995445882c73091578b889226323f38053gman@chromium.org    EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars));
818d8047995445882c73091578b889226323f38053gman@chromium.org
828d8047995445882c73091578b889226323f38053gman@chromium.org    // Check exactly the right amount of 1 type as an array.
838d8047995445882c73091578b889226323f38053gman@chromium.org    int num_vars = kMaxRows / num_rows;
848d8047995445882c73091578b889226323f38053gman@chromium.org    vars.clear();
85a3fe2b4e1fce3d0637e2626c6154d19707313a85Jamie Madill    vars.push_back(sh::ShaderVariable(type, num_vars == 1 ? 0 : num_vars));
868d8047995445882c73091578b889226323f38053gman@chromium.org    EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars));
878d8047995445882c73091578b889226323f38053gman@chromium.org
888d8047995445882c73091578b889226323f38053gman@chromium.org    // test too many
898d8047995445882c73091578b889226323f38053gman@chromium.org    vars.clear();
90a3fe2b4e1fce3d0637e2626c6154d19707313a85Jamie Madill    vars.push_back(sh::ShaderVariable(type, num_vars == 0 ? 0 : (num_vars + 1)));
918d8047995445882c73091578b889226323f38053gman@chromium.org    EXPECT_FALSE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars));
928d8047995445882c73091578b889226323f38053gman@chromium.org
938d8047995445882c73091578b889226323f38053gman@chromium.org    // Check exactly the right amount of 1 type as individual vars.
948d8047995445882c73091578b889226323f38053gman@chromium.org    num_vars = kMaxRows / num_rows *
958d8047995445882c73091578b889226323f38053gman@chromium.org        ((num_components_per_row > 2) ? 1 : (4 / num_components_per_row));
968d8047995445882c73091578b889226323f38053gman@chromium.org    vars.clear();
978d8047995445882c73091578b889226323f38053gman@chromium.org    for (int ii = 0; ii < num_vars; ++ii) {
98a3fe2b4e1fce3d0637e2626c6154d19707313a85Jamie Madill      vars.push_back(sh::ShaderVariable(type, 0));
998d8047995445882c73091578b889226323f38053gman@chromium.org    }
1008d8047995445882c73091578b889226323f38053gman@chromium.org    EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars));
1018d8047995445882c73091578b889226323f38053gman@chromium.org
1028d8047995445882c73091578b889226323f38053gman@chromium.org    // Check 1 too many.
103a3fe2b4e1fce3d0637e2626c6154d19707313a85Jamie Madill    vars.push_back(sh::ShaderVariable(type, 0));
1048d8047995445882c73091578b889226323f38053gman@chromium.org    EXPECT_FALSE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars));
1058d8047995445882c73091578b889226323f38053gman@chromium.org  }
1068d8047995445882c73091578b889226323f38053gman@chromium.org
1078d8047995445882c73091578b889226323f38053gman@chromium.org  // Test example from GLSL ES 3.0 spec chapter 11.
1088d8047995445882c73091578b889226323f38053gman@chromium.org  vars.clear();
109a3fe2b4e1fce3d0637e2626c6154d19707313a85Jamie Madill  vars.push_back(sh::ShaderVariable(GL_FLOAT_VEC4, 0));
110a3fe2b4e1fce3d0637e2626c6154d19707313a85Jamie Madill  vars.push_back(sh::ShaderVariable(GL_FLOAT_MAT3, 0));
111a3fe2b4e1fce3d0637e2626c6154d19707313a85Jamie Madill  vars.push_back(sh::ShaderVariable(GL_FLOAT_MAT3, 0));
112a3fe2b4e1fce3d0637e2626c6154d19707313a85Jamie Madill  vars.push_back(sh::ShaderVariable(GL_FLOAT_VEC2, 6));
113a3fe2b4e1fce3d0637e2626c6154d19707313a85Jamie Madill  vars.push_back(sh::ShaderVariable(GL_FLOAT_VEC2, 4));
114a3fe2b4e1fce3d0637e2626c6154d19707313a85Jamie Madill  vars.push_back(sh::ShaderVariable(GL_FLOAT_VEC2, 0));
115a3fe2b4e1fce3d0637e2626c6154d19707313a85Jamie Madill  vars.push_back(sh::ShaderVariable(GL_FLOAT, 3));
116a3fe2b4e1fce3d0637e2626c6154d19707313a85Jamie Madill  vars.push_back(sh::ShaderVariable(GL_FLOAT, 2));
117a3fe2b4e1fce3d0637e2626c6154d19707313a85Jamie Madill  vars.push_back(sh::ShaderVariable(GL_FLOAT, 0));
1188d8047995445882c73091578b889226323f38053gman@chromium.org  EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars));
1198d8047995445882c73091578b889226323f38053gman@chromium.org}
1208d8047995445882c73091578b889226323f38053gman@chromium.org
121aa72d782074e8ea2e74304ca12b372c5e36e758fJamie MadillTEST(VariablePacking, PackSizes) {
122aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill  for (size_t tt = 0; tt < ArraySize(types); ++tt) {
123aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill    GLenum type = types[tt];
124aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill
125aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill    int expectedComponents = gl::VariableComponentCount(type);
126aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill    int expectedRows = gl::VariableRowCount(type);
127aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill
128aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill    if (type == GL_FLOAT_MAT2) {
129aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill      expectedComponents = 4;
130aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill    } else if (gl::IsMatrixType(type)) {
131aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill      int squareSize = std::max(gl::VariableRowCount(type),
132aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill          gl::VariableColumnCount(type));
133aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill      expectedComponents = squareSize;
134aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill      expectedRows = squareSize;
135aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill    }
136aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill
137aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill    EXPECT_EQ(expectedComponents,
138aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill      VariablePacker::GetNumComponentsPerRow(type));
139aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill    EXPECT_EQ(expectedRows, VariablePacker::GetNumRows(type));
140aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill  }
141aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill}
142aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill
143aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill// Check special assumptions about packing non-square mats
144aa72d782074e8ea2e74304ca12b372c5e36e758fJamie MadillTEST(VariablePacking, NonSquareMats) {
145aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill
146aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill  for (size_t mt = 0; mt < ArraySize(nonSqMatTypes); ++mt) {
147aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill
148aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill    GLenum type = nonSqMatTypes[mt];
149aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill
150aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill    int rows = gl::VariableRowCount(type);
151aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill    int cols = gl::VariableColumnCount(type);
152aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill    int squareSize = std::max(rows, cols);
153aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill
154a718c1e00264edf434aeddf7beb14f4fae0f07a0Jamie Madill    std::vector<sh::ShaderVariable> vars;
155a3fe2b4e1fce3d0637e2626c6154d19707313a85Jamie Madill    vars.push_back(sh::ShaderVariable(type, 0));
156aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill
157aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill    // Fill columns
158aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill    for (int row = 0; row < squareSize; row++) {
159aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill      for (int col = squareSize; col < 4; ++col) {
160a3fe2b4e1fce3d0637e2626c6154d19707313a85Jamie Madill        vars.push_back(sh::ShaderVariable(GL_FLOAT, 0));
161aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill      }
162aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill    }
163aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill
164aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill    VariablePacker packer;
165aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill
166aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill    EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(squareSize, vars));
167aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill
168aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill    // and one scalar and packing should fail
169a3fe2b4e1fce3d0637e2626c6154d19707313a85Jamie Madill    vars.push_back(sh::ShaderVariable(GL_FLOAT, 0));
170aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill    EXPECT_FALSE(packer.CheckVariablesWithinPackingLimits(squareSize, vars));
171aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill  }
172aa72d782074e8ea2e74304ca12b372c5e36e758fJamie Madill}
173