xref: /aosp_15_r20/external/angle/src/libANGLE/VaryingPacking.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2015 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker // VaryingPacking:
7*8975f5c5SAndroid Build Coastguard Worker //   Class which describes a mapping from varyings to registers, according
8*8975f5c5SAndroid Build Coastguard Worker //   to the spec, or using custom packing algorithms. We also keep a register
9*8975f5c5SAndroid Build Coastguard Worker //   allocation list for the D3D renderer.
10*8975f5c5SAndroid Build Coastguard Worker //
11*8975f5c5SAndroid Build Coastguard Worker 
12*8975f5c5SAndroid Build Coastguard Worker #ifndef LIBANGLE_VARYINGPACKING_H_
13*8975f5c5SAndroid Build Coastguard Worker #define LIBANGLE_VARYINGPACKING_H_
14*8975f5c5SAndroid Build Coastguard Worker 
15*8975f5c5SAndroid Build Coastguard Worker #include <GLSLANG/ShaderVars.h>
16*8975f5c5SAndroid Build Coastguard Worker 
17*8975f5c5SAndroid Build Coastguard Worker #include "angle_gl.h"
18*8975f5c5SAndroid Build Coastguard Worker #include "common/angleutils.h"
19*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/angletypes.h"
20*8975f5c5SAndroid Build Coastguard Worker 
21*8975f5c5SAndroid Build Coastguard Worker #include <map>
22*8975f5c5SAndroid Build Coastguard Worker 
23*8975f5c5SAndroid Build Coastguard Worker namespace gl
24*8975f5c5SAndroid Build Coastguard Worker {
25*8975f5c5SAndroid Build Coastguard Worker class InfoLog;
26*8975f5c5SAndroid Build Coastguard Worker class ProgramExecutable;
27*8975f5c5SAndroid Build Coastguard Worker struct Caps;
28*8975f5c5SAndroid Build Coastguard Worker struct LinkingVariables;
29*8975f5c5SAndroid Build Coastguard Worker struct ProgramVaryingRef;
30*8975f5c5SAndroid Build Coastguard Worker 
31*8975f5c5SAndroid Build Coastguard Worker using ProgramMergedVaryings = std::vector<ProgramVaryingRef>;
32*8975f5c5SAndroid Build Coastguard Worker 
33*8975f5c5SAndroid Build Coastguard Worker // A varying can have different names between stages if matched by the location layout qualifier.
34*8975f5c5SAndroid Build Coastguard Worker // Additionally, same name varyings could still be of two identical struct types with different
35*8975f5c5SAndroid Build Coastguard Worker // names.  This struct contains information on the varying in one of the two stages.  PackedVarying
36*8975f5c5SAndroid Build Coastguard Worker // will thus contain two copies of this along with common information, such as interpolation or
37*8975f5c5SAndroid Build Coastguard Worker // field index.
38*8975f5c5SAndroid Build Coastguard Worker struct VaryingInShaderRef : angle::NonCopyable
39*8975f5c5SAndroid Build Coastguard Worker {
40*8975f5c5SAndroid Build Coastguard Worker     VaryingInShaderRef(ShaderType stageIn, const sh::ShaderVariable *varyingIn);
41*8975f5c5SAndroid Build Coastguard Worker     VaryingInShaderRef(VaryingInShaderRef &&other);
42*8975f5c5SAndroid Build Coastguard Worker     ~VaryingInShaderRef();
43*8975f5c5SAndroid Build Coastguard Worker 
44*8975f5c5SAndroid Build Coastguard Worker     VaryingInShaderRef &operator=(VaryingInShaderRef &&other);
45*8975f5c5SAndroid Build Coastguard Worker 
46*8975f5c5SAndroid Build Coastguard Worker     const sh::ShaderVariable *varying;
47*8975f5c5SAndroid Build Coastguard Worker 
48*8975f5c5SAndroid Build Coastguard Worker     ShaderType stage;
49*8975f5c5SAndroid Build Coastguard Worker 
50*8975f5c5SAndroid Build Coastguard Worker     // Struct name
51*8975f5c5SAndroid Build Coastguard Worker     std::string parentStructName;
52*8975f5c5SAndroid Build Coastguard Worker };
53*8975f5c5SAndroid Build Coastguard Worker 
54*8975f5c5SAndroid Build Coastguard Worker struct PackedVarying : angle::NonCopyable
55*8975f5c5SAndroid Build Coastguard Worker {
56*8975f5c5SAndroid Build Coastguard Worker     // Throughout this file, the "front" stage refers to the stage that outputs the varying, and the
57*8975f5c5SAndroid Build Coastguard Worker     // "back" stage refers to the stage that takes the varying as input.  Note that this struct
58*8975f5c5SAndroid Build Coastguard Worker     // contains linked varyings, which means both front and back stage varyings are valid, except
59*8975f5c5SAndroid Build Coastguard Worker     // for the following which may have only one valid stage.
60*8975f5c5SAndroid Build Coastguard Worker     //
61*8975f5c5SAndroid Build Coastguard Worker     //  - transform-feedback-captured varyings
62*8975f5c5SAndroid Build Coastguard Worker     //  - builtins
63*8975f5c5SAndroid Build Coastguard Worker     //  - separable program stages,
64*8975f5c5SAndroid Build Coastguard Worker     //
65*8975f5c5SAndroid Build Coastguard Worker     PackedVarying(VaryingInShaderRef &&frontVaryingIn,
66*8975f5c5SAndroid Build Coastguard Worker                   VaryingInShaderRef &&backVaryingIn,
67*8975f5c5SAndroid Build Coastguard Worker                   sh::InterpolationType interpolationIn);
68*8975f5c5SAndroid Build Coastguard Worker     PackedVarying(VaryingInShaderRef &&frontVaryingIn,
69*8975f5c5SAndroid Build Coastguard Worker                   VaryingInShaderRef &&backVaryingIn,
70*8975f5c5SAndroid Build Coastguard Worker                   sh::InterpolationType interpolationIn,
71*8975f5c5SAndroid Build Coastguard Worker                   GLuint arrayIndexIn,
72*8975f5c5SAndroid Build Coastguard Worker                   GLuint fieldIndexIn,
73*8975f5c5SAndroid Build Coastguard Worker                   GLuint secondaryFieldIndexIn);
74*8975f5c5SAndroid Build Coastguard Worker     PackedVarying(PackedVarying &&other);
75*8975f5c5SAndroid Build Coastguard Worker     ~PackedVarying();
76*8975f5c5SAndroid Build Coastguard Worker 
77*8975f5c5SAndroid Build Coastguard Worker     PackedVarying &operator=(PackedVarying &&other);
78*8975f5c5SAndroid Build Coastguard Worker 
isStructFieldPackedVarying79*8975f5c5SAndroid Build Coastguard Worker     bool isStructField() const
80*8975f5c5SAndroid Build Coastguard Worker     {
81*8975f5c5SAndroid Build Coastguard Worker         return frontVarying.varying ? !frontVarying.parentStructName.empty()
82*8975f5c5SAndroid Build Coastguard Worker                                     : !backVarying.parentStructName.empty();
83*8975f5c5SAndroid Build Coastguard Worker     }
84*8975f5c5SAndroid Build Coastguard Worker 
isTransformFeedbackArrayElementPackedVarying85*8975f5c5SAndroid Build Coastguard Worker     bool isTransformFeedbackArrayElement() const
86*8975f5c5SAndroid Build Coastguard Worker     {
87*8975f5c5SAndroid Build Coastguard Worker         return isTransformFeedback && arrayIndex != GL_INVALID_INDEX;
88*8975f5c5SAndroid Build Coastguard Worker     }
89*8975f5c5SAndroid Build Coastguard Worker 
90*8975f5c5SAndroid Build Coastguard Worker     // Return either front or back varying, whichever is available.  Only used when the name of the
91*8975f5c5SAndroid Build Coastguard Worker     // varying is not important, but only the type is interesting.
varyingPackedVarying92*8975f5c5SAndroid Build Coastguard Worker     const sh::ShaderVariable &varying() const
93*8975f5c5SAndroid Build Coastguard Worker     {
94*8975f5c5SAndroid Build Coastguard Worker         return frontVarying.varying ? *frontVarying.varying : *backVarying.varying;
95*8975f5c5SAndroid Build Coastguard Worker     }
96*8975f5c5SAndroid Build Coastguard Worker 
getParentStructNamePackedVarying97*8975f5c5SAndroid Build Coastguard Worker     const std::string &getParentStructName() const
98*8975f5c5SAndroid Build Coastguard Worker     {
99*8975f5c5SAndroid Build Coastguard Worker         ASSERT(isStructField());
100*8975f5c5SAndroid Build Coastguard Worker         return frontVarying.varying ? frontVarying.parentStructName : backVarying.parentStructName;
101*8975f5c5SAndroid Build Coastguard Worker     }
102*8975f5c5SAndroid Build Coastguard Worker 
fullNamePackedVarying103*8975f5c5SAndroid Build Coastguard Worker     std::string fullName(ShaderType stage) const
104*8975f5c5SAndroid Build Coastguard Worker     {
105*8975f5c5SAndroid Build Coastguard Worker         ASSERT(stage == frontVarying.stage || stage == backVarying.stage);
106*8975f5c5SAndroid Build Coastguard Worker         const VaryingInShaderRef &varying =
107*8975f5c5SAndroid Build Coastguard Worker             stage == frontVarying.stage ? frontVarying : backVarying;
108*8975f5c5SAndroid Build Coastguard Worker 
109*8975f5c5SAndroid Build Coastguard Worker         std::stringstream fullNameStr;
110*8975f5c5SAndroid Build Coastguard Worker         if (isStructField())
111*8975f5c5SAndroid Build Coastguard Worker         {
112*8975f5c5SAndroid Build Coastguard Worker             fullNameStr << varying.parentStructName << ".";
113*8975f5c5SAndroid Build Coastguard Worker         }
114*8975f5c5SAndroid Build Coastguard Worker 
115*8975f5c5SAndroid Build Coastguard Worker         fullNameStr << varying.varying->name;
116*8975f5c5SAndroid Build Coastguard Worker         if (arrayIndex != GL_INVALID_INDEX)
117*8975f5c5SAndroid Build Coastguard Worker         {
118*8975f5c5SAndroid Build Coastguard Worker             fullNameStr << "[" << arrayIndex << "]";
119*8975f5c5SAndroid Build Coastguard Worker         }
120*8975f5c5SAndroid Build Coastguard Worker         return fullNameStr.str();
121*8975f5c5SAndroid Build Coastguard Worker     }
122*8975f5c5SAndroid Build Coastguard Worker 
123*8975f5c5SAndroid Build Coastguard Worker     // Transform feedback varyings can be only referenced in the VS.
vertexOnlyPackedVarying124*8975f5c5SAndroid Build Coastguard Worker     bool vertexOnly() const
125*8975f5c5SAndroid Build Coastguard Worker     {
126*8975f5c5SAndroid Build Coastguard Worker         return frontVarying.stage == ShaderType::Vertex && backVarying.varying == nullptr;
127*8975f5c5SAndroid Build Coastguard Worker     }
128*8975f5c5SAndroid Build Coastguard Worker 
129*8975f5c5SAndroid Build Coastguard Worker     // Special handling for GS/TS array inputs.
130*8975f5c5SAndroid Build Coastguard Worker     unsigned int getBasicTypeElementCount() const;
131*8975f5c5SAndroid Build Coastguard Worker 
132*8975f5c5SAndroid Build Coastguard Worker     VaryingInShaderRef frontVarying;
133*8975f5c5SAndroid Build Coastguard Worker     VaryingInShaderRef backVarying;
134*8975f5c5SAndroid Build Coastguard Worker 
135*8975f5c5SAndroid Build Coastguard Worker     // Cached so we can store sh::ShaderVariable to point to varying fields.
136*8975f5c5SAndroid Build Coastguard Worker     sh::InterpolationType interpolation;
137*8975f5c5SAndroid Build Coastguard Worker 
138*8975f5c5SAndroid Build Coastguard Worker     // Used by varyings that are captured with transform feedback, xor arrays of shader I/O blocks,
139*8975f5c5SAndroid Build Coastguard Worker     // distinguished by isTransformFeedback;
140*8975f5c5SAndroid Build Coastguard Worker     GLuint arrayIndex;
141*8975f5c5SAndroid Build Coastguard Worker     bool isTransformFeedback;
142*8975f5c5SAndroid Build Coastguard Worker 
143*8975f5c5SAndroid Build Coastguard Worker     // Field index in the struct.  In Vulkan, this is used to assign a
144*8975f5c5SAndroid Build Coastguard Worker     // struct-typed varying location to the location of its first field.
145*8975f5c5SAndroid Build Coastguard Worker     GLuint fieldIndex;
146*8975f5c5SAndroid Build Coastguard Worker     GLuint secondaryFieldIndex;
147*8975f5c5SAndroid Build Coastguard Worker };
148*8975f5c5SAndroid Build Coastguard Worker 
149*8975f5c5SAndroid Build Coastguard Worker struct PackedVaryingRegister final
150*8975f5c5SAndroid Build Coastguard Worker {
PackedVaryingRegisterfinal151*8975f5c5SAndroid Build Coastguard Worker     PackedVaryingRegister()
152*8975f5c5SAndroid Build Coastguard Worker         : packedVarying(nullptr),
153*8975f5c5SAndroid Build Coastguard Worker           varyingArrayIndex(0),
154*8975f5c5SAndroid Build Coastguard Worker           varyingRowIndex(0),
155*8975f5c5SAndroid Build Coastguard Worker           registerRow(0),
156*8975f5c5SAndroid Build Coastguard Worker           registerColumn(0)
157*8975f5c5SAndroid Build Coastguard Worker     {}
158*8975f5c5SAndroid Build Coastguard Worker 
159*8975f5c5SAndroid Build Coastguard Worker     PackedVaryingRegister(const PackedVaryingRegister &)            = default;
160*8975f5c5SAndroid Build Coastguard Worker     PackedVaryingRegister &operator=(const PackedVaryingRegister &) = default;
161*8975f5c5SAndroid Build Coastguard Worker 
162*8975f5c5SAndroid Build Coastguard Worker     bool operator<(const PackedVaryingRegister &other) const
163*8975f5c5SAndroid Build Coastguard Worker     {
164*8975f5c5SAndroid Build Coastguard Worker         return sortOrder() < other.sortOrder();
165*8975f5c5SAndroid Build Coastguard Worker     }
166*8975f5c5SAndroid Build Coastguard Worker 
sortOrderfinal167*8975f5c5SAndroid Build Coastguard Worker     unsigned int sortOrder() const
168*8975f5c5SAndroid Build Coastguard Worker     {
169*8975f5c5SAndroid Build Coastguard Worker         // TODO(jmadill): Handle interpolation types
170*8975f5c5SAndroid Build Coastguard Worker         return registerRow * 4 + registerColumn;
171*8975f5c5SAndroid Build Coastguard Worker     }
172*8975f5c5SAndroid Build Coastguard Worker 
tfVaryingNamefinal173*8975f5c5SAndroid Build Coastguard Worker     std::string tfVaryingName() const
174*8975f5c5SAndroid Build Coastguard Worker     {
175*8975f5c5SAndroid Build Coastguard Worker         return packedVarying->fullName(packedVarying->frontVarying.stage);
176*8975f5c5SAndroid Build Coastguard Worker     }
177*8975f5c5SAndroid Build Coastguard Worker 
178*8975f5c5SAndroid Build Coastguard Worker     // Index to the array of varyings.
179*8975f5c5SAndroid Build Coastguard Worker     const PackedVarying *packedVarying;
180*8975f5c5SAndroid Build Coastguard Worker 
181*8975f5c5SAndroid Build Coastguard Worker     // The array element of the packed varying.
182*8975f5c5SAndroid Build Coastguard Worker     unsigned int varyingArrayIndex;
183*8975f5c5SAndroid Build Coastguard Worker 
184*8975f5c5SAndroid Build Coastguard Worker     // The row of the array element of the packed varying.
185*8975f5c5SAndroid Build Coastguard Worker     unsigned int varyingRowIndex;
186*8975f5c5SAndroid Build Coastguard Worker 
187*8975f5c5SAndroid Build Coastguard Worker     // The register row to which we've assigned this packed varying.
188*8975f5c5SAndroid Build Coastguard Worker     unsigned int registerRow;
189*8975f5c5SAndroid Build Coastguard Worker 
190*8975f5c5SAndroid Build Coastguard Worker     // The column of the register row into which we've packed this varying.
191*8975f5c5SAndroid Build Coastguard Worker     unsigned int registerColumn;
192*8975f5c5SAndroid Build Coastguard Worker };
193*8975f5c5SAndroid Build Coastguard Worker 
194*8975f5c5SAndroid Build Coastguard Worker // Supported packing modes:
195*8975f5c5SAndroid Build Coastguard Worker enum class PackMode
196*8975f5c5SAndroid Build Coastguard Worker {
197*8975f5c5SAndroid Build Coastguard Worker     // We treat mat2 arrays as taking two full rows.
198*8975f5c5SAndroid Build Coastguard Worker     WEBGL_STRICT,
199*8975f5c5SAndroid Build Coastguard Worker 
200*8975f5c5SAndroid Build Coastguard Worker     // We allow mat2 to take a 2x2 chunk.
201*8975f5c5SAndroid Build Coastguard Worker     ANGLE_RELAXED,
202*8975f5c5SAndroid Build Coastguard Worker 
203*8975f5c5SAndroid Build Coastguard Worker     // Each varying takes a separate register. No register sharing.
204*8975f5c5SAndroid Build Coastguard Worker     ANGLE_NON_CONFORMANT_D3D9,
205*8975f5c5SAndroid Build Coastguard Worker };
206*8975f5c5SAndroid Build Coastguard Worker 
207*8975f5c5SAndroid Build Coastguard Worker enum class PerVertexMember
208*8975f5c5SAndroid Build Coastguard Worker {
209*8975f5c5SAndroid Build Coastguard Worker     // The gl_Pervertex struct is defined as:
210*8975f5c5SAndroid Build Coastguard Worker     //
211*8975f5c5SAndroid Build Coastguard Worker     //     out gl_PerVertex
212*8975f5c5SAndroid Build Coastguard Worker     //     {
213*8975f5c5SAndroid Build Coastguard Worker     //         vec4 gl_Position;
214*8975f5c5SAndroid Build Coastguard Worker     //         float gl_PointSize;
215*8975f5c5SAndroid Build Coastguard Worker     //         float gl_ClipDistance[];
216*8975f5c5SAndroid Build Coastguard Worker     //         float gl_CullDistance[];
217*8975f5c5SAndroid Build Coastguard Worker     //     };
218*8975f5c5SAndroid Build Coastguard Worker     Position,
219*8975f5c5SAndroid Build Coastguard Worker     PointSize,
220*8975f5c5SAndroid Build Coastguard Worker     ClipDistance,
221*8975f5c5SAndroid Build Coastguard Worker     CullDistance,
222*8975f5c5SAndroid Build Coastguard Worker 
223*8975f5c5SAndroid Build Coastguard Worker     EnumCount,
224*8975f5c5SAndroid Build Coastguard Worker     InvalidEnum = EnumCount,
225*8975f5c5SAndroid Build Coastguard Worker };
226*8975f5c5SAndroid Build Coastguard Worker using PerVertexMemberBitSet = angle::PackedEnumBitSet<PerVertexMember, uint8_t>;
227*8975f5c5SAndroid Build Coastguard Worker 
228*8975f5c5SAndroid Build Coastguard Worker class VaryingPacking final : angle::NonCopyable
229*8975f5c5SAndroid Build Coastguard Worker {
230*8975f5c5SAndroid Build Coastguard Worker   public:
231*8975f5c5SAndroid Build Coastguard Worker     VaryingPacking();
232*8975f5c5SAndroid Build Coastguard Worker     ~VaryingPacking();
233*8975f5c5SAndroid Build Coastguard Worker 
234*8975f5c5SAndroid Build Coastguard Worker     [[nodiscard]] bool collectAndPackUserVaryings(InfoLog &infoLog,
235*8975f5c5SAndroid Build Coastguard Worker                                                   GLint maxVaryingVectors,
236*8975f5c5SAndroid Build Coastguard Worker                                                   PackMode packMode,
237*8975f5c5SAndroid Build Coastguard Worker                                                   ShaderType frontShaderStage,
238*8975f5c5SAndroid Build Coastguard Worker                                                   ShaderType backShaderStage,
239*8975f5c5SAndroid Build Coastguard Worker                                                   const ProgramMergedVaryings &mergedVaryings,
240*8975f5c5SAndroid Build Coastguard Worker                                                   const std::vector<std::string> &tfVaryings,
241*8975f5c5SAndroid Build Coastguard Worker                                                   const bool isSeparableProgram);
242*8975f5c5SAndroid Build Coastguard Worker 
243*8975f5c5SAndroid Build Coastguard Worker     struct Register
244*8975f5c5SAndroid Build Coastguard Worker     {
RegisterRegister245*8975f5c5SAndroid Build Coastguard Worker         Register() { data[0] = data[1] = data[2] = data[3] = false; }
246*8975f5c5SAndroid Build Coastguard Worker 
247*8975f5c5SAndroid Build Coastguard Worker         bool &operator[](unsigned int index) { return data[index]; }
248*8975f5c5SAndroid Build Coastguard Worker         bool operator[](unsigned int index) const { return data[index]; }
249*8975f5c5SAndroid Build Coastguard Worker 
250*8975f5c5SAndroid Build Coastguard Worker         bool data[4];
251*8975f5c5SAndroid Build Coastguard Worker     };
252*8975f5c5SAndroid Build Coastguard Worker 
253*8975f5c5SAndroid Build Coastguard Worker     Register &operator[](unsigned int index) { return mRegisterMap[index]; }
254*8975f5c5SAndroid Build Coastguard Worker     const Register &operator[](unsigned int index) const { return mRegisterMap[index]; }
255*8975f5c5SAndroid Build Coastguard Worker 
getRegisterList()256*8975f5c5SAndroid Build Coastguard Worker     const std::vector<PackedVaryingRegister> &getRegisterList() const { return mRegisterList; }
getMaxSemanticIndex()257*8975f5c5SAndroid Build Coastguard Worker     unsigned int getMaxSemanticIndex() const
258*8975f5c5SAndroid Build Coastguard Worker     {
259*8975f5c5SAndroid Build Coastguard Worker         return static_cast<unsigned int>(mRegisterList.size());
260*8975f5c5SAndroid Build Coastguard Worker     }
261*8975f5c5SAndroid Build Coastguard Worker 
getInactiveVaryingIds()262*8975f5c5SAndroid Build Coastguard Worker     const ShaderMap<std::vector<uint32_t>> &getInactiveVaryingIds() const
263*8975f5c5SAndroid Build Coastguard Worker     {
264*8975f5c5SAndroid Build Coastguard Worker         return mInactiveVaryingIds;
265*8975f5c5SAndroid Build Coastguard Worker     }
266*8975f5c5SAndroid Build Coastguard Worker 
getOutputPerVertexActiveMembers()267*8975f5c5SAndroid Build Coastguard Worker     const ShaderMap<PerVertexMemberBitSet> &getOutputPerVertexActiveMembers() const
268*8975f5c5SAndroid Build Coastguard Worker     {
269*8975f5c5SAndroid Build Coastguard Worker         return mOutputPerVertexActiveMembers;
270*8975f5c5SAndroid Build Coastguard Worker     }
271*8975f5c5SAndroid Build Coastguard Worker 
272*8975f5c5SAndroid Build Coastguard Worker     void reset();
273*8975f5c5SAndroid Build Coastguard Worker 
274*8975f5c5SAndroid Build Coastguard Worker   private:
275*8975f5c5SAndroid Build Coastguard Worker     using VaryingUniqueFullNames = ShaderMap<std::set<std::string>>;
276*8975f5c5SAndroid Build Coastguard Worker 
277*8975f5c5SAndroid Build Coastguard Worker     // Register map functions.
278*8975f5c5SAndroid Build Coastguard Worker     bool packUserVaryings(InfoLog &infoLog,
279*8975f5c5SAndroid Build Coastguard Worker                           GLint maxVaryingVectors,
280*8975f5c5SAndroid Build Coastguard Worker                           PackMode packMode,
281*8975f5c5SAndroid Build Coastguard Worker                           const std::vector<PackedVarying> &packedVaryings);
282*8975f5c5SAndroid Build Coastguard Worker     bool packVaryingIntoRegisterMap(PackMode packMode, const PackedVarying &packedVarying);
283*8975f5c5SAndroid Build Coastguard Worker     bool isRegisterRangeFree(unsigned int registerRow,
284*8975f5c5SAndroid Build Coastguard Worker                              unsigned int registerColumn,
285*8975f5c5SAndroid Build Coastguard Worker                              unsigned int varyingRows,
286*8975f5c5SAndroid Build Coastguard Worker                              unsigned int varyingColumns) const;
287*8975f5c5SAndroid Build Coastguard Worker     void insertVaryingIntoRegisterMap(unsigned int registerRow,
288*8975f5c5SAndroid Build Coastguard Worker                                       unsigned int registerColumn,
289*8975f5c5SAndroid Build Coastguard Worker                                       unsigned int varyingColumns,
290*8975f5c5SAndroid Build Coastguard Worker                                       const PackedVarying &packedVarying);
291*8975f5c5SAndroid Build Coastguard Worker     void clearRegisterMap();
292*8975f5c5SAndroid Build Coastguard Worker 
293*8975f5c5SAndroid Build Coastguard Worker     // Collection functions.
294*8975f5c5SAndroid Build Coastguard Worker     void collectUserVarying(const ProgramVaryingRef &ref, VaryingUniqueFullNames *uniqueFullNames);
295*8975f5c5SAndroid Build Coastguard Worker     void collectUserVaryingField(const ProgramVaryingRef &ref,
296*8975f5c5SAndroid Build Coastguard Worker                                  GLuint arrayIndex,
297*8975f5c5SAndroid Build Coastguard Worker                                  GLuint fieldIndex,
298*8975f5c5SAndroid Build Coastguard Worker                                  GLuint secondaryFieldIndex,
299*8975f5c5SAndroid Build Coastguard Worker                                  VaryingUniqueFullNames *uniqueFullNames);
300*8975f5c5SAndroid Build Coastguard Worker     void collectUserVaryingTF(const ProgramVaryingRef &ref, size_t subscript);
301*8975f5c5SAndroid Build Coastguard Worker     void collectUserVaryingFieldTF(const ProgramVaryingRef &ref,
302*8975f5c5SAndroid Build Coastguard Worker                                    const sh::ShaderVariable &field,
303*8975f5c5SAndroid Build Coastguard Worker                                    GLuint fieldIndex,
304*8975f5c5SAndroid Build Coastguard Worker                                    GLuint secondaryFieldIndex);
305*8975f5c5SAndroid Build Coastguard Worker     void collectVarying(const sh::ShaderVariable &varying,
306*8975f5c5SAndroid Build Coastguard Worker                         const ProgramVaryingRef &ref,
307*8975f5c5SAndroid Build Coastguard Worker                         PackMode packMode,
308*8975f5c5SAndroid Build Coastguard Worker                         VaryingUniqueFullNames *uniqueFullNames);
309*8975f5c5SAndroid Build Coastguard Worker     void collectTFVarying(const std::string &tfVarying,
310*8975f5c5SAndroid Build Coastguard Worker                           const ProgramVaryingRef &ref,
311*8975f5c5SAndroid Build Coastguard Worker                           VaryingUniqueFullNames *uniqueFullNames);
312*8975f5c5SAndroid Build Coastguard Worker 
313*8975f5c5SAndroid Build Coastguard Worker     std::vector<Register> mRegisterMap;
314*8975f5c5SAndroid Build Coastguard Worker     std::vector<PackedVaryingRegister> mRegisterList;
315*8975f5c5SAndroid Build Coastguard Worker     std::vector<PackedVarying> mPackedVaryings;
316*8975f5c5SAndroid Build Coastguard Worker     ShaderMap<std::vector<uint32_t>> mInactiveVaryingIds;
317*8975f5c5SAndroid Build Coastguard Worker     ShaderMap<PerVertexMemberBitSet> mOutputPerVertexActiveMembers;
318*8975f5c5SAndroid Build Coastguard Worker };
319*8975f5c5SAndroid Build Coastguard Worker 
320*8975f5c5SAndroid Build Coastguard Worker class ProgramVaryingPacking final : angle::NonCopyable
321*8975f5c5SAndroid Build Coastguard Worker {
322*8975f5c5SAndroid Build Coastguard Worker   public:
323*8975f5c5SAndroid Build Coastguard Worker     ProgramVaryingPacking();
324*8975f5c5SAndroid Build Coastguard Worker     ~ProgramVaryingPacking();
325*8975f5c5SAndroid Build Coastguard Worker 
326*8975f5c5SAndroid Build Coastguard Worker     const VaryingPacking &getInputPacking(ShaderType backShaderStage) const;
327*8975f5c5SAndroid Build Coastguard Worker     const VaryingPacking &getOutputPacking(ShaderType frontShaderStage) const;
328*8975f5c5SAndroid Build Coastguard Worker 
329*8975f5c5SAndroid Build Coastguard Worker     [[nodiscard]] bool collectAndPackUserVaryings(InfoLog &infoLog,
330*8975f5c5SAndroid Build Coastguard Worker                                                   const Caps &caps,
331*8975f5c5SAndroid Build Coastguard Worker                                                   PackMode packMode,
332*8975f5c5SAndroid Build Coastguard Worker                                                   const ShaderBitSet &activeShadersMask,
333*8975f5c5SAndroid Build Coastguard Worker                                                   const ProgramMergedVaryings &mergedVaryings,
334*8975f5c5SAndroid Build Coastguard Worker                                                   const std::vector<std::string> &tfVaryings,
335*8975f5c5SAndroid Build Coastguard Worker                                                   bool isSeparableProgram);
336*8975f5c5SAndroid Build Coastguard Worker 
337*8975f5c5SAndroid Build Coastguard Worker   private:
338*8975f5c5SAndroid Build Coastguard Worker     // Indexed by the front shader.
339*8975f5c5SAndroid Build Coastguard Worker     ShaderMap<VaryingPacking> mVaryingPackings;
340*8975f5c5SAndroid Build Coastguard Worker 
341*8975f5c5SAndroid Build Coastguard Worker     // Looks up the front stage from the back stage.
342*8975f5c5SAndroid Build Coastguard Worker     ShaderMap<ShaderType> mBackToFrontStageMap;
343*8975f5c5SAndroid Build Coastguard Worker };
344*8975f5c5SAndroid Build Coastguard Worker 
345*8975f5c5SAndroid Build Coastguard Worker ProgramMergedVaryings GetMergedVaryingsFromLinkingVariables(
346*8975f5c5SAndroid Build Coastguard Worker     const LinkingVariables &linkingVariables);
347*8975f5c5SAndroid Build Coastguard Worker }  // namespace gl
348*8975f5c5SAndroid Build Coastguard Worker 
349*8975f5c5SAndroid Build Coastguard Worker #endif  // LIBANGLE_VARYINGPACKING_H_
350