xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/renderer_utils.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2016 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // renderer_utils:
7 //   Helper methods pertaining to most or all back-ends.
8 //
9 
10 #ifndef LIBANGLE_RENDERER_RENDERER_UTILS_H_
11 #define LIBANGLE_RENDERER_RENDERER_UTILS_H_
12 
13 #include <cstdint>
14 
15 #include <limits>
16 #include <map>
17 
18 #include "GLSLANG/ShaderLang.h"
19 #include "common/angleutils.h"
20 #include "common/utilities.h"
21 #include "libANGLE/ImageIndex.h"
22 #include "libANGLE/angletypes.h"
23 
24 namespace angle
25 {
26 struct FeatureSetBase;
27 struct Format;
28 struct ImageLoadContext;
29 enum class FormatID;
30 }  // namespace angle
31 
32 namespace gl
33 {
34 struct FormatType;
35 struct InternalFormat;
36 class ProgramExecutable;
37 class State;
38 }  // namespace gl
39 
40 namespace egl
41 {
42 class AttributeMap;
43 struct DisplayState;
44 }  // namespace egl
45 
46 namespace sh
47 {
48 struct BlockMemberInfo;
49 }
50 
51 namespace rx
52 {
53 class ContextImpl;
54 
55 // The possible rotations of the surface/draw framebuffer, particularly for the Vulkan back-end on
56 // Android.
57 enum class SurfaceRotation
58 {
59     Identity,
60     Rotated90Degrees,
61     Rotated180Degrees,
62     Rotated270Degrees,
63     FlippedIdentity,
64     FlippedRotated90Degrees,
65     FlippedRotated180Degrees,
66     FlippedRotated270Degrees,
67 
68     InvalidEnum,
69     EnumCount = InvalidEnum,
70 };
71 
72 bool IsRotatedAspectRatio(SurfaceRotation rotation);
73 
74 using SpecConstUsageBits = angle::PackedEnumBitSet<sh::vk::SpecConstUsage, uint32_t>;
75 
76 void RotateRectangle(const SurfaceRotation rotation,
77                      const bool flipY,
78                      const int framebufferWidth,
79                      const int framebufferHeight,
80                      const gl::Rectangle &incoming,
81                      gl::Rectangle *outgoing);
82 
83 using MipGenerationFunction = void (*)(size_t sourceWidth,
84                                        size_t sourceHeight,
85                                        size_t sourceDepth,
86                                        const uint8_t *sourceData,
87                                        size_t sourceRowPitch,
88                                        size_t sourceDepthPitch,
89                                        uint8_t *destData,
90                                        size_t destRowPitch,
91                                        size_t destDepthPitch);
92 
93 typedef void (*PixelReadFunction)(const uint8_t *source, uint8_t *dest);
94 typedef void (*PixelWriteFunction)(const uint8_t *source, uint8_t *dest);
95 typedef void (*FastCopyFunction)(const uint8_t *source,
96                                  int srcXAxisPitch,
97                                  int srcYAxisPitch,
98                                  uint8_t *dest,
99                                  int destXAxisPitch,
100                                  int destYAxisPitch,
101                                  int width,
102                                  int height);
103 
104 class FastCopyFunctionMap
105 {
106   public:
107     struct Entry
108     {
109         angle::FormatID formatID;
110         FastCopyFunction func;
111     };
112 
FastCopyFunctionMap()113     constexpr FastCopyFunctionMap() : FastCopyFunctionMap(nullptr, 0) {}
114 
FastCopyFunctionMap(const Entry * data,size_t size)115     constexpr FastCopyFunctionMap(const Entry *data, size_t size) : mSize(size), mData(data) {}
116 
117     bool has(angle::FormatID formatID) const;
118     FastCopyFunction get(angle::FormatID formatID) const;
119 
120   private:
121     size_t mSize;
122     const Entry *mData;
123 };
124 
125 struct PackPixelsParams
126 {
127     PackPixelsParams();
128     PackPixelsParams(const gl::Rectangle &area,
129                      const angle::Format &destFormat,
130                      GLuint outputPitch,
131                      bool reverseRowOrderIn,
132                      gl::Buffer *packBufferIn,
133                      ptrdiff_t offset);
134 
135     gl::Rectangle area;
136     const angle::Format *destFormat;
137     GLuint outputPitch;
138     gl::Buffer *packBuffer;
139     bool reverseRowOrder;
140     ptrdiff_t offset;
141     SurfaceRotation rotation;
142 };
143 
144 void PackPixels(const PackPixelsParams &params,
145                 const angle::Format &sourceFormat,
146                 int inputPitch,
147                 const uint8_t *source,
148                 uint8_t *destination);
149 
150 angle::Result GetPackPixelsParams(const gl::InternalFormat &sizedFormatInfo,
151                                   GLuint outputPitch,
152                                   const gl::PixelPackState &packState,
153                                   gl::Buffer *packBuffer,
154                                   const gl::Rectangle &area,
155                                   const gl::Rectangle &clippedArea,
156                                   rx::PackPixelsParams *paramsOut,
157                                   GLuint *skipBytesOut);
158 
159 using InitializeTextureDataFunction = void (*)(size_t width,
160                                                size_t height,
161                                                size_t depth,
162                                                uint8_t *output,
163                                                size_t outputRowPitch,
164                                                size_t outputDepthPitch);
165 
166 using LoadImageFunction = void (*)(const angle::ImageLoadContext &context,
167                                    size_t width,
168                                    size_t height,
169                                    size_t depth,
170                                    const uint8_t *input,
171                                    size_t inputRowPitch,
172                                    size_t inputDepthPitch,
173                                    uint8_t *output,
174                                    size_t outputRowPitch,
175                                    size_t outputDepthPitch);
176 
177 struct LoadImageFunctionInfo
178 {
LoadImageFunctionInfoLoadImageFunctionInfo179     LoadImageFunctionInfo() : loadFunction(nullptr), requiresConversion(false) {}
LoadImageFunctionInfoLoadImageFunctionInfo180     LoadImageFunctionInfo(LoadImageFunction loadFunction, bool requiresConversion)
181         : loadFunction(loadFunction), requiresConversion(requiresConversion)
182     {}
183 
184     LoadImageFunction loadFunction;
185     bool requiresConversion;
186 };
187 
188 using LoadFunctionMap = LoadImageFunctionInfo (*)(GLenum);
189 
190 bool ShouldUseDebugLayers(const egl::AttributeMap &attribs);
191 
192 void CopyImageCHROMIUM(const uint8_t *sourceData,
193                        size_t sourceRowPitch,
194                        size_t sourcePixelBytes,
195                        size_t sourceDepthPitch,
196                        PixelReadFunction pixelReadFunction,
197                        uint8_t *destData,
198                        size_t destRowPitch,
199                        size_t destPixelBytes,
200                        size_t destDepthPitch,
201                        PixelWriteFunction pixelWriteFunction,
202                        GLenum destUnsizedFormat,
203                        GLenum destComponentType,
204                        size_t width,
205                        size_t height,
206                        size_t depth,
207                        bool unpackFlipY,
208                        bool unpackPremultiplyAlpha,
209                        bool unpackUnmultiplyAlpha);
210 
211 // Incomplete textures are 1x1 textures filled with black, used when samplers are incomplete.
212 // This helper class encapsulates handling incomplete textures. Because the GL back-end
213 // can take advantage of the driver's incomplete textures, and because clearing multisample
214 // textures is so difficult, we can keep an instance of this class in the back-end instead
215 // of moving the logic to the Context front-end.
216 
217 // This interface allows us to call-back to init a multisample texture.
218 class MultisampleTextureInitializer
219 {
220   public:
~MultisampleTextureInitializer()221     virtual ~MultisampleTextureInitializer() {}
222     virtual angle::Result initializeMultisampleTextureToBlack(const gl::Context *context,
223                                                               gl::Texture *glTexture) = 0;
224 };
225 
226 class IncompleteTextureSet final : angle::NonCopyable
227 {
228   public:
229     IncompleteTextureSet();
230     ~IncompleteTextureSet();
231 
232     void onDestroy(const gl::Context *context);
233 
234     angle::Result getIncompleteTexture(const gl::Context *context,
235                                        gl::TextureType type,
236                                        gl::SamplerFormat format,
237                                        MultisampleTextureInitializer *multisampleInitializer,
238                                        gl::Texture **textureOut);
239 
240   private:
241     using TextureMapWithSamplerFormat = angle::PackedEnumMap<gl::SamplerFormat, gl::TextureMap>;
242 
243     TextureMapWithSamplerFormat mIncompleteTextures;
244 };
245 
246 // Helpers to set a matrix uniform value based on GLSL or HLSL semantics.
247 // The return value indicate if the data was updated or not.
248 template <int cols, int rows>
249 struct SetFloatUniformMatrixGLSL
250 {
251     static void Run(unsigned int arrayElementOffset,
252                     unsigned int elementCount,
253                     GLsizei countIn,
254                     GLboolean transpose,
255                     const GLfloat *value,
256                     uint8_t *targetData);
257 };
258 
259 template <int cols, int rows>
260 struct SetFloatUniformMatrixHLSL
261 {
262     static void Run(unsigned int arrayElementOffset,
263                     unsigned int elementCount,
264                     GLsizei countIn,
265                     GLboolean transpose,
266                     const GLfloat *value,
267                     uint8_t *targetData);
268 };
269 
270 // Helper method to de-tranpose a matrix uniform for an API query.
271 void GetMatrixUniform(GLenum type, GLfloat *dataOut, const GLfloat *source, bool transpose);
272 
273 template <typename NonFloatT>
274 void GetMatrixUniform(GLenum type, NonFloatT *dataOut, const NonFloatT *source, bool transpose);
275 
276 // Contains a CPU-side buffer and its data layout, used as a shadow buffer for default uniform
277 // blocks in VK and WGPU backends.
278 struct BufferAndLayout final : private angle::NonCopyable
279 {
280     BufferAndLayout();
281     ~BufferAndLayout();
282 
283     // Shadow copies of the shader uniform data.
284     angle::MemoryBuffer uniformData;
285 
286     // Tells us where to write on a call to a setUniform method. They are arranged in uniform
287     // location order.
288     std::vector<sh::BlockMemberInfo> uniformLayout;
289 };
290 
291 template <typename T>
292 void UpdateBufferWithLayout(GLsizei count,
293                             uint32_t arrayIndex,
294                             int componentCount,
295                             const T *v,
296                             const sh::BlockMemberInfo &layoutInfo,
297                             angle::MemoryBuffer *uniformData);
298 
299 template <typename T>
300 void ReadFromBufferWithLayout(int componentCount,
301                               uint32_t arrayIndex,
302                               T *dst,
303                               const sh::BlockMemberInfo &layoutInfo,
304                               const angle::MemoryBuffer *uniformData);
305 
306 using DefaultUniformBlockMap = gl::ShaderMap<std::shared_ptr<BufferAndLayout>>;
307 
308 template <typename T>
309 void SetUniform(const gl::ProgramExecutable *executable,
310                 GLint location,
311                 GLsizei count,
312                 const T *v,
313                 GLenum entryPointType,
314                 DefaultUniformBlockMap *defaultUniformBlocks,
315                 gl::ShaderBitSet *defaultUniformBlocksDirty);
316 
317 template <int cols, int rows>
318 void SetUniformMatrixfv(const gl::ProgramExecutable *executable,
319                         GLint location,
320                         GLsizei count,
321                         GLboolean transpose,
322                         const GLfloat *value,
323                         DefaultUniformBlockMap *defaultUniformBlocks,
324                         gl::ShaderBitSet *defaultUniformBlocksDirty);
325 
326 template <typename T>
327 void GetUniform(const gl::ProgramExecutable *executable,
328                 GLint location,
329                 T *v,
330                 GLenum entryPointType,
331                 const DefaultUniformBlockMap *defaultUniformBlocks);
332 
333 const angle::Format &GetFormatFromFormatType(GLenum format, GLenum type);
334 
335 angle::Result ComputeStartVertex(ContextImpl *contextImpl,
336                                  const gl::IndexRange &indexRange,
337                                  GLint baseVertex,
338                                  GLint *firstVertexOut);
339 
340 angle::Result GetVertexRangeInfo(const gl::Context *context,
341                                  GLint firstVertex,
342                                  GLsizei vertexOrIndexCount,
343                                  gl::DrawElementsType indexTypeOrInvalid,
344                                  const void *indices,
345                                  GLint baseVertex,
346                                  GLint *startVertexOut,
347                                  size_t *vertexCountOut);
348 
349 gl::Rectangle ClipRectToScissor(const gl::State &glState, const gl::Rectangle &rect, bool invertY);
350 
351 // Helper method to intialize a FeatureSet with overrides from the DisplayState
352 void ApplyFeatureOverrides(angle::FeatureSetBase *features,
353                            const angle::FeatureOverrides &overrides);
354 
355 template <typename In>
LineLoopRestartIndexCountHelper(GLsizei indexCount,const uint8_t * srcPtr)356 uint32_t LineLoopRestartIndexCountHelper(GLsizei indexCount, const uint8_t *srcPtr)
357 {
358     constexpr In restartIndex = gl::GetPrimitiveRestartIndexFromType<In>();
359     const In *inIndices       = reinterpret_cast<const In *>(srcPtr);
360     uint32_t numIndices       = 0;
361     // See CopyLineLoopIndicesWithRestart() below for more info on how
362     // numIndices is calculated.
363     GLsizei loopStartIndex = 0;
364     for (GLsizei curIndex = 0; curIndex < indexCount; curIndex++)
365     {
366         In vertex = inIndices[curIndex];
367         if (vertex != restartIndex)
368         {
369             numIndices++;
370         }
371         else
372         {
373             if (curIndex > loopStartIndex)
374             {
375                 numIndices += 2;
376             }
377             loopStartIndex = curIndex + 1;
378         }
379     }
380     if (indexCount > loopStartIndex)
381     {
382         numIndices++;
383     }
384     return numIndices;
385 }
386 
GetLineLoopWithRestartIndexCount(gl::DrawElementsType glIndexType,GLsizei indexCount,const uint8_t * srcPtr)387 inline uint32_t GetLineLoopWithRestartIndexCount(gl::DrawElementsType glIndexType,
388                                                  GLsizei indexCount,
389                                                  const uint8_t *srcPtr)
390 {
391     switch (glIndexType)
392     {
393         case gl::DrawElementsType::UnsignedByte:
394             return LineLoopRestartIndexCountHelper<uint8_t>(indexCount, srcPtr);
395         case gl::DrawElementsType::UnsignedShort:
396             return LineLoopRestartIndexCountHelper<uint16_t>(indexCount, srcPtr);
397         case gl::DrawElementsType::UnsignedInt:
398             return LineLoopRestartIndexCountHelper<uint32_t>(indexCount, srcPtr);
399         default:
400             UNREACHABLE();
401             return 0;
402     }
403 }
404 
405 // Writes the line-strip vertices for a line loop to outPtr,
406 // where outLimit is calculated as in GetPrimitiveRestartIndexCount.
407 template <typename In, typename Out>
CopyLineLoopIndicesWithRestart(GLsizei indexCount,const uint8_t * srcPtr,uint8_t * outPtr)408 void CopyLineLoopIndicesWithRestart(GLsizei indexCount, const uint8_t *srcPtr, uint8_t *outPtr)
409 {
410     constexpr In restartIndex     = gl::GetPrimitiveRestartIndexFromType<In>();
411     constexpr Out outRestartIndex = gl::GetPrimitiveRestartIndexFromType<Out>();
412     const In *inIndices           = reinterpret_cast<const In *>(srcPtr);
413     Out *outIndices               = reinterpret_cast<Out *>(outPtr);
414     GLsizei loopStartIndex        = 0;
415     for (GLsizei curIndex = 0; curIndex < indexCount; curIndex++)
416     {
417         In vertex = inIndices[curIndex];
418         if (vertex != restartIndex)
419         {
420             *(outIndices++) = static_cast<Out>(vertex);
421         }
422         else
423         {
424             if (curIndex > loopStartIndex)
425             {
426                 // Emit an extra vertex only if the loop is not empty.
427                 *(outIndices++) = inIndices[loopStartIndex];
428                 // Then restart the strip.
429                 *(outIndices++) = outRestartIndex;
430             }
431             loopStartIndex = curIndex + 1;
432         }
433     }
434     if (indexCount > loopStartIndex)
435     {
436         // Close the last loop if not empty.
437         *(outIndices++) = inIndices[loopStartIndex];
438     }
439 }
440 
441 void GetSamplePosition(GLsizei sampleCount, size_t index, GLfloat *xy);
442 
443 angle::Result MultiDrawArraysGeneral(ContextImpl *contextImpl,
444                                      const gl::Context *context,
445                                      gl::PrimitiveMode mode,
446                                      const GLint *firsts,
447                                      const GLsizei *counts,
448                                      GLsizei drawcount);
449 angle::Result MultiDrawArraysIndirectGeneral(ContextImpl *contextImpl,
450                                              const gl::Context *context,
451                                              gl::PrimitiveMode mode,
452                                              const void *indirect,
453                                              GLsizei drawcount,
454                                              GLsizei stride);
455 angle::Result MultiDrawArraysInstancedGeneral(ContextImpl *contextImpl,
456                                               const gl::Context *context,
457                                               gl::PrimitiveMode mode,
458                                               const GLint *firsts,
459                                               const GLsizei *counts,
460                                               const GLsizei *instanceCounts,
461                                               GLsizei drawcount);
462 angle::Result MultiDrawElementsGeneral(ContextImpl *contextImpl,
463                                        const gl::Context *context,
464                                        gl::PrimitiveMode mode,
465                                        const GLsizei *counts,
466                                        gl::DrawElementsType type,
467                                        const GLvoid *const *indices,
468                                        GLsizei drawcount);
469 angle::Result MultiDrawElementsIndirectGeneral(ContextImpl *contextImpl,
470                                                const gl::Context *context,
471                                                gl::PrimitiveMode mode,
472                                                gl::DrawElementsType type,
473                                                const void *indirect,
474                                                GLsizei drawcount,
475                                                GLsizei stride);
476 angle::Result MultiDrawElementsInstancedGeneral(ContextImpl *contextImpl,
477                                                 const gl::Context *context,
478                                                 gl::PrimitiveMode mode,
479                                                 const GLsizei *counts,
480                                                 gl::DrawElementsType type,
481                                                 const GLvoid *const *indices,
482                                                 const GLsizei *instanceCounts,
483                                                 GLsizei drawcount);
484 angle::Result MultiDrawArraysInstancedBaseInstanceGeneral(ContextImpl *contextImpl,
485                                                           const gl::Context *context,
486                                                           gl::PrimitiveMode mode,
487                                                           const GLint *firsts,
488                                                           const GLsizei *counts,
489                                                           const GLsizei *instanceCounts,
490                                                           const GLuint *baseInstances,
491                                                           GLsizei drawcount);
492 angle::Result MultiDrawElementsInstancedBaseVertexBaseInstanceGeneral(ContextImpl *contextImpl,
493                                                                       const gl::Context *context,
494                                                                       gl::PrimitiveMode mode,
495                                                                       const GLsizei *counts,
496                                                                       gl::DrawElementsType type,
497                                                                       const GLvoid *const *indices,
498                                                                       const GLsizei *instanceCounts,
499                                                                       const GLint *baseVertices,
500                                                                       const GLuint *baseInstances,
501                                                                       GLsizei drawcount);
502 
503 // RAII object making sure reset uniforms is called no matter whether there's an error in draw calls
504 class ResetBaseVertexBaseInstance : angle::NonCopyable
505 {
506   public:
507     ResetBaseVertexBaseInstance(gl::ProgramExecutable *executable,
508                                 bool resetBaseVertex,
509                                 bool resetBaseInstance);
510 
511     ~ResetBaseVertexBaseInstance();
512 
513   private:
514     gl::ProgramExecutable *mExecutable;
515     bool mResetBaseVertex;
516     bool mResetBaseInstance;
517 };
518 
519 angle::FormatID ConvertToSRGB(angle::FormatID formatID);
520 angle::FormatID ConvertToLinear(angle::FormatID formatID);
521 bool IsOverridableLinearFormat(angle::FormatID formatID);
522 
523 template <bool swizzledLuma = true>
524 const gl::ColorGeneric AdjustBorderColor(const angle::ColorGeneric &borderColorGeneric,
525                                          const angle::Format &format,
526                                          bool stencilMode);
527 
528 template <typename LargerInt>
LimitToInt(const LargerInt physicalDeviceValue)529 GLint LimitToInt(const LargerInt physicalDeviceValue)
530 {
531     static_assert(sizeof(LargerInt) >= sizeof(int32_t), "Incorrect usage of LimitToInt");
532     return static_cast<GLint>(
533         std::min(physicalDeviceValue, static_cast<LargerInt>(std::numeric_limits<int32_t>::max())));
534 }
535 
536 bool TextureHasAnyRedefinedLevels(const gl::CubeFaceArray<gl::TexLevelMask> &redefinedLevels);
537 bool IsTextureLevelRedefined(const gl::CubeFaceArray<gl::TexLevelMask> &redefinedLevels,
538                              gl::TextureType textureType,
539                              gl::LevelIndex level);
540 
541 enum class TextureLevelDefinition
542 {
543     Compatible   = 0,
544     Incompatible = 1,
545 
546     InvalidEnum = 2
547 };
548 
549 enum class TextureLevelAllocation
550 {
551     WithinAllocatedImage  = 0,
552     OutsideAllocatedImage = 1,
553 
554     InvalidEnum = 2
555 };
556 // Returns true if the image should be released after the level is redefined, false otherwise.
557 bool TextureRedefineLevel(const TextureLevelAllocation levelAllocation,
558                           const TextureLevelDefinition levelDefinition,
559                           bool immutableFormat,
560                           uint32_t levelCount,
561                           const uint32_t layerIndex,
562                           const gl::ImageIndex &index,
563                           gl::LevelIndex imageFirstAllocatedLevel,
564                           gl::CubeFaceArray<gl::TexLevelMask> *redefinedLevels);
565 
566 void TextureRedefineGenerateMipmapLevels(gl::LevelIndex baseLevel,
567                                          gl::LevelIndex maxLevel,
568                                          gl::LevelIndex firstGeneratedLevel,
569                                          gl::CubeFaceArray<gl::TexLevelMask> *redefinedLevels);
570 
571 enum class ImageMipLevels
572 {
573     EnabledLevels                 = 0,
574     FullMipChainForGenerateMipmap = 1,
575 
576     InvalidEnum = 2,
577 };
578 
579 enum class PipelineType
580 {
581     Graphics = 0,
582     Compute  = 1,
583 
584     InvalidEnum = 2,
585     EnumCount   = 2,
586 };
587 
588 // Return the log of samples.  Assumes |sampleCount| is a power of 2.  The result can be used to
589 // index an array based on sample count.
PackSampleCount(int32_t sampleCount)590 inline size_t PackSampleCount(int32_t sampleCount)
591 {
592     if (sampleCount == 0)
593     {
594         sampleCount = 1;
595     }
596 
597     // We currently only support up to 16xMSAA.
598     ASSERT(1 <= sampleCount && sampleCount <= 16);
599     ASSERT(gl::isPow2(sampleCount));
600     return gl::ScanForward(static_cast<uint32_t>(sampleCount));
601 }
602 
603 }  // namespace rx
604 
605 // MultiDraw macro patterns
606 // These macros are to avoid too much code duplication as we don't want to have if detect for
607 // hasDrawID/BaseVertex/BaseInstance inside for loop in a multiDrawANGLE call Part of these are put
608 // in the header as we want to share with specialized context impl on some platforms for multidraw
609 #define ANGLE_SET_DRAW_ID_UNIFORM_0(drawID) \
610     {}
611 #define ANGLE_SET_DRAW_ID_UNIFORM_1(drawID) executable->setDrawIDUniform(drawID)
612 #define ANGLE_SET_DRAW_ID_UNIFORM(cond) ANGLE_SET_DRAW_ID_UNIFORM_##cond
613 
614 #define ANGLE_SET_BASE_VERTEX_UNIFORM_0(baseVertex) \
615     {}
616 #define ANGLE_SET_BASE_VERTEX_UNIFORM_1(baseVertex) executable->setBaseVertexUniform(baseVertex);
617 #define ANGLE_SET_BASE_VERTEX_UNIFORM(cond) ANGLE_SET_BASE_VERTEX_UNIFORM_##cond
618 
619 #define ANGLE_SET_BASE_INSTANCE_UNIFORM_0(baseInstance) \
620     {}
621 #define ANGLE_SET_BASE_INSTANCE_UNIFORM_1(baseInstance) \
622     executable->setBaseInstanceUniform(baseInstance)
623 #define ANGLE_SET_BASE_INSTANCE_UNIFORM(cond) ANGLE_SET_BASE_INSTANCE_UNIFORM_##cond
624 
625 #define ANGLE_NOOP_DRAW_ context->noopDraw(mode, counts[drawID])
626 #define ANGLE_NOOP_DRAW_INSTANCED \
627     context->noopDrawInstanced(mode, counts[drawID], instanceCounts[drawID])
628 #define ANGLE_NOOP_DRAW(_instanced) ANGLE_NOOP_DRAW##_instanced
629 
630 #define ANGLE_MARK_TRANSFORM_FEEDBACK_USAGE_ \
631     gl::MarkTransformFeedbackBufferUsage(context, counts[drawID], 1)
632 #define ANGLE_MARK_TRANSFORM_FEEDBACK_USAGE_INSTANCED \
633     gl::MarkTransformFeedbackBufferUsage(context, counts[drawID], instanceCounts[drawID])
634 #define ANGLE_MARK_TRANSFORM_FEEDBACK_USAGE(instanced) \
635     ANGLE_MARK_TRANSFORM_FEEDBACK_USAGE##instanced
636 
637 #endif  // LIBANGLE_RENDERER_RENDERER_UTILS_H_
638