Commit e58e1416 by Corentin Wallez Committed by Commit Bot

ShCheckVariablesWithinPackingLimits add sh::ShaderVariable overload

This overload doesn't take a stripped down version of the variable information, which makes it possible to handle varying structs correctly by flattening them as individual variables. BUG=621031 Change-Id: I367629fce3d17dd7e1f876c5937eb37f3d97c7f4 Reviewed-on: https://chromium-review.googlesource.com/361460Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Corentin Wallez <cwallez@chromium.org>
parent 7f539ea5
...@@ -48,7 +48,7 @@ typedef unsigned int GLenum; ...@@ -48,7 +48,7 @@ typedef unsigned int GLenum;
// Version number for shader translation API. // Version number for shader translation API.
// It is incremented every time the API changes. // It is incremented every time the API changes.
#define ANGLE_SH_VERSION 147 #define ANGLE_SH_VERSION 148
typedef enum { typedef enum {
SH_GLES2_SPEC = 0x8B40, SH_GLES2_SPEC = 0x8B40,
...@@ -438,12 +438,16 @@ typedef struct ...@@ -438,12 +438,16 @@ typedef struct
// flag above. // flag above.
// Parameters: // Parameters:
// maxVectors: the available rows of registers. // maxVectors: the available rows of registers.
// varInfoArray: an array of variable info (types and sizes). // varInfoArray / variables: an array of variables.
// varInfoArraySize: the size of the variable array. // varInfoArraySize: the size of the variable array.
// TODO(cwallez) remove the first overload once the second is rolled in Chromium
COMPILER_EXPORT bool ShCheckVariablesWithinPackingLimits( COMPILER_EXPORT bool ShCheckVariablesWithinPackingLimits(
int maxVectors, int maxVectors,
ShVariableInfo *varInfoArray, ShVariableInfo *varInfoArray,
size_t varInfoArraySize); size_t varInfoArraySize);
COMPILER_EXPORT bool ShCheckVariablesWithinPackingLimits(
int maxVectors,
const std::vector<sh::ShaderVariable> &variables);
// Gives the compiler-assigned register for an interface block. // Gives the compiler-assigned register for an interface block.
// The method writes the value to the output variable "indexOut". // The method writes the value to the output variable "indexOut".
......
...@@ -339,6 +339,11 @@ bool ShCheckVariablesWithinPackingLimits( ...@@ -339,6 +339,11 @@ bool ShCheckVariablesWithinPackingLimits(
sh::ShaderVariable var(varInfoArray[ii].type, varInfoArray[ii].size); sh::ShaderVariable var(varInfoArray[ii].type, varInfoArray[ii].size);
variables.push_back(var); variables.push_back(var);
} }
return ShCheckVariablesWithinPackingLimits(maxVectors, variables);
}
bool ShCheckVariablesWithinPackingLimits(int maxVectors,
const std::vector<sh::ShaderVariable> &variables)
{
VariablePacker packer; VariablePacker packer;
return packer.CheckVariablesWithinPackingLimits(maxVectors, variables); return packer.CheckVariablesWithinPackingLimits(maxVectors, variables);
} }
......
...@@ -31,58 +31,6 @@ void ExpandUserDefinedVariable(const ShaderVariable &variable, ...@@ -31,58 +31,6 @@ void ExpandUserDefinedVariable(const ShaderVariable &variable,
const std::string &name, const std::string &name,
const std::string &mappedName, const std::string &mappedName,
bool markStaticUse, bool markStaticUse,
std::vector<ShaderVariable> *expanded);
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 ExpandUserDefinedVariable(const ShaderVariable &variable,
const std::string &name,
const std::string &mappedName,
bool markStaticUse,
std::vector<ShaderVariable> *expanded) std::vector<ShaderVariable> *expanded)
{ {
ASSERT(variable.isStruct()); ASSERT(variable.isStruct());
...@@ -677,6 +625,52 @@ bool CollectVariables::visitBinary(Visit, TIntermBinary *binaryNode) ...@@ -677,6 +625,52 @@ bool CollectVariables::visitBinary(Visit, TIntermBinary *binaryNode)
return true; return true;
} }
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, void ExpandUniforms(const std::vector<Uniform> &compact,
std::vector<ShaderVariable> *expanded) std::vector<ShaderVariable> *expanded)
{ {
......
...@@ -69,6 +69,12 @@ class CollectVariables : public TIntermTraverser ...@@ -69,6 +69,12 @@ class CollectVariables : public TIntermTraverser
const TSymbolTable &mSymbolTable; const TSymbolTable &mSymbolTable;
}; };
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 // Expand struct uniforms to flattened lists of split variables
void ExpandUniforms(const std::vector<Uniform> &compact, void ExpandUniforms(const std::vector<Uniform> &compact,
std::vector<ShaderVariable> *expanded); std::vector<ShaderVariable> *expanded);
......
...@@ -148,15 +148,21 @@ bool VariablePacker::searchColumn(int column, int numRows, int* destRow, int* de ...@@ -148,15 +148,21 @@ bool VariablePacker::searchColumn(int column, int numRows, int* destRow, int* de
return true; return true;
} }
template <typename VarT> bool VariablePacker::CheckVariablesWithinPackingLimits(
bool VariablePacker::CheckVariablesWithinPackingLimits(unsigned int maxVectors, unsigned int maxVectors,
const std::vector<VarT> &in_variables) const std::vector<sh::ShaderVariable> &in_variables)
{ {
ASSERT(maxVectors > 0); ASSERT(maxVectors > 0);
maxRows_ = maxVectors; maxRows_ = maxVectors;
topNonFullRow_ = 0; topNonFullRow_ = 0;
bottomNonFullRow_ = maxRows_ - 1; bottomNonFullRow_ = maxRows_ - 1;
std::vector<VarT> variables(in_variables); 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 (size_t i = 0; i < variables.size(); i++) {
...@@ -261,9 +267,3 @@ bool VariablePacker::CheckVariablesWithinPackingLimits(unsigned int maxVectors, ...@@ -261,9 +267,3 @@ bool VariablePacker::CheckVariablesWithinPackingLimits(unsigned int maxVectors,
return true; return true;
} }
// Instantiate all possible variable packings
template bool VariablePacker::CheckVariablesWithinPackingLimits(unsigned int, const std::vector<sh::ShaderVariable> &);
template bool VariablePacker::CheckVariablesWithinPackingLimits(unsigned int, const std::vector<sh::Attribute> &);
template bool VariablePacker::CheckVariablesWithinPackingLimits(unsigned int, const std::vector<sh::Uniform> &);
template bool VariablePacker::CheckVariablesWithinPackingLimits(unsigned int, const std::vector<sh::Varying> &);
...@@ -14,9 +14,8 @@ class VariablePacker { ...@@ -14,9 +14,8 @@ class VariablePacker {
public: public:
// Returns true if the passed in variables pack in maxVectors following // Returns true if the passed in variables pack in maxVectors following
// the packing rules from the GLSL 1.017 spec, Appendix A, section 7. // the packing rules from the GLSL 1.017 spec, Appendix A, section 7.
template <typename VarT>
bool CheckVariablesWithinPackingLimits(unsigned int maxVectors, bool CheckVariablesWithinPackingLimits(unsigned int maxVectors,
const std::vector<VarT> &in_variables); const std::vector<sh::ShaderVariable> &in_variables);
// Gets how many components in a row a data type takes. // Gets how many components in a row a data type takes.
static int GetNumComponentsPerRow(sh::GLenum type); static int GetNumComponentsPerRow(sh::GLenum type);
...@@ -30,7 +29,7 @@ class VariablePacker { ...@@ -30,7 +29,7 @@ class VariablePacker {
unsigned makeColumnFlags(int column, int numComponentsPerRow); unsigned makeColumnFlags(int column, int numComponentsPerRow);
void fillColumns(int topRow, int numRows, int column, int numComponentsPerRow); void fillColumns(int topRow, int numRows, int column, int numComponentsPerRow);
bool searchColumn(int column, int numRows, int* destRow, int* destSize); bool searchColumn(int column, int numRows, int *destRow, int *destSize);
int topNonFullRow_; int topNonFullRow_;
int bottomNonFullRow_; int bottomNonFullRow_;
......
...@@ -70,7 +70,8 @@ TEST(VariablePacking, Pack) { ...@@ -70,7 +70,8 @@ TEST(VariablePacking, Pack) {
// test no vars. // test no vars.
EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars)); EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(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 = VariablePacker::GetNumRows(type);
int num_components_per_row = VariablePacker::GetNumComponentsPerRow(type); int num_components_per_row = VariablePacker::GetNumComponentsPerRow(type);
...@@ -91,10 +92,11 @@ TEST(VariablePacking, Pack) { ...@@ -91,10 +92,11 @@ TEST(VariablePacking, Pack) {
EXPECT_FALSE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars)); EXPECT_FALSE(packer.CheckVariablesWithinPackingLimits(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 = kMaxRows / num_rows * num_vars =
((num_components_per_row > 2) ? 1 : (4 / num_components_per_row)); kMaxRows / num_rows * ((num_components_per_row > 2) ? 1 : (4 / num_components_per_row));
vars.clear(); vars.clear();
for (int ii = 0; ii < num_vars; ++ii) { for (int ii = 0; ii < num_vars; ++ii)
{
vars.push_back(sh::ShaderVariable(type, 0)); vars.push_back(sh::ShaderVariable(type, 0));
} }
EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars)); EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars));
...@@ -204,3 +206,32 @@ TEST(VariablePacking, ReuseRows) ...@@ -204,3 +206,32 @@ TEST(VariablePacking, ReuseRows)
EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars)); EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars));
} }
} }
// Check the packer supports and flattens structures.
TEST(VariablePacking, Struct)
{
VariablePacker packer;
std::vector<sh::ShaderVariable> fields;
const int kMaxRows = 16;
// Test example from GLSL ES 3.0 spec chapter 11, but with structs
std::vector<sh::ShaderVariable> vars;
vars.push_back(sh::ShaderVariable(GL_STRUCT_ANGLEX, 0));
sh::ShaderVariable &parentStruct = vars[0];
parentStruct.fields.push_back(sh::ShaderVariable(GL_FLOAT_VEC4, 0));
parentStruct.fields.push_back(sh::ShaderVariable(GL_FLOAT_MAT3, 0));
parentStruct.fields.push_back(sh::ShaderVariable(GL_STRUCT_ANGLEX, 0));
sh::ShaderVariable &innerStruct = parentStruct.fields.back();
innerStruct.fields.push_back(sh::ShaderVariable(GL_FLOAT_MAT3, 0));
innerStruct.fields.push_back(sh::ShaderVariable(GL_FLOAT_VEC2, 6));
innerStruct.fields.push_back(sh::ShaderVariable(GL_FLOAT_VEC2, 4));
parentStruct.fields.push_back(sh::ShaderVariable(GL_FLOAT_VEC2, 0));
parentStruct.fields.push_back(sh::ShaderVariable(GL_FLOAT, 3));
parentStruct.fields.push_back(sh::ShaderVariable(GL_FLOAT, 2));
parentStruct.fields.push_back(sh::ShaderVariable(GL_FLOAT, 0));
EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(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