diff options
Diffstat (limited to 'src/3rdparty/angle/src/libANGLE/VaryingPacking.cpp')
-rw-r--r-- | src/3rdparty/angle/src/libANGLE/VaryingPacking.cpp | 408 |
1 files changed, 0 insertions, 408 deletions
diff --git a/src/3rdparty/angle/src/libANGLE/VaryingPacking.cpp b/src/3rdparty/angle/src/libANGLE/VaryingPacking.cpp deleted file mode 100644 index 6fc707b549..0000000000 --- a/src/3rdparty/angle/src/libANGLE/VaryingPacking.cpp +++ /dev/null @@ -1,408 +0,0 @@ -// -// Copyright 2015 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: -// Class which describes a mapping from varyings to registers, according -// to the spec, or using custom packing algorithms. We also keep a register -// allocation list for the D3D renderer. -// - -#include "libANGLE/VaryingPacking.h" - -#include "common/utilities.h" -#include "libANGLE/Program.h" -#include "libANGLE/Shader.h" - -namespace gl -{ - -namespace -{ - -// true if varying x has a higher priority in packing than y -bool ComparePackedVarying(const PackedVarying &x, const PackedVarying &y) -{ - // If the PackedVarying 'x' or 'y' to be compared is an array element, this clones an equivalent - // non-array shader variable 'vx' or 'vy' for actual comparison instead. - sh::ShaderVariable vx, vy; - const sh::ShaderVariable *px, *py; - if (x.isArrayElement()) - { - vx = *x.varying; - vx.arraySizes.clear(); - px = &vx; - } - else - { - px = x.varying; - } - - if (y.isArrayElement()) - { - vy = *y.varying; - vy.arraySizes.clear(); - py = &vy; - } - else - { - py = y.varying; - } - - return gl::CompareShaderVar(*px, *py); -} - -} // anonymous namespace - -// Implementation of VaryingPacking -VaryingPacking::VaryingPacking(GLuint maxVaryingVectors, PackMode packMode) - : mRegisterMap(maxVaryingVectors), mPackMode(packMode) -{ -} - -VaryingPacking::~VaryingPacking() = default; - -// Packs varyings into generic varying registers, using the algorithm from -// See [OpenGL ES Shading Language 1.00 rev. 17] appendix A section 7 page 111 -// Also [OpenGL ES Shading Language 3.00 rev. 4] Section 11 page 119 -// Returns false if unsuccessful. -bool VaryingPacking::packVarying(const PackedVarying &packedVarying) -{ - const auto &varying = *packedVarying.varying; - - // "Non - square matrices of type matCxR consume the same space as a square matrix of type matN - // where N is the greater of C and R." - // Here we are a bit more conservative and allow packing non-square matrices more tightly. - // Make sure we use transposed matrix types to count registers correctly. - ASSERT(!varying.isStruct()); - GLenum transposedType = gl::TransposeMatrixType(varying.type); - unsigned int varyingRows = gl::VariableRowCount(transposedType); - unsigned int varyingColumns = gl::VariableColumnCount(transposedType); - - // "Variables of type mat2 occupies 2 complete rows." - // For non-WebGL contexts, we allow mat2 to occupy only two columns per row. - if (mPackMode == PackMode::WEBGL_STRICT && varying.type == GL_FLOAT_MAT2) - { - varyingColumns = 4; - } - - // "Arrays of size N are assumed to take N times the size of the base type" - // GLSL ES 3.10 section 4.3.6: Output variables cannot be arrays of arrays or arrays of - // structures, so we may use getBasicTypeElementCount(). - const unsigned int elementCount = varying.getBasicTypeElementCount(); - varyingRows *= (packedVarying.isArrayElement() ? 1 : elementCount); - - unsigned int maxVaryingVectors = static_cast<unsigned int>(mRegisterMap.size()); - - // Fail if we are packing a single over-large varying. - if (varyingRows > maxVaryingVectors) - { - return false; - } - - // "For 2, 3 and 4 component variables packing is started using the 1st column of the 1st row. - // Variables are then allocated to successive rows, aligning them to the 1st column." - if (varyingColumns >= 2 && varyingColumns <= 4) - { - for (unsigned int row = 0; row <= maxVaryingVectors - varyingRows; ++row) - { - if (isFree(row, 0, varyingRows, varyingColumns)) - { - insert(row, 0, packedVarying); - return true; - } - } - - // "For 2 component variables, when there are no spare rows, the strategy is switched to - // using the highest numbered row and the lowest numbered column where the variable will - // fit." - if (varyingColumns == 2) - { - for (unsigned int r = maxVaryingVectors - varyingRows + 1; r-- >= 1;) - { - if (isFree(r, 2, varyingRows, 2)) - { - insert(r, 2, packedVarying); - return true; - } - } - } - - return false; - } - - // "1 component variables have their own packing rule. They are packed in order of size, largest - // first. Each variable is placed in the column that leaves the least amount of space in the - // column and aligned to the lowest available rows within that column." - ASSERT(varyingColumns == 1); - unsigned int contiguousSpace[4] = {0}; - unsigned int bestContiguousSpace[4] = {0}; - unsigned int totalSpace[4] = {0}; - - for (unsigned int row = 0; row < maxVaryingVectors; ++row) - { - for (unsigned int column = 0; column < 4; ++column) - { - if (mRegisterMap[row][column]) - { - contiguousSpace[column] = 0; - } - else - { - contiguousSpace[column]++; - totalSpace[column]++; - - if (contiguousSpace[column] > bestContiguousSpace[column]) - { - bestContiguousSpace[column] = contiguousSpace[column]; - } - } - } - } - - unsigned int bestColumn = 0; - for (unsigned int column = 1; column < 4; ++column) - { - if (bestContiguousSpace[column] >= varyingRows && - (bestContiguousSpace[bestColumn] < varyingRows || - totalSpace[column] < totalSpace[bestColumn])) - { - bestColumn = column; - } - } - - if (bestContiguousSpace[bestColumn] >= varyingRows) - { - for (unsigned int row = 0; row < maxVaryingVectors; row++) - { - if (isFree(row, bestColumn, varyingRows, 1)) - { - for (unsigned int arrayIndex = 0; arrayIndex < varyingRows; ++arrayIndex) - { - // If varyingRows > 1, it must be an array. - PackedVaryingRegister registerInfo; - registerInfo.packedVarying = &packedVarying; - registerInfo.registerRow = row + arrayIndex; - registerInfo.registerColumn = bestColumn; - registerInfo.varyingArrayIndex = - (packedVarying.isArrayElement() ? packedVarying.arrayIndex : arrayIndex); - registerInfo.varyingRowIndex = 0; - // Do not record register info for builtins. - // TODO(jmadill): Clean this up. - if (!packedVarying.varying->isBuiltIn()) - { - mRegisterList.push_back(registerInfo); - } - mRegisterMap[row + arrayIndex][bestColumn] = true; - } - break; - } - } - return true; - } - - return false; -} - -bool VaryingPacking::isFree(unsigned int registerRow, - unsigned int registerColumn, - unsigned int varyingRows, - unsigned int varyingColumns) const -{ - for (unsigned int row = 0; row < varyingRows; ++row) - { - ASSERT(registerRow + row < mRegisterMap.size()); - for (unsigned int column = 0; column < varyingColumns; ++column) - { - ASSERT(registerColumn + column < 4); - if (mRegisterMap[registerRow + row][registerColumn + column]) - { - return false; - } - } - } - - return true; -} - -void VaryingPacking::insert(unsigned int registerRow, - unsigned int registerColumn, - const PackedVarying &packedVarying) -{ - unsigned int varyingRows = 0; - unsigned int varyingColumns = 0; - - const auto &varying = *packedVarying.varying; - ASSERT(!varying.isStruct()); - GLenum transposedType = gl::TransposeMatrixType(varying.type); - varyingRows = gl::VariableRowCount(transposedType); - varyingColumns = gl::VariableColumnCount(transposedType); - - PackedVaryingRegister registerInfo; - registerInfo.packedVarying = &packedVarying; - registerInfo.registerColumn = registerColumn; - - // GLSL ES 3.10 section 4.3.6: Output variables cannot be arrays of arrays or arrays of - // structures, so we may use getBasicTypeElementCount(). - const unsigned int arrayElementCount = varying.getBasicTypeElementCount(); - for (unsigned int arrayElement = 0; arrayElement < arrayElementCount; ++arrayElement) - { - if (packedVarying.isArrayElement() && arrayElement != packedVarying.arrayIndex) - { - continue; - } - for (unsigned int varyingRow = 0; varyingRow < varyingRows; ++varyingRow) - { - registerInfo.registerRow = registerRow + (arrayElement * varyingRows) + varyingRow; - registerInfo.varyingRowIndex = varyingRow; - registerInfo.varyingArrayIndex = arrayElement; - // Do not record register info for builtins. - // TODO(jmadill): Clean this up. - if (!packedVarying.varying->isBuiltIn()) - { - mRegisterList.push_back(registerInfo); - } - - for (unsigned int columnIndex = 0; columnIndex < varyingColumns; ++columnIndex) - { - mRegisterMap[registerInfo.registerRow][registerColumn + columnIndex] = true; - } - } - } -} - -bool VaryingPacking::collectAndPackUserVaryings(gl::InfoLog &infoLog, - const Program::MergedVaryings &mergedVaryings, - const std::vector<std::string> &tfVaryings) -{ - std::set<std::string> uniqueFullNames; - mPackedVaryings.clear(); - - for (const auto &ref : mergedVaryings) - { - const sh::Varying *input = ref.second.vertex; - const sh::Varying *output = ref.second.fragment; - - // Only pack statically used varyings that have a matched input or output, plus special - // builtins. - if (((input && output) || (output && output->isBuiltIn())) && output->staticUse) - { - // Will get the vertex shader interpolation by default. - auto interpolation = ref.second.get()->interpolation; - - // Note that we lose the vertex shader static use information here. The data for the - // variable is taken from the fragment shader. - if (output->isStruct()) - { - ASSERT(!output->isArray()); - for (const auto &field : output->fields) - { - ASSERT(!field.isStruct() && !field.isArray()); - mPackedVaryings.push_back(PackedVarying(field, interpolation, output->name)); - uniqueFullNames.insert(mPackedVaryings.back().nameWithArrayIndex()); - } - } - else - { - mPackedVaryings.push_back(PackedVarying(*output, interpolation)); - uniqueFullNames.insert(mPackedVaryings.back().nameWithArrayIndex()); - } - continue; - } - - // Keep Transform FB varyings in the merged list always. - if (!input) - { - continue; - } - - for (const std::string &tfVarying : tfVaryings) - { - std::vector<unsigned int> subscripts; - std::string baseName = ParseResourceName(tfVarying, &subscripts); - size_t subscript = GL_INVALID_INDEX; - if (!subscripts.empty()) - { - subscript = subscripts.back(); - } - // Already packed for fragment shader. - if (uniqueFullNames.count(tfVarying) > 0 || uniqueFullNames.count(baseName) > 0) - { - continue; - } - // Array as a whole and array element conflict has already been checked in - // linkValidateTransformFeedback. - if (baseName == input->name) - { - // Transform feedback for varying structs is underspecified. - // See Khronos bug 9856. - // TODO(jmadill): Figure out how to be spec-compliant here. - if (!input->isStruct() && tfVarying.compare(0, 3, "gl_") != 0) - { - mPackedVaryings.push_back(PackedVarying(*input, input->interpolation)); - mPackedVaryings.back().vertexOnly = true; - mPackedVaryings.back().arrayIndex = static_cast<GLuint>(subscript); - uniqueFullNames.insert(tfVarying); - } - // Continue to match next array element for 'input' if the current match is array - // element. - if (subscript == GL_INVALID_INDEX) - { - break; - } - } - } - } - - std::sort(mPackedVaryings.begin(), mPackedVaryings.end(), ComparePackedVarying); - - return packUserVaryings(infoLog, mPackedVaryings, tfVaryings); -} - -// See comment on packVarying. -bool VaryingPacking::packUserVaryings(gl::InfoLog &infoLog, - const std::vector<PackedVarying> &packedVaryings, - const std::vector<std::string> &transformFeedbackVaryings) -{ - - // "Variables are packed into the registers one at a time so that they each occupy a contiguous - // subrectangle. No splitting of variables is permitted." - for (const PackedVarying &packedVarying : packedVaryings) - { - if (!packVarying(packedVarying)) - { - infoLog << "Could not pack varying " << packedVarying.nameWithArrayIndex(); - return false; - } - } - - // Sort the packed register list - std::sort(mRegisterList.begin(), mRegisterList.end()); - - // Assign semantic indices - for (unsigned int semanticIndex = 0; - semanticIndex < static_cast<unsigned int>(mRegisterList.size()); ++semanticIndex) - { - mRegisterList[semanticIndex].semanticIndex = semanticIndex; - } - - return true; -} - -unsigned int VaryingPacking::getRegisterCount() const -{ - unsigned int count = 0; - - for (const Register ® : mRegisterMap) - { - if (reg.data[0] || reg.data[1] || reg.data[2] || reg.data[3]) - { - ++count; - } - } - - return count; -} - -} // namespace rx |