summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/angle/src/libANGLE/VaryingPacking.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/angle/src/libANGLE/VaryingPacking.cpp')
-rw-r--r--src/3rdparty/angle/src/libANGLE/VaryingPacking.cpp408
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 &reg : mRegisterMap)
- {
- if (reg.data[0] || reg.data[1] || reg.data[2] || reg.data[3])
- {
- ++count;
- }
- }
-
- return count;
-}
-
-} // namespace rx