Edit

kc3-lang/angle/src/libANGLE/VaryingPacking_unittest.cpp

Branch :

  • Show log

    Commit

  • Author : Jiawei Shao
    Date : 2018-07-02 15:55:19
    Hash : da92a476
    Message : Clean up VaryingPacking This patch intends to clean up some issues in VaryingPacking to implement geometry shader easiler. 1. Use emplace_back() instead of push_back() when necessary. 2. Remove unnecessary parameter in VaryingPacking::packUserVaryings(). 3. Remove the assignment of semanticIndex and only handle them in D3D11 back-ends. BUG=angleproject:1941 Change-Id: Ia09c07f01dc442ce95cb4984e4b768d0c79872c7 Reviewed-on: https://chromium-review.googlesource.com/1128576 Reviewed-by: Jamie Madill <jmadill@chromium.org> Reviewed-by: Corentin Wallez <cwallez@chromium.org> Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>

  • src/libANGLE/VaryingPacking_unittest.cpp
  • //
    // Copyright 2016 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.
    //
    // VaryingPacking_unittest.cpp:
    //   Tests for ANGLE's internal varying packing algorithm.
    //
    
    #include <gtest/gtest.h>
    // 'None' is defined as 'struct None {};' in
    // third_party/googletest/src/googletest/include/gtest/internal/gtest-type-util.h.
    // But 'None' is also define as a numberic constant 0L in <X11/X.h>.
    // So we need to include gtest first to avoid such conflict.
    
    #include "libANGLE/Program.h"
    #include "libANGLE/VaryingPacking.h"
    
    using namespace gl;
    
    namespace
    {
    
    class VaryingPackingTest : public ::testing::TestWithParam<GLuint>
    {
      protected:
        VaryingPackingTest() {}
    
        bool testVaryingPacking(const std::vector<sh::Varying> &shVaryings,
                                VaryingPacking *varyingPacking)
        {
            std::vector<PackedVarying> packedVaryings;
            for (const auto &shVarying : shVaryings)
            {
                packedVaryings.push_back(PackedVarying(shVarying, shVarying.interpolation));
            }
    
            InfoLog infoLog;
            std::vector<std::string> transformFeedbackVaryings;
    
            return varyingPacking->packUserVaryings(infoLog, packedVaryings);
        }
    
        // Uses the "relaxed" ANGLE packing mode.
        bool packVaryings(GLuint maxVaryings, const std::vector<sh::Varying> &shVaryings)
        {
            VaryingPacking varyingPacking(maxVaryings, PackMode::ANGLE_RELAXED);
            return testVaryingPacking(shVaryings, &varyingPacking);
        }
    
        // Uses the stricter WebGL style packing rules.
        bool packVaryingsStrict(GLuint maxVaryings, const std::vector<sh::Varying> &shVaryings)
        {
            VaryingPacking varyingPacking(maxVaryings, PackMode::WEBGL_STRICT);
            return testVaryingPacking(shVaryings, &varyingPacking);
        }
    
        const int kMaxVaryings = GetParam();
    };
    
    std::vector<sh::Varying> MakeVaryings(GLenum type, size_t count, size_t arraySize)
    {
        std::vector<sh::Varying> varyings;
    
        for (size_t index = 0; index < count; ++index)
        {
            std::stringstream strstr;
            strstr << type << index;
    
            sh::Varying varying;
            varying.type          = type;
            varying.precision     = GL_MEDIUM_FLOAT;
            varying.name          = strstr.str();
            varying.mappedName    = strstr.str();
            if (arraySize > 0)
            {
                varying.arraySizes.push_back(static_cast<unsigned int>(arraySize));
            }
            varying.staticUse     = true;
            varying.interpolation = sh::INTERPOLATION_FLAT;
            varying.isInvariant   = false;
    
            varyings.push_back(varying);
        }
    
        return varyings;
    }
    
    void AddVaryings(std::vector<sh::Varying> *varyings, GLenum type, size_t count, size_t arraySize)
    {
        const auto &newVaryings = MakeVaryings(type, count, arraySize);
        varyings->insert(varyings->end(), newVaryings.begin(), newVaryings.end());
    }
    
    // Test that a single varying can't overflow the packing.
    TEST_P(VaryingPackingTest, OneVaryingLargerThanMax)
    {
        ASSERT_FALSE(packVaryings(1, MakeVaryings(GL_FLOAT_MAT4, 1, 0)));
    }
    
    // This will overflow the available varying space.
    TEST_P(VaryingPackingTest, MaxPlusOneVaryingVec3)
    {
        ASSERT_FALSE(packVaryings(kMaxVaryings, MakeVaryings(GL_FLOAT_VEC3, kMaxVaryings + 1, 0)));
    }
    
    // This will overflow the available varying space.
    TEST_P(VaryingPackingTest, MaxPlusOneVaryingVec3Array)
    {
        ASSERT_FALSE(packVaryings(kMaxVaryings, MakeVaryings(GL_FLOAT_VEC3, kMaxVaryings / 2 + 1, 2)));
    }
    
    // This will overflow the available varying space.
    TEST_P(VaryingPackingTest, MaxVaryingVec3AndOneVec2)
    {
        std::vector<sh::Varying> varyings = MakeVaryings(GL_FLOAT_VEC3, kMaxVaryings, 0);
        AddVaryings(&varyings, GL_FLOAT_VEC2, 1, 0);
        ASSERT_FALSE(packVaryings(kMaxVaryings, varyings));
    }
    
    // This should work since two vec2s are packed in a single register.
    TEST_P(VaryingPackingTest, MaxPlusOneVaryingVec2)
    {
        ASSERT_TRUE(packVaryings(kMaxVaryings, MakeVaryings(GL_FLOAT_VEC2, kMaxVaryings + 1, 0)));
    }
    
    // Same for this one as above.
    TEST_P(VaryingPackingTest, TwiceMaxVaryingVec2)
    {
        ASSERT_TRUE(packVaryings(kMaxVaryings, MakeVaryings(GL_FLOAT_VEC2, kMaxVaryings * 2, 0)));
    }
    
    // This should not work since it overflows available varying space.
    TEST_P(VaryingPackingTest, TooManyVaryingVec2)
    {
        ASSERT_FALSE(packVaryings(kMaxVaryings, MakeVaryings(GL_FLOAT_VEC2, kMaxVaryings * 2 + 1, 0)));
    }
    
    // This should work according to the example GL packing rules - the float varyings are slotted
    // into the end of the vec3 varying arrays.
    TEST_P(VaryingPackingTest, MaxVaryingVec3ArrayAndFloatArrays)
    {
        std::vector<sh::Varying> varyings = MakeVaryings(GL_FLOAT_VEC3, kMaxVaryings / 2, 2);
        AddVaryings(&varyings, GL_FLOAT, kMaxVaryings / 2, 2);
        ASSERT_TRUE(packVaryings(kMaxVaryings, varyings));
    }
    
    // This should not work - it has one too many float arrays.
    TEST_P(VaryingPackingTest, MaxVaryingVec3ArrayAndMaxPlusOneFloatArray)
    {
        std::vector<sh::Varying> varyings = MakeVaryings(GL_FLOAT_VEC3, kMaxVaryings / 2, 2);
        AddVaryings(&varyings, GL_FLOAT, kMaxVaryings / 2 + 1, 2);
        ASSERT_FALSE(packVaryings(kMaxVaryings, varyings));
    }
    
    // WebGL should fail to pack max+1 vec2 arrays, unlike our more relaxed packing.
    TEST_P(VaryingPackingTest, MaxPlusOneMat2VaryingsFailsWebGL)
    {
        auto varyings = MakeVaryings(GL_FLOAT_MAT2, kMaxVaryings / 2 + 1, 0);
        ASSERT_FALSE(packVaryingsStrict(kMaxVaryings, varyings));
    }
    
    // Makes separate tests for different values of kMaxVaryings.
    INSTANTIATE_TEST_CASE_P(, VaryingPackingTest, ::testing::Values(1, 4, 8));
    
    }  // anonymous namespace