Struct varyings implementation
Varying variables can be structure in OpenGL ES3.
This cl adds support for structure varyings.
Change-Id: I4d1d80c6afed0a86a23b0a467d4764a4e08f133d
Reviewed-on: https://swiftshader-review.googlesource.com/13529
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/OpenGL/compiler/OutputASM.cpp b/src/OpenGL/compiler/OutputASM.cpp
index 1c70f6c..6e2e6e8 100644
--- a/src/OpenGL/compiler/OutputASM.cpp
+++ b/src/OpenGL/compiler/OutputASM.cpp
@@ -2755,6 +2755,28 @@
return allocate(temporaries, temporary);
}
+ void OutputASM::setPixelShaderInputs(const TType& type, int var, bool flat)
+ {
+ if(type.isStruct())
+ {
+ const TFieldList &fields = type.getStruct()->fields();
+ int fieldVar = var;
+ for(size_t i = 0; i < fields.size(); i++)
+ {
+ const TType& fieldType = *(fields[i]->type());
+ setPixelShaderInputs(fieldType, fieldVar, flat);
+ fieldVar += fieldType.totalRegisterCount();
+ }
+ }
+ else
+ {
+ for(int i = 0; i < type.totalRegisterCount(); i++)
+ {
+ pixelShader->setInput(var + i, type.registerSize(), sw::Shader::Semantic(sw::Shader::USAGE_COLOR, var + i, flat));
+ }
+ }
+ }
+
int OutputASM::varyingRegister(TIntermTyped *varying)
{
int var = lookup(varyings, varying);
@@ -2762,7 +2784,6 @@
if(var == -1)
{
var = allocate(varyings, varying);
- int componentCount = varying->registerSize();
int registerCount = varying->totalRegisterCount();
if(pixelShader)
@@ -2776,16 +2797,11 @@
if(varying->getQualifier() == EvqPointCoord)
{
ASSERT(varying->isRegister());
- pixelShader->setInput(var, componentCount, sw::Shader::Semantic(sw::Shader::USAGE_TEXCOORD, var));
+ pixelShader->setInput(var, varying->registerSize(), sw::Shader::Semantic(sw::Shader::USAGE_TEXCOORD, var));
}
else
{
- for(int i = 0; i < varying->totalRegisterCount(); i++)
- {
- bool flat = hasFlatQualifier(varying);
-
- pixelShader->setInput(var + i, componentCount, sw::Shader::Semantic(sw::Shader::USAGE_COLOR, var + i, flat));
- }
+ setPixelShaderInputs(varying->getType(), var, hasFlatQualifier(varying));
}
}
else if(vertexShader)
@@ -2823,26 +2839,50 @@
{
if(varying->getQualifier() != EvqPointCoord) // gl_PointCoord does not need linking
{
- const TType &type = varying->getType();
- const char *name = varying->getAsSymbolNode()->getSymbol().c_str();
- VaryingList &activeVaryings = shaderObject->varyings;
+ TIntermSymbol *symbol = varying->getAsSymbolNode();
+ declareVarying(varying->getType(), symbol->getSymbol(), reg);
+ }
+ }
+ void OutputASM::declareVarying(const TType &type, const TString &varyingName, int registerIndex)
+ {
+ const char *name = varyingName.c_str();
+ VaryingList &activeVaryings = shaderObject->varyings;
+
+ TStructure* structure = type.getStruct();
+ if(structure)
+ {
+ int fieldRegisterIndex = registerIndex;
+
+ const TFieldList &fields = type.getStruct()->fields();
+ for(size_t i = 0; i < fields.size(); i++)
+ {
+ const TType& fieldType = *(fields[i]->type());
+ declareVarying(fieldType, varyingName + "." + fields[i]->name(), fieldRegisterIndex);
+ if(fieldRegisterIndex >= 0)
+ {
+ fieldRegisterIndex += fieldType.totalRegisterCount();
+ }
+ }
+ }
+ else
+ {
// Check if this varying has been declared before without having a register assigned
for(VaryingList::iterator v = activeVaryings.begin(); v != activeVaryings.end(); v++)
{
if(v->name == name)
{
- if(reg >= 0)
+ if(registerIndex >= 0)
{
- ASSERT(v->reg < 0 || v->reg == reg);
- v->reg = reg;
+ ASSERT(v->reg < 0 || v->reg == registerIndex);
+ v->reg = registerIndex;
}
return;
}
}
- activeVaryings.push_back(glsl::Varying(glVariableType(type), name, varying->getArraySize(), reg, 0));
+ activeVaryings.push_back(glsl::Varying(glVariableType(type), name, type.getArraySize(), registerIndex, 0));
}
}