Commit 6f182c12 by Geoff Lang Committed by Nicolas Capens

Add padding to HLSL structures to prevent the D3DCompiler from packing them.

BUG=359225 Change-Id: I74e7ca2fe931cf9cfe67193d2e805d91713a7e0c Reviewed-on: https://chromium-review.googlesource.com/199100Reviewed-by: 's avatarShannon Woods <shannonwoods@chromium.org> Tested-by: 's avatarNicolas Capens <nicolascapens@chromium.org>
parent 12a3c6bf
...@@ -2485,7 +2485,7 @@ TString OutputHLSL::qualifierString(TQualifier qualifier) ...@@ -2485,7 +2485,7 @@ TString OutputHLSL::qualifierString(TQualifier qualifier)
switch(qualifier) switch(qualifier)
{ {
case EvqIn: return "in"; case EvqIn: return "in";
case EvqOut: return "out"; case EvqOut: return "inout"; // 'out' results in an HLSL error if not all fields are written, for GLSL it's undefined
case EvqInOut: return "inout"; case EvqInOut: return "inout";
case EvqConstReadOnly: return "const"; case EvqConstReadOnly: return "const";
default: UNREACHABLE(); default: UNREACHABLE();
...@@ -2604,11 +2604,44 @@ TString OutputHLSL::arrayString(const TType &type) ...@@ -2604,11 +2604,44 @@ TString OutputHLSL::arrayString(const TType &type)
return "[" + str(type.getArraySize()) + "]"; return "[" + str(type.getArraySize()) + "]";
} }
static size_t getTypeComponentCount(const TType &type)
{
if (type.getStruct())
{
size_t compCount = 0;
const TFieldList &fields = type.getStruct()->fields();
for (size_t i = 0; i < fields.size(); i++)
{
const TField *field = fields[i];
const TType *fieldType = field->type();
compCount += getTypeComponentCount(*fieldType);
if (!fieldType->getStruct())
{
// Add padding size
compCount += 4 - fieldType->getNominalSize();
}
}
if (type.isArray())
{
compCount *= type.getArraySize();
}
return compCount;
}
else
{
return type.getObjectSize();
}
}
TString OutputHLSL::initializer(const TType &type) TString OutputHLSL::initializer(const TType &type)
{ {
TString string; TString string;
size_t size = type.getObjectSize(); size_t size = getTypeComponentCount(type);
for (size_t component = 0; component < size; component++) for (size_t component = 0; component < size; component++)
{ {
string += "0"; string += "0";
...@@ -2654,11 +2687,32 @@ void OutputHLSL::addConstructor(const TType &type, const TString &name, const TI ...@@ -2654,11 +2687,32 @@ void OutputHLSL::addConstructor(const TType &type, const TString &name, const TI
const TFieldList &fields = type.getStruct()->fields(); const TFieldList &fields = type.getStruct()->fields();
unsigned int padCount = 0;
for (unsigned int i = 0; i < fields.size(); i++) for (unsigned int i = 0; i < fields.size(); i++)
{ {
const TField *field = fields[i]; const TField *field = fields[i];
structure += " " + typeString(*field->type()) + " " + decorateField(field->name(), type) + arrayString(*field->type()) + ";\n"; structure += " " + typeString(*field->type()) + " " + decorateField(field->name(), type) + arrayString(*field->type()) + ";\n";
if (!field->type()->getStruct())
{
// Add padding to prevent tight packing (crbug.com/359225)
unsigned int padRequired = 4 - field->type()->getNominalSize();
if (padRequired > 0)
{
structure += " ";
switch (padRequired)
{
case 1: structure += "float "; break;
case 2: structure += "float2 "; break;
case 3: structure += "float3 "; break;
}
structure += "pad" + str(padCount) + ";\n";
padCount++;
}
}
} }
structure += "};\n"; structure += "};\n";
...@@ -2761,6 +2815,35 @@ void OutputHLSL::addConstructor(const TType &type, const TString &name, const TI ...@@ -2761,6 +2815,35 @@ void OutputHLSL::addConstructor(const TType &type, const TString &name, const TI
} }
else UNREACHABLE(); else UNREACHABLE();
} }
else if (ctorType.getStruct())
{
const TFieldList &fields = type.getStruct()->fields();
ASSERT(ctorParameters.size() == fields.size());
for (unsigned int parameterIndex = 0; parameterIndex < ctorParameters.size(); parameterIndex++)
{
const TField *field = fields[parameterIndex];
bool moreParameters = parameterIndex + 1 < ctorParameters.size();
constructor += "x" + str(parameterIndex);
if (!field->type()->getStruct())
{
unsigned int padRequired = 4 - field->type()->getNominalSize();
switch (padRequired)
{
case 1: constructor += ", 0.0"; break;
case 2: constructor += ", float2(0.0, 0.0)"; break;
case 3: constructor += ", float3(0.0, 0.0, 0.0)"; break;
}
}
if (moreParameters)
{
constructor += ", ";
}
}
}
else else
{ {
size_t remainingComponents = ctorType.getObjectSize(); size_t remainingComponents = ctorType.getObjectSize();
......
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