1 //
2 // Copyright 2018 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 // UtilsVk.h:
7 //    Defines the UtilsVk class, a helper for various internal draw/dispatch utilities such as
8 //    buffer clear and copy, image clear and copy, texture mip map generation, etc.
9 //
10 //    - Convert index buffer:
11 //      * Used by VertexArrayVk::convertIndexBufferGPU() to convert a ubyte element array to ushort
12 //    - Convert vertex buffer:
13 //      * Used by VertexArrayVk::convertVertexBufferGPU() to convert vertex attributes from
14 //        unsupported formats to their fallbacks.
15 //    - Image clear: Used by FramebufferVk::clearWithDraw().
16 //    - Image copy: Used by TextureVk::copySubImageImplWithDraw().
17 //    - Image copy bits: Used by ImageHelper::CopyImageSubData() to perform bitwise copies between
18 //      RGB formats where at least one of src and dest use RGBA as fallback.
19 //    - Color blit/resolve: Used by FramebufferVk::blit() to implement blit or multisample resolve
20 //      on color images.
21 //    - Depth/Stencil blit/resolve: Used by FramebufferVk::blit() to implement blit or multisample
22 //      resolve on depth/stencil images.
23 //    - Generate mipmap: Used by TextureVk::generateMipmapsWithCompute().
24 //    - Overlay Cull/Draw: Used by OverlayVk to efficiently draw a UI for debugging.
25 //    - Mipmap generation: Used by TextureVk to generate mipmaps more efficiently in compute.
26 //
27 
28 #ifndef LIBANGLE_RENDERER_VULKAN_UTILSVK_H_
29 #define LIBANGLE_RENDERER_VULKAN_UTILSVK_H_
30 
31 #include "libANGLE/renderer/vulkan/vk_cache_utils.h"
32 #include "libANGLE/renderer/vulkan/vk_helpers.h"
33 #include "libANGLE/renderer/vulkan/vk_internal_shaders_autogen.h"
34 
35 namespace rx
36 {
37 struct InternalShaderPerfCounters
38 {
39     // Total descriptor set allocations for all UtilsVk::Functions
40     uint32_t descriptorSetsAllocated;
41 };
42 
43 class UtilsVk : angle::NonCopyable
44 {
45   public:
46     UtilsVk();
47     ~UtilsVk();
48 
49     void destroy(RendererVk *renderer);
50 
51     struct ConvertIndexParameters
52     {
53         uint32_t srcOffset = 0;
54         uint32_t dstOffset = 0;
55         uint32_t maxIndex  = 0;
56     };
57 
58     struct ConvertIndexIndirectParameters
59     {
60         uint32_t srcIndirectBufOffset = 0;
61         uint32_t srcIndexBufOffset    = 0;
62         uint32_t dstIndexBufOffset    = 0;
63         uint32_t maxIndex             = 0;
64         uint32_t dstIndirectBufOffset = 0;
65     };
66 
67     struct ConvertLineLoopIndexIndirectParameters
68     {
69         uint32_t indirectBufferOffset    = 0;
70         uint32_t dstIndirectBufferOffset = 0;
71         uint32_t srcIndexBufferOffset    = 0;
72         uint32_t dstIndexBufferOffset    = 0;
73         uint32_t indicesBitsWidth        = 0;
74     };
75 
76     struct ConvertLineLoopArrayIndirectParameters
77     {
78         uint32_t indirectBufferOffset    = 0;
79         uint32_t dstIndirectBufferOffset = 0;
80         uint32_t dstIndexBufferOffset    = 0;
81     };
82 
83     struct ConvertVertexParameters
84     {
85         size_t vertexCount;
86         const angle::Format *srcFormat;
87         const angle::Format *destFormat;
88         size_t srcStride;
89         size_t srcOffset;
90         size_t destOffset;
91     };
92 
93     struct ClearFramebufferParameters
94     {
95         // Satisfy chromium-style with a constructor that does what = {} was already doing in a
96         // safer way.
97         ClearFramebufferParameters();
98 
99         gl::Rectangle clearArea;
100 
101         bool clearColor;
102         bool clearDepth;
103         bool clearStencil;
104 
105         uint8_t stencilMask;
106         VkColorComponentFlags colorMaskFlags;
107         uint32_t colorAttachmentIndexGL;
108         const angle::Format *colorFormat;
109 
110         VkClearColorValue colorClearValue;
111         VkClearDepthStencilValue depthStencilClearValue;
112     };
113 
114     struct BlitResolveParameters
115     {
116         // |srcOffset| and |dstIndexBufferOffset| define the original blit/resolve offsets, possibly
117         // flipped.
118         int srcOffset[2];
119         int destOffset[2];
120         // Amount to add to x and y axis for certain rotations
121         int rotatedOffsetFactor[2];
122         // |stretch| is SourceDimension / DestDimension used to transfer dest coordinates to source.
123         float stretch[2];
124         // |srcExtents| is used to normalize source coordinates for sampling.
125         int srcExtents[2];
126         // |blitArea| is the area in destination where blit happens.  It's expected that scissor
127         // and source clipping effects have already been applied to it.
128         gl::Rectangle blitArea;
129         int srcLayer;
130         // Whether linear or point sampling should be used.
131         bool linear;
132         bool flipX;
133         bool flipY;
134         SurfaceRotation rotation;
135     };
136 
137     struct CopyImageParameters
138     {
139         int srcOffset[2];
140         int srcExtents[2];
141         int destOffset[2];
142         int srcMip;
143         int srcLayer;
144         int srcHeight;
145         gl::LevelIndex dstMip;
146         int dstLayer;
147         bool srcPremultiplyAlpha;
148         bool srcUnmultiplyAlpha;
149         bool srcFlipY;
150         bool destFlipY;
151         SurfaceRotation srcRotation;
152     };
153 
154     struct CopyImageBitsParameters
155     {
156         int srcOffset[3];
157         gl::LevelIndex srcLevel;
158         int dstOffset[3];
159         gl::LevelIndex dstLevel;
160         uint32_t copyExtents[3];
161     };
162 
163     struct OverlayCullParameters
164     {
165         uint32_t subgroupSize[2];
166         bool supportsSubgroupBallot;
167         bool supportsSubgroupArithmetic;
168     };
169 
170     struct OverlayDrawParameters
171     {
172         uint32_t subgroupSize[2];
173         bool rotateXY;
174     };
175 
176     struct GenerateMipmapParameters
177     {
178         uint32_t srcLevel;
179         uint32_t destLevelCount;
180     };
181 
182     struct UnresolveParameters
183     {
184         gl::DrawBufferMask unresolveColorMask;
185         bool unresolveDepth;
186         bool unresolveStencil;
187     };
188 
189     // Based on the maximum number of levels in GenerateMipmap.comp.
190     static constexpr uint32_t kGenerateMipmapMaxLevels = 6;
191     static uint32_t GetGenerateMipmapMaxLevels(ContextVk *contextVk);
192 
193     angle::Result convertIndexBuffer(ContextVk *contextVk,
194                                      vk::BufferHelper *dest,
195                                      vk::BufferHelper *src,
196                                      const ConvertIndexParameters &params);
197     angle::Result convertIndexIndirectBuffer(ContextVk *contextVk,
198                                              vk::BufferHelper *srcIndirectBuf,
199                                              vk::BufferHelper *srcIndexBuf,
200                                              vk::BufferHelper *dstIndirectBuf,
201                                              vk::BufferHelper *dstIndexBuf,
202                                              const ConvertIndexIndirectParameters &params);
203 
204     angle::Result convertLineLoopIndexIndirectBuffer(
205         ContextVk *contextVk,
206         vk::BufferHelper *srcIndirectBuffer,
207         vk::BufferHelper *destIndirectBuffer,
208         vk::BufferHelper *destIndexBuffer,
209         vk::BufferHelper *srcIndexBuffer,
210         const ConvertLineLoopIndexIndirectParameters &params);
211 
212     angle::Result convertLineLoopArrayIndirectBuffer(
213         ContextVk *contextVk,
214         vk::BufferHelper *srcIndirectBuffer,
215         vk::BufferHelper *destIndirectBuffer,
216         vk::BufferHelper *destIndexBuffer,
217         const ConvertLineLoopArrayIndirectParameters &params);
218 
219     angle::Result convertVertexBuffer(ContextVk *contextVk,
220                                       vk::BufferHelper *dest,
221                                       vk::BufferHelper *src,
222                                       const ConvertVertexParameters &params);
223 
224     angle::Result clearFramebuffer(ContextVk *contextVk,
225                                    FramebufferVk *framebuffer,
226                                    const ClearFramebufferParameters &params);
227 
228     // Resolve images if multisampled.  Blit otherwise.
229     angle::Result colorBlitResolve(ContextVk *contextVk,
230                                    FramebufferVk *framebuffer,
231                                    vk::ImageHelper *src,
232                                    const vk::ImageView *srcView,
233                                    const BlitResolveParameters &params);
234     angle::Result depthStencilBlitResolve(ContextVk *contextVk,
235                                           FramebufferVk *framebuffer,
236                                           vk::ImageHelper *src,
237                                           const vk::ImageView *srcDepthView,
238                                           const vk::ImageView *srcStencilView,
239                                           const BlitResolveParameters &params);
240     angle::Result stencilBlitResolveNoShaderExport(ContextVk *contextVk,
241                                                    FramebufferVk *framebuffer,
242                                                    vk::ImageHelper *src,
243                                                    const vk::ImageView *srcStencilView,
244                                                    const BlitResolveParameters &params);
245 
246     angle::Result copyImage(ContextVk *contextVk,
247                             vk::ImageHelper *dest,
248                             const vk::ImageView *destView,
249                             vk::ImageHelper *src,
250                             const vk::ImageView *srcView,
251                             const CopyImageParameters &params);
252 
253     angle::Result copyImageBits(ContextVk *contextVk,
254                                 vk::ImageHelper *dest,
255                                 vk::ImageHelper *src,
256                                 const CopyImageBitsParameters &params);
257 
258     using GenerateMipmapDestLevelViews =
259         std::array<const vk::ImageView *, kGenerateMipmapMaxLevels>;
260     angle::Result generateMipmap(ContextVk *contextVk,
261                                  vk::ImageHelper *src,
262                                  const vk::ImageView *srcLevelZeroView,
263                                  vk::ImageHelper *dest,
264                                  const GenerateMipmapDestLevelViews &destLevelViews,
265                                  const vk::Sampler &sampler,
266                                  const GenerateMipmapParameters &params);
267 
268     angle::Result unresolve(ContextVk *contextVk,
269                             const FramebufferVk *framebuffer,
270                             const UnresolveParameters &params);
271 
272     // Overlay utilities.
273     angle::Result cullOverlayWidgets(ContextVk *contextVk,
274                                      vk::BufferHelper *enabledWidgetsBuffer,
275                                      vk::ImageHelper *dest,
276                                      const vk::ImageView *destView,
277                                      const OverlayCullParameters &params);
278 
279     angle::Result drawOverlay(ContextVk *contextVk,
280                               vk::BufferHelper *textWidgetsBuffer,
281                               vk::BufferHelper *graphWidgetsBuffer,
282                               vk::ImageHelper *font,
283                               const vk::ImageView *fontView,
284                               vk::ImageHelper *culledWidgets,
285                               const vk::ImageView *culledWidgetsView,
286                               vk::ImageHelper *dest,
287                               const vk::ImageView *destView,
288                               const OverlayDrawParameters &params);
289 
290     InternalShaderPerfCounters getAndResetObjectPerfCounters();
291 
292   private:
293     ANGLE_ENABLE_STRUCT_PADDING_WARNINGS
294 
295     struct ConvertIndexShaderParams
296     {
297         uint32_t srcOffset     = 0;
298         uint32_t dstOffsetDiv4 = 0;
299         uint32_t maxIndex      = 0;
300         uint32_t _padding      = 0;
301     };
302 
303     struct ConvertIndexIndirectShaderParams
304     {
305         uint32_t srcIndirectOffsetDiv4 = 0;
306         uint32_t srcOffset             = 0;
307         uint32_t dstOffsetDiv4         = 0;
308         uint32_t maxIndex              = 0;
309         uint32_t dstIndirectOffsetDiv4 = 0;
310     };
311 
312     struct ConvertIndexIndirectLineLoopShaderParams
313     {
314         uint32_t cmdOffsetDiv4    = 0;
315         uint32_t dstCmdOffsetDiv4 = 0;
316         uint32_t srcOffset        = 0;
317         uint32_t dstOffsetDiv4    = 0;
318         uint32_t isRestartEnabled = 0;
319     };
320 
321     struct ConvertIndirectLineLoopShaderParams
322     {
323         uint32_t cmdOffsetDiv4    = 0;
324         uint32_t dstCmdOffsetDiv4 = 0;
325         uint32_t dstOffsetDiv4    = 0;
326     };
327 
328     struct ConvertVertexShaderParams
329     {
330         ConvertVertexShaderParams();
331 
332         // Structure matching PushConstants in ConvertVertex.comp
333         uint32_t outputCount      = 0;
334         uint32_t componentCount   = 0;
335         uint32_t srcOffset        = 0;
336         uint32_t destOffset       = 0;
337         uint32_t Ns               = 0;
338         uint32_t Bs               = 0;
339         uint32_t Ss               = 0;
340         uint32_t Es               = 0;
341         uint32_t Nd               = 0;
342         uint32_t Bd               = 0;
343         uint32_t Sd               = 0;
344         uint32_t Ed               = 0;
345         uint32_t srcEmulatedAlpha = 0;
346         uint32_t isSrcHDR         = 0;
347         uint32_t isSrcA2BGR10     = 0;
348         uint32_t _padding         = 0;
349     };
350 
351     struct ImageClearShaderParams
352     {
353         // Structure matching PushConstants in ImageClear.frag
354         VkClearColorValue clearValue = {};
355         float clearDepth             = 0.0f;
356     };
357 
358     struct ImageCopyShaderParams
359     {
360         ImageCopyShaderParams();
361 
362         // Structure matching PushConstants in ImageCopy.frag
363         int32_t srcOffset[2]             = {};
364         int32_t destOffset[2]            = {};
365         int32_t srcMip                   = 0;
366         int32_t srcLayer                 = 0;
367         uint32_t flipX                   = 0;
368         uint32_t flipY                   = 0;
369         uint32_t premultiplyAlpha        = 0;
370         uint32_t unmultiplyAlpha         = 0;
371         uint32_t destHasLuminance        = 0;
372         uint32_t destIsAlpha             = 0;
373         uint32_t srcIsSRGB               = 0;
374         uint32_t destIsSRGB              = 0;
375         uint32_t destDefaultChannelsMask = 0;
376         uint32_t rotateXY                = 0;
377     };
378 
379     union BlitResolveOffset
380     {
381         int32_t resolve[2];
382         float blit[2];
383     };
384 
385     struct BlitResolveShaderParams
386     {
387         // Structure matching PushConstants in BlitResolve.frag
388         BlitResolveOffset offset = {};
389         float stretch[2]         = {};
390         float invSrcExtent[2]    = {};
391         int32_t srcLayer         = 0;
392         int32_t samples          = 0;
393         float invSamples         = 0;
394         uint32_t outputMask      = 0;
395         uint32_t flipX           = 0;
396         uint32_t flipY           = 0;
397         uint32_t rotateXY        = 0;
398     };
399 
400     struct BlitResolveStencilNoExportShaderParams
401     {
402         // Structure matching PushConstants in BlitResolveStencilNoExport.comp
403         BlitResolveOffset offset = {};
404         float stretch[2]         = {};
405         float invSrcExtent[2]    = {};
406         int32_t srcLayer         = 0;
407         int32_t srcWidth         = 0;
408         int32_t blitArea[4]      = {};
409         int32_t destPitch        = 0;
410         uint32_t flipX           = 0;
411         uint32_t flipY           = 0;
412         uint32_t rotateXY        = 0;
413     };
414 
415     struct OverlayDrawShaderParams
416     {
417         // Structure matching PushConstants in OverlayDraw.comp
418         uint32_t outputSize[2] = {};
419         uint32_t rotateXY;
420     };
421 
422     struct GenerateMipmapShaderParams
423     {
424         // Structure matching PushConstants in GenerateMipmap.comp
425         float invSrcExtent[2] = {};
426         uint32_t levelCount   = 0;
427     };
428 
429     ANGLE_DISABLE_STRUCT_PADDING_WARNINGS
430 
431     // Functions implemented by the class:
432     enum class Function
433     {
434         // Functions implemented in graphics
435         ImageClear  = 0,
436         ImageCopy   = 1,
437         BlitResolve = 2,
438         // Note: unresolve is special as it has a different layout per attachment count.  Depth and
439         // stencil each require a binding, so are counted separately.
440         Unresolve1Attachment   = 3,
441         Unresolve2Attachments  = 4,
442         Unresolve3Attachments  = 5,
443         Unresolve4Attachments  = 6,
444         Unresolve5Attachments  = 7,
445         Unresolve6Attachments  = 8,
446         Unresolve7Attachments  = 9,
447         Unresolve8Attachments  = 10,
448         Unresolve9Attachments  = 11,
449         Unresolve10Attachments = 12,
450 
451         // Functions implemented in compute
452         ComputeStartIndex          = 13,  // Special value to separate draw and dispatch functions.
453         ConvertIndexBuffer         = 13,
454         ConvertVertexBuffer        = 14,
455         BlitResolveStencilNoExport = 15,
456         OverlayCull                = 16,
457         OverlayDraw                = 17,
458         ConvertIndexIndirectBuffer = 18,
459         ConvertIndexIndirectLineLoopBuffer = 19,
460         ConvertIndirectLineLoopBuffer      = 20,
461         GenerateMipmap                     = 21,
462 
463         InvalidEnum = 22,
464         EnumCount   = 22,
465     };
466 
467     // Common function that creates the pipeline for the specified function, binds it and prepares
468     // the draw/dispatch call.  If function >= ComputeStartIndex, fsCsShader is expected to be a
469     // compute shader, vsShader and pipelineDesc should be nullptr, and this will set up a dispatch
470     // call. Otherwise fsCsShader is expected to be a fragment shader and this will set up a draw
471     // call.
472     angle::Result setupProgram(ContextVk *contextVk,
473                                Function function,
474                                vk::RefCounted<vk::ShaderAndSerial> *fsCsShader,
475                                vk::RefCounted<vk::ShaderAndSerial> *vsShader,
476                                vk::ShaderProgramHelper *program,
477                                const vk::GraphicsPipelineDesc *pipelineDesc,
478                                const VkDescriptorSet descriptorSet,
479                                const void *pushConstants,
480                                size_t pushConstantsSize,
481                                vk::CommandBuffer *commandBuffer);
482 
483     // Initializes descriptor set layout, pipeline layout and descriptor pool corresponding to given
484     // function, if not already initialized.  Uses setSizes to create the layout.  For example, if
485     // this array has two entries {STORAGE_TEXEL_BUFFER, 1} and {UNIFORM_TEXEL_BUFFER, 3}, then the
486     // created set layout would be binding 0 for storage texel buffer and bindings 1 through 3 for
487     // uniform texel buffer.  All resources are put in set 0.
488     angle::Result ensureResourcesInitialized(ContextVk *contextVk,
489                                              Function function,
490                                              VkDescriptorPoolSize *setSizes,
491                                              size_t setSizesCount,
492                                              size_t pushConstantsSize);
493 
494     // Initializers corresponding to functions, calling into ensureResourcesInitialized with the
495     // appropriate parameters.
496     angle::Result ensureConvertIndexResourcesInitialized(ContextVk *contextVk);
497     angle::Result ensureConvertIndexIndirectResourcesInitialized(ContextVk *contextVk);
498     angle::Result ensureConvertIndexIndirectLineLoopResourcesInitialized(ContextVk *contextVk);
499     angle::Result ensureConvertIndirectLineLoopResourcesInitialized(ContextVk *contextVk);
500     angle::Result ensureConvertVertexResourcesInitialized(ContextVk *contextVk);
501     angle::Result ensureImageClearResourcesInitialized(ContextVk *contextVk);
502     angle::Result ensureImageCopyResourcesInitialized(ContextVk *contextVk);
503     angle::Result ensureBlitResolveResourcesInitialized(ContextVk *contextVk);
504     angle::Result ensureBlitResolveStencilNoExportResourcesInitialized(ContextVk *contextVk);
505     angle::Result ensureOverlayCullResourcesInitialized(ContextVk *contextVk);
506     angle::Result ensureOverlayDrawResourcesInitialized(ContextVk *contextVk);
507     angle::Result ensureGenerateMipmapResourcesInitialized(ContextVk *contextVk);
508     angle::Result ensureUnresolveResourcesInitialized(ContextVk *contextVk,
509                                                       Function function,
510                                                       uint32_t attachmentIndex);
511 
512     angle::Result ensureSamplersInitialized(ContextVk *context);
513 
514     angle::Result startRenderPass(ContextVk *contextVk,
515                                   vk::ImageHelper *image,
516                                   const vk::ImageView *imageView,
517                                   const vk::RenderPassDesc &renderPassDesc,
518                                   const gl::Rectangle &renderArea,
519                                   vk::CommandBuffer **commandBufferOut);
520 
521     // Set up descriptor set and call dispatch.
522     angle::Result convertVertexBufferImpl(ContextVk *contextVk,
523                                           vk::BufferHelper *dest,
524                                           vk::BufferHelper *src,
525                                           uint32_t flags,
526                                           vk::CommandBuffer *commandBuffer,
527                                           const ConvertVertexShaderParams &shaderParams);
528 
529     // Blits or resolves either color or depth/stencil, based on which view is given.
530     angle::Result blitResolveImpl(ContextVk *contextVk,
531                                   FramebufferVk *framebuffer,
532                                   vk::ImageHelper *src,
533                                   const vk::ImageView *srcColorView,
534                                   const vk::ImageView *srcDepthView,
535                                   const vk::ImageView *srcStencilView,
536                                   const BlitResolveParameters &params);
537 
538     // Allocates a single descriptor set.
539     angle::Result allocateDescriptorSet(ContextVk *contextVk,
540                                         Function function,
541                                         vk::RefCountedDescriptorPoolBinding *bindingOut,
542                                         VkDescriptorSet *descriptorSetOut);
543 
544     void outputCumulativePerfCounters();
545 
546     angle::PackedEnumMap<Function, vk::DescriptorSetLayoutPointerArray> mDescriptorSetLayouts;
547     angle::PackedEnumMap<Function, vk::BindingPointer<vk::PipelineLayout>> mPipelineLayouts;
548     angle::PackedEnumMap<Function, vk::DynamicDescriptorPool> mDescriptorPools;
549 
550     vk::ShaderProgramHelper mConvertIndexPrograms[vk::InternalShader::ConvertIndex_comp::kArrayLen];
551     vk::ShaderProgramHelper mConvertIndexIndirectLineLoopPrograms
552         [vk::InternalShader::ConvertIndexIndirectLineLoop_comp::kArrayLen];
553     vk::ShaderProgramHelper mConvertIndirectLineLoopPrograms
554         [vk::InternalShader::ConvertIndirectLineLoop_comp::kArrayLen];
555     vk::ShaderProgramHelper
556         mConvertVertexPrograms[vk::InternalShader::ConvertVertex_comp::kArrayLen];
557     vk::ShaderProgramHelper mImageClearProgramVSOnly;
558     vk::ShaderProgramHelper mImageClearProgram[vk::InternalShader::ImageClear_frag::kArrayLen];
559     vk::ShaderProgramHelper mImageCopyPrograms[vk::InternalShader::ImageCopy_frag::kArrayLen];
560     vk::ShaderProgramHelper mBlitResolvePrograms[vk::InternalShader::BlitResolve_frag::kArrayLen];
561     vk::ShaderProgramHelper mBlitResolveStencilNoExportPrograms
562         [vk::InternalShader::BlitResolveStencilNoExport_comp::kArrayLen];
563     vk::ShaderProgramHelper mOverlayCullPrograms[vk::InternalShader::OverlayCull_comp::kArrayLen];
564     vk::ShaderProgramHelper mOverlayDrawPrograms[vk::InternalShader::OverlayDraw_comp::kArrayLen];
565     vk::ShaderProgramHelper
566         mGenerateMipmapPrograms[vk::InternalShader::GenerateMipmap_comp::kArrayLen];
567 
568     // Unresolve shaders are special as they are generated on the fly due to the large number of
569     // combinations.
570     std::unordered_map<uint32_t, vk::RefCounted<vk::ShaderAndSerial>> mUnresolveFragShaders;
571     std::unordered_map<uint32_t, vk::ShaderProgramHelper> mUnresolvePrograms;
572 
573     vk::Sampler mPointSampler;
574     vk::Sampler mLinearSampler;
575 
576     InternalShaderPerfCounters mPerfCounters;
577     InternalShaderPerfCounters mCumulativePerfCounters;
578 };
579 
580 }  // namespace rx
581 
582 #endif  // LIBANGLE_RENDERER_VULKAN_UTILSVK_H_
583