gfx/angle/src/compiler/VariablePacker.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/angle/src/compiler/VariablePacker.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,297 @@
     1.4 +//
     1.5 +// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
     1.6 +// Use of this source code is governed by a BSD-style license that can be
     1.7 +// found in the LICENSE file.
     1.8 +//
     1.9 +#include "compiler/VariablePacker.h"
    1.10 +
    1.11 +#include <algorithm>
    1.12 +#include "compiler/ShHandle.h"
    1.13 +
    1.14 +namespace {
    1.15 +int GetSortOrder(ShDataType type)
    1.16 +{
    1.17 +    switch (type) {
    1.18 +        case SH_FLOAT_MAT4:
    1.19 +            return 0;
    1.20 +        case SH_FLOAT_MAT2:
    1.21 +            return 1;
    1.22 +        case SH_FLOAT_VEC4:
    1.23 +        case SH_INT_VEC4:
    1.24 +        case SH_BOOL_VEC4:
    1.25 +            return 2;
    1.26 +        case SH_FLOAT_MAT3:
    1.27 +            return 3;
    1.28 +        case SH_FLOAT_VEC3:
    1.29 +        case SH_INT_VEC3:
    1.30 +        case SH_BOOL_VEC3:
    1.31 +            return 4;
    1.32 +        case SH_FLOAT_VEC2:
    1.33 +        case SH_INT_VEC2:
    1.34 +        case SH_BOOL_VEC2:
    1.35 +            return 5;
    1.36 +        case SH_FLOAT:
    1.37 +        case SH_INT:
    1.38 +        case SH_BOOL:
    1.39 +        case SH_SAMPLER_2D:
    1.40 +        case SH_SAMPLER_CUBE:
    1.41 +        case SH_SAMPLER_EXTERNAL_OES:
    1.42 +        case SH_SAMPLER_2D_RECT_ARB:
    1.43 +            return 6;
    1.44 +        default:
    1.45 +            ASSERT(false);
    1.46 +            return 7;
    1.47 +    }
    1.48 +}
    1.49 +}    // namespace
    1.50 +
    1.51 +int VariablePacker::GetNumComponentsPerRow(ShDataType type)
    1.52 +{
    1.53 +    switch (type) {
    1.54 +        case SH_FLOAT_MAT4:
    1.55 +        case SH_FLOAT_MAT2:
    1.56 +        case SH_FLOAT_VEC4:
    1.57 +        case SH_INT_VEC4:
    1.58 +        case SH_BOOL_VEC4:
    1.59 +            return 4;
    1.60 +        case SH_FLOAT_MAT3:
    1.61 +        case SH_FLOAT_VEC3:
    1.62 +        case SH_INT_VEC3:
    1.63 +        case SH_BOOL_VEC3:
    1.64 +            return 3;
    1.65 +        case SH_FLOAT_VEC2:
    1.66 +        case SH_INT_VEC2:
    1.67 +        case SH_BOOL_VEC2:
    1.68 +            return 2;
    1.69 +        case SH_FLOAT:
    1.70 +        case SH_INT:
    1.71 +        case SH_BOOL:
    1.72 +        case SH_SAMPLER_2D:
    1.73 +        case SH_SAMPLER_CUBE:
    1.74 +        case SH_SAMPLER_EXTERNAL_OES:
    1.75 +        case SH_SAMPLER_2D_RECT_ARB:
    1.76 +            return 1;
    1.77 +        default:
    1.78 +            ASSERT(false);
    1.79 +            return 5;
    1.80 +    }
    1.81 +}
    1.82 +
    1.83 +int VariablePacker::GetNumRows(ShDataType type)
    1.84 +{
    1.85 +    switch (type) {
    1.86 +        case SH_FLOAT_MAT4:
    1.87 +            return 4;
    1.88 +        case SH_FLOAT_MAT3:
    1.89 +            return 3;
    1.90 +        case SH_FLOAT_MAT2:
    1.91 +            return 2;
    1.92 +        case SH_FLOAT_VEC4:
    1.93 +        case SH_INT_VEC4:
    1.94 +        case SH_BOOL_VEC4:
    1.95 +        case SH_FLOAT_VEC3:
    1.96 +        case SH_INT_VEC3:
    1.97 +        case SH_BOOL_VEC3:
    1.98 +        case SH_FLOAT_VEC2:
    1.99 +        case SH_INT_VEC2:
   1.100 +        case SH_BOOL_VEC2:
   1.101 +        case SH_FLOAT:
   1.102 +        case SH_INT:
   1.103 +        case SH_BOOL:
   1.104 +        case SH_SAMPLER_2D:
   1.105 +        case SH_SAMPLER_CUBE:
   1.106 +        case SH_SAMPLER_EXTERNAL_OES:
   1.107 +        case SH_SAMPLER_2D_RECT_ARB:
   1.108 +            return 1;
   1.109 +        default:
   1.110 +            ASSERT(false);
   1.111 +            return 100000;
   1.112 +    }
   1.113 +}
   1.114 +
   1.115 +struct TVariableInfoComparer {
   1.116 +    bool operator()(const TVariableInfo& lhs, const TVariableInfo& rhs) const
   1.117 +    {
   1.118 +        int lhsSortOrder = GetSortOrder(lhs.type);
   1.119 +        int rhsSortOrder = GetSortOrder(rhs.type);
   1.120 +        if (lhsSortOrder != rhsSortOrder) {
   1.121 +            return lhsSortOrder < rhsSortOrder;
   1.122 +        }
   1.123 +        // Sort by largest first.
   1.124 +        return lhs.size > rhs.size;
   1.125 +    }
   1.126 +};
   1.127 +
   1.128 +unsigned VariablePacker::makeColumnFlags(int column, int numComponentsPerRow)
   1.129 +{
   1.130 +    return ((kColumnMask << (kNumColumns - numComponentsPerRow)) &
   1.131 +                    kColumnMask) >> column;
   1.132 +}
   1.133 +
   1.134 +void VariablePacker::fillColumns(int topRow, int numRows, int column, int numComponentsPerRow)
   1.135 +{
   1.136 +    unsigned columnFlags = makeColumnFlags(column, numComponentsPerRow);
   1.137 +    for (int r = 0; r < numRows; ++r) {
   1.138 +        int row = topRow + r;
   1.139 +        ASSERT((rows_[row] & columnFlags) == 0);
   1.140 +        rows_[row] |= columnFlags;
   1.141 +    }
   1.142 +}
   1.143 +
   1.144 +bool VariablePacker::searchColumn(int column, int numRows, int* destRow, int* destSize)
   1.145 +{
   1.146 +    ASSERT(destRow);
   1.147 +
   1.148 +    for (; topNonFullRow_ < maxRows_ && rows_[topNonFullRow_] == kColumnMask;
   1.149 +         ++topNonFullRow_) {
   1.150 +    }
   1.151 +
   1.152 +    for (; bottomNonFullRow_ >= 0 && rows_[bottomNonFullRow_] == kColumnMask;
   1.153 +         --bottomNonFullRow_) {
   1.154 +    }
   1.155 +
   1.156 +    if (bottomNonFullRow_ - topNonFullRow_ + 1 < numRows) {
   1.157 +        return false;
   1.158 +    }
   1.159 +
   1.160 +    unsigned columnFlags = makeColumnFlags(column, 1);
   1.161 +    int topGoodRow = 0;
   1.162 +    int smallestGoodTop = -1;
   1.163 +    int smallestGoodSize = maxRows_ + 1;
   1.164 +    int bottomRow = bottomNonFullRow_ + 1;
   1.165 +    bool found = false;
   1.166 +    for (int row = topNonFullRow_; row <= bottomRow; ++row) {
   1.167 +        bool rowEmpty = row < bottomRow ? ((rows_[row] & columnFlags) == 0) : false;
   1.168 +        if (rowEmpty) {
   1.169 +            if (!found) {
   1.170 +                topGoodRow = row;
   1.171 +                found = true;
   1.172 +            }
   1.173 +        } else {
   1.174 +            if (found) {
   1.175 +                int size = row - topGoodRow;
   1.176 +                if (size >= numRows && size < smallestGoodSize) {
   1.177 +                    smallestGoodSize = size;
   1.178 +                    smallestGoodTop = topGoodRow;
   1.179 +                }
   1.180 +            }
   1.181 +            found = false;
   1.182 +        }
   1.183 +    }
   1.184 +    if (smallestGoodTop < 0) {
   1.185 +        return false;
   1.186 +    }
   1.187 +
   1.188 +    *destRow = smallestGoodTop;
   1.189 +    if (destSize) {
   1.190 +        *destSize = smallestGoodSize;
   1.191 +    }
   1.192 +    return true;
   1.193 +}
   1.194 +
   1.195 +bool VariablePacker::CheckVariablesWithinPackingLimits(int maxVectors, const TVariableInfoList& in_variables)
   1.196 +{
   1.197 +    ASSERT(maxVectors > 0);
   1.198 +    maxRows_ = maxVectors;
   1.199 +    topNonFullRow_ = 0;
   1.200 +    bottomNonFullRow_ = maxRows_ - 1;
   1.201 +    TVariableInfoList variables(in_variables);
   1.202 +
   1.203 +    // As per GLSL 1.017 Appendix A, Section 7 variables are packed in specific
   1.204 +    // order by type, then by size of array, largest first.
   1.205 +    std::sort(variables.begin(), variables.end(), TVariableInfoComparer());
   1.206 +    rows_.clear();
   1.207 +    rows_.resize(maxVectors, 0);
   1.208 +
   1.209 +    // Packs the 4 column variables.
   1.210 +    size_t ii = 0;
   1.211 +    for (; ii < variables.size(); ++ii) {
   1.212 +        const TVariableInfo& variable = variables[ii];
   1.213 +        if (GetNumComponentsPerRow(variable.type) != 4) {
   1.214 +            break;
   1.215 +        }
   1.216 +        topNonFullRow_ += GetNumRows(variable.type) * variable.size;
   1.217 +    }
   1.218 +
   1.219 +    if (topNonFullRow_ > maxRows_) {
   1.220 +        return false;
   1.221 +    }
   1.222 +
   1.223 +    // Packs the 3 column variables.
   1.224 +    int num3ColumnRows = 0;
   1.225 +    for (; ii < variables.size(); ++ii) {
   1.226 +        const TVariableInfo& variable = variables[ii];
   1.227 +        if (GetNumComponentsPerRow(variable.type) != 3) {
   1.228 +            break;
   1.229 +        }
   1.230 +        num3ColumnRows += GetNumRows(variable.type) * variable.size;
   1.231 +    }
   1.232 +
   1.233 +    if (topNonFullRow_ + num3ColumnRows > maxRows_) {
   1.234 +        return false;
   1.235 +    }
   1.236 +
   1.237 +    fillColumns(topNonFullRow_, num3ColumnRows, 0, 3);
   1.238 +
   1.239 +    // Packs the 2 column variables.
   1.240 +    int top2ColumnRow = topNonFullRow_ + num3ColumnRows;
   1.241 +    int twoColumnRowsAvailable = maxRows_ - top2ColumnRow;
   1.242 +    int rowsAvailableInColumns01 = twoColumnRowsAvailable;
   1.243 +    int rowsAvailableInColumns23 = twoColumnRowsAvailable;
   1.244 +    for (; ii < variables.size(); ++ii) {
   1.245 +        const TVariableInfo& variable = variables[ii];
   1.246 +        if (GetNumComponentsPerRow(variable.type) != 2) {
   1.247 +            break;
   1.248 +        }
   1.249 +        int numRows = GetNumRows(variable.type) * variable.size;
   1.250 +        if (numRows <= rowsAvailableInColumns01) {
   1.251 +            rowsAvailableInColumns01 -= numRows;
   1.252 +        } else if (numRows <= rowsAvailableInColumns23) {
   1.253 +            rowsAvailableInColumns23 -= numRows;
   1.254 +        } else {
   1.255 +            return false;
   1.256 +        }
   1.257 +    }
   1.258 +
   1.259 +    int numRowsUsedInColumns01 =
   1.260 +        twoColumnRowsAvailable - rowsAvailableInColumns01;
   1.261 +    int numRowsUsedInColumns23 =
   1.262 +        twoColumnRowsAvailable - rowsAvailableInColumns23;
   1.263 +    fillColumns(top2ColumnRow, numRowsUsedInColumns01, 0, 2);
   1.264 +    fillColumns(maxRows_ - numRowsUsedInColumns23, numRowsUsedInColumns23,
   1.265 +                2, 2);
   1.266 +
   1.267 +    // Packs the 1 column variables.
   1.268 +    for (; ii < variables.size(); ++ii) {
   1.269 +        const TVariableInfo& variable = variables[ii];
   1.270 +        ASSERT(1 == GetNumComponentsPerRow(variable.type));
   1.271 +        int numRows = GetNumRows(variable.type) * variable.size;
   1.272 +        int smallestColumn = -1;
   1.273 +        int smallestSize = maxRows_ + 1;
   1.274 +        int topRow = -1;
   1.275 +        for (int column = 0; column < kNumColumns; ++column) {
   1.276 +            int row = 0;
   1.277 +            int size = 0;
   1.278 +            if (searchColumn(column, numRows, &row, &size)) {
   1.279 +                if (size < smallestSize) {
   1.280 +                    smallestSize = size;
   1.281 +                    smallestColumn = column;
   1.282 +                    topRow = row;
   1.283 +                }
   1.284 +            }
   1.285 +        }
   1.286 +
   1.287 +        if (smallestColumn < 0) {
   1.288 +            return false;
   1.289 +        }
   1.290 +
   1.291 +        fillColumns(topRow, numRows, smallestColumn, 1);
   1.292 +    }
   1.293 +
   1.294 +    ASSERT(variables.size() == ii);
   1.295 +
   1.296 +    return true;
   1.297 +}
   1.298 +
   1.299 +
   1.300 +

mercurial