Commit ccdf74b8 by Jamie Madill

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/293764Tested-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org>
parent 11cd6af6
......@@ -144,7 +144,6 @@ LinkedVarying::LinkedVarying(const std::string &name, GLenum type, GLsizei size,
Program::Data::Data()
: mAttachedFragmentShader(nullptr),
mAttachedVertexShader(nullptr),
mTransformFeedbackVaryings(),
mTransformFeedbackBufferMode(GL_NONE)
{
}
......@@ -305,22 +304,22 @@ Error Program::link(const gl::Data &data)
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,
&registers, &linkedVaryings, &mOutputVariables);
&registers, &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 @@ Error Program::link(const gl::Data &data)
return result.error;
}
gatherTransformFeedbackVaryings(mergedVaryings);
mLinked = true;
return gl::Error(GL_NO_ERROR);
}
......@@ -367,7 +368,7 @@ void Program::unlink(bool destroy)
}
mLinkedAttributes.assign(mLinkedAttributes.size(), sh::Attribute());
mOutputVariables.clear();
mData.mTransformFeedbackVaryingVars.clear();
mProgram->reset();
......@@ -1170,10 +1171,10 @@ void Program::resetUniformBlockBindings()
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 @@ void Program::getTransformFeedbackVarying(GLuint index, GLsizei bufSize, GLsizei
{
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 @@ void Program::getTransformFeedbackVarying(GLuint index, GLsizei bufSize, GLsizei
}
if (size)
{
*size = varying.size;
*size = varying.elementCount();
}
if (type)
{
......@@ -1210,7 +1211,7 @@ GLsizei Program::getTransformFeedbackVaryingCount() const
{
if (mLinked)
{
return static_cast<GLsizei>(mProgram->getTransformFeedbackLinkedVaryings().size());
return static_cast<GLsizei>(mData.mTransformFeedbackVaryingVars.size());
}
else
{
......@@ -1223,9 +1224,8 @@ GLsizei Program::getTransformFeedbackVaryingMaxLength() const
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 @@ bool Program::linkValidateVaryings(InfoLog &infoLog, const std::string &varyingN
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 @@ bool Program::gatherTransformFeedbackLinkedVaryings(InfoLog &infoLog, const std:
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;
}
}
......@@ -170,9 +170,9 @@ class Program : angle::NonCopyable
const Shader *getAttachedVertexShader() const { return mAttachedVertexShader; }
const Shader *getAttachedFragmentShader() const { return mAttachedFragmentShader; }
const std::vector<std::string> &getTransformFeedbackVaryings() const
const std::vector<std::string> &getTransformFeedbackVaryingNames() const
{
return mTransformFeedbackVaryings;
return mTransformFeedbackVaryingNames;
}
GLint getTransformFeedbackBufferMode() const { return mTransformFeedbackBufferMode; }
......@@ -182,7 +182,8 @@ class Program : angle::NonCopyable
Shader *mAttachedFragmentShader;
Shader *mAttachedVertexShader;
std::vector<std::string> mTransformFeedbackVaryings;
std::vector<std::string> mTransformFeedbackVaryingNames;
std::vector<sh::Varying> mTransformFeedbackVaryingVars;
GLenum mTransformFeedbackBufferMode;
// TODO(jmadill): move more state into Data.
......@@ -323,12 +324,16 @@ class Program : angle::NonCopyable
bool validatePrecision);
static bool linkValidateVaryings(InfoLog &infoLog, const std::string &varyingName, const sh::Varying &vertexVarying, const sh::Varying &fragmentVarying);
bool gatherTransformFeedbackLinkedVaryings(InfoLog &infoLog, const std::vector<LinkedVarying> &linkedVaryings,
std::vector<LinkedVarying> *outTransformFeedbackLinkedVaryings,
const Caps &caps) const;
bool linkValidateTransformFeedback(InfoLog &infoLog,
const std::vector<const sh::Varying *> &linkedVaryings,
const Caps &caps) const;
void gatherTransformFeedbackVaryings(const std::vector<const sh::Varying *> &varyings);
bool assignUniformBlockRegister(InfoLog &infoLog, UniformBlock *uniformBlock, GLenum shader, unsigned int registerIndex, const Caps &caps);
void defineOutputVariables(Shader *fragmentShader);
std::vector<const sh::Varying *> getMergedVaryings() const;
Data mData;
rx::ProgramImpl *mProgram;
......
......@@ -133,7 +133,6 @@ void ProgramImpl::reset()
SafeDeleteContainer(mUniforms);
mUniformIndex.clear();
SafeDeleteContainer(mUniformBlocks);
mTransformFeedbackLinkedVaryings.clear();
}
void ProgramImpl::setShaderAttribute(size_t index, const sh::Attribute &attrib)
......
......@@ -43,9 +43,11 @@ class ProgramImpl : angle::NonCopyable
virtual LinkResult load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) = 0;
virtual gl::Error save(gl::BinaryOutputStream *stream) = 0;
virtual LinkResult link(const gl::Data &data, gl::InfoLog &infoLog,
gl::Shader *fragmentShader, gl::Shader *vertexShader,
int *registers, std::vector<gl::LinkedVarying> *linkedVaryings,
virtual LinkResult link(const gl::Data &data,
gl::InfoLog &infoLog,
gl::Shader *fragmentShader,
gl::Shader *vertexShader,
int *registers,
std::map<int, gl::VariableLocation> *outputVariables) = 0;
virtual void bindAttributeLocation(GLuint index, const std::string &name) = 0;
......@@ -92,14 +94,12 @@ class ProgramImpl : angle::NonCopyable
const std::vector<gl::LinkedUniform*> &getUniforms() const { return mUniforms; }
const std::map<GLuint, gl::VariableLocation> &getUniformIndices() const { return mUniformIndex; }
const std::vector<gl::UniformBlock*> &getUniformBlocks() const { return mUniformBlocks; }
const std::vector<gl::LinkedVarying> &getTransformFeedbackLinkedVaryings() const { return mTransformFeedbackLinkedVaryings; }
const std::vector<sh::Attribute> getShaderAttributes() { return mShaderAttributes; }
const SemanticIndexArray &getSemanticIndexes() const { return mSemanticIndex; }
std::vector<gl::LinkedUniform*> &getUniforms() { return mUniforms; }
std::map<GLuint, gl::VariableLocation> &getUniformIndices() { return mUniformIndex; }
std::vector<gl::UniformBlock*> &getUniformBlocks() { return mUniformBlocks; }
std::vector<gl::LinkedVarying> &getTransformFeedbackLinkedVaryings() { return mTransformFeedbackLinkedVaryings; }
SemanticIndexArray &getSemanticIndexes() { return mSemanticIndex; }
gl::LinkedUniform *getUniformByLocation(GLint location) const;
......@@ -124,7 +124,6 @@ class ProgramImpl : angle::NonCopyable
std::map<GLuint, gl::VariableLocation> mUniformIndex;
std::vector<gl::UniformBlock*> mUniformBlocks;
std::vector<gl::LinkedVarying> mTransformFeedbackLinkedVaryings;
SemanticIndexArray mSemanticIndex;
......
......@@ -1096,9 +1096,11 @@ LinkResult ProgramD3D::compileProgramExecutables(gl::InfoLog &infoLog, int regis
return LinkResult(linkSuccess, gl::Error(GL_NO_ERROR));
}
LinkResult ProgramD3D::link(const gl::Data &data, gl::InfoLog &infoLog,
gl::Shader *fragmentShader, gl::Shader *vertexShader,
int *registers, std::vector<gl::LinkedVarying> *linkedVaryings,
LinkResult ProgramD3D::link(const gl::Data &data,
gl::InfoLog &infoLog,
gl::Shader *fragmentShader,
gl::Shader *vertexShader,
int *registers,
std::map<int, gl::VariableLocation> *outputVariables)
{
ShaderD3D *vertexShaderD3D = GetImplAs<ShaderD3D>(vertexShader);
......@@ -1126,7 +1128,7 @@ LinkResult ProgramD3D::link(const gl::Data &data, gl::InfoLog &infoLog,
// Map the varyings to the register file
VaryingPacking packing = {};
*registers = mDynamicHLSL->packVaryings(infoLog, packing, fragmentShaderD3D, vertexShaderD3D,
mData.getTransformFeedbackVaryings());
mData.getTransformFeedbackVaryingNames());
if (*registers < 0)
{
......@@ -1135,10 +1137,11 @@ LinkResult ProgramD3D::link(const gl::Data &data, gl::InfoLog &infoLog,
LinkVaryingRegisters(infoLog, vertexShaderD3D, fragmentShaderD3D);
if (!mDynamicHLSL->generateShaderLinkHLSL(data, infoLog, *registers, packing, mPixelHLSL,
mVertexHLSL, fragmentShaderD3D, vertexShaderD3D,
mData.getTransformFeedbackVaryings(), linkedVaryings,
outputVariables, &mPixelShaderKey, &mUsesFragDepth))
std::vector<gl::LinkedVarying> linkedVaryings;
if (!mDynamicHLSL->generateShaderLinkHLSL(
data, infoLog, *registers, packing, mPixelHLSL, mVertexHLSL, fragmentShaderD3D,
vertexShaderD3D, mData.getTransformFeedbackVaryingNames(), &linkedVaryings,
outputVariables, &mPixelShaderKey, &mUsesFragDepth))
{
return LinkResult(false, gl::Error(GL_NO_ERROR));
}
......@@ -1154,6 +1157,8 @@ LinkResult ProgramD3D::link(const gl::Data &data, gl::InfoLog &infoLog,
defineUniformBlocks(*data.caps);
gatherTransformFeedbackVaryings(linkedVaryings);
return LinkResult(true, gl::Error(GL_NO_ERROR));
}
......@@ -2052,6 +2057,8 @@ void ProgramD3D::reset()
mDirtySamplerMapping = true;
std::fill(mAttributesByLayout, mAttributesByLayout + ArraySize(mAttributesByLayout), -1);
mTransformFeedbackLinkedVaryings.clear();
}
unsigned int ProgramD3D::getSerial() const
......@@ -2110,4 +2117,21 @@ void ProgramD3D::updateCachedInputLayout(const gl::Program *program, const gl::S
}
}
void ProgramD3D::gatherTransformFeedbackVaryings(
const std::vector<gl::LinkedVarying> &linkedVaryings)
{
// Gather the linked varyings that are used for transform feedback, they should all exist.
mTransformFeedbackLinkedVaryings.clear();
for (const std::string &tfVaryingName : mData.getTransformFeedbackVaryingNames())
{
for (const gl::LinkedVarying &linkedVarying : linkedVaryings)
{
if (tfVaryingName == linkedVarying.name)
{
mTransformFeedbackLinkedVaryings.push_back(linkedVarying);
break;
}
}
}
}
}
......@@ -70,9 +70,11 @@ class ProgramD3D : public ProgramImpl
LinkResult compileProgramExecutables(gl::InfoLog &infoLog, int registers);
LinkResult link(const gl::Data &data, gl::InfoLog &infoLog,
gl::Shader *fragmentShader, gl::Shader *vertexShader,
int *registers, std::vector<gl::LinkedVarying> *linkedVaryings,
LinkResult link(const gl::Data &data,
gl::InfoLog &infoLog,
gl::Shader *fragmentShader,
gl::Shader *vertexShader,
int *registers,
std::map<int, gl::VariableLocation> *outputVariables);
void bindAttributeLocation(GLuint index, const std::string &name) override;
......@@ -206,6 +208,8 @@ class ProgramD3D : public ProgramImpl
sh::BlockLayoutEncoder *encoder, std::vector<unsigned int> *blockUniformIndexes,
bool inRowMajorLayout);
void gatherTransformFeedbackVaryings(const std::vector<gl::LinkedVarying> &varyings);
RendererD3D *mRenderer;
DynamicHLSL *mDynamicHLSL;
......@@ -251,6 +255,8 @@ class ProgramD3D : public ProgramImpl
VertexExecutable::Signature mCachedVertexSignature;
gl::InputLayout mCachedInputLayout;
std::vector<gl::LinkedVarying> mTransformFeedbackLinkedVaryings;
static unsigned int issueSerial();
static unsigned int mCurrentSerial;
};
......
......@@ -64,9 +64,11 @@ gl::Error ProgramGL::save(gl::BinaryOutputStream *stream)
return gl::Error(GL_INVALID_OPERATION);
}
LinkResult ProgramGL::link(const gl::Data &data, gl::InfoLog &infoLog,
gl::Shader *fragmentShader, gl::Shader *vertexShader,
int *registers, std::vector<gl::LinkedVarying> *linkedVaryings,
LinkResult ProgramGL::link(const gl::Data &data,
gl::InfoLog &infoLog,
gl::Shader *fragmentShader,
gl::Shader *vertexShader,
int *registers,
std::map<int, gl::VariableLocation> *outputVariables)
{
// Reset the program state, delete the current program if one exists
......
......@@ -38,9 +38,11 @@ class ProgramGL : public ProgramImpl
LinkResult load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) override;
gl::Error save(gl::BinaryOutputStream *stream) override;
LinkResult link(const gl::Data &data, gl::InfoLog &infoLog,
gl::Shader *fragmentShader, gl::Shader *vertexShader,
int *registers, std::vector<gl::LinkedVarying> *linkedVaryings,
LinkResult link(const gl::Data &data,
gl::InfoLog &infoLog,
gl::Shader *fragmentShader,
gl::Shader *vertexShader,
int *registers,
std::map<int, gl::VariableLocation> *outputVariables) override;
void bindAttributeLocation(GLuint index, const std::string &name) override;
......
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