Source/ThirdParty/ANGLE/src/libGLESv2/Program.cpp
int Program::packVaryings(const Varying *packing[][4])
{
    Context *context = getContext();
    const int maxVaryingVectors = context->getMaximumVaryingVectors();

    for (VaryingList::iterator varying = mFragmentShader->varyings.begin(); varying != mFragmentShader->varyings.end(); varying++)
    {
        int n = VariableRowCount(varying->type) * varying->size;
        int m = VariableColumnCount(varying->type);
        bool success = false;

        if (m == 2 || m == 3 || m == 4)
        {
            for (int r = 0; r <= maxVaryingVectors - n && !success; r++)
            {
                bool available = true;

                for (int y = 0; y < n && available; y++)
                {
                    for (int x = 0; x < m && available; x++)
                    {
                        if (packing[r + y][x])
                        {
                            available = false;
                        }
                    }
                }

                if (available)
                {
                    varying->reg = r;
                    varying->col = 0;

                    for (int y = 0; y < n; y++)
                    {
                        for (int x = 0; x < m; x++)
                        {
                            packing[r + y][x] = &*varying;
                        }
                    }

                    success = true;
                }
            }

            if (!success && m == 2)
            {
                for (int r = maxVaryingVectors - n; r >= 0 && !success; r--)
                {
                    bool available = true;

                    for (int y = 0; y < n && available; y++)
                    {
                        for (int x = 2; x < 4 && available; x++)
                        {
                            if (packing[r + y][x])
                            {
                                available = false;
                            }
                        }
                    }

                    if (available)
                    {
                        varying->reg = r;
                        varying->col = 2;

                        for (int y = 0; y < n; y++)
                        {
                            for (int x = 2; x < 4; x++)
                            {
                                packing[r + y][x] = &*varying;
                            }
                        }

                        success = true;
                    }
                }
            }
        }
        else if (m == 1)
        {
            int space[4] = {0};

            for (int y = 0; y < maxVaryingVectors; y++)
            {
                for (int x = 0; x < 4; x++)
                {
                    space[x] += packing[y][x] ? 0 : 1;
                }
            }

            int column = 0;

            for (int x = 0; x < 4; x++)
            {
                if (space[x] > n && space[x] < space[column])
                {
                    column = x;
                }
            }

            if (space[column] > n)
            {
                for (int r = 0; r < maxVaryingVectors; r++)
                {
                    if (!packing[r][column])
                    {
                        varying->reg = r;

                        for (int y = r; y < r + n; y++)
                        {
                            packing[y][column] = &*varying;
                        }

                        break;
                    }
                }

                varying->col = column;

                success = true;
            }
        }
        else UNREACHABLE();

        if (!success)
        {
            appendToInfoLog("Could not pack varying %s", varying->name.c_str());

            return -1;
        }
    }

    // Return the number of used registers
    int registers = 0;

    for (int r = 0; r < maxVaryingVectors; r++)
    {
        if (packing[r][0] || packing[r][1] || packing[r][2] || packing[r][3])
        {
            registers++;
        }
    }

    return registers;
}
// Packs varyings into generic varying registers, using the algorithm from [OpenGL ES Shading Language 1.00 rev. 17] appendix A section 7 page 111
// Returns the number of used varying registers, or -1 if unsuccesful
Packs varyings into generic varying registers, using the algorithm from [OpenGL ES Shading Language 1.00 rev. 17] appendix A section 7 page 111
Returns the number of used varying registers, or -1 if unsuccesful
Packs varyings into generic varying registers using the algorithm from [ OpenGL ES Shading Language 1 . 00 rev . 17 ] appendix A section 7 page 111 Returns the number of used varying registers or - 1 if unsuccesful
int Program::packVaryings(const Varying *packing[][4])
{
    Context *context = getContext();
    const int maxVaryingVectors = context->getMaximumVaryingVectors();
    for (VaryingList::iterator varying = mFragmentShader->varyings.begin(); varying != mFragmentShader->varyings.end(); varying++)
    {
        int n = VariableRowCount(varying->type) * varying->size;
        int m = VariableColumnCount(varying->type);
        bool success = false;
        if (m == 2 || m == 3 || m == 4)
        {
            for (int r = 0; r <= maxVaryingVectors - n && !success; r++)
            {
                bool available = true;
                for (int y = 0; y < n && available; y++)
                {
                    for (int x = 0; x < m && available; x++)
                    {
                        if (packing[r + y][x])
                        {
                            available = false;
                        }
                    }
                }
                if (available)
                {
                    varying->reg = r;
                    varying->col = 0;
                    for (int y = 0; y < n; y++)
                    {
                        for (int x = 0; x < m; x++)
                        {
                            packing[r + y][x] = &*varying;
                        }
                    }
                    success = true;
                }
            }
            if (!success && m == 2)
            {
                for (int r = maxVaryingVectors - n; r >= 0 && !success; r--)
                {
                    bool available = true;
                    for (int y = 0; y < n && available; y++)
                    {
                        for (int x = 2; x < 4 && available; x++)
                        {
                            if (packing[r + y][x])
                            {
                                available = false;
                            }
                        }
                    }
                    if (available)
                    {
                        varying->reg = r;
                        varying->col = 2;
                        for (int y = 0; y < n; y++)
                        {
                            for (int x = 2; x < 4; x++)
                            {
                                packing[r + y][x] = &*varying;
                            }
                        }
                        success = true;
                    }
                }
            }
        }
        else if (m == 1)
        {
            int space[4] = {0};
            for (int y = 0; y < maxVaryingVectors; y++)
            {
                for (int x = 0; x < 4; x++)
                {
                    space[x] += packing[y][x] ? 0 : 1;
                }
            }
            int column = 0;
            for (int x = 0; x < 4; x++)
            {
                if (space[x] > n && space[x] < space[column])
                {
                    column = x;
                }
            }
            if (space[column] > n)
            {
                for (int r = 0; r < maxVaryingVectors; r++)
                {
                    if (!packing[r][column])
                    {
                        varying->reg = r;
                        for (int y = r; y < r + n; y++)
                        {
                            packing[y][column] = &*varying;
                        }
                        break;
                    }
                }
                varying->col = column;
                success = true;
            }
        }
        else UNREACHABLE();
        if (!success)
        {
            appendToInfoLog("Could not pack varying %s", varying->name.c_str());
            return -1;
        }
    }
    int registers = 0;
    for (int r = 0; r < maxVaryingVectors; r++)
    {
        if (packing[r][0] || packing[r][1] || packing[r][2] || packing[r][3])
        {
            registers++;
        }
    }
    return registers;
}
int Program :: packVaryings ( const Varying * packing [ ] [ 4 ] ) { Context * context = getContext ( ) ; const int maxVaryingVectors = context -> getMaximumVaryingVectors ( ) ; for ( VaryingList :: iterator varying = mFragmentShader -> varyings . begin ( ) ; varying != mFragmentShader -> varyings . end ( ) ; varying ++ ) { int n = VariableRowCount ( varying -> type ) * varying -> size ; int m = VariableColumnCount ( varying -> type ) ; bool success = false ; if ( m == 2 || m == 3 || m == 4 ) { for ( int r = 0 ; r <= maxVaryingVectors - n && ! success ; r ++ ) { bool available = true ; for ( int y = 0 ; y < n && available ; y ++ ) { for ( int x = 0 ; x < m && available ; x ++ ) { if ( packing [ r + y ] [ x ] ) { available = false ; } } } if ( available ) { varying -> reg = r ; varying -> col = 0 ; for ( int y = 0 ; y < n ; y ++ ) { for ( int x = 0 ; x < m ; x ++ ) { packing [ r + y ] [ x ] = & * varying ; } } success = true ; } } if ( ! success && m == 2 ) { for ( int r = maxVaryingVectors - n ; r >= 0 && ! success ; r -- ) { bool available = true ; for ( int y = 0 ; y < n && available ; y ++ ) { for ( int x = 2 ; x < 4 && available ; x ++ ) { if ( packing [ r + y ] [ x ] ) { available = false ; } } } if ( available ) { varying -> reg = r ; varying -> col = 2 ; for ( int y = 0 ; y < n ; y ++ ) { for ( int x = 2 ; x < 4 ; x ++ ) { packing [ r + y ] [ x ] = & * varying ; } } success = true ; } } } } else if ( m == 1 ) { int space [ 4 ] = { 0 } ; for ( int y = 0 ; y < maxVaryingVectors ; y ++ ) { for ( int x = 0 ; x < 4 ; x ++ ) { space [ x ] += packing [ y ] [ x ] ? 0 : 1 ; } } int column = 0 ; for ( int x = 0 ; x < 4 ; x ++ ) { if ( space [ x ] > n && space [ x ] < space [ column ] ) { column = x ; } } if ( space [ column ] > n ) { for ( int r = 0 ; r < maxVaryingVectors ; r ++ ) { if ( ! packing [ r ] [ column ] ) { varying -> reg = r ; for ( int y = r ; y < r + n ; y ++ ) { packing [ y ] [ column ] = & * varying ; } break ; } } varying -> col = column ; success = true ; } } else UNREACHABLE ( ) ; if ( ! success ) { appendToInfoLog ( " " , varying -> name . c_str ( ) ) ; return -1 ; } } int registers = 0 ; for ( int r = 0 ; r < maxVaryingVectors ; r ++ ) { if ( packing [ r ] [ 0 ] || packing [ r ] [ 1 ] || packing [ r ] [ 2 ] || packing [ r ] [ 3 ] ) { registers ++ ; } } return registers ; }
Packs varyings into generic varying registers, using the algorithm from [OpenGL ES Shading Language 1.00 rev.
Packs varyings into generic varying registers using the algorithm from [ OpenGL ES Shading Language 1 . 00 rev .
// Return the number of used registers