Commit af875527 by Austin Kinross Committed by Geoff Lang

Improve D3D11 varying packing when there are more varyings than registers.

BUG=angle:738 Change-Id: I0599840fc79d571230acf26105d512322bcffdcd Reviewed-on: https://chromium-review.googlesource.com/214108Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Tested-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent bdee2d59
...@@ -1072,6 +1072,7 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, Shader *fragmentShader, Shade ...@@ -1072,6 +1072,7 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, Shader *fragmentShader, Shade
} }
output->registerIndex = input->registerIndex; output->registerIndex = input->registerIndex;
output->columnIndex = input->columnIndex;
matched = true; matched = true;
break; break;
......
...@@ -35,10 +35,12 @@ class ResourceManager; ...@@ -35,10 +35,12 @@ class ResourceManager;
struct PackedVarying : public sh::Varying struct PackedVarying : public sh::Varying
{ {
unsigned int registerIndex; // Assigned during link unsigned int registerIndex; // Assigned during link
unsigned int columnIndex; // Assigned during link, defaults to 0
PackedVarying(const sh::Varying &varying) PackedVarying(const sh::Varying &varying)
: sh::Varying(varying), : sh::Varying(varying),
registerIndex(GL_INVALID_INDEX) registerIndex(GL_INVALID_INDEX),
columnIndex(0)
{} {}
bool registerAssigned() const { return registerIndex != GL_INVALID_INDEX; } bool registerAssigned() const { return registerIndex != GL_INVALID_INDEX; }
......
...@@ -126,6 +126,7 @@ static bool packVarying(PackedVarying *varying, const int maxVaryingVectors, Var ...@@ -126,6 +126,7 @@ static bool packVarying(PackedVarying *varying, const int maxVaryingVectors, Var
if (available) if (available)
{ {
varying->registerIndex = r; varying->registerIndex = r;
varying->columnIndex = 0;
for (int y = 0; y < registers; y++) for (int y = 0; y < registers; y++)
{ {
...@@ -159,6 +160,7 @@ static bool packVarying(PackedVarying *varying, const int maxVaryingVectors, Var ...@@ -159,6 +160,7 @@ static bool packVarying(PackedVarying *varying, const int maxVaryingVectors, Var
if (available) if (available)
{ {
varying->registerIndex = r; varying->registerIndex = r;
varying->columnIndex = 2;
for (int y = 0; y < registers; y++) for (int y = 0; y < registers; y++)
{ {
...@@ -189,7 +191,7 @@ static bool packVarying(PackedVarying *varying, const int maxVaryingVectors, Var ...@@ -189,7 +191,7 @@ static bool packVarying(PackedVarying *varying, const int maxVaryingVectors, Var
for (int x = 0; x < 4; x++) for (int x = 0; x < 4; x++)
{ {
if (space[x] >= registers && space[x] < space[column]) if (space[x] >= registers && (space[column] < registers || space[x] < space[column]))
{ {
column = x; column = x;
} }
...@@ -202,6 +204,7 @@ static bool packVarying(PackedVarying *varying, const int maxVaryingVectors, Var ...@@ -202,6 +204,7 @@ static bool packVarying(PackedVarying *varying, const int maxVaryingVectors, Var
if (!packing[r][column]) if (!packing[r][column])
{ {
varying->registerIndex = r; varying->registerIndex = r;
varying->columnIndex = column;
for (int y = r; y < r + registers; y++) for (int y = r; y < r + registers; y++)
{ {
...@@ -320,6 +323,10 @@ std::string DynamicHLSL::generateVaryingHLSL(const ShaderD3D *shader) const ...@@ -320,6 +323,10 @@ std::string DynamicHLSL::generateVaryingHLSL(const ShaderD3D *shader) const
{ {
for (int row = 0; row < variableRows; row++) for (int row = 0; row < variableRows; row++)
{ {
// TODO: Add checks to ensure D3D interpolation modifiers don't result in too many registers being used.
// For example, if there are N registers, and we have N vec3 varyings and 1 float varying, then D3D will pack them into N registers.
// If the float varying has the 'nointerpolation' modifier on it then we would need N + 1 registers, and D3D compilation will fail.
switch (varying.interpolation) switch (varying.interpolation)
{ {
case sh::INTERPOLATION_SMOOTH: varyingHLSL += " "; break; case sh::INTERPOLATION_SMOOTH: varyingHLSL += " "; break;
...@@ -328,7 +335,7 @@ std::string DynamicHLSL::generateVaryingHLSL(const ShaderD3D *shader) const ...@@ -328,7 +335,7 @@ std::string DynamicHLSL::generateVaryingHLSL(const ShaderD3D *shader) const
default: UNREACHABLE(); default: UNREACHABLE();
} }
unsigned int semanticIndex = elementIndex * variableRows + varying.registerIndex + row; unsigned int semanticIndex = elementIndex * variableRows + varying.columnIndex * mRenderer->getRendererCaps().maxVaryingVectors + varying.registerIndex + row;
std::string n = Str(semanticIndex); std::string n = Str(semanticIndex);
std::string typeString; std::string typeString;
...@@ -765,39 +772,9 @@ bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const ...@@ -765,39 +772,9 @@ bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const
for (int row = 0; row < variableRows; row++) for (int row = 0; row < variableRows; row++)
{ {
int r = varying.registerIndex + elementIndex * variableRows + row; int r = varying.registerIndex + varying.columnIndex * mRenderer->getRendererCaps().maxVaryingVectors + elementIndex * variableRows + row;
vertexHLSL += " output.v" + Str(r); vertexHLSL += " output.v" + Str(r);
bool sharedRegister = false; // Register used by multiple varyings
for (int x = 0; x < 4; x++)
{
if (packing[r][x] && packing[r][x] != packing[r][0])
{
sharedRegister = true;
break;
}
}
if(sharedRegister)
{
vertexHLSL += ".";
for (int x = 0; x < 4; x++)
{
if (packing[r][x] == &varying)
{
switch(x)
{
case 0: vertexHLSL += "x"; break;
case 1: vertexHLSL += "y"; break;
case 2: vertexHLSL += "z"; break;
case 3: vertexHLSL += "w"; break;
}
}
}
}
vertexHLSL += " = _" + varying.name; vertexHLSL += " = _" + varying.name;
if (varying.isArray()) if (varying.isArray())
...@@ -943,7 +920,7 @@ bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const ...@@ -943,7 +920,7 @@ bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const
int variableRows = (varying.isStruct() ? 1 : VariableRowCount(transposedType)); int variableRows = (varying.isStruct() ? 1 : VariableRowCount(transposedType));
for (int row = 0; row < variableRows; row++) for (int row = 0; row < variableRows; row++)
{ {
std::string n = Str(varying.registerIndex + elementIndex * variableRows + row); std::string n = Str(varying.registerIndex + varying.columnIndex * mRenderer->getRendererCaps().maxVaryingVectors + elementIndex * variableRows + row);
pixelHLSL += " _" + varying.name; pixelHLSL += " _" + varying.name;
if (varying.isArray()) if (varying.isArray())
......
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