Commit f4b2c4fd by Jamie Madill

Refactor DynamicHLSL geometry shader code more.

This refactor adds a typed iterator class for helping to iterate over varying registers from packed varyings. We use the same iteration logic in several places and it has a triple loop, so encapsulating this into an iterator class keeps it cleaner. The other change is to use std::stringstream in places where we would return a std::string. These refactorings will aid in subsequent work to implement provoking vertex fixes and to refactor our varying packing algorithm. BUG=angleproject:754 Change-Id: Id44a1f68ccd4edc3458f1cf514f5eab4b8cd4151 Reviewed-on: https://chromium-review.googlesource.com/309811Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Tested-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 62c49f5d
...@@ -245,9 +245,141 @@ bool PackVarying(PackedVarying *packedVarying, const int maxVaryingVectors, Vary ...@@ -245,9 +245,141 @@ bool PackVarying(PackedVarying *packedVarying, const int maxVaryingVectors, Vary
return false; return false;
} }
unsigned int VaryingRegisterIndex(const gl::Caps &caps,
const PackedVarying &packedVarying,
unsigned int elementIndex,
unsigned int row)
{
const sh::Varying &varying = *packedVarying.varying;
GLenum transposedType = TransposeMatrixType(varying.type);
unsigned int variableRows =
static_cast<unsigned int>(varying.isStruct() ? 1 : VariableRowCount(transposedType));
return (elementIndex * variableRows + (packedVarying.columnIndex * caps.maxVaryingVectors) +
(packedVarying.registerIndex + row));
}
struct PackedVaryingRegister final
{
PackedVaryingRegister() : varyingIndex(0), elementIndex(0), rowIndex(0) {}
unsigned int registerIndex(const gl::Caps &caps,
const std::vector<PackedVarying> &packedVaryings) const
{
const PackedVarying &packedVarying = packedVaryings[varyingIndex];
return VaryingRegisterIndex(caps, packedVarying, elementIndex, rowIndex);
}
size_t varyingIndex;
unsigned int elementIndex;
unsigned int rowIndex;
};
class PackedVaryingIterator final : public angle::NonCopyable
{
public:
PackedVaryingIterator(const std::vector<PackedVarying> &packedVaryings);
class Iterator final
{
public:
Iterator(const PackedVaryingIterator &parent);
Iterator &operator++();
bool operator==(const Iterator &other) const;
bool operator!=(const Iterator &other) const;
const PackedVaryingRegister &operator*() const { return mRegister; }
void setEnd() { mRegister.varyingIndex = mParent.mPackedVaryings.size(); }
private:
const PackedVaryingIterator &mParent;
PackedVaryingRegister mRegister;
};
Iterator begin() const;
const Iterator &end() const;
private:
const std::vector<PackedVarying> &mPackedVaryings;
Iterator mEnd;
};
PackedVaryingIterator::PackedVaryingIterator(const std::vector<PackedVarying> &packedVaryings)
: mPackedVaryings(packedVaryings), mEnd(*this)
{
mEnd.setEnd();
}
PackedVaryingIterator::Iterator PackedVaryingIterator::begin() const
{
return Iterator(*this);
}
const PackedVaryingIterator::Iterator &PackedVaryingIterator::end() const
{
return mEnd;
}
PackedVaryingIterator::Iterator::Iterator(const PackedVaryingIterator &parent) : mParent(parent)
{
while (mRegister.varyingIndex < mParent.mPackedVaryings.size() &&
!mParent.mPackedVaryings[mRegister.varyingIndex].registerAssigned())
{
++mRegister.varyingIndex;
}
}
PackedVaryingIterator::Iterator &PackedVaryingIterator::Iterator::operator++()
{
const sh::Varying *varying = mParent.mPackedVaryings[mRegister.varyingIndex].varying;
GLenum transposedType = TransposeMatrixType(varying->type);
unsigned int variableRows =
static_cast<unsigned int>(varying->isStruct() ? 1 : VariableRowCount(transposedType));
// Innermost iteration: row count
if (mRegister.rowIndex + 1 < variableRows)
{
++mRegister.rowIndex;
return *this;
}
mRegister.rowIndex = 0;
// Middle iteration: element count
if (mRegister.elementIndex + 1 < varying->elementCount())
{
++mRegister.elementIndex;
return *this;
}
mRegister.elementIndex = 0;
// Outer iteration: the varying itself. Once we pass the last varying, this Iterator will
// equal the end Iterator.
do
{
++mRegister.varyingIndex;
} while (mRegister.varyingIndex < mParent.mPackedVaryings.size() &&
!mParent.mPackedVaryings[mRegister.varyingIndex].registerAssigned());
return *this;
}
bool PackedVaryingIterator::Iterator::operator==(const Iterator &other) const
{
return mRegister.elementIndex == other.mRegister.elementIndex &&
mRegister.rowIndex == other.mRegister.rowIndex &&
mRegister.varyingIndex == other.mRegister.varyingIndex;
}
bool PackedVaryingIterator::Iterator::operator!=(const Iterator &other) const
{
return !(*this == other);
}
const std::string VERTEX_ATTRIBUTE_STUB_STRING = "@@ VERTEX ATTRIBUTES @@"; const std::string VERTEX_ATTRIBUTE_STUB_STRING = "@@ VERTEX ATTRIBUTES @@";
const std::string PIXEL_OUTPUT_STUB_STRING = "@@ PIXEL OUTPUT @@"; const std::string PIXEL_OUTPUT_STUB_STRING = "@@ PIXEL OUTPUT @@";
} } // anonymous namespace
DynamicHLSL::DynamicHLSL(RendererD3D *const renderer) : mRenderer(renderer) DynamicHLSL::DynamicHLSL(RendererD3D *const renderer) : mRenderer(renderer)
{ {
...@@ -292,19 +424,20 @@ bool DynamicHLSL::packVaryings(const gl::Caps &caps, ...@@ -292,19 +424,20 @@ bool DynamicHLSL::packVaryings(const gl::Caps &caps,
for (const std::string &transformFeedbackVaryingName : transformFeedbackVaryings) for (const std::string &transformFeedbackVaryingName : transformFeedbackVaryings)
{ {
if (transformFeedbackVaryingName == "gl_Position" || if (transformFeedbackVaryingName.compare(0, 3, "gl_") == 0)
transformFeedbackVaryingName == "gl_PointSize")
{ {
// do not pack builtin XFB varyings // do not pack builtin XFB varyings
continue; continue;
} }
if (uniqueVaryingNames.count(transformFeedbackVaryingName) == 0) for (PackedVarying &packedVarying : *packedVaryings)
{ {
bool found = false; const sh::Varying &varying = *packedVarying.varying;
for (PackedVarying &packedVarying : *packedVaryings)
// Make sure transform feedback varyings aren't optimized out.
if (uniqueVaryingNames.count(transformFeedbackVaryingName) == 0)
{ {
const sh::Varying &varying = *packedVarying.varying; bool found = false;
if (transformFeedbackVaryingName == varying.name) if (transformFeedbackVaryingName == varying.name)
{ {
if (!PackVarying(&packedVarying, caps.maxVaryingVectors, packing)) if (!PackVarying(&packedVarying, caps.maxVaryingVectors, packing))
...@@ -316,13 +449,21 @@ bool DynamicHLSL::packVaryings(const gl::Caps &caps, ...@@ -316,13 +449,21 @@ bool DynamicHLSL::packVaryings(const gl::Caps &caps,
found = true; found = true;
break; break;
} }
if (!found)
{
infoLog << "Transform feedback varying " << transformFeedbackVaryingName
<< " does not exist in the vertex shader.";
return false;
}
} }
if (!found) // Add duplicate transform feedback varyings for 'flat' shaded attributes. This is
// necessary because we write out modified vertex data to correct for the provoking
// vertex in D3D11. This extra transform feedback varying is the unmodified stream.
if (varying.interpolation == sh::INTERPOLATION_FLAT)
{ {
infoLog << "Transform feedback varying " << transformFeedbackVaryingName sh::Varying duplicateVarying(varying);
<< " does not exist in the vertex shader."; duplicateVarying.name = "StreamOut_" + duplicateVarying.name;
return false;
} }
} }
} }
...@@ -339,76 +480,56 @@ bool DynamicHLSL::packVaryings(const gl::Caps &caps, ...@@ -339,76 +480,56 @@ bool DynamicHLSL::packVaryings(const gl::Caps &caps,
return true; return true;
} }
std::string DynamicHLSL::generateVaryingHLSL(const gl::Caps &caps, void DynamicHLSL::generateVaryingHLSL(const gl::Caps &caps,
const std::vector<PackedVarying> &varyings, const std::vector<PackedVarying> &varyings,
bool shaderUsesPointSize) const bool programUsesPointSize,
std::stringstream &hlslStream) const
{ {
std::string varyingSemantic = getVaryingSemantic(shaderUsesPointSize); std::string varyingSemantic = getVaryingSemantic(programUsesPointSize);
std::string varyingHLSL;
for (const PackedVarying &packedVarying : varyings) for (const PackedVaryingRegister &registerInfo : PackedVaryingIterator(varyings))
{ {
if (!packedVarying.registerAssigned()) const PackedVarying &packedVarying = varyings[registerInfo.varyingIndex];
{
continue;
}
const sh::Varying &varying = *packedVarying.varying; const sh::Varying &varying = *packedVarying.varying;
GLenum transposedType = gl::TransposeMatrixType(varying.type);
unsigned int registerIndex = registerInfo.registerIndex(caps, varyings);
ASSERT(!varying.isBuiltIn()); // TODO: Add checks to ensure D3D interpolation modifiers don't result in too many
GLenum transposedType = TransposeMatrixType(varying.type); // registers being used.
int variableRows = (varying.isStruct() ? 1 : VariableRowCount(transposedType)); // 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.
for (unsigned int elementIndex = 0; elementIndex < varying.elementCount(); elementIndex++) switch (varying.interpolation)
{ {
for (int row = 0; row < variableRows; row++) case sh::INTERPOLATION_SMOOTH:
{ hlslStream << " ";
// TODO: Add checks to ensure D3D interpolation modifiers don't result in too many break;
// registers being used. case sh::INTERPOLATION_FLAT:
// For example, if there are N registers, and we have N vec3 varyings and 1 float hlslStream << " nointerpolation ";
// varying, then D3D will pack them into N registers. break;
// If the float varying has the 'nointerpolation' modifier on it then we would need case sh::INTERPOLATION_CENTROID:
// N + 1 registers, and D3D compilation will fail. hlslStream << " centroid ";
break;
switch (varying.interpolation) default:
{ UNREACHABLE();
case sh::INTERPOLATION_SMOOTH: }
varyingHLSL += " ";
break;
case sh::INTERPOLATION_FLAT:
varyingHLSL += " nointerpolation ";
break;
case sh::INTERPOLATION_CENTROID:
varyingHLSL += " centroid ";
break;
default:
UNREACHABLE();
}
unsigned int semanticIndex = elementIndex * variableRows +
packedVarying.columnIndex * caps.maxVaryingVectors +
packedVarying.registerIndex + row;
std::string n = Str(semanticIndex);
std::string typeString;
if (varying.isStruct()) if (varying.isStruct())
{ {
// TODO(jmadill): pass back translated name from the shader translator // TODO(jmadill): pass back translated name from the shader translator
typeString = decorateVariable(varying.structName); hlslStream << decorateVariable(varying.structName);
} }
else else
{ {
GLenum componentType = VariableComponentType(transposedType); GLenum componentType = VariableComponentType(transposedType);
int columnCount = VariableColumnCount(transposedType); int columnCount = VariableColumnCount(transposedType);
typeString = HLSLComponentTypeString(componentType, columnCount); hlslStream << HLSLComponentTypeString(componentType, columnCount);
}
varyingHLSL += typeString + " v" + n + " : " + varyingSemantic + n + ";\n";
}
} }
}
return varyingHLSL; hlslStream << " v" << registerIndex << " : " << varyingSemantic << registerIndex << ";\n";
}
} }
std::string DynamicHLSL::generateVertexShaderForInputLayout( std::string DynamicHLSL::generateVertexShaderForInputLayout(
...@@ -596,12 +717,12 @@ std::string DynamicHLSL::generatePixelShaderForOutputSignature( ...@@ -596,12 +717,12 @@ std::string DynamicHLSL::generatePixelShaderForOutputSignature(
return pixelHLSL; return pixelHLSL;
} }
std::string DynamicHLSL::getVaryingSemantic(bool pointSize) const std::string DynamicHLSL::getVaryingSemantic(bool programUsesPointSize) const
{ {
// SM3 reserves the TEXCOORD semantic for point sprite texcoords (gl_PointCoord) // SM3 reserves the TEXCOORD semantic for point sprite texcoords (gl_PointCoord)
// In D3D11 we manually compute gl_PointCoord in the GS. // In D3D11 we manually compute gl_PointCoord in the GS.
int shaderModel = mRenderer->getMajorShaderModel(); int shaderModel = mRenderer->getMajorShaderModel();
return ((pointSize && shaderModel < 4) ? "COLOR" : "TEXCOORD"); return ((programUsesPointSize && shaderModel < 4) ? "COLOR" : "TEXCOORD");
} }
struct DynamicHLSL::SemanticInfo struct DynamicHLSL::SemanticInfo
...@@ -698,41 +819,41 @@ DynamicHLSL::SemanticInfo DynamicHLSL::getSemanticInfo(unsigned int startRegiste ...@@ -698,41 +819,41 @@ DynamicHLSL::SemanticInfo DynamicHLSL::getSemanticInfo(unsigned int startRegiste
return info; return info;
} }
std::string DynamicHLSL::generateVaryingLinkHLSL(const SemanticInfo &info, void DynamicHLSL::generateVaryingLinkHLSL(const gl::Caps &caps,
const std::string &varyingHLSL) const bool programUsesPointSize,
const SemanticInfo &info,
const std::vector<PackedVarying> &packedVaryings,
std::stringstream &linkStream) const
{ {
std::string linkHLSL = "{\n";
ASSERT(info.dxPosition.enabled); ASSERT(info.dxPosition.enabled);
linkHLSL += " float4 dx_Position : " + info.dxPosition.str() + ";\n"; linkStream << "{\n"
<< " float4 dx_Position : " << info.dxPosition.str() << ";\n";
if (info.glPosition.enabled) if (info.glPosition.enabled)
{ {
linkHLSL += " float4 gl_Position : " + info.glPosition.str() + ";\n"; linkStream << " float4 gl_Position : " << info.glPosition.str() << ";\n";
} }
if (info.glFragCoord.enabled) if (info.glFragCoord.enabled)
{ {
linkHLSL += " float4 gl_FragCoord : " + info.glFragCoord.str() + ";\n"; linkStream << " float4 gl_FragCoord : " << info.glFragCoord.str() << ";\n";
} }
if (info.glPointCoord.enabled) if (info.glPointCoord.enabled)
{ {
linkHLSL += " float2 gl_PointCoord : " + info.glPointCoord.str() + ";\n"; linkStream << " float2 gl_PointCoord : " << info.glPointCoord.str() << ";\n";
} }
if (info.glPointSize.enabled) if (info.glPointSize.enabled)
{ {
linkHLSL += " float gl_PointSize : " + info.glPointSize.str() + ";\n"; linkStream << " float gl_PointSize : " << info.glPointSize.str() << ";\n";
} }
// Do this after glPointSize, to potentially combine gl_PointCoord and gl_PointSize into the // Do this after glPointSize, to potentially combine gl_PointCoord and gl_PointSize into the
// same register. // same register.
linkHLSL += varyingHLSL; generateVaryingHLSL(caps, packedVaryings, programUsesPointSize, linkStream);
linkHLSL += "};\n"; linkStream << "};\n";
return linkHLSL;
} }
void DynamicHLSL::storeBuiltinLinkedVaryings(const SemanticInfo &info, void DynamicHLSL::storeBuiltinLinkedVaryings(const SemanticInfo &info,
...@@ -758,10 +879,10 @@ void DynamicHLSL::storeBuiltinLinkedVaryings(const SemanticInfo &info, ...@@ -758,10 +879,10 @@ void DynamicHLSL::storeBuiltinLinkedVaryings(const SemanticInfo &info,
} }
void DynamicHLSL::storeUserLinkedVaryings(const std::vector<PackedVarying> &packedVaryings, void DynamicHLSL::storeUserLinkedVaryings(const std::vector<PackedVarying> &packedVaryings,
bool shaderUsesPointSize, bool programUsesPointSize,
std::vector<LinkedVarying> *linkedVaryings) const std::vector<LinkedVarying> *linkedVaryings) const
{ {
const std::string &varyingSemantic = getVaryingSemantic(shaderUsesPointSize); const std::string &varyingSemantic = getVaryingSemantic(programUsesPointSize);
for (const PackedVarying &packedVarying : packedVaryings) for (const PackedVarying &packedVarying : packedVaryings)
{ {
...@@ -835,8 +956,6 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, ...@@ -835,8 +956,6 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data,
return false; return false;
} }
const std::string &varyingHLSL = generateVaryingHLSL(*data.caps, packedVaryings, usesPointSize);
// Instanced PointSprite emulation requires that gl_PointCoord is present in the vertex shader // Instanced PointSprite emulation requires that gl_PointCoord is present in the vertex shader
// VS_OUTPUT structure to ensure compatibility with the generated PS_INPUT of the pixel shader. // VS_OUTPUT structure to ensure compatibility with the generated PS_INPUT of the pixel shader.
// GeometryShader PointSprite emulation does not require this additional entry because the // GeometryShader PointSprite emulation does not require this additional entry because the
...@@ -866,8 +985,10 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, ...@@ -866,8 +985,10 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data,
// Add stub string to be replaced when shader is dynamically defined by its layout // Add stub string to be replaced when shader is dynamically defined by its layout
vertexStream << "\n" << VERTEX_ATTRIBUTE_STUB_STRING + "\n" vertexStream << "\n" << VERTEX_ATTRIBUTE_STUB_STRING + "\n"
<< "struct VS_OUTPUT\n" + generateVaryingLinkHLSL(vertexSemantics, varyingHLSL) + << "struct VS_OUTPUT\n";
"\n" generateVaryingLinkHLSL(*data.caps, usesPointSize, vertexSemantics, packedVaryings,
vertexStream);
vertexStream << "\n"
<< "VS_OUTPUT main(VS_INPUT input)\n" << "VS_OUTPUT main(VS_INPUT input)\n"
<< "{\n" << "{\n"
<< " initAttributes(input);\n"; << " initAttributes(input);\n";
...@@ -917,40 +1038,28 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, ...@@ -917,40 +1038,28 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data,
vertexStream << " output.gl_FragCoord = gl_Position;\n"; vertexStream << " output.gl_FragCoord = gl_Position;\n";
} }
for (const PackedVarying &packedVarying : packedVaryings) for (const PackedVaryingRegister &registerInfo : PackedVaryingIterator(packedVaryings))
{ {
if (!packedVarying.registerAssigned()) const PackedVarying &packedVarying = packedVaryings[registerInfo.varyingIndex];
{
continue;
}
const sh::Varying &varying = *packedVarying.varying; const sh::Varying &varying = *packedVarying.varying;
GLenum transposedType = TransposeMatrixType(varying.type);
unsigned int variableRows =
static_cast<unsigned int>(varying.isStruct() ? 1 : VariableRowCount(transposedType));
for (unsigned int elementIndex = 0; elementIndex < varying.elementCount(); elementIndex++) int r = registerInfo.registerIndex(*data.caps, packedVaryings);
{ vertexStream << " output.v" << r << " = _" + varying.name;
int variableRows =
(varying.isStruct() ? 1 : VariableRowCount(TransposeMatrixType(varying.type)));
for (int row = 0; row < variableRows; row++)
{
int r = packedVarying.registerIndex +
packedVarying.columnIndex * data.caps->maxVaryingVectors +
elementIndex * variableRows + row;
vertexStream << " output.v" << r << " = _" + varying.name;
if (varying.isArray())
{
vertexStream << ArrayString(elementIndex);
}
if (variableRows > 1) if (varying.isArray())
{ {
vertexStream << ArrayString(row); vertexStream << ArrayString(registerInfo.elementIndex);
} }
vertexStream << ";\n"; if (variableRows > 1)
} {
vertexStream << ArrayString(registerInfo.rowIndex);
} }
vertexStream << ";\n";
} }
// Instanced PointSprite emulation requires additional entries to calculate // Instanced PointSprite emulation requires additional entries to calculate
...@@ -992,8 +1101,9 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, ...@@ -992,8 +1101,9 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data,
getSemanticInfo(registerCount, outputPositionFromVS, usesFragCoord, usesPointCoord, getSemanticInfo(registerCount, outputPositionFromVS, usesFragCoord, usesPointCoord,
(!useInstancedPointSpriteEmulation && usesPointSize), true); (!useInstancedPointSpriteEmulation && usesPointSize), true);
pixelStream << "struct PS_INPUT\n" << generateVaryingLinkHLSL(pixelSemantics, varyingHLSL) pixelStream << "struct PS_INPUT\n";
<< "\n"; generateVaryingLinkHLSL(*data.caps, usesPointSize, pixelSemantics, packedVaryings, pixelStream);
pixelStream << "\n";
if (shaderVersion < 300) if (shaderVersion < 300)
{ {
...@@ -1109,69 +1219,53 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, ...@@ -1109,69 +1219,53 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data,
} }
} }
for (const PackedVarying &packedVarying : packedVaryings) for (const PackedVaryingRegister &registerInfo : PackedVaryingIterator(packedVaryings))
{ {
const PackedVarying &packedVarying = packedVaryings[registerInfo.varyingIndex];
const sh::Varying &varying = *packedVarying.varying; const sh::Varying &varying = *packedVarying.varying;
if (!packedVarying.registerAssigned())
{
ASSERT(varying.isBuiltIn() || !varying.staticUse);
continue;
}
// Don't reference VS-only transform feedback varyings in the PS. // Don't reference VS-only transform feedback varyings in the PS.
if (packedVarying.vertexOnly) if (packedVarying.vertexOnly)
continue; continue;
ASSERT(!varying.isBuiltIn()); ASSERT(!varying.isBuiltIn());
for (unsigned int elementIndex = 0; elementIndex < varying.elementCount(); elementIndex++) GLenum transposedType = TransposeMatrixType(varying.type);
int variableRows = (varying.isStruct() ? 1 : VariableRowCount(transposedType));
unsigned int registerIndex = registerInfo.registerIndex(*data.caps, packedVaryings);
pixelStream << " _" << varying.name;
if (varying.isArray())
{ {
GLenum transposedType = TransposeMatrixType(varying.type); pixelStream << ArrayString(registerInfo.elementIndex);
int variableRows = (varying.isStruct() ? 1 : VariableRowCount(transposedType)); }
for (int row = 0; row < variableRows; row++)
{
std::string n = Str(packedVarying.registerIndex +
packedVarying.columnIndex * data.caps->maxVaryingVectors +
elementIndex * variableRows + row);
pixelStream << " _" + varying.name;
if (varying.isArray()) if (variableRows > 1)
{ {
pixelStream << ArrayString(elementIndex); pixelStream << ArrayString(registerInfo.rowIndex);
} }
if (variableRows > 1) pixelStream << " = input.v" << registerIndex;
{
pixelStream << ArrayString(row);
}
if (varying.isStruct()) if (!varying.isStruct())
{ {
pixelStream << " = input.v" << n << ";\n"; switch (VariableColumnCount(transposedType))
{
case 1:
pixelStream << ".x";
break; break;
} case 2:
else pixelStream << ".xy";
{ break;
switch (VariableColumnCount(transposedType)) case 3:
{ pixelStream << ".xyz";
case 1: break;
pixelStream << " = input.v" << n << ".x;\n"; case 4:
break; break;
case 2: default:
pixelStream << " = input.v" << n << ".xy;\n"; UNREACHABLE();
break;
case 3:
pixelStream << " = input.v" << n << ".xyz;\n";
break;
case 4:
pixelStream << " = input.v" << n << ";\n";
break;
default:
UNREACHABLE();
}
}
} }
} }
pixelStream << ";\n";
} }
if (fragmentShader->usesDeferredInit()) if (fragmentShader->usesDeferredInit())
...@@ -1215,14 +1309,15 @@ std::string DynamicHLSL::generateGeometryShaderPreamble( ...@@ -1215,14 +1309,15 @@ std::string DynamicHLSL::generateGeometryShaderPreamble(
const SemanticInfo &outSemantics = const SemanticInfo &outSemantics =
getSemanticInfo(registerCount, true, usesFragCoord, usesPointCoord, usesPointSize, false); getSemanticInfo(registerCount, true, usesFragCoord, usesPointCoord, usesPointSize, false);
const std::string &varyingHLSL = generateVaryingHLSL(*data.caps, packedVaryings, usesPointSize);
std::string inLinkHLSL = generateVaryingLinkHLSL(inSemantics, varyingHLSL);
std::string outLinkHLSL = generateVaryingLinkHLSL(outSemantics, varyingHLSL);
std::stringstream preambleStream; std::stringstream preambleStream;
preambleStream << "struct GS_INPUT\n" << inLinkHLSL << "\n" preambleStream << "struct GS_INPUT\n";
<< "struct GS_OUTPUT\n" << outLinkHLSL << "\n" generateVaryingLinkHLSL(*data.caps, usesPointSize, inSemantics, packedVaryings, preambleStream);
preambleStream << "\n"
<< "struct GS_OUTPUT\n";
generateVaryingLinkHLSL(*data.caps, usesPointSize, outSemantics, packedVaryings,
preambleStream);
preambleStream << "\n"
<< "void copyVertex(inout GS_OUTPUT output, GS_INPUT input)\n" << "void copyVertex(inout GS_OUTPUT output, GS_INPUT input)\n"
<< "{\n" << "{\n"
<< " output.gl_Position = input.gl_Position;\n"; << " output.gl_Position = input.gl_Position;\n";
...@@ -1232,9 +1327,12 @@ std::string DynamicHLSL::generateGeometryShaderPreamble( ...@@ -1232,9 +1327,12 @@ std::string DynamicHLSL::generateGeometryShaderPreamble(
preambleStream << " output.gl_PointSize = input.gl_PointSize;\n"; preambleStream << " output.gl_PointSize = input.gl_PointSize;\n";
} }
for (unsigned int r = 0; r < registerCount; ++r) for (const PackedVaryingRegister &varyingRegister : PackedVaryingIterator(packedVaryings))
{ {
preambleStream << " output.v" << r << " = input.v" << r << ";\n"; unsigned int registerIndex = varyingRegister.registerIndex(*data.caps, packedVaryings);
preambleStream << " output.v" << registerIndex << " = ";
preambleStream << "input.v" << registerIndex << "; \n";
} }
if (usesFragCoord) if (usesFragCoord)
......
...@@ -115,20 +115,24 @@ class DynamicHLSL : angle::NonCopyable ...@@ -115,20 +115,24 @@ class DynamicHLSL : angle::NonCopyable
struct SemanticInfo; struct SemanticInfo;
std::string getVaryingSemantic(bool pointSize) const; std::string getVaryingSemantic(bool programUsesPointSize) const;
SemanticInfo getSemanticInfo(unsigned int startRegisters, SemanticInfo getSemanticInfo(unsigned int startRegisters,
bool position, bool position,
bool fragCoord, bool fragCoord,
bool pointCoord, bool pointCoord,
bool pointSize, bool pointSize,
bool pixelShader) const; bool pixelShader) const;
std::string generateVaryingLinkHLSL(const SemanticInfo &info, void generateVaryingLinkHLSL(const gl::Caps &caps,
const std::string &varyingHLSL) const; bool programUsesPointSize,
std::string generateVaryingHLSL(const gl::Caps &caps, const SemanticInfo &info,
const std::vector<PackedVarying> &varyings, const std::vector<PackedVarying> &packedVaryings,
bool shaderUsesPointSize) const; std::stringstream &linkStream) const;
void generateVaryingHLSL(const gl::Caps &caps,
const std::vector<PackedVarying> &varyings,
bool programUsesPointSize,
std::stringstream &hlslStream) const;
void storeUserLinkedVaryings(const std::vector<PackedVarying> &packedVaryings, void storeUserLinkedVaryings(const std::vector<PackedVarying> &packedVaryings,
bool shaderUsesPointSize, bool programUsesPointSize,
std::vector<gl::LinkedVarying> *linkedVaryings) const; std::vector<gl::LinkedVarying> *linkedVaryings) const;
void storeBuiltinLinkedVaryings(const SemanticInfo &info, void storeBuiltinLinkedVaryings(const SemanticInfo &info,
std::vector<gl::LinkedVarying> *linkedVaryings) const; std::vector<gl::LinkedVarying> *linkedVaryings) const;
......
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