• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 : uint8_t;
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(SurfaceRotation rotation,
77                      bool flipY,
78                      int framebufferWidth,
79                      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()  = default;
230     ~IncompleteTextureSet() = default;
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                 if (curIndex > (loopStartIndex + 1))
376                 {
377                     numIndices += 1;
378                 }
379                 numIndices += 1;
380             }
381             loopStartIndex = curIndex + 1;
382         }
383     }
384     if (indexCount > (loopStartIndex + 1))
385     {
386         numIndices++;
387     }
388     return numIndices;
389 }
390 
GetLineLoopWithRestartIndexCount(gl::DrawElementsType glIndexType,GLsizei indexCount,const uint8_t * srcPtr)391 inline uint32_t GetLineLoopWithRestartIndexCount(gl::DrawElementsType glIndexType,
392                                                  GLsizei indexCount,
393                                                  const uint8_t *srcPtr)
394 {
395     switch (glIndexType)
396     {
397         case gl::DrawElementsType::UnsignedByte:
398             return LineLoopRestartIndexCountHelper<uint8_t>(indexCount, srcPtr);
399         case gl::DrawElementsType::UnsignedShort:
400             return LineLoopRestartIndexCountHelper<uint16_t>(indexCount, srcPtr);
401         case gl::DrawElementsType::UnsignedInt:
402             return LineLoopRestartIndexCountHelper<uint32_t>(indexCount, srcPtr);
403         default:
404             UNREACHABLE();
405             return 0;
406     }
407 }
408 
409 // Writes the line-strip vertices for a line loop to outPtr,
410 // where outLimit is calculated as in GetPrimitiveRestartIndexCount.
411 // Returns number of vertices written.
412 template <typename In, typename Out>
CopyLineLoopIndicesWithRestart(GLsizei indexCount,const uint8_t * srcPtr,uint8_t * outPtr)413 size_t CopyLineLoopIndicesWithRestart(GLsizei indexCount, const uint8_t *srcPtr, uint8_t *outPtr)
414 {
415     constexpr In restartIndex     = gl::GetPrimitiveRestartIndexFromType<In>();
416     constexpr Out outRestartIndex = gl::GetPrimitiveRestartIndexFromType<Out>();
417     const In *inIndices           = reinterpret_cast<const In *>(srcPtr);
418     Out *outIndices               = reinterpret_cast<Out *>(outPtr);
419     GLsizei loopStartIndex        = 0;
420     for (GLsizei curIndex = 0; curIndex < indexCount; curIndex++)
421     {
422         In vertex = inIndices[curIndex];
423         if (vertex != restartIndex)
424         {
425             *(outIndices++) = static_cast<Out>(vertex);
426         }
427         else
428         {
429             if (curIndex > loopStartIndex)
430             {
431                 if (curIndex > (loopStartIndex + 1))
432                 {
433                     // Emit an extra vertex only if the loop has more than one vertex.
434                     *(outIndices++) = inIndices[loopStartIndex];
435                 }
436                 // Then restart the strip.
437                 *(outIndices++) = outRestartIndex;
438             }
439             loopStartIndex = curIndex + 1;
440         }
441     }
442     if (indexCount > (loopStartIndex + 1))
443     {
444         // Close the last loop if it has more than one vertex.
445         *(outIndices++) = inIndices[loopStartIndex];
446     }
447     return static_cast<size_t>(outIndices - reinterpret_cast<Out *>(outPtr));
448 }
449 
450 void GetSamplePosition(GLsizei sampleCount, size_t index, GLfloat *xy);
451 
452 angle::Result MultiDrawArraysGeneral(ContextImpl *contextImpl,
453                                      const gl::Context *context,
454                                      gl::PrimitiveMode mode,
455                                      const GLint *firsts,
456                                      const GLsizei *counts,
457                                      GLsizei drawcount);
458 angle::Result MultiDrawArraysIndirectGeneral(ContextImpl *contextImpl,
459                                              const gl::Context *context,
460                                              gl::PrimitiveMode mode,
461                                              const void *indirect,
462                                              GLsizei drawcount,
463                                              GLsizei stride);
464 angle::Result MultiDrawArraysInstancedGeneral(ContextImpl *contextImpl,
465                                               const gl::Context *context,
466                                               gl::PrimitiveMode mode,
467                                               const GLint *firsts,
468                                               const GLsizei *counts,
469                                               const GLsizei *instanceCounts,
470                                               GLsizei drawcount);
471 angle::Result MultiDrawElementsGeneral(ContextImpl *contextImpl,
472                                        const gl::Context *context,
473                                        gl::PrimitiveMode mode,
474                                        const GLsizei *counts,
475                                        gl::DrawElementsType type,
476                                        const GLvoid *const *indices,
477                                        GLsizei drawcount);
478 angle::Result MultiDrawElementsIndirectGeneral(ContextImpl *contextImpl,
479                                                const gl::Context *context,
480                                                gl::PrimitiveMode mode,
481                                                gl::DrawElementsType type,
482                                                const void *indirect,
483                                                GLsizei drawcount,
484                                                GLsizei stride);
485 angle::Result MultiDrawElementsInstancedGeneral(ContextImpl *contextImpl,
486                                                 const gl::Context *context,
487                                                 gl::PrimitiveMode mode,
488                                                 const GLsizei *counts,
489                                                 gl::DrawElementsType type,
490                                                 const GLvoid *const *indices,
491                                                 const GLsizei *instanceCounts,
492                                                 GLsizei drawcount);
493 angle::Result MultiDrawArraysInstancedBaseInstanceGeneral(ContextImpl *contextImpl,
494                                                           const gl::Context *context,
495                                                           gl::PrimitiveMode mode,
496                                                           const GLint *firsts,
497                                                           const GLsizei *counts,
498                                                           const GLsizei *instanceCounts,
499                                                           const GLuint *baseInstances,
500                                                           GLsizei drawcount);
501 angle::Result MultiDrawElementsInstancedBaseVertexBaseInstanceGeneral(ContextImpl *contextImpl,
502                                                                       const gl::Context *context,
503                                                                       gl::PrimitiveMode mode,
504                                                                       const GLsizei *counts,
505                                                                       gl::DrawElementsType type,
506                                                                       const GLvoid *const *indices,
507                                                                       const GLsizei *instanceCounts,
508                                                                       const GLint *baseVertices,
509                                                                       const GLuint *baseInstances,
510                                                                       GLsizei drawcount);
511 
512 // RAII object making sure reset uniforms is called no matter whether there's an error in draw calls
513 class ResetBaseVertexBaseInstance : angle::NonCopyable
514 {
515   public:
516     ResetBaseVertexBaseInstance(gl::ProgramExecutable *executable,
517                                 bool resetBaseVertex,
518                                 bool resetBaseInstance);
519 
520     ~ResetBaseVertexBaseInstance();
521 
522   private:
523     gl::ProgramExecutable *mExecutable;
524     bool mResetBaseVertex;
525     bool mResetBaseInstance;
526 };
527 
528 angle::FormatID ConvertToSRGB(angle::FormatID formatID);
529 angle::FormatID ConvertToLinear(angle::FormatID formatID);
530 bool IsOverridableLinearFormat(angle::FormatID formatID);
531 
532 template <bool swizzledLuma = true>
533 const gl::ColorGeneric AdjustBorderColor(const angle::ColorGeneric &borderColorGeneric,
534                                          const angle::Format &format,
535                                          bool stencilMode);
536 
537 template <typename LargerInt>
LimitToInt(const LargerInt physicalDeviceValue)538 GLint LimitToInt(const LargerInt physicalDeviceValue)
539 {
540     static_assert(sizeof(LargerInt) >= sizeof(int32_t), "Incorrect usage of LimitToInt");
541     return static_cast<GLint>(
542         std::min(physicalDeviceValue, static_cast<LargerInt>(std::numeric_limits<int32_t>::max())));
543 }
544 
545 template <typename LargerInt>
LimitToIntAnd(const LargerInt physicalDeviceValue,const uint64_t cap)546 GLint LimitToIntAnd(const LargerInt physicalDeviceValue, const uint64_t cap)
547 {
548     LargerInt result = LimitToInt(physicalDeviceValue);
549     return static_cast<GLint>(std::min(static_cast<uint64_t>(result), cap));
550 }
551 
552 bool TextureHasAnyRedefinedLevels(const gl::CubeFaceArray<gl::TexLevelMask> &redefinedLevels);
553 bool IsTextureLevelRedefined(const gl::CubeFaceArray<gl::TexLevelMask> &redefinedLevels,
554                              gl::TextureType textureType,
555                              gl::LevelIndex level);
556 
557 enum class TextureLevelDefinition
558 {
559     Compatible   = 0,
560     Incompatible = 1,
561 
562     InvalidEnum = 2
563 };
564 
565 enum class TextureLevelAllocation
566 {
567     WithinAllocatedImage  = 0,
568     OutsideAllocatedImage = 1,
569 
570     InvalidEnum = 2
571 };
572 // Returns true if the image should be released after the level is redefined, false otherwise.
573 bool TextureRedefineLevel(const TextureLevelAllocation levelAllocation,
574                           const TextureLevelDefinition levelDefinition,
575                           bool immutableFormat,
576                           uint32_t levelCount,
577                           const uint32_t layerIndex,
578                           const gl::ImageIndex &index,
579                           gl::LevelIndex imageFirstAllocatedLevel,
580                           gl::CubeFaceArray<gl::TexLevelMask> *redefinedLevels);
581 
582 void TextureRedefineGenerateMipmapLevels(gl::LevelIndex baseLevel,
583                                          gl::LevelIndex maxLevel,
584                                          gl::LevelIndex firstGeneratedLevel,
585                                          gl::CubeFaceArray<gl::TexLevelMask> *redefinedLevels);
586 
587 enum class ImageMipLevels
588 {
589     EnabledLevels                 = 0,
590     FullMipChainForGenerateMipmap = 1,
591 
592     InvalidEnum = 2,
593 };
594 
595 enum class PipelineType
596 {
597     Graphics = 0,
598     Compute  = 1,
599 
600     InvalidEnum = 2,
601     EnumCount   = 2,
602 };
603 
604 // Return the log of samples.  Assumes |sampleCount| is a power of 2.  The result can be used to
605 // index an array based on sample count.
PackSampleCount(int32_t sampleCount)606 inline size_t PackSampleCount(int32_t sampleCount)
607 {
608     if (sampleCount == 0)
609     {
610         sampleCount = 1;
611     }
612 
613     // We currently only support up to 16xMSAA.
614     ASSERT(1 <= sampleCount && sampleCount <= 16);
615     ASSERT(gl::isPow2(sampleCount));
616     return gl::ScanForward(static_cast<uint32_t>(sampleCount));
617 }
618 
619 }  // namespace rx
620 
621 // MultiDraw macro patterns
622 // These macros are to avoid too much code duplication as we don't want to have if detect for
623 // hasDrawID/BaseVertex/BaseInstance inside for loop in a multiDrawANGLE call Part of these are put
624 // in the header as we want to share with specialized context impl on some platforms for multidraw
625 #define ANGLE_SET_DRAW_ID_UNIFORM_0(drawID) \
626     {}
627 #define ANGLE_SET_DRAW_ID_UNIFORM_1(drawID) executable->setDrawIDUniform(drawID)
628 #define ANGLE_SET_DRAW_ID_UNIFORM(cond) ANGLE_SET_DRAW_ID_UNIFORM_##cond
629 
630 #define ANGLE_SET_BASE_VERTEX_UNIFORM_0(baseVertex) \
631     {}
632 #define ANGLE_SET_BASE_VERTEX_UNIFORM_1(baseVertex) executable->setBaseVertexUniform(baseVertex);
633 #define ANGLE_SET_BASE_VERTEX_UNIFORM(cond) ANGLE_SET_BASE_VERTEX_UNIFORM_##cond
634 
635 #define ANGLE_SET_BASE_INSTANCE_UNIFORM_0(baseInstance) \
636     {}
637 #define ANGLE_SET_BASE_INSTANCE_UNIFORM_1(baseInstance) \
638     executable->setBaseInstanceUniform(baseInstance)
639 #define ANGLE_SET_BASE_INSTANCE_UNIFORM(cond) ANGLE_SET_BASE_INSTANCE_UNIFORM_##cond
640 
641 #define ANGLE_NOOP_DRAW_ context->noopDraw(mode, counts[drawID])
642 #define ANGLE_NOOP_DRAW_INSTANCED \
643     context->noopDrawInstanced(mode, counts[drawID], instanceCounts[drawID])
644 #define ANGLE_NOOP_DRAW(_instanced) ANGLE_NOOP_DRAW##_instanced
645 
646 #define ANGLE_MARK_TRANSFORM_FEEDBACK_USAGE_ \
647     gl::MarkTransformFeedbackBufferUsage(context, counts[drawID], 1)
648 #define ANGLE_MARK_TRANSFORM_FEEDBACK_USAGE_INSTANCED \
649     gl::MarkTransformFeedbackBufferUsage(context, counts[drawID], instanceCounts[drawID])
650 #define ANGLE_MARK_TRANSFORM_FEEDBACK_USAGE(instanced) \
651     ANGLE_MARK_TRANSFORM_FEEDBACK_USAGE##instanced
652 
653 #endif  // LIBANGLE_RENDERER_RENDERER_UTILS_H_
654