Commit d33ffb22 by Jamie Madill Committed by Commit Bot

Organize VaryingPacking methods.

This clarifies the difference between "collect" and "pack" methods. Previously the naming was overlapping between the two. Also makes the "packUserVaryings" method private. Refactoring change only. Will enable further improvements for capturing varyings with multiple shader stages. Bug: angleproject:5496 Change-Id: I854590ceab39f3a0e7a785516e0d1fd44e4ccc98 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2606529 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarTim Van Patten <timvp@google.com> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org>
parent 92e7bc89
...@@ -203,7 +203,7 @@ void VaryingPacking::clearRegisterMap() ...@@ -203,7 +203,7 @@ void VaryingPacking::clearRegisterMap()
// See [OpenGL ES Shading Language 1.00 rev. 17] appendix A section 7 page 111 // See [OpenGL ES Shading Language 1.00 rev. 17] appendix A section 7 page 111
// Also [OpenGL ES Shading Language 3.00 rev. 4] Section 11 page 119 // Also [OpenGL ES Shading Language 3.00 rev. 4] Section 11 page 119
// Returns false if unsuccessful. // Returns false if unsuccessful.
bool VaryingPacking::packVarying(const PackedVarying &packedVarying) bool VaryingPacking::packVaryingIntoRegisterMap(const PackedVarying &packedVarying)
{ {
const sh::ShaderVariable &varying = packedVarying.varying(); const sh::ShaderVariable &varying = packedVarying.varying();
...@@ -250,9 +250,9 @@ bool VaryingPacking::packVarying(const PackedVarying &packedVarying) ...@@ -250,9 +250,9 @@ bool VaryingPacking::packVarying(const PackedVarying &packedVarying)
{ {
for (unsigned int row = 0; row <= maxVaryingVectors - varyingRows; ++row) for (unsigned int row = 0; row <= maxVaryingVectors - varyingRows; ++row)
{ {
if (isFree(row, 0, varyingRows, varyingColumns)) if (isRegisterRangeFree(row, 0, varyingRows, varyingColumns))
{ {
insert(row, 0, packedVarying); insertVaryingIntoRegisterMap(row, 0, packedVarying);
return true; return true;
} }
} }
...@@ -264,9 +264,9 @@ bool VaryingPacking::packVarying(const PackedVarying &packedVarying) ...@@ -264,9 +264,9 @@ bool VaryingPacking::packVarying(const PackedVarying &packedVarying)
{ {
for (unsigned int r = maxVaryingVectors - varyingRows + 1; r-- >= 1;) for (unsigned int r = maxVaryingVectors - varyingRows + 1; r-- >= 1;)
{ {
if (isFree(r, 2, varyingRows, 2)) if (isRegisterRangeFree(r, 2, varyingRows, 2))
{ {
insert(r, 2, packedVarying); insertVaryingIntoRegisterMap(r, 2, packedVarying);
return true; return true;
} }
} }
...@@ -319,7 +319,7 @@ bool VaryingPacking::packVarying(const PackedVarying &packedVarying) ...@@ -319,7 +319,7 @@ bool VaryingPacking::packVarying(const PackedVarying &packedVarying)
{ {
for (unsigned int row = 0; row < maxVaryingVectors; row++) for (unsigned int row = 0; row < maxVaryingVectors; row++)
{ {
if (isFree(row, bestColumn, varyingRows, 1)) if (isRegisterRangeFree(row, bestColumn, varyingRows, 1))
{ {
for (unsigned int arrayIndex = 0; arrayIndex < varyingRows; ++arrayIndex) for (unsigned int arrayIndex = 0; arrayIndex < varyingRows; ++arrayIndex)
{ {
...@@ -349,7 +349,7 @@ bool VaryingPacking::packVarying(const PackedVarying &packedVarying) ...@@ -349,7 +349,7 @@ bool VaryingPacking::packVarying(const PackedVarying &packedVarying)
return false; return false;
} }
bool VaryingPacking::isFree(unsigned int registerRow, bool VaryingPacking::isRegisterRangeFree(unsigned int registerRow,
unsigned int registerColumn, unsigned int registerColumn,
unsigned int varyingRows, unsigned int varyingRows,
unsigned int varyingColumns) const unsigned int varyingColumns) const
...@@ -370,7 +370,7 @@ bool VaryingPacking::isFree(unsigned int registerRow, ...@@ -370,7 +370,7 @@ bool VaryingPacking::isFree(unsigned int registerRow,
return true; return true;
} }
void VaryingPacking::insert(unsigned int registerRow, void VaryingPacking::insertVaryingIntoRegisterMap(unsigned int registerRow,
unsigned int registerColumn, unsigned int registerColumn,
const PackedVarying &packedVarying) const PackedVarying &packedVarying)
{ {
...@@ -417,7 +417,7 @@ void VaryingPacking::insert(unsigned int registerRow, ...@@ -417,7 +417,7 @@ void VaryingPacking::insert(unsigned int registerRow,
} }
} }
void VaryingPacking::packUserVarying(const ProgramVaryingRef &ref, void VaryingPacking::collectUserVarying(const ProgramVaryingRef &ref,
VaryingUniqueFullNames *uniqueFullNames) VaryingUniqueFullNames *uniqueFullNames)
{ {
const sh::ShaderVariable *input = ref.frontShader; const sh::ShaderVariable *input = ref.frontShader;
...@@ -442,7 +442,7 @@ void VaryingPacking::packUserVarying(const ProgramVaryingRef &ref, ...@@ -442,7 +442,7 @@ void VaryingPacking::packUserVarying(const ProgramVaryingRef &ref,
} }
} }
void VaryingPacking::packUserVaryingField(const ProgramVaryingRef &ref, void VaryingPacking::collectUserVaryingField(const ProgramVaryingRef &ref,
GLuint arrayIndex, GLuint arrayIndex,
GLuint fieldIndex, GLuint fieldIndex,
GLuint secondaryFieldIndex, GLuint secondaryFieldIndex,
...@@ -511,7 +511,7 @@ void VaryingPacking::packUserVaryingField(const ProgramVaryingRef &ref, ...@@ -511,7 +511,7 @@ void VaryingPacking::packUserVaryingField(const ProgramVaryingRef &ref,
} }
} }
void VaryingPacking::packUserVaryingTF(const ProgramVaryingRef &ref, size_t subscript) void VaryingPacking::collectUserVaryingTF(const ProgramVaryingRef &ref, size_t subscript)
{ {
const sh::ShaderVariable *input = ref.frontShader; const sh::ShaderVariable *input = ref.frontShader;
...@@ -524,7 +524,7 @@ void VaryingPacking::packUserVaryingTF(const ProgramVaryingRef &ref, size_t subs ...@@ -524,7 +524,7 @@ void VaryingPacking::packUserVaryingTF(const ProgramVaryingRef &ref, size_t subs
mPackedVaryings.back().isTransformFeedback = true; mPackedVaryings.back().isTransformFeedback = true;
} }
void VaryingPacking::packUserVaryingFieldTF(const ProgramVaryingRef &ref, void VaryingPacking::collectUserVaryingFieldTF(const ProgramVaryingRef &ref,
const sh::ShaderVariable &field, const sh::ShaderVariable &field,
GLuint fieldIndex, GLuint fieldIndex,
GLuint secondaryFieldIndex) GLuint secondaryFieldIndex)
...@@ -557,54 +557,21 @@ void VaryingPacking::packUserVaryingFieldTF(const ProgramVaryingRef &ref, ...@@ -557,54 +557,21 @@ void VaryingPacking::packUserVaryingFieldTF(const ProgramVaryingRef &ref,
secondaryFieldIndex == GL_INVALID_INDEX ? 0 : secondaryFieldIndex); secondaryFieldIndex == GL_INVALID_INDEX ? 0 : secondaryFieldIndex);
} }
bool VaryingPacking::collectAndPackUserVaryings(gl::InfoLog &infoLog, void VaryingPacking::collectVarying(const sh::ShaderVariable &varying,
const ProgramMergedVaryings &mergedVaryings, const ProgramVaryingRef &ref,
const std::vector<std::string> &tfVaryings, VaryingUniqueFullNames *uniqueFullNames)
const bool isSeparableProgram)
{ {
VaryingUniqueFullNames uniqueFullNames;
reset();
for (const ProgramVaryingRef &ref : mergedVaryings)
{
const sh::ShaderVariable *input = ref.frontShader; const sh::ShaderVariable *input = ref.frontShader;
const sh::ShaderVariable *output = ref.backShader; const sh::ShaderVariable *output = ref.backShader;
const bool isActiveBuiltInInput = input && input->isBuiltIn() && input->active; if (varying.isStruct())
const bool isActiveBuiltInOutput = output && output->isBuiltIn() && output->active;
// Keep track of output builtins that are used by the shader, such as gl_Position,
// gl_PointSize etc.
if (isActiveBuiltInInput)
{ {
mActiveOutputBuiltIns[ref.frontShaderStage].push_back(input->name); const std::vector<unsigned int> &arraySizes = varying.arraySizes;
}
// Only pack statically used varyings that have a matched input or output, plus special
// builtins. Note that we pack all statically used user-defined varyings even if they are
// not active. GLES specs are a bit vague on whether it's allowed to only pack active
// varyings, though GLES 3.1 spec section 11.1.2.1 says that "device-dependent
// optimizations" may be used to make vertex shader outputs fit.
if ((input && output && output->staticUse) || isActiveBuiltInInput ||
isActiveBuiltInOutput ||
(isSeparableProgram && ((input && input->active) || (output && output->active))))
{
const sh::ShaderVariable *varying = output ? output : input;
// Don't count gl_Position. Also don't count gl_PointSize for D3D9.
if (varying->name != "gl_Position" &&
!(varying->name == "gl_PointSize" &&
mPackMode == PackMode::ANGLE_NON_CONFORMANT_D3D9))
{
if (varying->isStruct())
{
const std::vector<unsigned int> &arraySizes = varying->arraySizes;
size_t arrayDimensions = arraySizes.size(); size_t arrayDimensions = arraySizes.size();
// Geometry shader inputs have an extra level of array-ness that should be // Geometry shader inputs have an extra level of array-ness that should be
// removed. // removed.
if (varying == output && ref.backShaderStage == ShaderType::Geometry) if (&varying == output && ref.backShaderStage == ShaderType::Geometry)
{ {
ASSERT(arrayDimensions > 0); ASSERT(arrayDimensions > 0);
--arrayDimensions; --arrayDimensions;
...@@ -617,77 +584,62 @@ bool VaryingPacking::collectAndPackUserVaryings(gl::InfoLog &infoLog, ...@@ -617,77 +584,62 @@ bool VaryingPacking::collectAndPackUserVaryings(gl::InfoLog &infoLog,
for (GLuint arrayIndex = 0; arrayIndex < arraySize; ++arrayIndex) for (GLuint arrayIndex = 0; arrayIndex < arraySize; ++arrayIndex)
{ {
const GLuint effectiveArrayIndex = isArray ? arrayIndex : GL_INVALID_INDEX; const GLuint effectiveArrayIndex = isArray ? arrayIndex : GL_INVALID_INDEX;
for (GLuint fieldIndex = 0; fieldIndex < varying->fields.size(); for (GLuint fieldIndex = 0; fieldIndex < varying.fields.size(); ++fieldIndex)
++fieldIndex)
{ {
if (varying->fields[fieldIndex].isStruct()) if (varying.fields[fieldIndex].isStruct())
{ {
for (GLuint nestedIndex = 0; for (GLuint nestedIndex = 0;
nestedIndex < varying->fields[fieldIndex].fields.size(); nestedIndex < varying.fields[fieldIndex].fields.size(); nestedIndex++)
nestedIndex++)
{ {
packUserVaryingField(ref, effectiveArrayIndex, fieldIndex, collectUserVaryingField(ref, effectiveArrayIndex, fieldIndex, nestedIndex,
nestedIndex, &uniqueFullNames); uniqueFullNames);
} }
} }
else else
{ {
packUserVaryingField(ref, effectiveArrayIndex, fieldIndex, collectUserVaryingField(ref, effectiveArrayIndex, fieldIndex, GL_INVALID_INDEX,
GL_INVALID_INDEX, &uniqueFullNames); uniqueFullNames);
} }
} }
} }
if (input) if (input)
{ {
uniqueFullNames[ref.frontShaderStage].insert(input->name); (*uniqueFullNames)[ref.frontShaderStage].insert(input->name);
if (input->isShaderIOBlock) if (input->isShaderIOBlock)
{ {
uniqueFullNames[ref.frontShaderStage].insert(input->structName); (*uniqueFullNames)[ref.frontShaderStage].insert(input->structName);
} }
} }
if (output) if (output)
{ {
uniqueFullNames[ref.backShaderStage].insert(output->name); (*uniqueFullNames)[ref.backShaderStage].insert(output->name);
} }
} }
else else
{ {
packUserVarying(ref, &uniqueFullNames); collectUserVarying(ref, uniqueFullNames);
}
continue;
}
} }
}
// If the varying is not used in the input, we know it is inactive, unless it's a separable void VaryingPacking::collectTFVarying(const std::string &tfVarying,
// program, in which case the input shader may not exist in this program. const ProgramVaryingRef &ref,
if (!input && !isSeparableProgram) VaryingUniqueFullNames *uniqueFullNames)
{ {
if (!output->isBuiltIn()) const sh::ShaderVariable *input = ref.frontShader;
{
mInactiveVaryingMappedNames[ref.backShaderStage].push_back(output->mappedName);
}
continue;
}
// Keep Transform FB varyings in the merged list always.
for (const std::string &tfVarying : tfVaryings)
{
std::vector<unsigned int> subscripts; std::vector<unsigned int> subscripts;
std::string baseName = ParseResourceName(tfVarying, &subscripts); std::string baseName = ParseResourceName(tfVarying, &subscripts);
size_t subscript = GL_INVALID_INDEX;
if (!subscripts.empty())
{
subscript = subscripts.back();
}
// Already packed as active varying. // Already packed as active varying.
if (uniqueFullNames[ref.frontShaderStage].count(tfVarying) > 0 || if ((*uniqueFullNames)[ref.frontShaderStage].count(tfVarying) > 0 ||
uniqueFullNames[ref.frontShaderStage].count(baseName) > 0 || (*uniqueFullNames)[ref.frontShaderStage].count(baseName) > 0 ||
(input->isShaderIOBlock && (input->isShaderIOBlock &&
uniqueFullNames[ref.frontShaderStage].count(input->structName) > 0)) (*uniqueFullNames)[ref.frontShaderStage].count(input->structName) > 0))
{ {
continue; return;
} }
if (input->isStruct()) if (input->isStruct())
{ {
GLuint fieldIndex = 0; GLuint fieldIndex = 0;
...@@ -706,49 +658,110 @@ bool VaryingPacking::collectAndPackUserVaryings(gl::InfoLog &infoLog, ...@@ -706,49 +658,110 @@ bool VaryingPacking::collectAndPackUserVaryings(gl::InfoLog &infoLog,
{ {
for (GLuint nestedIndex = 0; for (GLuint nestedIndex = 0;
nestedIndex < input->fields[fieldIndex].fields.size(); nestedIndex < input->fields[fieldIndex].fields.size(); nestedIndex++)
nestedIndex++)
{ {
packUserVaryingFieldTF(ref, input->fields[fieldIndex], collectUserVaryingFieldTF(ref, input->fields[fieldIndex], fieldIndex,
fieldIndex, nestedIndex); nestedIndex);
} }
} }
else else
{ {
packUserVaryingFieldTF(ref, input->fields[fieldIndex], fieldIndex, collectUserVaryingFieldTF(ref, input->fields[fieldIndex], fieldIndex,
GL_INVALID_INDEX); GL_INVALID_INDEX);
} }
} }
uniqueFullNames[ref.frontShaderStage].insert(input->structName); (*uniqueFullNames)[ref.frontShaderStage].insert(input->structName);
} }
else else
{ {
packUserVaryingFieldTF(ref, *field, fieldIndex, GL_INVALID_INDEX); collectUserVaryingFieldTF(ref, *field, fieldIndex, GL_INVALID_INDEX);
} }
uniqueFullNames[ref.frontShaderStage].insert(tfVarying); (*uniqueFullNames)[ref.frontShaderStage].insert(tfVarying);
} }
uniqueFullNames[ref.frontShaderStage].insert(input->name); (*uniqueFullNames)[ref.frontShaderStage].insert(input->name);
} }
// Array as a whole and array element conflict has already been checked in // Array as a whole and array element conflict has already been checked in
// linkValidateTransformFeedback. // linkValidateTransformFeedback.
else if (baseName == input->name) else if (baseName == input->name)
{ {
size_t subscript = GL_INVALID_INDEX;
if (!subscripts.empty())
{
subscript = subscripts.back();
}
// only pack varyings that are not builtins. // only pack varyings that are not builtins.
if (tfVarying.compare(0, 3, "gl_") != 0) if (tfVarying.compare(0, 3, "gl_") != 0)
{ {
packUserVaryingTF(ref, subscript); collectUserVaryingTF(ref, subscript);
uniqueFullNames[ref.frontShaderStage].insert(tfVarying); (*uniqueFullNames)[ref.frontShaderStage].insert(tfVarying);
}
} }
// Continue to match next array element for 'input' if the current match is array }
// element.
if (subscript == GL_INVALID_INDEX) bool VaryingPacking::collectAndPackUserVaryings(gl::InfoLog &infoLog,
const ProgramMergedVaryings &mergedVaryings,
const std::vector<std::string> &tfVaryings,
const bool isSeparableProgram)
{
VaryingUniqueFullNames uniqueFullNames;
reset();
for (const ProgramVaryingRef &ref : mergedVaryings)
{ {
break; const sh::ShaderVariable *input = ref.frontShader;
const sh::ShaderVariable *output = ref.backShader;
const bool isActiveBuiltInInput = input && input->isBuiltIn() && input->active;
const bool isActiveBuiltInOutput = output && output->isBuiltIn() && output->active;
// Keep track of output builtins that are used by the shader, such as gl_Position,
// gl_PointSize etc.
if (isActiveBuiltInInput)
{
mActiveOutputBuiltIns[ref.frontShaderStage].push_back(input->name);
} }
// Only pack statically used varyings that have a matched input or output, plus special
// builtins. Note that we pack all statically used user-defined varyings even if they are
// not active. GLES specs are a bit vague on whether it's allowed to only pack active
// varyings, though GLES 3.1 spec section 11.1.2.1 says that "device-dependent
// optimizations" may be used to make vertex shader outputs fit.
if ((input && output && output->staticUse) || isActiveBuiltInInput ||
isActiveBuiltInOutput ||
(isSeparableProgram && ((input && input->active) || (output && output->active))))
{
const sh::ShaderVariable *varying = output ? output : input;
// Don't count gl_Position. Also don't count gl_PointSize for D3D9.
if (varying->name != "gl_Position" &&
!(varying->name == "gl_PointSize" &&
mPackMode == PackMode::ANGLE_NON_CONFORMANT_D3D9))
{
collectVarying(*varying, ref, &uniqueFullNames);
continue;
} }
} }
// If the varying is not used in the input, we know it is inactive, unless it's a separable
// program, in which case the input shader may not exist in this program.
if (!input && !isSeparableProgram)
{
if (!output->isBuiltIn())
{
mInactiveVaryingMappedNames[ref.backShaderStage].push_back(output->mappedName);
}
continue;
}
// Keep Transform FB varyings in the merged list always.
for (const std::string &tfVarying : tfVaryings)
{
collectTFVarying(tfVarying, ref, &uniqueFullNames);
}
if (input && !input->isBuiltIn() && if (input && !input->isBuiltIn() &&
uniqueFullNames[ref.frontShaderStage].count(input->name) == 0) uniqueFullNames[ref.frontShaderStage].count(input->name) == 0)
{ {
...@@ -774,7 +787,7 @@ bool VaryingPacking::packUserVaryings(gl::InfoLog &infoLog, ...@@ -774,7 +787,7 @@ bool VaryingPacking::packUserVaryings(gl::InfoLog &infoLog,
// subrectangle. No splitting of variables is permitted." // subrectangle. No splitting of variables is permitted."
for (const PackedVarying &packedVarying : packedVaryings) for (const PackedVarying &packedVarying : packedVaryings)
{ {
if (!packVarying(packedVarying)) if (!packVaryingIntoRegisterMap(packedVarying))
{ {
ShaderType eitherStage = packedVarying.frontVarying.varying ShaderType eitherStage = packedVarying.frontVarying.varying
? packedVarying.frontVarying.stage ? packedVarying.frontVarying.stage
......
...@@ -207,8 +207,6 @@ class VaryingPacking final : angle::NonCopyable ...@@ -207,8 +207,6 @@ class VaryingPacking final : angle::NonCopyable
void init(GLuint maxVaryingVectors, PackMode packMode); void init(GLuint maxVaryingVectors, PackMode packMode);
bool packUserVaryings(gl::InfoLog &infoLog, const std::vector<PackedVarying> &packedVaryings);
bool collectAndPackUserVaryings(gl::InfoLog &infoLog, bool collectAndPackUserVaryings(gl::InfoLog &infoLog,
const ProgramMergedVaryings &mergedVaryings, const ProgramMergedVaryings &mergedVaryings,
const std::vector<std::string> &tfVaryings, const std::vector<std::string> &tfVaryings,
...@@ -246,29 +244,38 @@ class VaryingPacking final : angle::NonCopyable ...@@ -246,29 +244,38 @@ class VaryingPacking final : angle::NonCopyable
void reset(); void reset();
private: private:
bool packVarying(const PackedVarying &packedVarying); using VaryingUniqueFullNames = ShaderMap<std::set<std::string>>;
bool isFree(unsigned int registerRow,
// Register map functions.
bool packUserVaryings(gl::InfoLog &infoLog, const std::vector<PackedVarying> &packedVaryings);
bool packVaryingIntoRegisterMap(const PackedVarying &packedVarying);
bool isRegisterRangeFree(unsigned int registerRow,
unsigned int registerColumn, unsigned int registerColumn,
unsigned int varyingRows, unsigned int varyingRows,
unsigned int varyingColumns) const; unsigned int varyingColumns) const;
void insert(unsigned int registerRow, void insertVaryingIntoRegisterMap(unsigned int registerRow,
unsigned int registerColumn, unsigned int registerColumn,
const PackedVarying &packedVarying); const PackedVarying &packedVarying);
void clearRegisterMap();
using VaryingUniqueFullNames = ShaderMap<std::set<std::string>>; // Collection functions.
void packUserVarying(const ProgramVaryingRef &ref, VaryingUniqueFullNames *uniqueFullNames); void collectUserVarying(const ProgramVaryingRef &ref, VaryingUniqueFullNames *uniqueFullNames);
void packUserVaryingField(const ProgramVaryingRef &ref, void collectUserVaryingField(const ProgramVaryingRef &ref,
GLuint arrayIndex, GLuint arrayIndex,
GLuint fieldIndex, GLuint fieldIndex,
GLuint secondaryFieldIndex, GLuint secondaryFieldIndex,
VaryingUniqueFullNames *uniqueFullNames); VaryingUniqueFullNames *uniqueFullNames);
void packUserVaryingTF(const ProgramVaryingRef &ref, size_t subscript); void collectUserVaryingTF(const ProgramVaryingRef &ref, size_t subscript);
void packUserVaryingFieldTF(const ProgramVaryingRef &ref, void collectUserVaryingFieldTF(const ProgramVaryingRef &ref,
const sh::ShaderVariable &field, const sh::ShaderVariable &field,
GLuint fieldIndex, GLuint fieldIndex,
GLuint secondaryFieldIndex); GLuint secondaryFieldIndex);
void collectVarying(const sh::ShaderVariable &varying,
void clearRegisterMap(); const ProgramVaryingRef &ref,
VaryingUniqueFullNames *uniqueFullNames);
void collectTFVarying(const std::string &tfVarying,
const ProgramVaryingRef &ref,
VaryingUniqueFullNames *uniqueFullNames);
std::vector<Register> mRegisterMap; std::vector<Register> mRegisterMap;
std::vector<PackedVaryingRegister> mRegisterList; std::vector<PackedVaryingRegister> mRegisterList;
......
...@@ -29,18 +29,22 @@ class VaryingPackingTest : public ::testing::TestWithParam<GLuint> ...@@ -29,18 +29,22 @@ class VaryingPackingTest : public ::testing::TestWithParam<GLuint>
bool testVaryingPacking(const std::vector<sh::ShaderVariable> &shVaryings, bool testVaryingPacking(const std::vector<sh::ShaderVariable> &shVaryings,
VaryingPacking *varyingPacking) VaryingPacking *varyingPacking)
{ {
std::vector<PackedVarying> packedVaryings; ProgramMergedVaryings mergedVaryings;
for (const sh::ShaderVariable &shVarying : shVaryings) for (const sh::ShaderVariable &shVarying : shVaryings)
{ {
packedVaryings.push_back(PackedVarying( ProgramVaryingRef ref;
VaryingInShaderRef(ShaderType::Vertex, &shVarying), ref.frontShader = &shVarying;
VaryingInShaderRef(ShaderType::Fragment, &shVarying), shVarying.interpolation)); ref.backShader = &shVarying;
ref.frontShaderStage = ShaderType::Vertex;
ref.backShaderStage = ShaderType::Fragment;
mergedVaryings.push_back(ref);
} }
InfoLog infoLog; InfoLog infoLog;
std::vector<std::string> transformFeedbackVaryings; std::vector<std::string> transformFeedbackVaryings;
return varyingPacking->packUserVaryings(infoLog, packedVaryings); return varyingPacking->collectAndPackUserVaryings(infoLog, mergedVaryings,
transformFeedbackVaryings, false);
} }
// Uses the "relaxed" ANGLE packing mode. // Uses the "relaxed" ANGLE packing mode.
......
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