Edit

kc3-lang/angle/src/tests/compiler_tests/VariablePacker_test.cpp

Branch :

  • Show log

    Commit

  • Author : Olli Etuaho
    Date : 2017-10-23 16:29:33
    Hash : e7c2857d
    Message : Clean up direct access of ShaderVariable::arraySize This change is pure refactoring. It's intended to help with adding support for arrays of arrays. BUG=angleproject:2125 TEST=angle_unittests Change-Id: I82881a98c3c476fd6666a551ce6be255ae0de4cf Reviewed-on: https://chromium-review.googlesource.com/733127 Reviewed-by: Jamie Madill <jmadill@chromium.org> Reviewed-by: Corentin Wallez <cwallez@chromium.org> Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>

  • src/tests/compiler_tests/VariablePacker_test.cpp
  • //
    // Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
    // Use of this source code is governed by a BSD-style license that can be
    // found in the LICENSE file.
    //
    #include "gtest/gtest.h"
    #include "angle_gl.h"
    #include "common/utilities.h"
    #include "common/angleutils.h"
    #include "compiler/translator/VariablePacker.h"
    
    namespace
    {
    
    static sh::GLenum types[] = {
        GL_FLOAT_MAT4,                     // 0
        GL_FLOAT_MAT2,                     // 1
        GL_FLOAT_VEC4,                     // 2
        GL_INT_VEC4,                       // 3
        GL_BOOL_VEC4,                      // 4
        GL_FLOAT_MAT3,                     // 5
        GL_FLOAT_VEC3,                     // 6
        GL_INT_VEC3,                       // 7
        GL_BOOL_VEC3,                      // 8
        GL_FLOAT_VEC2,                     // 9
        GL_INT_VEC2,                       // 10
        GL_BOOL_VEC2,                      // 11
        GL_FLOAT,                          // 12
        GL_INT,                            // 13
        GL_BOOL,                           // 14
        GL_SAMPLER_2D,                     // 15
        GL_SAMPLER_CUBE,                   // 16
        GL_SAMPLER_EXTERNAL_OES,           // 17
        GL_SAMPLER_2D_RECT_ANGLE,          // 18
        GL_UNSIGNED_INT,                   // 19
        GL_UNSIGNED_INT_VEC2,              // 20
        GL_UNSIGNED_INT_VEC3,              // 21
        GL_UNSIGNED_INT_VEC4,              // 22
        GL_FLOAT_MAT2x3,                   // 23
        GL_FLOAT_MAT2x4,                   // 24
        GL_FLOAT_MAT3x2,                   // 25
        GL_FLOAT_MAT3x4,                   // 26
        GL_FLOAT_MAT4x2,                   // 27
        GL_FLOAT_MAT4x3,                   // 28
        GL_SAMPLER_3D,                     // 29
        GL_SAMPLER_2D_ARRAY,               // 30
        GL_SAMPLER_2D_SHADOW,              // 31
        GL_SAMPLER_CUBE_SHADOW,            // 32
        GL_SAMPLER_2D_ARRAY_SHADOW,        // 33
        GL_INT_SAMPLER_2D,                 // 34
        GL_INT_SAMPLER_CUBE,               // 35
        GL_INT_SAMPLER_3D,                 // 36
        GL_INT_SAMPLER_2D_ARRAY,           // 37
        GL_UNSIGNED_INT_SAMPLER_2D,        // 38
        GL_UNSIGNED_INT_SAMPLER_CUBE,      // 39
        GL_UNSIGNED_INT_SAMPLER_3D,        // 40
        GL_UNSIGNED_INT_SAMPLER_2D_ARRAY,  // 41
    };
    
    static sh::GLenum nonSqMatTypes[] = {GL_FLOAT_MAT2x3, GL_FLOAT_MAT2x4, GL_FLOAT_MAT3x2,
                                         GL_FLOAT_MAT3x4, GL_FLOAT_MAT4x2, GL_FLOAT_MAT4x3};
    
    // Creates either a single variable or an array variable depending on numVars.
    sh::ShaderVariable CreateShaderVariable(sh::GLenum type, int numVars)
    {
        ASSERT(numVars != 0);
        if (numVars == 1)
        {
            return sh::ShaderVariable(type);
        }
        return sh::ShaderVariable(type, numVars);
    }
    
    }  // anonymous namespace
    
    TEST(VariablePacking, Pack)
    {
        std::vector<sh::ShaderVariable> vars;
        const int kMaxRows = 16;
        // test no vars.
        EXPECT_TRUE(CheckVariablesInPackingLimits(kMaxRows, vars));
    
        for (size_t tt = 0; tt < ArraySize(types); ++tt)
        {
            sh::GLenum type            = types[tt];
            int num_rows               = sh::GetTypePackingRows(type);
            int num_components_per_row = sh::GetTypePackingComponentsPerRow(type);
            // Check 1 of the type.
            vars.clear();
            vars.push_back(sh::ShaderVariable(type));
            EXPECT_TRUE(CheckVariablesInPackingLimits(kMaxRows, vars));
    
            // Check exactly the right amount of 1 type as an array.
            int num_vars = kMaxRows / num_rows;
            vars.clear();
            vars.push_back(CreateShaderVariable(type, num_vars));
            EXPECT_TRUE(CheckVariablesInPackingLimits(kMaxRows, vars));
    
            // test too many
            vars.clear();
            vars.push_back(CreateShaderVariable(type, num_vars + 1));
            EXPECT_FALSE(CheckVariablesInPackingLimits(kMaxRows, vars));
    
            // Check exactly the right amount of 1 type as individual vars.
            num_vars =
                kMaxRows / num_rows * ((num_components_per_row > 2) ? 1 : (4 / num_components_per_row));
            vars.clear();
            for (int ii = 0; ii < num_vars; ++ii)
            {
                vars.push_back(sh::ShaderVariable(type));
            }
            EXPECT_TRUE(CheckVariablesInPackingLimits(kMaxRows, vars));
    
            // Check 1 too many.
            vars.push_back(sh::ShaderVariable(type));
            EXPECT_FALSE(CheckVariablesInPackingLimits(kMaxRows, vars));
        }
    
        // Test example from GLSL ES 3.0 spec chapter 11.
        vars.clear();
        vars.push_back(sh::ShaderVariable(GL_FLOAT_VEC4));
        vars.push_back(sh::ShaderVariable(GL_FLOAT_MAT3));
        vars.push_back(sh::ShaderVariable(GL_FLOAT_MAT3));
        vars.push_back(sh::ShaderVariable(GL_FLOAT_VEC2, 6));
        vars.push_back(sh::ShaderVariable(GL_FLOAT_VEC2, 4));
        vars.push_back(sh::ShaderVariable(GL_FLOAT_VEC2));
        vars.push_back(sh::ShaderVariable(GL_FLOAT, 3));
        vars.push_back(sh::ShaderVariable(GL_FLOAT, 2));
        vars.push_back(sh::ShaderVariable(GL_FLOAT));
        EXPECT_TRUE(CheckVariablesInPackingLimits(kMaxRows, vars));
    }
    
    TEST(VariablePacking, PackSizes)
    {
        for (size_t tt = 0; tt < ArraySize(types); ++tt)
        {
            sh::GLenum type = types[tt];
    
            int expectedComponents = gl::VariableComponentCount(type);
            int expectedRows       = gl::VariableRowCount(type);
    
            if (type == GL_FLOAT_MAT2)
            {
                expectedComponents = 4;
            }
            else if (gl::IsMatrixType(type))
            {
                int squareSize = std::max(gl::VariableRowCount(type), gl::VariableColumnCount(type));
                expectedComponents = squareSize;
                expectedRows       = squareSize;
            }
    
            EXPECT_EQ(expectedComponents, sh::GetTypePackingComponentsPerRow(type));
            EXPECT_EQ(expectedRows, sh::GetTypePackingRows(type));
        }
    }
    
    // Check special assumptions about packing non-square mats
    TEST(VariablePacking, NonSquareMats)
    {
    
        for (size_t mt = 0; mt < ArraySize(nonSqMatTypes); ++mt)
        {
    
            sh::GLenum type = nonSqMatTypes[mt];
    
            int rows       = gl::VariableRowCount(type);
            int cols       = gl::VariableColumnCount(type);
            int squareSize = std::max(rows, cols);
    
            std::vector<sh::ShaderVariable> vars;
            vars.push_back(sh::ShaderVariable(type));
    
            // Fill columns
            for (int row = 0; row < squareSize; row++)
            {
                for (int col = squareSize; col < 4; ++col)
                {
                    vars.push_back(sh::ShaderVariable(GL_FLOAT));
                }
            }
    
            EXPECT_TRUE(CheckVariablesInPackingLimits(squareSize, vars));
    
            // and one scalar and packing should fail
            vars.push_back(sh::ShaderVariable(GL_FLOAT));
            EXPECT_FALSE(CheckVariablesInPackingLimits(squareSize, vars));
        }
    }
    
    // Scalar type variables can be packed sharing rows with other variables.
    TEST(VariablePacking, ReuseRows)
    {
        std::vector<sh::ShaderVariable> vars;
        const int kMaxRows = 512;
    
        // uniform bool u0[129];
        // uniform bool u1[129];
        // uniform bool u2[129];
        // uniform bool u3[129];
        {
            int num_arrays             = 4;
            int num_elements_per_array = kMaxRows / num_arrays + 1;
            for (int ii = 0; ii < num_arrays; ++ii)
            {
                vars.push_back(sh::ShaderVariable(GL_BOOL, num_elements_per_array));
            }
            EXPECT_TRUE(CheckVariablesInPackingLimits(kMaxRows, vars));
        }
    
        vars.clear();
        // uniform vec2 u0[257];
        // uniform float u1[257];
        // uniform int u1[257];
        {
            int num_elements_per_array = kMaxRows / 2 + 1;
            vars.push_back(sh::ShaderVariable(GL_FLOAT_VEC2, num_elements_per_array));
            vars.push_back(sh::ShaderVariable(GL_FLOAT, num_elements_per_array));
            vars.push_back(sh::ShaderVariable(GL_INT, num_elements_per_array));
            EXPECT_TRUE(CheckVariablesInPackingLimits(kMaxRows, vars));
        }
    }
    
    // Check the packer supports and flattens structures.
    TEST(VariablePacking, Struct)
    {
        std::vector<sh::ShaderVariable> fields;
        const int kMaxRows = 16;
    
        // Test example from GLSL ES 3.0 spec chapter 11, but with structs
        std::vector<sh::ShaderVariable> vars;
        vars.push_back(sh::ShaderVariable(GL_NONE));
    
        sh::ShaderVariable &parentStruct = vars[0];
        parentStruct.fields.push_back(sh::ShaderVariable(GL_FLOAT_VEC4));
        parentStruct.fields.push_back(sh::ShaderVariable(GL_FLOAT_MAT3));
    
        parentStruct.fields.push_back(sh::ShaderVariable(GL_NONE));
        sh::ShaderVariable &innerStruct = parentStruct.fields.back();
        innerStruct.fields.push_back(sh::ShaderVariable(GL_FLOAT_MAT3));
        innerStruct.fields.push_back(sh::ShaderVariable(GL_FLOAT_VEC2, 6));
        innerStruct.fields.push_back(sh::ShaderVariable(GL_FLOAT_VEC2, 4));
    
        parentStruct.fields.push_back(sh::ShaderVariable(GL_FLOAT_VEC2));
        parentStruct.fields.push_back(sh::ShaderVariable(GL_FLOAT, 3));
        parentStruct.fields.push_back(sh::ShaderVariable(GL_FLOAT, 2));
        parentStruct.fields.push_back(sh::ShaderVariable(GL_FLOAT));
    
        EXPECT_TRUE(CheckVariablesInPackingLimits(kMaxRows, vars));
    }