Commit d7487b13 by Olli Etuaho Committed by Commit Bot

Clean up checking variable packing limits

This encapsulates expanding struct variables inside the VariablePacker class that packs variables according to the GLSL ES spec. The variable expansion step is no longer run twice when checking uniforms against the max uniforms limit. BUG=angleproject:2068 TEST=angle_unittests Change-Id: I012ddaa249f71c0a78d937c98007c61352e64888 Reviewed-on: https://chromium-review.googlesource.com/608367 Commit-Queue: Olli Etuaho <oetuaho@nvidia.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 9b11ea4f
...@@ -484,13 +484,9 @@ TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[], ...@@ -484,13 +484,9 @@ TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[],
} }
if (compileOptions & SH_ENFORCE_PACKING_RESTRICTIONS) if (compileOptions & SH_ENFORCE_PACKING_RESTRICTIONS)
{ {
std::vector<sh::ShaderVariable> expandedUniforms;
sh::ExpandUniforms(uniforms, &expandedUniforms);
VariablePacker packer;
// Returns true if, after applying the packing rules in the GLSL ES 1.00.17 spec // Returns true if, after applying the packing rules in the GLSL ES 1.00.17 spec
// Appendix A, section 7, the shader does not use too many uniforms. // Appendix A, section 7, the shader does not use too many uniforms.
success = success = CheckVariablesInPackingLimits(maxUniformVectors, uniforms);
packer.CheckVariablesWithinPackingLimits(maxUniformVectors, expandedUniforms);
if (!success) if (!success)
{ {
mDiagnostics.globalError("too many uniforms"); mDiagnostics.globalError("too many uniforms");
......
...@@ -448,8 +448,7 @@ int GetVertexShaderNumViews(const ShHandle handle) ...@@ -448,8 +448,7 @@ int GetVertexShaderNumViews(const ShHandle handle)
bool CheckVariablesWithinPackingLimits(int maxVectors, const std::vector<ShaderVariable> &variables) bool CheckVariablesWithinPackingLimits(int maxVectors, const std::vector<ShaderVariable> &variables)
{ {
VariablePacker packer; return CheckVariablesInPackingLimits(maxVectors, variables);
return packer.CheckVariablesWithinPackingLimits(maxVectors, variables);
} }
bool GetUniformBlockRegister(const ShHandle handle, bool GetUniformBlockRegister(const ShHandle handle,
......
...@@ -49,24 +49,6 @@ BlockType GetBlockType(TQualifier qualifier) ...@@ -49,24 +49,6 @@ BlockType GetBlockType(TQualifier qualifier)
} }
} }
void ExpandUserDefinedVariable(const ShaderVariable &variable,
const std::string &name,
const std::string &mappedName,
bool markStaticUse,
std::vector<ShaderVariable> *expanded)
{
ASSERT(variable.isStruct());
const std::vector<ShaderVariable> &fields = variable.fields;
for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
{
const ShaderVariable &field = fields[fieldIndex];
ExpandVariable(field, name + "." + field.name, mappedName + "." + field.mappedName,
markStaticUse, expanded);
}
}
template <class VarT> template <class VarT>
VarT *FindVariable(const TString &name, std::vector<VarT> *infoList) VarT *FindVariable(const TString &name, std::vector<VarT> *infoList)
{ {
...@@ -716,58 +698,4 @@ void CollectVariables(TIntermBlock *root, ...@@ -716,58 +698,4 @@ void CollectVariables(TIntermBlock *root,
root->traverse(&collect); root->traverse(&collect);
} }
void ExpandVariable(const ShaderVariable &variable,
const std::string &name,
const std::string &mappedName,
bool markStaticUse,
std::vector<ShaderVariable> *expanded)
{
if (variable.isStruct())
{
if (variable.isArray())
{
for (unsigned int elementIndex = 0; elementIndex < variable.elementCount();
elementIndex++)
{
std::string lname = name + ::ArrayString(elementIndex);
std::string lmappedName = mappedName + ::ArrayString(elementIndex);
ExpandUserDefinedVariable(variable, lname, lmappedName, markStaticUse, expanded);
}
}
else
{
ExpandUserDefinedVariable(variable, name, mappedName, markStaticUse, expanded);
}
}
else
{
ShaderVariable expandedVar = variable;
expandedVar.name = name;
expandedVar.mappedName = mappedName;
// Mark all expanded fields as used if the parent is used
if (markStaticUse)
{
expandedVar.staticUse = true;
}
if (expandedVar.isArray())
{
expandedVar.name += "[0]";
expandedVar.mappedName += "[0]";
}
expanded->push_back(expandedVar);
}
}
void ExpandUniforms(const std::vector<Uniform> &compact, std::vector<ShaderVariable> *expanded)
{
for (const Uniform &variable : compact)
{
ExpandVariable(variable, variable.name, variable.mappedName, variable.staticUse, expanded);
}
}
} // namespace sh } // namespace sh
...@@ -29,15 +29,6 @@ void CollectVariables(TIntermBlock *root, ...@@ -29,15 +29,6 @@ void CollectVariables(TIntermBlock *root,
TSymbolTable *symbolTable, TSymbolTable *symbolTable,
int shaderVersion, int shaderVersion,
const TExtensionBehavior &extensionBehavior); const TExtensionBehavior &extensionBehavior);
void ExpandVariable(const ShaderVariable &variable,
const std::string &name,
const std::string &mappedName,
bool markStaticUse,
std::vector<ShaderVariable> *expanded);
// Expand struct uniforms to flattened lists of split variables
void ExpandUniforms(const std::vector<Uniform> &compact, std::vector<ShaderVariable> *expanded);
} }
#endif // COMPILER_TRANSLATOR_VARIABLEINFO_H_ #endif // COMPILER_TRANSLATOR_VARIABLEINFO_H_
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// //
// Check whether variables fit within packing limits according to the packing rules from the GLSL ES
// 1.00.17 spec, Appendix A, section 7.
#include <algorithm> #include <algorithm>
...@@ -11,62 +13,102 @@ ...@@ -11,62 +13,102 @@
#include "compiler/translator/VariablePacker.h" #include "compiler/translator/VariablePacker.h"
#include "common/utilities.h" #include "common/utilities.h"
int VariablePacker::GetNumComponentsPerRow(sh::GLenum type) namespace sh
{ {
switch (type)
namespace
{
void ExpandVariable(const ShaderVariable &variable,
const std::string &name,
const std::string &mappedName,
bool markStaticUse,
std::vector<ShaderVariable> *expanded);
void ExpandUserDefinedVariable(const ShaderVariable &variable,
const std::string &name,
const std::string &mappedName,
bool markStaticUse,
std::vector<ShaderVariable> *expanded)
{
ASSERT(variable.isStruct());
const std::vector<ShaderVariable> &fields = variable.fields;
for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
{ {
case GL_FLOAT_MAT4: const ShaderVariable &field = fields[fieldIndex];
case GL_FLOAT_MAT2: ExpandVariable(field, name + "." + field.name, mappedName + "." + field.mappedName,
case GL_FLOAT_MAT2x4: markStaticUse, expanded);
case GL_FLOAT_MAT3x4:
case GL_FLOAT_MAT4x2:
case GL_FLOAT_MAT4x3:
case GL_FLOAT_VEC4:
case GL_INT_VEC4:
case GL_BOOL_VEC4:
case GL_UNSIGNED_INT_VEC4:
return 4;
case GL_FLOAT_MAT3:
case GL_FLOAT_MAT2x3:
case GL_FLOAT_MAT3x2:
case GL_FLOAT_VEC3:
case GL_INT_VEC3:
case GL_BOOL_VEC3:
case GL_UNSIGNED_INT_VEC3:
return 3;
case GL_FLOAT_VEC2:
case GL_INT_VEC2:
case GL_BOOL_VEC2:
case GL_UNSIGNED_INT_VEC2:
return 2;
default:
ASSERT(gl::VariableComponentCount(type) == 1);
return 1;
} }
} }
int VariablePacker::GetNumRows(sh::GLenum type) void ExpandVariable(const ShaderVariable &variable,
const std::string &name,
const std::string &mappedName,
bool markStaticUse,
std::vector<ShaderVariable> *expanded)
{ {
switch (type) if (variable.isStruct())
{ {
case GL_FLOAT_MAT4: if (variable.isArray())
case GL_FLOAT_MAT2x4: {
case GL_FLOAT_MAT3x4: for (unsigned int elementIndex = 0; elementIndex < variable.elementCount();
case GL_FLOAT_MAT4x3: elementIndex++)
case GL_FLOAT_MAT4x2: {
return 4; std::string lname = name + ::ArrayString(elementIndex);
case GL_FLOAT_MAT3: std::string lmappedName = mappedName + ::ArrayString(elementIndex);
case GL_FLOAT_MAT2x3: ExpandUserDefinedVariable(variable, lname, lmappedName, markStaticUse, expanded);
case GL_FLOAT_MAT3x2: }
return 3; }
case GL_FLOAT_MAT2: else
return 2; {
default: ExpandUserDefinedVariable(variable, name, mappedName, markStaticUse, expanded);
ASSERT(gl::VariableRowCount(type) == 1); }
return 1; }
else
{
ShaderVariable expandedVar = variable;
expandedVar.name = name;
expandedVar.mappedName = mappedName;
// Mark all expanded fields as used if the parent is used
if (markStaticUse)
{
expandedVar.staticUse = true;
}
if (expandedVar.isArray())
{
expandedVar.name += "[0]";
expandedVar.mappedName += "[0]";
}
expanded->push_back(expandedVar);
} }
} }
class VariablePacker
{
public:
bool checkExpandedVariablesWithinPackingLimits(unsigned int maxVectors,
std::vector<sh::ShaderVariable> *variables);
private:
static const int kNumColumns = 4;
static const unsigned kColumnMask = (1 << kNumColumns) - 1;
unsigned makeColumnFlags(int column, int numComponentsPerRow);
void fillColumns(int topRow, int numRows, int column, int numComponentsPerRow);
bool searchColumn(int column, int numRows, int *destRow, int *destSize);
int topNonFullRow_;
int bottomNonFullRow_;
int maxRows_;
std::vector<unsigned> rows_;
};
struct TVariableInfoComparer struct TVariableInfoComparer
{ {
bool operator()(const sh::ShaderVariable &lhs, const sh::ShaderVariable &rhs) const bool operator()(const sh::ShaderVariable &lhs, const sh::ShaderVariable &rhs) const
...@@ -159,27 +201,21 @@ bool VariablePacker::searchColumn(int column, int numRows, int *destRow, int *de ...@@ -159,27 +201,21 @@ bool VariablePacker::searchColumn(int column, int numRows, int *destRow, int *de
return true; return true;
} }
bool VariablePacker::CheckVariablesWithinPackingLimits( bool VariablePacker::checkExpandedVariablesWithinPackingLimits(
unsigned int maxVectors, unsigned int maxVectors,
const std::vector<sh::ShaderVariable> &in_variables) std::vector<sh::ShaderVariable> *variables)
{ {
ASSERT(maxVectors > 0); ASSERT(maxVectors > 0);
maxRows_ = maxVectors; maxRows_ = maxVectors;
topNonFullRow_ = 0; topNonFullRow_ = 0;
bottomNonFullRow_ = maxRows_ - 1; bottomNonFullRow_ = maxRows_ - 1;
std::vector<sh::ShaderVariable> variables;
for (const auto &variable : in_variables)
{
ExpandVariable(variable, variable.name, variable.mappedName, variable.staticUse,
&variables);
}
// Check whether each variable fits in the available vectors. // Check whether each variable fits in the available vectors.
for (size_t i = 0; i < variables.size(); i++) for (const sh::ShaderVariable &variable : *variables)
{ {
const sh::ShaderVariable &variable = variables[i]; // Structs should have been expanded before reaching here.
if (variable.elementCount() > maxVectors / GetNumRows(variable.type)) ASSERT(!variable.isStruct());
if (variable.elementCount() > maxVectors / GetVariablePackingRows(variable.type))
{ {
return false; return false;
} }
...@@ -187,20 +223,20 @@ bool VariablePacker::CheckVariablesWithinPackingLimits( ...@@ -187,20 +223,20 @@ bool VariablePacker::CheckVariablesWithinPackingLimits(
// As per GLSL 1.017 Appendix A, Section 7 variables are packed in specific // As per GLSL 1.017 Appendix A, Section 7 variables are packed in specific
// order by type, then by size of array, largest first. // order by type, then by size of array, largest first.
std::sort(variables.begin(), variables.end(), TVariableInfoComparer()); std::sort(variables->begin(), variables->end(), TVariableInfoComparer());
rows_.clear(); rows_.clear();
rows_.resize(maxVectors, 0); rows_.resize(maxVectors, 0);
// Packs the 4 column variables. // Packs the 4 column variables.
size_t ii = 0; size_t ii = 0;
for (; ii < variables.size(); ++ii) for (; ii < variables->size(); ++ii)
{ {
const sh::ShaderVariable &variable = variables[ii]; const sh::ShaderVariable &variable = (*variables)[ii];
if (GetNumComponentsPerRow(variable.type) != 4) if (GetVariablePackingComponentsPerRow(variable.type) != 4)
{ {
break; break;
} }
topNonFullRow_ += GetNumRows(variable.type) * variable.elementCount(); topNonFullRow_ += GetVariablePackingRows(variable.type) * variable.elementCount();
} }
if (topNonFullRow_ > maxRows_) if (topNonFullRow_ > maxRows_)
...@@ -210,14 +246,14 @@ bool VariablePacker::CheckVariablesWithinPackingLimits( ...@@ -210,14 +246,14 @@ bool VariablePacker::CheckVariablesWithinPackingLimits(
// Packs the 3 column variables. // Packs the 3 column variables.
int num3ColumnRows = 0; int num3ColumnRows = 0;
for (; ii < variables.size(); ++ii) for (; ii < variables->size(); ++ii)
{ {
const sh::ShaderVariable &variable = variables[ii]; const sh::ShaderVariable &variable = (*variables)[ii];
if (GetNumComponentsPerRow(variable.type) != 3) if (GetVariablePackingComponentsPerRow(variable.type) != 3)
{ {
break; break;
} }
num3ColumnRows += GetNumRows(variable.type) * variable.elementCount(); num3ColumnRows += GetVariablePackingRows(variable.type) * variable.elementCount();
} }
if (topNonFullRow_ + num3ColumnRows > maxRows_) if (topNonFullRow_ + num3ColumnRows > maxRows_)
...@@ -232,14 +268,14 @@ bool VariablePacker::CheckVariablesWithinPackingLimits( ...@@ -232,14 +268,14 @@ bool VariablePacker::CheckVariablesWithinPackingLimits(
int twoColumnRowsAvailable = maxRows_ - top2ColumnRow; int twoColumnRowsAvailable = maxRows_ - top2ColumnRow;
int rowsAvailableInColumns01 = twoColumnRowsAvailable; int rowsAvailableInColumns01 = twoColumnRowsAvailable;
int rowsAvailableInColumns23 = twoColumnRowsAvailable; int rowsAvailableInColumns23 = twoColumnRowsAvailable;
for (; ii < variables.size(); ++ii) for (; ii < variables->size(); ++ii)
{ {
const sh::ShaderVariable &variable = variables[ii]; const sh::ShaderVariable &variable = (*variables)[ii];
if (GetNumComponentsPerRow(variable.type) != 2) if (GetVariablePackingComponentsPerRow(variable.type) != 2)
{ {
break; break;
} }
int numRows = GetNumRows(variable.type) * variable.elementCount(); int numRows = GetVariablePackingRows(variable.type) * variable.elementCount();
if (numRows <= rowsAvailableInColumns01) if (numRows <= rowsAvailableInColumns01)
{ {
rowsAvailableInColumns01 -= numRows; rowsAvailableInColumns01 -= numRows;
...@@ -260,11 +296,11 @@ bool VariablePacker::CheckVariablesWithinPackingLimits( ...@@ -260,11 +296,11 @@ bool VariablePacker::CheckVariablesWithinPackingLimits(
fillColumns(maxRows_ - numRowsUsedInColumns23, numRowsUsedInColumns23, 2, 2); fillColumns(maxRows_ - numRowsUsedInColumns23, numRowsUsedInColumns23, 2, 2);
// Packs the 1 column variables. // Packs the 1 column variables.
for (; ii < variables.size(); ++ii) for (; ii < variables->size(); ++ii)
{ {
const sh::ShaderVariable &variable = variables[ii]; const sh::ShaderVariable &variable = (*variables)[ii];
ASSERT(1 == GetNumComponentsPerRow(variable.type)); ASSERT(1 == GetVariablePackingComponentsPerRow(variable.type));
int numRows = GetNumRows(variable.type) * variable.elementCount(); int numRows = GetVariablePackingRows(variable.type) * variable.elementCount();
int smallestColumn = -1; int smallestColumn = -1;
int smallestSize = maxRows_ + 1; int smallestSize = maxRows_ + 1;
int topRow = -1; int topRow = -1;
...@@ -291,7 +327,86 @@ bool VariablePacker::CheckVariablesWithinPackingLimits( ...@@ -291,7 +327,86 @@ bool VariablePacker::CheckVariablesWithinPackingLimits(
fillColumns(topRow, numRows, smallestColumn, 1); fillColumns(topRow, numRows, smallestColumn, 1);
} }
ASSERT(variables.size() == ii); ASSERT(variables->size() == ii);
return true; return true;
} }
} // anonymous namespace
int GetVariablePackingComponentsPerRow(sh::GLenum type)
{
switch (type)
{
case GL_FLOAT_MAT4:
case GL_FLOAT_MAT2:
case GL_FLOAT_MAT2x4:
case GL_FLOAT_MAT3x4:
case GL_FLOAT_MAT4x2:
case GL_FLOAT_MAT4x3:
case GL_FLOAT_VEC4:
case GL_INT_VEC4:
case GL_BOOL_VEC4:
case GL_UNSIGNED_INT_VEC4:
return 4;
case GL_FLOAT_MAT3:
case GL_FLOAT_MAT2x3:
case GL_FLOAT_MAT3x2:
case GL_FLOAT_VEC3:
case GL_INT_VEC3:
case GL_BOOL_VEC3:
case GL_UNSIGNED_INT_VEC3:
return 3;
case GL_FLOAT_VEC2:
case GL_INT_VEC2:
case GL_BOOL_VEC2:
case GL_UNSIGNED_INT_VEC2:
return 2;
default:
ASSERT(gl::VariableComponentCount(type) == 1);
return 1;
}
}
int GetVariablePackingRows(sh::GLenum type)
{
switch (type)
{
case GL_FLOAT_MAT4:
case GL_FLOAT_MAT2x4:
case GL_FLOAT_MAT3x4:
case GL_FLOAT_MAT4x3:
case GL_FLOAT_MAT4x2:
return 4;
case GL_FLOAT_MAT3:
case GL_FLOAT_MAT2x3:
case GL_FLOAT_MAT3x2:
return 3;
case GL_FLOAT_MAT2:
return 2;
default:
ASSERT(gl::VariableRowCount(type) == 1);
return 1;
}
}
template <typename T>
bool CheckVariablesInPackingLimits(unsigned int maxVectors, const std::vector<T> &variables)
{
VariablePacker packer;
std::vector<sh::ShaderVariable> expandedVariables;
for (const ShaderVariable &variable : variables)
{
ExpandVariable(variable, variable.name, variable.mappedName, variable.staticUse,
&expandedVariables);
}
return packer.checkExpandedVariablesWithinPackingLimits(maxVectors, &expandedVariables);
}
template bool CheckVariablesInPackingLimits<ShaderVariable>(
unsigned int maxVectors,
const std::vector<ShaderVariable> &variables);
template bool CheckVariablesInPackingLimits<Uniform>(unsigned int maxVectors,
const std::vector<Uniform> &variables);
} // namespace sh
...@@ -3,39 +3,30 @@ ...@@ -3,39 +3,30 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// //
// Check whether variables fit within packing limits according to the packing rules from the GLSL ES
// 1.00.17 spec, Appendix A, section 7.
#ifndef COMPILER_TRANSLATOR_VARIABLEPACKER_H_ #ifndef COMPILER_TRANSLATOR_VARIABLEPACKER_H_
#define COMPILER_TRANSLATOR_VARIABLEPACKER_H_ #define COMPILER_TRANSLATOR_VARIABLEPACKER_H_
#include <vector> #include <vector>
#include "compiler/translator/VariableInfo.h"
class VariablePacker #include <GLSLANG/ShaderLang.h>
namespace sh
{ {
public:
// Returns true if the passed in variables pack in maxVectors following // Gets how many components in a row a data type takes.
// the packing rules from the GLSL 1.017 spec, Appendix A, section 7. int GetVariablePackingComponentsPerRow(sh::GLenum type);
bool CheckVariablesWithinPackingLimits(unsigned int maxVectors,
const std::vector<sh::ShaderVariable> &in_variables); // Gets how many rows a data type takes.
int GetVariablePackingRows(sh::GLenum type);
// Gets how many components in a row a data type takes.
static int GetNumComponentsPerRow(sh::GLenum type); // Returns true if the passed in variables pack in maxVectors.
// T should be ShaderVariable or one of the subclasses of ShaderVariable.
// Gets how many rows a data type takes. template <typename T>
static int GetNumRows(sh::GLenum type); bool CheckVariablesInPackingLimits(unsigned int maxVectors, const std::vector<T> &variables);
private: } // namespace sh
static const int kNumColumns = 4;
static const unsigned kColumnMask = (1 << kNumColumns) - 1;
unsigned makeColumnFlags(int column, int numComponentsPerRow);
void fillColumns(int topRow, int numRows, int column, int numComponentsPerRow);
bool searchColumn(int column, int numRows, int *destRow, int *destSize);
int topNonFullRow_;
int bottomNonFullRow_;
int maxRows_;
std::vector<unsigned> rows_;
};
#endif // COMPILER_TRANSLATOR_VARIABLEPACKER_H_ #endif // COMPILER_TRANSLATOR_VARIABLEPACKER_H_
...@@ -9,6 +9,9 @@ ...@@ -9,6 +9,9 @@
#include "common/angleutils.h" #include "common/angleutils.h"
#include "compiler/translator/VariablePacker.h" #include "compiler/translator/VariablePacker.h"
namespace
{
static sh::GLenum types[] = { static sh::GLenum types[] = {
GL_FLOAT_MAT4, // 0 GL_FLOAT_MAT4, // 0
GL_FLOAT_MAT2, // 1 GL_FLOAT_MAT2, // 1
...@@ -54,42 +57,38 @@ static sh::GLenum types[] = { ...@@ -54,42 +57,38 @@ static sh::GLenum types[] = {
GL_UNSIGNED_INT_SAMPLER_2D_ARRAY, // 41 GL_UNSIGNED_INT_SAMPLER_2D_ARRAY, // 41
}; };
static sh::GLenum nonSqMatTypes[] = { static sh::GLenum nonSqMatTypes[] = {GL_FLOAT_MAT2x3, GL_FLOAT_MAT2x4, GL_FLOAT_MAT3x2,
GL_FLOAT_MAT2x3, GL_FLOAT_MAT3x4, GL_FLOAT_MAT4x2, GL_FLOAT_MAT4x3};
GL_FLOAT_MAT2x4,
GL_FLOAT_MAT3x2, } // anonymous namespace
GL_FLOAT_MAT3x4,
GL_FLOAT_MAT4x2,
GL_FLOAT_MAT4x3
};
TEST(VariablePacking, Pack) { TEST(VariablePacking, Pack)
VariablePacker packer; {
std::vector<sh::ShaderVariable> vars; std::vector<sh::ShaderVariable> vars;
const int kMaxRows = 16; const int kMaxRows = 16;
// test no vars. // test no vars.
EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars)); EXPECT_TRUE(CheckVariablesInPackingLimits(kMaxRows, vars));
for (size_t tt = 0; tt < ArraySize(types); ++tt) for (size_t tt = 0; tt < ArraySize(types); ++tt)
{ {
sh::GLenum type = types[tt]; sh::GLenum type = types[tt];
int num_rows = VariablePacker::GetNumRows(type); int num_rows = sh::GetVariablePackingRows(type);
int num_components_per_row = VariablePacker::GetNumComponentsPerRow(type); int num_components_per_row = sh::GetVariablePackingComponentsPerRow(type);
// Check 1 of the type. // Check 1 of the type.
vars.clear(); vars.clear();
vars.push_back(sh::ShaderVariable(type, 0)); vars.push_back(sh::ShaderVariable(type, 0));
EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars)); EXPECT_TRUE(CheckVariablesInPackingLimits(kMaxRows, vars));
// Check exactly the right amount of 1 type as an array. // Check exactly the right amount of 1 type as an array.
int num_vars = kMaxRows / num_rows; int num_vars = kMaxRows / num_rows;
vars.clear(); vars.clear();
vars.push_back(sh::ShaderVariable(type, num_vars == 1 ? 0 : num_vars)); vars.push_back(sh::ShaderVariable(type, num_vars == 1 ? 0 : num_vars));
EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars)); EXPECT_TRUE(CheckVariablesInPackingLimits(kMaxRows, vars));
// test too many // test too many
vars.clear(); vars.clear();
vars.push_back(sh::ShaderVariable(type, num_vars == 0 ? 0 : (num_vars + 1))); vars.push_back(sh::ShaderVariable(type, num_vars == 0 ? 0 : (num_vars + 1)));
EXPECT_FALSE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars)); EXPECT_FALSE(CheckVariablesInPackingLimits(kMaxRows, vars));
// Check exactly the right amount of 1 type as individual vars. // Check exactly the right amount of 1 type as individual vars.
num_vars = num_vars =
...@@ -99,11 +98,11 @@ TEST(VariablePacking, Pack) { ...@@ -99,11 +98,11 @@ TEST(VariablePacking, Pack) {
{ {
vars.push_back(sh::ShaderVariable(type, 0)); vars.push_back(sh::ShaderVariable(type, 0));
} }
EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars)); EXPECT_TRUE(CheckVariablesInPackingLimits(kMaxRows, vars));
// Check 1 too many. // Check 1 too many.
vars.push_back(sh::ShaderVariable(type, 0)); vars.push_back(sh::ShaderVariable(type, 0));
EXPECT_FALSE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars)); EXPECT_FALSE(CheckVariablesInPackingLimits(kMaxRows, vars));
} }
// Test example from GLSL ES 3.0 spec chapter 11. // Test example from GLSL ES 3.0 spec chapter 11.
...@@ -117,66 +116,70 @@ TEST(VariablePacking, Pack) { ...@@ -117,66 +116,70 @@ TEST(VariablePacking, Pack) {
vars.push_back(sh::ShaderVariable(GL_FLOAT, 3)); vars.push_back(sh::ShaderVariable(GL_FLOAT, 3));
vars.push_back(sh::ShaderVariable(GL_FLOAT, 2)); vars.push_back(sh::ShaderVariable(GL_FLOAT, 2));
vars.push_back(sh::ShaderVariable(GL_FLOAT, 0)); vars.push_back(sh::ShaderVariable(GL_FLOAT, 0));
EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars)); EXPECT_TRUE(CheckVariablesInPackingLimits(kMaxRows, vars));
} }
TEST(VariablePacking, PackSizes) { TEST(VariablePacking, PackSizes)
for (size_t tt = 0; tt < ArraySize(types); ++tt) { {
GLenum type = types[tt]; for (size_t tt = 0; tt < ArraySize(types); ++tt)
{
sh::GLenum type = types[tt];
int expectedComponents = gl::VariableComponentCount(type); int expectedComponents = gl::VariableComponentCount(type);
int expectedRows = gl::VariableRowCount(type); int expectedRows = gl::VariableRowCount(type);
if (type == GL_FLOAT_MAT2) { if (type == GL_FLOAT_MAT2)
expectedComponents = 4; {
} else if (gl::IsMatrixType(type)) { expectedComponents = 4;
int squareSize = std::max(gl::VariableRowCount(type), }
gl::VariableColumnCount(type)); else if (gl::IsMatrixType(type))
expectedComponents = squareSize; {
expectedRows = squareSize; int squareSize = std::max(gl::VariableRowCount(type), gl::VariableColumnCount(type));
} expectedComponents = squareSize;
expectedRows = squareSize;
}
EXPECT_EQ(expectedComponents, EXPECT_EQ(expectedComponents, sh::GetVariablePackingComponentsPerRow(type));
VariablePacker::GetNumComponentsPerRow(type)); EXPECT_EQ(expectedRows, sh::GetVariablePackingRows(type));
EXPECT_EQ(expectedRows, VariablePacker::GetNumRows(type)); }
}
} }
// Check special assumptions about packing non-square mats // Check special assumptions about packing non-square mats
TEST(VariablePacking, NonSquareMats) { TEST(VariablePacking, NonSquareMats)
{
for (size_t mt = 0; mt < ArraySize(nonSqMatTypes); ++mt) { for (size_t mt = 0; mt < ArraySize(nonSqMatTypes); ++mt)
{
GLenum type = nonSqMatTypes[mt];
int rows = gl::VariableRowCount(type); sh::GLenum type = nonSqMatTypes[mt];
int cols = gl::VariableColumnCount(type);
int squareSize = std::max(rows, cols);
std::vector<sh::ShaderVariable> vars; int rows = gl::VariableRowCount(type);
vars.push_back(sh::ShaderVariable(type, 0)); int cols = gl::VariableColumnCount(type);
int squareSize = std::max(rows, cols);
// Fill columns std::vector<sh::ShaderVariable> vars;
for (int row = 0; row < squareSize; row++) { vars.push_back(sh::ShaderVariable(type, 0));
for (int col = squareSize; col < 4; ++col) {
vars.push_back(sh::ShaderVariable(GL_FLOAT, 0));
}
}
VariablePacker packer; // Fill columns
for (int row = 0; row < squareSize; row++)
{
for (int col = squareSize; col < 4; ++col)
{
vars.push_back(sh::ShaderVariable(GL_FLOAT, 0));
}
}
EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(squareSize, vars)); EXPECT_TRUE(CheckVariablesInPackingLimits(squareSize, vars));
// and one scalar and packing should fail // and one scalar and packing should fail
vars.push_back(sh::ShaderVariable(GL_FLOAT, 0)); vars.push_back(sh::ShaderVariable(GL_FLOAT, 0));
EXPECT_FALSE(packer.CheckVariablesWithinPackingLimits(squareSize, vars)); EXPECT_FALSE(CheckVariablesInPackingLimits(squareSize, vars));
} }
} }
// Scalar type variables can be packed sharing rows with other variables. // Scalar type variables can be packed sharing rows with other variables.
TEST(VariablePacking, ReuseRows) TEST(VariablePacking, ReuseRows)
{ {
VariablePacker packer;
std::vector<sh::ShaderVariable> vars; std::vector<sh::ShaderVariable> vars;
const int kMaxRows = 512; const int kMaxRows = 512;
...@@ -185,13 +188,13 @@ TEST(VariablePacking, ReuseRows) ...@@ -185,13 +188,13 @@ TEST(VariablePacking, ReuseRows)
// uniform bool u2[129]; // uniform bool u2[129];
// uniform bool u3[129]; // uniform bool u3[129];
{ {
int num_arrays = 4; int num_arrays = 4;
int num_elements_per_array = kMaxRows / num_arrays + 1; int num_elements_per_array = kMaxRows / num_arrays + 1;
for (int ii = 0; ii < num_arrays; ++ii) for (int ii = 0; ii < num_arrays; ++ii)
{ {
vars.push_back(sh::ShaderVariable(GL_BOOL, num_elements_per_array)); vars.push_back(sh::ShaderVariable(GL_BOOL, num_elements_per_array));
} }
EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars)); EXPECT_TRUE(CheckVariablesInPackingLimits(kMaxRows, vars));
} }
vars.clear(); vars.clear();
...@@ -203,14 +206,13 @@ TEST(VariablePacking, ReuseRows) ...@@ -203,14 +206,13 @@ TEST(VariablePacking, ReuseRows)
vars.push_back(sh::ShaderVariable(GL_FLOAT_VEC2, num_elements_per_array)); vars.push_back(sh::ShaderVariable(GL_FLOAT_VEC2, num_elements_per_array));
vars.push_back(sh::ShaderVariable(GL_FLOAT, num_elements_per_array)); vars.push_back(sh::ShaderVariable(GL_FLOAT, num_elements_per_array));
vars.push_back(sh::ShaderVariable(GL_INT, num_elements_per_array)); vars.push_back(sh::ShaderVariable(GL_INT, num_elements_per_array));
EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars)); EXPECT_TRUE(CheckVariablesInPackingLimits(kMaxRows, vars));
} }
} }
// Check the packer supports and flattens structures. // Check the packer supports and flattens structures.
TEST(VariablePacking, Struct) TEST(VariablePacking, Struct)
{ {
VariablePacker packer;
std::vector<sh::ShaderVariable> fields; std::vector<sh::ShaderVariable> fields;
const int kMaxRows = 16; const int kMaxRows = 16;
...@@ -233,5 +235,5 @@ TEST(VariablePacking, Struct) ...@@ -233,5 +235,5 @@ TEST(VariablePacking, Struct)
parentStruct.fields.push_back(sh::ShaderVariable(GL_FLOAT, 2)); parentStruct.fields.push_back(sh::ShaderVariable(GL_FLOAT, 2));
parentStruct.fields.push_back(sh::ShaderVariable(GL_FLOAT, 0)); parentStruct.fields.push_back(sh::ShaderVariable(GL_FLOAT, 0));
EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars)); EXPECT_TRUE(CheckVariablesInPackingLimits(kMaxRows, vars));
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment