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);
} }
...@@ -376,4 +381,4 @@ const std::map<std::string, unsigned int> *ShGetUniformRegisterMap(const ShHandl ...@@ -376,4 +381,4 @@ const std::map<std::string, unsigned int> *ShGetUniformRegisterMap(const ShHandl
static std::map<std::string, unsigned int> map; static std::map<std::string, unsigned int> map;
return &map; return &map;
#endif // ANGLE_ENABLE_HLSL #endif // ANGLE_ENABLE_HLSL
} }
\ No newline at end of file
...@@ -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> &);
...@@ -12,30 +12,29 @@ ...@@ -12,30 +12,29 @@
class VariablePacker { 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<sh::ShaderVariable> &in_variables);
const std::vector<VarT> &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);
// Gets how many rows a data type takes.
// Gets how many rows a data type takes. static int GetNumRows(sh::GLenum type);
static int GetNumRows(sh::GLenum type);
private:
private: static const int kNumColumns = 4;
static const int kNumColumns = 4; static const unsigned kColumnMask = (1 << kNumColumns) - 1;
static const unsigned kColumnMask = (1 << kNumColumns) - 1;
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_; int maxRows_;
int maxRows_; std::vector<unsigned> rows_;
std::vector<unsigned> rows_;
}; };
#endif // COMPILER_TRANSLATOR_VARIABLEPACKER_H_ #endif // COMPILER_TRANSLATOR_VARIABLEPACKER_H_
...@@ -64,58 +64,60 @@ static sh::GLenum nonSqMatTypes[] = { ...@@ -64,58 +64,60 @@ static sh::GLenum nonSqMatTypes[] = {
}; };
TEST(VariablePacking, Pack) { TEST(VariablePacking, Pack) {
VariablePacker packer; 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));
for (size_t tt = 0; tt < ArraySize(types); ++tt) {
sh::GLenum type = types[tt];
int num_rows = VariablePacker::GetNumRows(type);
int num_components_per_row = VariablePacker::GetNumComponentsPerRow(type);
// Check 1 of the type.
vars.clear();
vars.push_back(sh::ShaderVariable(type, 0));
EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars)); EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars));
// Check exactly the right amount of 1 type as an array. for (size_t tt = 0; tt < ArraySize(types); ++tt)
int num_vars = kMaxRows / num_rows; {
vars.clear(); sh::GLenum type = types[tt];
vars.push_back(sh::ShaderVariable(type, num_vars == 1 ? 0 : num_vars)); int num_rows = VariablePacker::GetNumRows(type);
EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars)); int num_components_per_row = VariablePacker::GetNumComponentsPerRow(type);
// Check 1 of the type.
vars.clear();
vars.push_back(sh::ShaderVariable(type, 0));
EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars));
// test too many // Check exactly the right amount of 1 type as an array.
vars.clear(); int num_vars = kMaxRows / num_rows;
vars.push_back(sh::ShaderVariable(type, num_vars == 0 ? 0 : (num_vars + 1))); vars.clear();
EXPECT_FALSE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars)); vars.push_back(sh::ShaderVariable(type, num_vars == 1 ? 0 : num_vars));
EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars));
// Check exactly the right amount of 1 type as individual vars. // test too many
num_vars = kMaxRows / num_rows * vars.clear();
((num_components_per_row > 2) ? 1 : (4 / num_components_per_row)); vars.push_back(sh::ShaderVariable(type, num_vars == 0 ? 0 : (num_vars + 1)));
vars.clear(); EXPECT_FALSE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars));
for (int ii = 0; ii < num_vars; ++ii) {
vars.push_back(sh::ShaderVariable(type, 0));
}
EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars));
// Check 1 too many. // Check exactly the right amount of 1 type as individual vars.
vars.push_back(sh::ShaderVariable(type, 0)); num_vars =
EXPECT_FALSE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars)); kMaxRows / num_rows * ((num_components_per_row > 2) ? 1 : (4 / num_components_per_row));
} vars.clear();
for (int ii = 0; ii < num_vars; ++ii)
{
vars.push_back(sh::ShaderVariable(type, 0));
}
EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars));
// Test example from GLSL ES 3.0 spec chapter 11. // Check 1 too many.
vars.clear(); vars.push_back(sh::ShaderVariable(type, 0));
vars.push_back(sh::ShaderVariable(GL_FLOAT_VEC4, 0)); EXPECT_FALSE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars));
vars.push_back(sh::ShaderVariable(GL_FLOAT_MAT3, 0)); }
vars.push_back(sh::ShaderVariable(GL_FLOAT_MAT3, 0));
vars.push_back(sh::ShaderVariable(GL_FLOAT_VEC2, 6)); // Test example from GLSL ES 3.0 spec chapter 11.
vars.push_back(sh::ShaderVariable(GL_FLOAT_VEC2, 4)); vars.clear();
vars.push_back(sh::ShaderVariable(GL_FLOAT_VEC2, 0)); vars.push_back(sh::ShaderVariable(GL_FLOAT_VEC4, 0));
vars.push_back(sh::ShaderVariable(GL_FLOAT, 3)); vars.push_back(sh::ShaderVariable(GL_FLOAT_MAT3, 0));
vars.push_back(sh::ShaderVariable(GL_FLOAT, 2)); vars.push_back(sh::ShaderVariable(GL_FLOAT_MAT3, 0));
vars.push_back(sh::ShaderVariable(GL_FLOAT, 0)); vars.push_back(sh::ShaderVariable(GL_FLOAT_VEC2, 6));
EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars)); vars.push_back(sh::ShaderVariable(GL_FLOAT_VEC2, 4));
vars.push_back(sh::ShaderVariable(GL_FLOAT_VEC2, 0));
vars.push_back(sh::ShaderVariable(GL_FLOAT, 3));
vars.push_back(sh::ShaderVariable(GL_FLOAT, 2));
vars.push_back(sh::ShaderVariable(GL_FLOAT, 0));
EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars));
} }
TEST(VariablePacking, PackSizes) { TEST(VariablePacking, PackSizes) {
...@@ -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