Commit 73d4d9fa by Shahbaz Youssefi Committed by Commit Bot

Refactor varying location count and validation

In preparation for support for mid-block location qualifiers. Bug: angleproject:3580 Change-Id: Ia63f20c8dc26e8f0e90371c4f00913585a22267a Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2577983Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
parent 4f26a81e
...@@ -25,32 +25,41 @@ void error(const TIntermSymbol &symbol, const char *reason, TDiagnostics *diagno ...@@ -25,32 +25,41 @@ void error(const TIntermSymbol &symbol, const char *reason, TDiagnostics *diagno
diagnostics->error(symbol.getLine(), reason, symbol.getName().data()); diagnostics->error(symbol.getLine(), reason, symbol.getName().data());
} }
int GetLocationCount(const TStructure *structure) int GetStructLocationCount(const TStructure *structure);
int GetFieldLocationCount(const TField *field)
{ {
int totalLocation = 0; int field_size = 0;
for (const TField *field : structure->fields()) const TType *fieldType = field->type();
if (fieldType->getStruct() != nullptr)
{
field_size = GetStructLocationCount(fieldType->getStruct());
}
else if (fieldType->isMatrix())
{
field_size = fieldType->getNominalSize();
}
else
{ {
int field_size = 0; ASSERT(fieldType->getSecondarySize() == 1);
const TType *fieldType = field->type(); field_size = 1;
}
if (fieldType->getStruct() != nullptr) if (fieldType->isArray())
{ {
field_size = GetLocationCount(fieldType->getStruct()); field_size *= fieldType->getArraySizeProduct();
} }
else if (fieldType->isMatrix())
{
field_size = fieldType->getNominalSize();
}
else
{
field_size = 1;
}
if (fieldType->isArray()) return field_size;
{ }
field_size *= fieldType->getArraySizeProduct();
} int GetStructLocationCount(const TStructure *structure)
totalLocation += field_size; {
int totalLocation = 0;
for (const TField *field : structure->fields())
{
totalLocation += GetFieldLocationCount(field);
} }
return totalLocation; return totalLocation;
} }
...@@ -66,65 +75,44 @@ int GetLocationCount(const TIntermSymbol *varying, bool ignoreVaryingArraySize) ...@@ -66,65 +75,44 @@ int GetLocationCount(const TIntermSymbol *varying, bool ignoreVaryingArraySize)
const TType *fieldType = field->type(); const TType *fieldType = field->type();
ASSERT(fieldType->getStruct() == nullptr && !fieldType->isArray()); ASSERT(fieldType->getStruct() == nullptr && !fieldType->isArray());
totalLocation += totalLocation += GetFieldLocationCount(field);
fieldType->isMatrix() ? fieldType->getNominalSize() : fieldType->getSecondarySize();
} }
return totalLocation; return totalLocation;
} }
// [GL_EXT_shader_io_blocks SPEC Chapter 4.4.1]
// Geometry shader inputs, tessellation control shader inputs and outputs, and tessellation if (varyingType.isInterfaceBlock())
// evaluation inputs all have an additional level of arrayness relative to other shader inputs
// and outputs. This outer array level is removed from the type before considering how many
// locations the type consumes.
else if (ignoreVaryingArraySize)
{
// Array-of-arrays cannot be inputs or outputs of a geometry shader.
// (GL_EXT_geometry_shader SPEC issues(5))
ASSERT(!varyingType.isArrayOfArrays());
return varyingType.getSecondarySize();
}
else if (varyingType.isInterfaceBlock())
{ {
unsigned int totalLocation = 0; unsigned int totalLocation = 0;
for (const TField *field : varyingType.getInterfaceBlock()->fields()) for (const TField *field : varyingType.getInterfaceBlock()->fields())
{ {
int field_size = 0; totalLocation += GetFieldLocationCount(field);
const TType *fieldType = field->type();
if (fieldType->getStruct() != nullptr)
{
field_size = GetLocationCount(fieldType->getStruct());
}
else if (fieldType->isMatrix())
{
field_size = fieldType->getNominalSize() * fieldType->getArraySizeProduct();
}
else
{
field_size = fieldType->getLocationCount();
}
if (fieldType->isArray())
{
field_size *= fieldType->getArraySizeProduct();
}
totalLocation += field_size;
} }
if (varyingType.isArray()) ASSERT(!varyingType.isArrayOfArrays() || ignoreVaryingArraySize);
if (!ignoreVaryingArraySize && varyingType.isArray())
{ {
totalLocation *= varyingType.getArraySizeProduct(); totalLocation *= varyingType.getArraySizeProduct();
} }
return totalLocation; return totalLocation;
} }
else if (varyingType.isMatrix())
{ ASSERT(varyingType.isMatrix() || varyingType.getSecondarySize() == 1);
return varyingType.getNominalSize() * varyingType.getArraySizeProduct(); int elementLocationCount = varyingType.isMatrix() ? varyingType.getNominalSize() : 1;
}
else // [GL_EXT_shader_io_blocks SPEC Chapter 4.4.1]
// Geometry shader inputs, tessellation control shader inputs and outputs, and tessellation
// evaluation inputs all have an additional level of arrayness relative to other shader inputs
// and outputs. This outer array level is removed from the type before considering how many
// locations the type consumes.
if (ignoreVaryingArraySize)
{ {
return varyingType.getArraySizeProduct(); // Array-of-arrays cannot be inputs or outputs of a geometry shader.
// (GL_EXT_geometry_shader SPEC issues(5))
ASSERT(!varyingType.isArrayOfArrays());
return elementLocationCount;
} }
return elementLocationCount * varyingType.getArraySizeProduct();
} }
using VaryingVector = std::vector<const TIntermSymbol *>; using VaryingVector = std::vector<const TIntermSymbol *>;
...@@ -237,7 +225,10 @@ void ValidateVaryingLocationsTraverser::validate(TDiagnostics *diagnostics) ...@@ -237,7 +225,10 @@ void ValidateVaryingLocationsTraverser::validate(TDiagnostics *diagnostics)
unsigned int CalculateVaryingLocationCount(TIntermSymbol *varying, GLenum shaderType) unsigned int CalculateVaryingLocationCount(TIntermSymbol *varying, GLenum shaderType)
{ {
return GetLocationCount(varying, shaderType == GL_GEOMETRY_SHADER_EXT); const TQualifier qualifier = varying->getType().getQualifier();
const bool isShaderIn = IsShaderIn(qualifier);
const bool ignoreVaryingArraySize = isShaderIn && shaderType == GL_GEOMETRY_SHADER_EXT;
return GetLocationCount(varying, ignoreVaryingArraySize);
} }
bool ValidateVaryingLocations(TIntermBlock *root, TDiagnostics *diagnostics, GLenum shaderType) bool ValidateVaryingLocations(TIntermBlock *root, TDiagnostics *diagnostics, GLenum shaderType)
......
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