Move TF Feedback linked varyings into D3D-only.
The LinkedVarying structure is a D3D-specific type, and the GL
back-end doesn't need the extra info. Isolate this into the D3D
back-end so we can clean up the Impl inteface.
BUG=angleproject:1123
Change-Id: I76d77ac505876d865e3e02f47acbfd6665a9507e
Reviewed-on: https://chromium-review.googlesource.com/293764
Tested-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/libANGLE/Program.cpp b/src/libANGLE/Program.cpp
index 969f35b..f470818 100644
--- a/src/libANGLE/Program.cpp
+++ b/src/libANGLE/Program.cpp
@@ -144,7 +144,6 @@
Program::Data::Data()
: mAttachedFragmentShader(nullptr),
mAttachedVertexShader(nullptr),
- mTransformFeedbackVaryings(),
mTransformFeedbackBufferMode(GL_NONE)
{
}
@@ -305,22 +304,22 @@
return Error(GL_NO_ERROR);
}
+ const auto &mergedVaryings = getMergedVaryings();
+
+ if (!linkValidateTransformFeedback(mInfoLog, mergedVaryings, *data.caps))
+ {
+ return Error(GL_NO_ERROR);
+ }
+
int registers;
- std::vector<LinkedVarying> linkedVaryings;
rx::LinkResult result =
mProgram->link(data, mInfoLog, mData.mAttachedFragmentShader, mData.mAttachedVertexShader,
- ®isters, &linkedVaryings, &mOutputVariables);
+ ®isters, &mOutputVariables);
if (result.error.isError() || !result.linkSuccess)
{
return result.error;
}
- if (!gatherTransformFeedbackLinkedVaryings(
- mInfoLog, linkedVaryings, &mProgram->getTransformFeedbackLinkedVaryings(), *data.caps))
- {
- return Error(GL_NO_ERROR);
- }
-
// TODO: The concept of "executables" is D3D only, and as such this belongs in ProgramD3D. It must be called,
// however, last in this function, so it can't simply be moved to ProgramD3D::link without further shuffling.
result = mProgram->compileProgramExecutables(mInfoLog, registers);
@@ -331,6 +330,8 @@
return result.error;
}
+ gatherTransformFeedbackVaryings(mergedVaryings);
+
mLinked = true;
return gl::Error(GL_NO_ERROR);
}
@@ -367,7 +368,7 @@
}
mLinkedAttributes.assign(mLinkedAttributes.size(), sh::Attribute());
- mOutputVariables.clear();
+ mData.mTransformFeedbackVaryingVars.clear();
mProgram->reset();
@@ -1170,10 +1171,10 @@
void Program::setTransformFeedbackVaryings(GLsizei count, const GLchar *const *varyings, GLenum bufferMode)
{
- mData.mTransformFeedbackVaryings.resize(count);
+ mData.mTransformFeedbackVaryingNames.resize(count);
for (GLsizei i = 0; i < count; i++)
{
- mData.mTransformFeedbackVaryings[i] = varyings[i];
+ mData.mTransformFeedbackVaryingNames[i] = varyings[i];
}
mData.mTransformFeedbackBufferMode = bufferMode;
@@ -1183,8 +1184,8 @@
{
if (mLinked)
{
- ASSERT(index < mProgram->getTransformFeedbackLinkedVaryings().size());
- const LinkedVarying &varying = mProgram->getTransformFeedbackLinkedVaryings()[index];
+ ASSERT(index < mData.mTransformFeedbackVaryingVars.size());
+ const sh::Varying &varying = mData.mTransformFeedbackVaryingVars[index];
GLsizei lastNameIdx = std::min(bufSize - 1, static_cast<GLsizei>(varying.name.length()));
if (length)
{
@@ -1192,7 +1193,7 @@
}
if (size)
{
- *size = varying.size;
+ *size = varying.elementCount();
}
if (type)
{
@@ -1210,7 +1211,7 @@
{
if (mLinked)
{
- return static_cast<GLsizei>(mProgram->getTransformFeedbackLinkedVaryings().size());
+ return static_cast<GLsizei>(mData.mTransformFeedbackVaryingVars.size());
}
else
{
@@ -1223,9 +1224,8 @@
if (mLinked)
{
GLsizei maxSize = 0;
- for (size_t i = 0; i < mProgram->getTransformFeedbackLinkedVaryings().size(); i++)
+ for (const sh::Varying &varying : mData.mTransformFeedbackVaryingVars)
{
- const LinkedVarying &varying = mProgram->getTransformFeedbackLinkedVaryings()[i];
maxSize = std::max(maxSize, static_cast<GLsizei>(varying.name.length() + 1));
}
@@ -1625,45 +1625,41 @@
return true;
}
-bool Program::gatherTransformFeedbackLinkedVaryings(InfoLog &infoLog, const std::vector<LinkedVarying> &linkedVaryings,
- std::vector<LinkedVarying> *outTransformFeedbackLinkedVaryings,
- const Caps &caps) const
+bool Program::linkValidateTransformFeedback(InfoLog &infoLog,
+ const std::vector<const sh::Varying *> &varyings,
+ const Caps &caps) const
{
size_t totalComponents = 0;
- // Gather the linked varyings that are used for transform feedback, they should all exist.
- outTransformFeedbackLinkedVaryings->clear();
- for (size_t i = 0; i < mData.mTransformFeedbackVaryings.size(); i++)
+ std::set<std::string> uniqueNames;
+
+ for (const std::string &tfVaryingName : mData.mTransformFeedbackVaryingNames)
{
bool found = false;
- for (size_t j = 0; j < linkedVaryings.size(); j++)
+ for (const sh::Varying *varying : varyings)
{
- if (mData.mTransformFeedbackVaryings[i] == linkedVaryings[j].name)
+ if (tfVaryingName == varying->name)
{
- for (size_t k = 0; k < outTransformFeedbackLinkedVaryings->size(); k++)
+ if (uniqueNames.count(tfVaryingName) > 0)
{
- if (outTransformFeedbackLinkedVaryings->at(k).name == linkedVaryings[j].name)
- {
- infoLog << "Two transform feedback varyings specify the same output variable ("
- << linkedVaryings[j].name << ").";
- return false;
- }
+ infoLog << "Two transform feedback varyings specify the same output variable ("
+ << tfVaryingName << ").";
+ return false;
}
+ uniqueNames.insert(tfVaryingName);
- size_t componentCount = linkedVaryings[j].semanticIndexCount * 4;
+ // TODO(jmadill): Investigate implementation limits on D3D11
+ size_t componentCount = gl::VariableComponentCount(varying->type);
if (mData.mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS &&
componentCount > caps.maxTransformFeedbackSeparateComponents)
{
- infoLog << "Transform feedback varying's " << linkedVaryings[j].name
- << " components (" << componentCount
- << ") exceed the maximum separate components ("
+ infoLog << "Transform feedback varying's " << varying->name << " components ("
+ << componentCount << ") exceed the maximum separate components ("
<< caps.maxTransformFeedbackSeparateComponents << ").";
return false;
}
totalComponents += componentCount;
-
- outTransformFeedbackLinkedVaryings->push_back(linkedVaryings[j]);
found = true;
break;
}
@@ -1686,4 +1682,46 @@
return true;
}
+void Program::gatherTransformFeedbackVaryings(const std::vector<const sh::Varying *> &varyings)
+{
+ // Gather the linked varyings that are used for transform feedback, they should all exist.
+ mData.mTransformFeedbackVaryingVars.clear();
+ for (const std::string &tfVaryingName : mData.mTransformFeedbackVaryingNames)
+ {
+ for (const sh::Varying *varying : varyings)
+ {
+ if (tfVaryingName == varying->name)
+ {
+ mData.mTransformFeedbackVaryingVars.push_back(*varying);
+ break;
+ }
+ }
+ }
+}
+
+std::vector<const sh::Varying *> Program::getMergedVaryings() const
+{
+ std::set<std::string> uniqueNames;
+ std::vector<const sh::Varying *> varyings;
+
+ for (const sh::Varying &varying : mData.mAttachedVertexShader->getVaryings())
+ {
+ if (uniqueNames.count(varying.name) == 0)
+ {
+ uniqueNames.insert(varying.name);
+ varyings.push_back(&varying);
+ }
+ }
+
+ for (const sh::Varying &varying : mData.mAttachedFragmentShader->getVaryings())
+ {
+ if (uniqueNames.count(varying.name) == 0)
+ {
+ uniqueNames.insert(varying.name);
+ varyings.push_back(&varying);
+ }
+ }
+
+ return varyings;
+}
}