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 dst 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 *dstFormat; 88 size_t srcStride; 89 size_t srcOffset; 90 size_t dstOffset; 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 dstOffset[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 dst 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 ClearImageParameters 138 { 139 gl::Rectangle clearArea; 140 141 vk::LevelIndex dstMip; 142 int dstLayer; 143 144 VkColorComponentFlags colorMaskFlags; 145 VkClearColorValue colorClearValue; 146 }; 147 148 struct CopyImageParameters 149 { 150 int srcOffset[2]; 151 int srcExtents[2]; 152 int dstOffset[2]; 153 int srcMip; 154 int srcLayer; 155 int srcHeight; 156 gl::LevelIndex dstMip; 157 int dstLayer; 158 bool srcPremultiplyAlpha; 159 bool srcUnmultiplyAlpha; 160 bool srcFlipY; 161 bool dstFlipY; 162 SurfaceRotation srcRotation; 163 GLenum srcColorEncoding; 164 GLenum dstColorEncoding; 165 }; 166 167 struct CopyImageBitsParameters 168 { 169 int srcOffset[3]; 170 gl::LevelIndex srcLevel; 171 int dstOffset[3]; 172 gl::LevelIndex dstLevel; 173 uint32_t copyExtents[3]; 174 }; 175 176 struct OverlayCullParameters 177 { 178 uint32_t subgroupSize[2]; 179 bool supportsSubgroupBallot; 180 bool supportsSubgroupArithmetic; 181 }; 182 183 struct OverlayDrawParameters 184 { 185 uint32_t subgroupSize[2]; 186 bool rotateXY; 187 }; 188 189 struct GenerateMipmapParameters 190 { 191 uint32_t srcLevel; 192 uint32_t dstLevelCount; 193 }; 194 195 struct UnresolveParameters 196 { 197 gl::DrawBufferMask unresolveColorMask; 198 bool unresolveDepth; 199 bool unresolveStencil; 200 }; 201 202 // Based on the maximum number of levels in GenerateMipmap.comp. 203 static constexpr uint32_t kGenerateMipmapMaxLevels = 6; 204 static uint32_t GetGenerateMipmapMaxLevels(ContextVk *contextVk); 205 206 angle::Result convertIndexBuffer(ContextVk *contextVk, 207 vk::BufferHelper *dst, 208 vk::BufferHelper *src, 209 const ConvertIndexParameters ¶ms); 210 angle::Result convertIndexIndirectBuffer(ContextVk *contextVk, 211 vk::BufferHelper *srcIndirectBuf, 212 vk::BufferHelper *srcIndexBuf, 213 vk::BufferHelper *dstIndirectBuf, 214 vk::BufferHelper *dstIndexBuf, 215 const ConvertIndexIndirectParameters ¶ms); 216 217 angle::Result convertLineLoopIndexIndirectBuffer( 218 ContextVk *contextVk, 219 vk::BufferHelper *srcIndirectBuffer, 220 vk::BufferHelper *dstIndirectBuffer, 221 vk::BufferHelper *dstIndexBuffer, 222 vk::BufferHelper *srcIndexBuffer, 223 const ConvertLineLoopIndexIndirectParameters ¶ms); 224 225 angle::Result convertLineLoopArrayIndirectBuffer( 226 ContextVk *contextVk, 227 vk::BufferHelper *srcIndirectBuffer, 228 vk::BufferHelper *dstIndirectBuffer, 229 vk::BufferHelper *dstIndexBuffer, 230 const ConvertLineLoopArrayIndirectParameters ¶ms); 231 232 angle::Result convertVertexBuffer(ContextVk *contextVk, 233 vk::BufferHelper *dst, 234 vk::BufferHelper *src, 235 const ConvertVertexParameters ¶ms); 236 237 angle::Result clearFramebuffer(ContextVk *contextVk, 238 FramebufferVk *framebuffer, 239 const ClearFramebufferParameters ¶ms); 240 241 // Resolve images if multisampled. Blit otherwise. 242 angle::Result colorBlitResolve(ContextVk *contextVk, 243 FramebufferVk *framebuffer, 244 vk::ImageHelper *src, 245 const vk::ImageView *srcView, 246 const BlitResolveParameters ¶ms); 247 angle::Result depthStencilBlitResolve(ContextVk *contextVk, 248 FramebufferVk *framebuffer, 249 vk::ImageHelper *src, 250 const vk::ImageView *srcDepthView, 251 const vk::ImageView *srcStencilView, 252 const BlitResolveParameters ¶ms); 253 angle::Result stencilBlitResolveNoShaderExport(ContextVk *contextVk, 254 FramebufferVk *framebuffer, 255 vk::ImageHelper *src, 256 const vk::ImageView *srcStencilView, 257 const BlitResolveParameters ¶ms); 258 259 angle::Result clearImage(ContextVk *contextVk, 260 vk::ImageHelper *dst, 261 const ClearImageParameters ¶ms); 262 263 angle::Result copyImage(ContextVk *contextVk, 264 vk::ImageHelper *dst, 265 const vk::ImageView *dstView, 266 vk::ImageHelper *src, 267 const vk::ImageView *srcView, 268 const CopyImageParameters ¶ms); 269 270 angle::Result copyImageBits(ContextVk *contextVk, 271 vk::ImageHelper *dst, 272 vk::ImageHelper *src, 273 const CopyImageBitsParameters ¶ms); 274 275 using GenerateMipmapDestLevelViews = 276 std::array<const vk::ImageView *, kGenerateMipmapMaxLevels>; 277 angle::Result generateMipmap(ContextVk *contextVk, 278 vk::ImageHelper *src, 279 const vk::ImageView *srcLevelZeroView, 280 vk::ImageHelper *dst, 281 const GenerateMipmapDestLevelViews &dstLevelViews, 282 const vk::Sampler &sampler, 283 const GenerateMipmapParameters ¶ms); 284 285 angle::Result unresolve(ContextVk *contextVk, 286 const FramebufferVk *framebuffer, 287 const UnresolveParameters ¶ms); 288 289 // Overlay utilities. 290 angle::Result cullOverlayWidgets(ContextVk *contextVk, 291 vk::BufferHelper *enabledWidgetsBuffer, 292 vk::ImageHelper *dst, 293 const vk::ImageView *dstView, 294 const OverlayCullParameters ¶ms); 295 296 angle::Result drawOverlay(ContextVk *contextVk, 297 vk::BufferHelper *textWidgetsBuffer, 298 vk::BufferHelper *graphWidgetsBuffer, 299 vk::ImageHelper *font, 300 const vk::ImageView *fontView, 301 vk::ImageHelper *culledWidgets, 302 const vk::ImageView *culledWidgetsView, 303 vk::ImageHelper *dst, 304 const vk::ImageView *dstView, 305 const OverlayDrawParameters ¶ms); 306 307 InternalShaderPerfCounters getAndResetObjectPerfCounters(); 308 309 private: 310 ANGLE_ENABLE_STRUCT_PADDING_WARNINGS 311 312 struct ConvertIndexShaderParams 313 { 314 uint32_t srcOffset = 0; 315 uint32_t dstOffsetDiv4 = 0; 316 uint32_t maxIndex = 0; 317 uint32_t _padding = 0; 318 }; 319 320 struct ConvertIndexIndirectShaderParams 321 { 322 uint32_t srcIndirectOffsetDiv4 = 0; 323 uint32_t srcOffset = 0; 324 uint32_t dstOffsetDiv4 = 0; 325 uint32_t maxIndex = 0; 326 uint32_t dstIndirectOffsetDiv4 = 0; 327 }; 328 329 struct ConvertIndexIndirectLineLoopShaderParams 330 { 331 uint32_t cmdOffsetDiv4 = 0; 332 uint32_t dstCmdOffsetDiv4 = 0; 333 uint32_t srcOffset = 0; 334 uint32_t dstOffsetDiv4 = 0; 335 uint32_t isRestartEnabled = 0; 336 }; 337 338 struct ConvertIndirectLineLoopShaderParams 339 { 340 uint32_t cmdOffsetDiv4 = 0; 341 uint32_t dstCmdOffsetDiv4 = 0; 342 uint32_t dstOffsetDiv4 = 0; 343 }; 344 345 struct ConvertVertexShaderParams 346 { 347 ConvertVertexShaderParams(); 348 349 // Structure matching PushConstants in ConvertVertex.comp 350 uint32_t outputCount = 0; 351 uint32_t componentCount = 0; 352 uint32_t srcOffset = 0; 353 uint32_t dstOffset = 0; 354 uint32_t Ns = 0; 355 uint32_t Bs = 0; 356 uint32_t Ss = 0; 357 uint32_t Es = 0; 358 uint32_t Nd = 0; 359 uint32_t Bd = 0; 360 uint32_t Sd = 0; 361 uint32_t Ed = 0; 362 uint32_t srcEmulatedAlpha = 0; 363 uint32_t isSrcHDR = 0; 364 uint32_t isSrcA2BGR10 = 0; 365 uint32_t _padding = 0; 366 }; 367 368 struct ImageClearShaderParams 369 { 370 // Structure matching PushConstants in ImageClear.frag 371 VkClearColorValue clearValue = {}; 372 float clearDepth = 0.0f; 373 }; 374 375 struct ImageCopyShaderParams 376 { 377 ImageCopyShaderParams(); 378 379 // Structure matching PushConstants in ImageCopy.frag 380 int32_t srcOffset[2] = {}; 381 int32_t dstOffset[2] = {}; 382 int32_t srcMip = 0; 383 int32_t srcLayer = 0; 384 uint32_t flipX = 0; 385 uint32_t flipY = 0; 386 uint32_t premultiplyAlpha = 0; 387 uint32_t unmultiplyAlpha = 0; 388 uint32_t dstHasLuminance = 0; 389 uint32_t dstIsAlpha = 0; 390 uint32_t srcIsSRGB = 0; 391 uint32_t dstIsSRGB = 0; 392 uint32_t dstDefaultChannelsMask = 0; 393 uint32_t rotateXY = 0; 394 }; 395 396 union BlitResolveOffset 397 { 398 int32_t resolve[2]; 399 float blit[2]; 400 }; 401 402 struct BlitResolveShaderParams 403 { 404 // Structure matching PushConstants in BlitResolve.frag 405 BlitResolveOffset offset = {}; 406 float stretch[2] = {}; 407 float invSrcExtent[2] = {}; 408 int32_t srcLayer = 0; 409 int32_t samples = 0; 410 float invSamples = 0; 411 uint32_t outputMask = 0; 412 uint32_t flipX = 0; 413 uint32_t flipY = 0; 414 uint32_t rotateXY = 0; 415 }; 416 417 struct BlitResolveStencilNoExportShaderParams 418 { 419 // Structure matching PushConstants in BlitResolveStencilNoExport.comp 420 BlitResolveOffset offset = {}; 421 float stretch[2] = {}; 422 float invSrcExtent[2] = {}; 423 int32_t srcLayer = 0; 424 int32_t srcWidth = 0; 425 int32_t blitArea[4] = {}; 426 int32_t dstPitch = 0; 427 uint32_t flipX = 0; 428 uint32_t flipY = 0; 429 uint32_t rotateXY = 0; 430 }; 431 432 struct OverlayDrawShaderParams 433 { 434 // Structure matching PushConstants in OverlayDraw.comp 435 uint32_t outputSize[2] = {}; 436 uint32_t rotateXY; 437 }; 438 439 struct GenerateMipmapShaderParams 440 { 441 // Structure matching PushConstants in GenerateMipmap.comp 442 float invSrcExtent[2] = {}; 443 uint32_t levelCount = 0; 444 }; 445 446 ANGLE_DISABLE_STRUCT_PADDING_WARNINGS 447 448 // Functions implemented by the class: 449 enum class Function 450 { 451 // Functions implemented in graphics 452 ImageClear = 0, 453 ImageCopy = 1, 454 BlitResolve = 2, 455 // Note: unresolve is special as it has a different layout per attachment count. Depth and 456 // stencil each require a binding, so are counted separately. 457 Unresolve1Attachment = 3, 458 Unresolve2Attachments = 4, 459 Unresolve3Attachments = 5, 460 Unresolve4Attachments = 6, 461 Unresolve5Attachments = 7, 462 Unresolve6Attachments = 8, 463 Unresolve7Attachments = 9, 464 Unresolve8Attachments = 10, 465 Unresolve9Attachments = 11, 466 Unresolve10Attachments = 12, 467 468 // Functions implemented in compute 469 ComputeStartIndex = 13, // Special value to separate draw and dispatch functions. 470 ConvertIndexBuffer = 13, 471 ConvertVertexBuffer = 14, 472 BlitResolveStencilNoExport = 15, 473 OverlayCull = 16, 474 OverlayDraw = 17, 475 ConvertIndexIndirectBuffer = 18, 476 ConvertIndexIndirectLineLoopBuffer = 19, 477 ConvertIndirectLineLoopBuffer = 20, 478 GenerateMipmap = 21, 479 480 InvalidEnum = 22, 481 EnumCount = 22, 482 }; 483 484 // Common function that creates the pipeline for the specified function, binds it and prepares 485 // the draw/dispatch call. If function >= ComputeStartIndex, fsCsShader is expected to be a 486 // compute shader, vsShader and pipelineDesc should be nullptr, and this will set up a dispatch 487 // call. Otherwise fsCsShader is expected to be a fragment shader and this will set up a draw 488 // call. 489 angle::Result setupProgram(ContextVk *contextVk, 490 Function function, 491 vk::RefCounted<vk::ShaderAndSerial> *fsCsShader, 492 vk::RefCounted<vk::ShaderAndSerial> *vsShader, 493 vk::ShaderProgramHelper *program, 494 const vk::GraphicsPipelineDesc *pipelineDesc, 495 const VkDescriptorSet descriptorSet, 496 const void *pushConstants, 497 size_t pushConstantsSize, 498 vk::CommandBuffer *commandBuffer); 499 500 // Initializes descriptor set layout, pipeline layout and descriptor pool corresponding to given 501 // function, if not already initialized. Uses setSizes to create the layout. For example, if 502 // this array has two entries {STORAGE_TEXEL_BUFFER, 1} and {UNIFORM_TEXEL_BUFFER, 3}, then the 503 // created set layout would be binding 0 for storage texel buffer and bindings 1 through 3 for 504 // uniform texel buffer. All resources are put in set 0. 505 angle::Result ensureResourcesInitialized(ContextVk *contextVk, 506 Function function, 507 VkDescriptorPoolSize *setSizes, 508 size_t setSizesCount, 509 size_t pushConstantsSize); 510 511 // Initializers corresponding to functions, calling into ensureResourcesInitialized with the 512 // appropriate parameters. 513 angle::Result ensureConvertIndexResourcesInitialized(ContextVk *contextVk); 514 angle::Result ensureConvertIndexIndirectResourcesInitialized(ContextVk *contextVk); 515 angle::Result ensureConvertIndexIndirectLineLoopResourcesInitialized(ContextVk *contextVk); 516 angle::Result ensureConvertIndirectLineLoopResourcesInitialized(ContextVk *contextVk); 517 angle::Result ensureConvertVertexResourcesInitialized(ContextVk *contextVk); 518 angle::Result ensureImageClearResourcesInitialized(ContextVk *contextVk); 519 angle::Result ensureImageCopyResourcesInitialized(ContextVk *contextVk); 520 angle::Result ensureBlitResolveResourcesInitialized(ContextVk *contextVk); 521 angle::Result ensureBlitResolveStencilNoExportResourcesInitialized(ContextVk *contextVk); 522 angle::Result ensureOverlayCullResourcesInitialized(ContextVk *contextVk); 523 angle::Result ensureOverlayDrawResourcesInitialized(ContextVk *contextVk); 524 angle::Result ensureGenerateMipmapResourcesInitialized(ContextVk *contextVk); 525 angle::Result ensureUnresolveResourcesInitialized(ContextVk *contextVk, 526 Function function, 527 uint32_t attachmentIndex); 528 529 angle::Result ensureSamplersInitialized(ContextVk *context); 530 531 angle::Result startRenderPass(ContextVk *contextVk, 532 vk::ImageHelper *image, 533 const vk::ImageView *imageView, 534 const vk::RenderPassDesc &renderPassDesc, 535 const gl::Rectangle &renderArea, 536 vk::CommandBuffer **commandBufferOut); 537 538 // Set up descriptor set and call dispatch. 539 angle::Result convertVertexBufferImpl(ContextVk *contextVk, 540 vk::BufferHelper *dst, 541 vk::BufferHelper *src, 542 uint32_t flags, 543 vk::CommandBuffer *commandBuffer, 544 const ConvertVertexShaderParams &shaderParams); 545 546 // Blits or resolves either color or depth/stencil, based on which view is given. 547 angle::Result blitResolveImpl(ContextVk *contextVk, 548 FramebufferVk *framebuffer, 549 vk::ImageHelper *src, 550 const vk::ImageView *srcColorView, 551 const vk::ImageView *srcDepthView, 552 const vk::ImageView *srcStencilView, 553 const BlitResolveParameters ¶ms); 554 555 // Allocates a single descriptor set. 556 angle::Result allocateDescriptorSet(ContextVk *contextVk, 557 Function function, 558 vk::RefCountedDescriptorPoolBinding *bindingOut, 559 VkDescriptorSet *descriptorSetOut); 560 561 void outputCumulativePerfCounters(); 562 563 angle::PackedEnumMap<Function, vk::DescriptorSetLayoutPointerArray> mDescriptorSetLayouts; 564 angle::PackedEnumMap<Function, vk::BindingPointer<vk::PipelineLayout>> mPipelineLayouts; 565 angle::PackedEnumMap<Function, vk::DynamicDescriptorPool> mDescriptorPools; 566 567 vk::ShaderProgramHelper mConvertIndexPrograms[vk::InternalShader::ConvertIndex_comp::kArrayLen]; 568 vk::ShaderProgramHelper mConvertIndexIndirectLineLoopPrograms 569 [vk::InternalShader::ConvertIndexIndirectLineLoop_comp::kArrayLen]; 570 vk::ShaderProgramHelper mConvertIndirectLineLoopPrograms 571 [vk::InternalShader::ConvertIndirectLineLoop_comp::kArrayLen]; 572 vk::ShaderProgramHelper 573 mConvertVertexPrograms[vk::InternalShader::ConvertVertex_comp::kArrayLen]; 574 vk::ShaderProgramHelper mImageClearProgramVSOnly; 575 vk::ShaderProgramHelper mImageClearPrograms[vk::InternalShader::ImageClear_frag::kArrayLen]; 576 vk::ShaderProgramHelper mImageCopyPrograms[vk::InternalShader::ImageCopy_frag::kArrayLen]; 577 vk::ShaderProgramHelper mBlitResolvePrograms[vk::InternalShader::BlitResolve_frag::kArrayLen]; 578 vk::ShaderProgramHelper mBlitResolveStencilNoExportPrograms 579 [vk::InternalShader::BlitResolveStencilNoExport_comp::kArrayLen]; 580 vk::ShaderProgramHelper mOverlayCullPrograms[vk::InternalShader::OverlayCull_comp::kArrayLen]; 581 vk::ShaderProgramHelper mOverlayDrawPrograms[vk::InternalShader::OverlayDraw_comp::kArrayLen]; 582 vk::ShaderProgramHelper 583 mGenerateMipmapPrograms[vk::InternalShader::GenerateMipmap_comp::kArrayLen]; 584 585 // Unresolve shaders are special as they are generated on the fly due to the large number of 586 // combinations. 587 std::unordered_map<uint32_t, vk::RefCounted<vk::ShaderAndSerial>> mUnresolveFragShaders; 588 std::unordered_map<uint32_t, vk::ShaderProgramHelper> mUnresolvePrograms; 589 590 vk::Sampler mPointSampler; 591 vk::Sampler mLinearSampler; 592 593 InternalShaderPerfCounters mPerfCounters; 594 InternalShaderPerfCounters mCumulativePerfCounters; 595 }; 596 597 } // namespace rx 598 599 #endif // LIBANGLE_RENDERER_VULKAN_UTILSVK_H_ 600