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