• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 Draw: Used by OverlayVk to 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/BufferVk.h"
32 #include "libANGLE/renderer/vulkan/vk_cache_utils.h"
33 #include "libANGLE/renderer/vulkan/vk_helpers.h"
34 #include "libANGLE/renderer/vulkan/vk_internal_shaders_autogen.h"
35 
36 namespace rx
37 {
38 class UtilsVk : angle::NonCopyable
39 {
40   public:
41     UtilsVk();
42     ~UtilsVk();
43 
44     void destroy(ContextVk *contextVk);
45 
46     struct ConvertIndexParameters
47     {
48         uint32_t srcOffset = 0;
49         uint32_t dstOffset = 0;
50         uint32_t maxIndex  = 0;
51     };
52 
53     struct ConvertIndexIndirectParameters
54     {
55         uint32_t srcIndirectBufOffset = 0;
56         uint32_t srcIndexBufOffset    = 0;
57         uint32_t dstIndexBufOffset    = 0;
58         uint32_t maxIndex             = 0;
59         uint32_t dstIndirectBufOffset = 0;
60     };
61 
62     struct ConvertLineLoopIndexIndirectParameters
63     {
64         uint32_t indirectBufferOffset    = 0;
65         uint32_t dstIndirectBufferOffset = 0;
66         uint32_t srcIndexBufferOffset    = 0;
67         uint32_t dstIndexBufferOffset    = 0;
68         uint32_t indicesBitsWidth        = 0;
69     };
70 
71     struct ConvertLineLoopArrayIndirectParameters
72     {
73         uint32_t indirectBufferOffset    = 0;
74         uint32_t dstIndirectBufferOffset = 0;
75         uint32_t dstIndexBufferOffset    = 0;
76     };
77 
78     struct OffsetAndVertexCount
79     {
80         uint32_t srcOffset;
81         uint32_t dstOffset;
82         uint32_t vertexCount;
83     };
84     using OffsetAndVertexCounts = std::vector<OffsetAndVertexCount>;
85 
86     struct ConvertVertexParameters
87     {
88         size_t vertexCount;
89         const angle::Format *srcFormat;
90         const angle::Format *dstFormat;
91         size_t srcStride;
92         size_t srcOffset;
93         size_t dstOffset;
94     };
95 
96     struct ClearFramebufferParameters
97     {
98         // Satisfy chromium-style with a constructor that does what = {} was already doing in a
99         // safer way.
100         ClearFramebufferParameters();
101 
102         gl::Rectangle clearArea;
103 
104         bool clearColor;
105         bool clearDepth;
106         bool clearStencil;
107 
108         uint8_t stencilMask;
109         VkColorComponentFlags colorMaskFlags;
110         uint32_t colorAttachmentIndexGL;
111         const angle::Format *colorFormat;
112 
113         VkClearColorValue colorClearValue;
114         VkClearDepthStencilValue depthStencilClearValue;
115     };
116 
117     struct ClearTextureParameters
118     {
119         VkImageAspectFlags aspectFlags;
120         vk::LevelIndex level;
121         uint32_t layer;
122         gl::Box clearArea;
123         VkClearValue clearValue;
124     };
125 
126     struct BlitResolveParameters
127     {
128         // |srcOffset| and |dstIndexBufferOffset| define the original blit/resolve offsets, possibly
129         // flipped.
130         int srcOffset[2];
131         int dstOffset[2];
132         // Amount to add to x and y axis for certain rotations
133         int rotatedOffsetFactor[2];
134         // |stretch| is SourceDimension / DestDimension used to transfer dst coordinates to source.
135         float stretch[2];
136         // |srcExtents| is used to normalize source coordinates for sampling.
137         int srcExtents[2];
138         // |blitArea| is the area in destination where blit happens.  It's expected that scissor
139         // and source clipping effects have already been applied to it.
140         gl::Rectangle blitArea;
141         int srcLayer;
142         // Whether linear or point sampling should be used.
143         bool linear;
144         bool flipX;
145         bool flipY;
146         SurfaceRotation rotation;
147     };
148 
149     struct ClearImageParameters
150     {
151         gl::Rectangle clearArea;
152 
153         vk::LevelIndex dstMip;
154         int dstLayer;
155 
156         VkColorComponentFlags colorMaskFlags;
157         VkClearColorValue colorClearValue;
158     };
159 
160     struct CopyImageParameters
161     {
162         int srcOffset[2];
163         int srcExtents[2];
164         int dstOffset[2];
165         int srcMip;
166         int srcLayer;
167         int srcSampleCount;
168         int srcHeight;
169         gl::LevelIndex dstMip;
170         int dstLayer;
171         bool srcPremultiplyAlpha;
172         bool srcUnmultiplyAlpha;
173         bool srcFlipY;
174         bool dstFlipY;
175         SurfaceRotation srcRotation;
176         GLenum srcColorEncoding;
177         GLenum dstColorEncoding;
178     };
179 
180     struct CopyImageBitsParameters
181     {
182         int srcOffset[3];
183         gl::LevelIndex srcLevel;
184         int dstOffset[3];
185         gl::LevelIndex dstLevel;
186         uint32_t copyExtents[3];
187     };
188 
189     struct CopyImageToBufferParameters
190     {
191         int srcOffset[2];
192         vk::LevelIndex srcMip;
193         int srcLayer;
194         uint32_t size[2];
195         ptrdiff_t outputOffset;
196         uint32_t outputPitch;
197         bool reverseRowOrder;
198         const angle::Format *outputFormat;
199     };
200 
201     struct OverlayDrawParameters
202     {
203         uint32_t textWidgetCount;
204         uint32_t graphWidgetCount;
205         bool rotateXY;
206     };
207 
208     struct GenerateMipmapParameters
209     {
210         uint32_t srcLevel;
211         uint32_t dstLevelCount;
212     };
213 
214     struct UnresolveParameters
215     {
216         gl::DrawBufferMask unresolveColorMask;
217         bool unresolveDepth;
218         bool unresolveStencil;
219     };
220 
221     struct GenerateFragmentShadingRateParameters
222     {
223         uint32_t textureWidth;
224         uint32_t textureHeight;
225         uint32_t attachmentWidth;
226         uint32_t attachmentHeight;
227         uint32_t attachmentBlockWidth;
228         uint32_t attachmentBlockHeight;
229         uint32_t numFocalPoints;
230         gl::FocalPoint focalPoints[gl::IMPLEMENTATION_MAX_FOCAL_POINTS];
231     };
232 
233     // Based on the maximum number of levels in GenerateMipmap.comp.
234     static constexpr uint32_t kGenerateMipmapMaxLevels = 6;
235     static uint32_t GetGenerateMipmapMaxLevels(ContextVk *contextVk);
236 
237     angle::Result convertIndexBuffer(ContextVk *contextVk,
238                                      vk::BufferHelper *dst,
239                                      vk::BufferHelper *src,
240                                      const ConvertIndexParameters &params);
241     angle::Result convertIndexIndirectBuffer(ContextVk *contextVk,
242                                              vk::BufferHelper *srcIndirectBuf,
243                                              vk::BufferHelper *srcIndexBuf,
244                                              vk::BufferHelper *dstIndirectBuf,
245                                              vk::BufferHelper *dstIndexBuf,
246                                              const ConvertIndexIndirectParameters &params);
247 
248     angle::Result convertLineLoopIndexIndirectBuffer(
249         ContextVk *contextVk,
250         vk::BufferHelper *srcIndirectBuffer,
251         vk::BufferHelper *srcIndexBuffer,
252         vk::BufferHelper *dstIndirectBuffer,
253         vk::BufferHelper *dstIndexBuffer,
254         const ConvertLineLoopIndexIndirectParameters &params);
255 
256     angle::Result convertLineLoopArrayIndirectBuffer(
257         ContextVk *contextVk,
258         vk::BufferHelper *srcIndirectBuffer,
259         vk::BufferHelper *dstIndirectBuffer,
260         vk::BufferHelper *dstIndexBuffer,
261         const ConvertLineLoopArrayIndirectParameters &params);
262 
263     angle::Result convertVertexBuffer(ContextVk *contextVk,
264                                       vk::BufferHelper *dst,
265                                       vk::BufferHelper *src,
266                                       const ConvertVertexParameters &params,
267                                       const OffsetAndVertexCounts &additionalOffsetVertexCounts);
268 
269     // EXT_clear_texture
270     angle::Result clearTexture(ContextVk *contextVk,
271                                vk::ImageHelper *dst,
272                                ClearTextureParameters &params);
273 
274     angle::Result clearFramebuffer(ContextVk *contextVk,
275                                    FramebufferVk *framebuffer,
276                                    const ClearFramebufferParameters &params);
277 
278     // Resolve images if multisampled.  Blit otherwise.
279     angle::Result colorBlitResolve(ContextVk *contextVk,
280                                    FramebufferVk *framebuffer,
281                                    vk::ImageHelper *src,
282                                    const vk::ImageView *srcView,
283                                    const BlitResolveParameters &params);
284     angle::Result depthStencilBlitResolve(ContextVk *contextVk,
285                                           FramebufferVk *framebuffer,
286                                           vk::ImageHelper *src,
287                                           const vk::ImageView *srcDepthView,
288                                           const vk::ImageView *srcStencilView,
289                                           const BlitResolveParameters &params);
290     angle::Result stencilBlitResolveNoShaderExport(ContextVk *contextVk,
291                                                    FramebufferVk *framebuffer,
292                                                    vk::ImageHelper *src,
293                                                    const vk::ImageView *srcStencilView,
294                                                    const BlitResolveParameters &params);
295 
296     angle::Result clearImage(ContextVk *contextVk,
297                              vk::ImageHelper *dst,
298                              const ClearImageParameters &params);
299 
300     angle::Result copyImage(ContextVk *contextVk,
301                             vk::ImageHelper *dst,
302                             const vk::ImageView *dstView,
303                             vk::ImageHelper *src,
304                             const vk::ImageView *srcView,
305                             const CopyImageParameters &params);
306 
307     angle::Result copyImageBits(ContextVk *contextVk,
308                                 vk::ImageHelper *dst,
309                                 vk::ImageHelper *src,
310                                 const CopyImageBitsParameters &params);
311 
312     angle::Result copyImageToBuffer(ContextVk *contextVk,
313                                     vk::BufferHelper *dst,
314                                     vk::ImageHelper *src,
315                                     const CopyImageToBufferParameters &params);
316 
317     angle::Result copyRgbToRgba(ContextVk *contextVk,
318                                 const angle::Format &srcFormat,
319                                 vk::BufferHelper *srcBuffer,
320                                 uint32_t srcOffset,
321                                 uint32_t pixelCount,
322                                 vk::BufferHelper *dstBuffer);
323 
324     angle::Result transCodeEtcToBc(ContextVk *contextVk,
325                                    vk::BufferHelper *srcBuffer,
326                                    vk::ImageHelper *dstImage,
327                                    const VkBufferImageCopy *copyRegion);
328 
329     using GenerateMipmapDestLevelViews =
330         std::array<const vk::ImageView *, kGenerateMipmapMaxLevels>;
331     angle::Result generateMipmap(ContextVk *contextVk,
332                                  vk::ImageHelper *src,
333                                  const vk::ImageView *srcLevelZeroView,
334                                  vk::ImageHelper *dst,
335                                  const GenerateMipmapDestLevelViews &dstLevelViews,
336                                  const vk::Sampler &sampler,
337                                  const GenerateMipmapParameters &params);
338     angle::Result generateMipmapWithDraw(ContextVk *contextVk,
339                                          vk::ImageHelper *image,
340                                          const angle::FormatID actualFormatID,
341                                          const bool isMipmapFiltered);
342 
343     angle::Result unresolve(ContextVk *contextVk,
344                             const FramebufferVk *framebuffer,
345                             const UnresolveParameters &params);
346 
347     // Overlay utilities.
348     angle::Result drawOverlay(ContextVk *contextVk,
349                               vk::BufferHelper *textWidgetsBuffer,
350                               vk::BufferHelper *graphWidgetsBuffer,
351                               vk::ImageHelper *font,
352                               const vk::ImageView *fontView,
353                               vk::ImageHelper *dst,
354                               const vk::ImageView *dstView,
355                               const OverlayDrawParameters &params);
356 
357     // Fragment shading rate utility
358     angle::Result generateFragmentShadingRate(
359         ContextVk *contextVk,
360         vk::ImageHelper *shadingRateAttachmentImageHelper,
361         vk::ImageViewHelper *shadingRateAttachmentImageViewHelper,
362         const GenerateFragmentShadingRateParameters &shadingRateParameters);
363 
364   private:
365     ANGLE_ENABLE_STRUCT_PADDING_WARNINGS
366 
367     struct ConvertIndexShaderParams
368     {
369         uint32_t srcOffset     = 0;
370         uint32_t dstOffsetDiv4 = 0;
371         uint32_t maxIndex      = 0;
372         uint32_t _padding      = 0;
373     };
374 
375     struct ConvertIndexIndirectShaderParams
376     {
377         uint32_t srcIndirectOffsetDiv4 = 0;
378         uint32_t srcOffset             = 0;
379         uint32_t dstOffsetDiv4         = 0;
380         uint32_t maxIndex              = 0;
381         uint32_t dstIndirectOffsetDiv4 = 0;
382     };
383 
384     struct ConvertIndexIndirectLineLoopShaderParams
385     {
386         uint32_t cmdOffsetDiv4    = 0;
387         uint32_t dstCmdOffsetDiv4 = 0;
388         uint32_t srcOffset        = 0;
389         uint32_t dstOffsetDiv4    = 0;
390         uint32_t isRestartEnabled = 0;
391     };
392 
393     struct ConvertIndirectLineLoopShaderParams
394     {
395         uint32_t cmdOffsetDiv4    = 0;
396         uint32_t dstCmdOffsetDiv4 = 0;
397         uint32_t dstOffsetDiv4    = 0;
398     };
399 
400     struct ConvertVertexShaderParams
401     {
402         ConvertVertexShaderParams();
403 
404         // Structure matching PushConstants in ConvertVertex.comp
405         uint32_t outputCount      = 0;
406         uint32_t componentCount   = 0;
407         uint32_t srcOffset        = 0;
408         uint32_t dstOffset        = 0;
409         uint32_t Ns               = 0;
410         uint32_t Bs               = 0;
411         uint32_t Ss               = 0;
412         uint32_t Es               = 0;
413         uint32_t Nd               = 0;
414         uint32_t Bd               = 0;
415         uint32_t Sd               = 0;
416         uint32_t Ed               = 0;
417         uint32_t srcEmulatedAlpha = 0;
418         uint32_t isSrcHDR         = 0;
419         uint32_t isSrcA2BGR10     = 0;
420         uint32_t _padding         = 0;
421     };
422 
423     struct ImageClearShaderParams
424     {
425         // Structure matching PushConstants in ImageClear.frag
426         VkClearColorValue clearValue = {};
427         float clearDepth             = 0.0f;
428     };
429 
430     struct ImageCopyShaderParams
431     {
432         ImageCopyShaderParams();
433 
434         // Structure matching PushConstants in ImageCopy.frag
435         int32_t srcOffset[2]            = {};
436         int32_t dstOffset[2]            = {};
437         int32_t srcMip                  = 0;
438         int32_t srcLayer                = 0;
439         int32_t srcSampleCount          = 0;
440         uint32_t flipX                  = 0;
441         uint32_t flipY                  = 0;
442         uint32_t premultiplyAlpha       = 0;
443         uint32_t unmultiplyAlpha        = 0;
444         uint32_t dstHasLuminance        = 0;
445         uint32_t dstIsAlpha             = 0;
446         uint32_t srcIsSRGB              = 0;
447         uint32_t dstIsSRGB              = 0;
448         uint32_t dstDefaultChannelsMask = 0;
449         uint32_t rotateXY               = 0;
450     };
451 
452     struct CopyImageToBufferShaderParams
453     {
454         // Structure matching PushConstants in CopyImageToBuffer.comp
455         int32_t srcOffset[2]     = {};
456         int32_t srcDepth         = 0;
457         uint32_t reverseRowOrder = 0;
458         uint32_t size[2]         = {};
459         uint32_t outputOffset    = 0;
460         uint32_t outputPitch     = 0;
461         uint32_t isDstSnorm      = 0;
462     };
463 
464     union BlitResolveOffset
465     {
466         int32_t resolve[2];
467         float blit[2];
468     };
469 
470     struct BlitResolveShaderParams
471     {
472         // Structure matching PushConstants in BlitResolve.frag
473         BlitResolveOffset offset = {};
474         float stretch[2]         = {};
475         float invSrcExtent[2]    = {};
476         int32_t srcLayer         = 0;
477         int32_t samples          = 0;
478         float invSamples         = 0;
479         uint32_t outputMask      = 0;
480         uint32_t flipX           = 0;
481         uint32_t flipY           = 0;
482         uint32_t rotateXY        = 0;
483     };
484 
485     struct BlitResolveStencilNoExportShaderParams
486     {
487         // Structure matching PushConstants in BlitResolveStencilNoExport.comp
488         BlitResolveOffset offset = {};
489         float stretch[2]         = {};
490         float invSrcExtent[2]    = {};
491         int32_t srcLayer         = 0;
492         int32_t srcWidth         = 0;
493         int32_t srcHeight        = 0;
494         uint32_t flipX           = 0;
495         uint32_t flipY           = 0;
496         uint32_t rotateXY        = 0;
497         int32_t blitArea[4]      = {};
498         int32_t dstPitch         = 0;
499     };
500 
501     struct ExportStencilShaderParams
502     {
503         uint32_t bit = 0;
504     };
505 
506     struct OverlayDrawShaderParams
507     {
508         // Structure matching PushConstants in OverlayDraw.vert and OverlayDraw.frag
509         uint32_t viewportSize[2] = {};
510         uint32_t isText          = 0;
511         uint32_t rotateXY        = 0;
512     };
513 
514     struct GenerateMipmapShaderParams
515     {
516         // Structure matching PushConstants in GenerateMipmap.comp
517         float invSrcExtent[2] = {};
518         uint32_t levelCount   = 0;
519     };
520 
521     struct EtcToBcShaderParams
522     {
523         uint32_t offsetX;
524         uint32_t offsetY;
525         int32_t texelOffset;
526         uint32_t width;
527         uint32_t height;
528         uint32_t alphaBits;
529         uint32_t isSigned;
530         uint32_t isEacRg;
531     };
532 
533     ANGLE_DISABLE_STRUCT_PADDING_WARNINGS
534 
535     // Functions implemented by the class:
536     enum class Function
537     {
538         // Functions implemented in graphics
539         ImageClear,
540         ImageCopy,
541         BlitResolve,
542         Blit3DSrc,
543         ExportStencil,
544         OverlayDraw,
545         // Note: unresolve is special as it has a different layout per attachment count.  Depth and
546         // stencil each require a binding, so are counted separately.
547         Unresolve1Attachment,
548         Unresolve2Attachments,
549         Unresolve3Attachments,
550         Unresolve4Attachments,
551         Unresolve5Attachments,
552         Unresolve6Attachments,
553         Unresolve7Attachments,
554         Unresolve8Attachments,
555         Unresolve9Attachments,
556         Unresolve10Attachments,
557 
558         // Functions implemented in compute
559         ComputeStartIndex,  // Special value to separate draw and dispatch functions.
560         ConvertIndexBuffer = ComputeStartIndex,
561         ConvertVertexBuffer,
562         ClearTexture,
563         BlitResolveStencilNoExport,
564         ConvertIndexIndirectBuffer,
565         ConvertIndexIndirectLineLoopBuffer,
566         ConvertIndirectLineLoopBuffer,
567         GenerateMipmap,
568         TransCodeEtcToBc,
569         CopyImageToBuffer,
570         GenerateFragmentShadingRate,
571 
572         InvalidEnum,
573         EnumCount = InvalidEnum,
574     };
575 
576     struct GraphicsShaderProgramAndPipelines
577     {
578         vk::ShaderProgramHelper program;
579         CompleteGraphicsPipelineCache pipelines;
580     };
581     struct ComputeShaderProgramAndPipelines
582     {
583         vk::ShaderProgramHelper program;
584         ComputePipelineCache pipelines;
585     };
586 
587     // Common functions that create the pipeline for the specified function, binds it and prepares
588     // the draw/dispatch call.
589     angle::Result setupComputeProgram(
590         ContextVk *contextVk,
591         Function function,
592         const vk::ShaderModulePtr &csShader,
593         ComputeShaderProgramAndPipelines *programAndPipelines,
594         const VkDescriptorSet descriptorSet,
595         const void *pushConstants,
596         size_t pushConstantsSize,
597         vk::OutsideRenderPassCommandBufferHelper *commandBufferHelper);
598     angle::Result setupGraphicsProgramWithLayout(
599         ContextVk *contextVk,
600         const vk::PipelineLayout &pipelineLayout,
601         const vk::ShaderModulePtr &vsShader,
602         const vk::ShaderModulePtr &fsShader,
603         GraphicsShaderProgramAndPipelines *programAndPipelines,
604         const vk::GraphicsPipelineDesc *pipelineDesc,
605         const VkDescriptorSet descriptorSet,
606         const void *pushConstants,
607         size_t pushConstantsSize,
608         vk::RenderPassCommandBuffer *commandBuffer);
609     angle::Result setupGraphicsProgram(ContextVk *contextVk,
610                                        Function function,
611                                        const vk::ShaderModulePtr &vsShader,
612                                        const vk::ShaderModulePtr &fsShader,
613                                        GraphicsShaderProgramAndPipelines *programAndPipelines,
614                                        const vk::GraphicsPipelineDesc *pipelineDesc,
615                                        const VkDescriptorSet descriptorSet,
616                                        const void *pushConstants,
617                                        size_t pushConstantsSize,
618                                        vk::RenderPassCommandBuffer *commandBuffer);
619 
620     // Initializes descriptor set layout, pipeline layout and descriptor pool corresponding to given
621     // function, if not already initialized.  Uses setSizes to create the layout.  For example, if
622     // this array has two entries {STORAGE_TEXEL_BUFFER, 1} and {UNIFORM_TEXEL_BUFFER, 3}, then the
623     // created set layout would be binding 0 for storage texel buffer and bindings 1 through 3 for
624     // uniform texel buffer.  All resources are put in set 0.
625     angle::Result ensureResourcesInitialized(ContextVk *contextVk,
626                                              Function function,
627                                              VkDescriptorPoolSize *setSizes,
628                                              size_t setSizesCount,
629                                              size_t pushConstantsSize);
630 
631     // Initializers corresponding to functions, calling into ensureResourcesInitialized with the
632     // appropriate parameters.
633     angle::Result ensureConvertIndexResourcesInitialized(ContextVk *contextVk);
634     angle::Result ensureConvertIndexIndirectResourcesInitialized(ContextVk *contextVk);
635     angle::Result ensureConvertIndexIndirectLineLoopResourcesInitialized(ContextVk *contextVk);
636     angle::Result ensureConvertIndirectLineLoopResourcesInitialized(ContextVk *contextVk);
637     angle::Result ensureConvertVertexResourcesInitialized(ContextVk *contextVk);
638     angle::Result ensureImageClearResourcesInitialized(ContextVk *contextVk);
639     angle::Result ensureImageCopyResourcesInitialized(ContextVk *contextVk);
640     angle::Result ensureCopyImageToBufferResourcesInitialized(ContextVk *contextVk);
641     angle::Result ensureBlitResolveResourcesInitialized(ContextVk *contextVk);
642     angle::Result ensureBlitResolveStencilNoExportResourcesInitialized(ContextVk *contextVk);
643     angle::Result ensureExportStencilResourcesInitialized(ContextVk *contextVk);
644     angle::Result ensureOverlayDrawResourcesInitialized(ContextVk *contextVk);
645     angle::Result ensureGenerateMipmapResourcesInitialized(ContextVk *contextVk);
646     angle::Result ensureTransCodeEtcToBcResourcesInitialized(ContextVk *contextVk);
647     angle::Result ensureUnresolveResourcesInitialized(ContextVk *contextVk,
648                                                       Function function,
649                                                       uint32_t attachmentIndex);
650 
651     angle::Result ensureImageCopyResourcesInitializedWithSampler(
652         ContextVk *contextVk,
653         const vk::SamplerDesc &samplerDesc);
654 
655     angle::Result ensureSamplersInitialized(ContextVk *context);
656 
657     angle::Result ensureGenerateFragmentShadingRateResourcesInitialized(ContextVk *contextVk);
658 
659     angle::Result startRenderPass(ContextVk *contextVk,
660                                   vk::ImageHelper *image,
661                                   const vk::ImageView *imageView,
662                                   const vk::RenderPassDesc &renderPassDesc,
663                                   const gl::Rectangle &renderArea,
664                                   const VkImageAspectFlags aspectFlags,
665                                   const VkClearValue *clearValue,
666                                   vk::RenderPassSource renderPassSource,
667                                   vk::RenderPassCommandBuffer **commandBufferOut);
668 
669     // Set up descriptor set and call dispatch.
670     angle::Result convertVertexBufferImpl(
671         ContextVk *contextVk,
672         vk::BufferHelper *dst,
673         vk::BufferHelper *src,
674         uint32_t flags,
675         vk::OutsideRenderPassCommandBufferHelper *commandBufferHelper,
676         const ConvertVertexShaderParams &shaderParams,
677         const OffsetAndVertexCounts &additionalOffsetVertexCounts);
678 
679     // Blits or resolves either color or depth/stencil, based on which view is given.
680     angle::Result blitResolveImpl(ContextVk *contextVk,
681                                   FramebufferVk *framebuffer,
682                                   vk::ImageHelper *src,
683                                   const vk::ImageView *srcColorView,
684                                   const vk::ImageView *srcDepthView,
685                                   const vk::ImageView *srcStencilView,
686                                   const BlitResolveParameters &params);
687 
688     // Allocates a single descriptor set.
689     angle::Result allocateDescriptorSetWithLayout(
690         ContextVk *contextVk,
691         vk::CommandBufferHelperCommon *commandBufferHelper,
692         vk::DynamicDescriptorPool &descriptorPool,
693         const vk::DescriptorSetLayout &descriptorSetLayout,
694         VkDescriptorSet *descriptorSetOut);
695 
696     angle::Result allocateDescriptorSet(ContextVk *contextVk,
697                                         vk::CommandBufferHelperCommon *commandBufferHelper,
698                                         Function function,
699                                         VkDescriptorSet *descriptorSetOut);
700 
701     angle::Result allocateDescriptorSetForImageCopyWithSampler(
702         ContextVk *contextVk,
703         vk::CommandBufferHelperCommon *commandBufferHelper,
704         const vk::SamplerDesc &samplerDesc,
705         VkDescriptorSet *descriptorSetOut);
706 
707     angle::PackedEnumMap<Function, vk::DescriptorSetLayoutPointerArray> mDescriptorSetLayouts;
708     angle::PackedEnumMap<Function, vk::PipelineLayoutPtr> mPipelineLayouts;
709     angle::PackedEnumMap<Function, vk::DynamicDescriptorPool> mDescriptorPools;
710 
711     std::unordered_map<vk::SamplerDesc, vk::DescriptorSetLayoutPointerArray>
712         mImageCopyWithSamplerDescriptorSetLayouts;
713     std::unordered_map<vk::SamplerDesc, vk::PipelineLayoutPtr> mImageCopyWithSamplerPipelineLayouts;
714     std::unordered_map<vk::SamplerDesc, vk::DynamicDescriptorPool>
715         mImageCopyWithSamplerDescriptorPools;
716 
717     ComputeShaderProgramAndPipelines
718         mConvertIndex[vk::InternalShader::ConvertIndex_comp::kArrayLen];
719     ComputeShaderProgramAndPipelines mConvertIndexIndirectLineLoop
720         [vk::InternalShader::ConvertIndexIndirectLineLoop_comp::kArrayLen];
721     ComputeShaderProgramAndPipelines
722         mConvertIndirectLineLoop[vk::InternalShader::ConvertIndirectLineLoop_comp::kArrayLen];
723     ComputeShaderProgramAndPipelines
724         mConvertVertex[vk::InternalShader::ConvertVertex_comp::kArrayLen];
725     GraphicsShaderProgramAndPipelines mImageClearVSOnly;
726     GraphicsShaderProgramAndPipelines mImageClear[vk::InternalShader::ImageClear_frag::kArrayLen];
727     GraphicsShaderProgramAndPipelines mImageCopy[vk::InternalShader::ImageCopy_frag::kArrayLen];
728     GraphicsShaderProgramAndPipelines mImageCopyFloat;
729     std::unordered_map<vk::SamplerDesc, GraphicsShaderProgramAndPipelines> mImageCopyWithSampler;
730     ComputeShaderProgramAndPipelines
731         mCopyImageToBuffer[vk::InternalShader::CopyImageToBuffer_comp::kArrayLen];
732     GraphicsShaderProgramAndPipelines mBlitResolve[vk::InternalShader::BlitResolve_frag::kArrayLen];
733     GraphicsShaderProgramAndPipelines mBlit3DSrc[vk::InternalShader::Blit3DSrc_frag::kArrayLen];
734     ComputeShaderProgramAndPipelines
735         mBlitResolveStencilNoExport[vk::InternalShader::BlitResolveStencilNoExport_comp::kArrayLen];
736     GraphicsShaderProgramAndPipelines mExportStencil;
737     GraphicsShaderProgramAndPipelines mOverlayDraw;
738     ComputeShaderProgramAndPipelines
739         mGenerateMipmap[vk::InternalShader::GenerateMipmap_comp::kArrayLen];
740     ComputeShaderProgramAndPipelines mEtcToBc[vk::InternalShader::EtcToBc_comp::kArrayLen];
741 
742     // Unresolve shaders are special as they are generated on the fly due to the large number of
743     // combinations.
744     std::unordered_map<uint32_t, vk::ShaderModulePtr> mUnresolveFragShaders;
745     std::unordered_map<uint32_t, GraphicsShaderProgramAndPipelines> mUnresolve;
746 
747     ComputeShaderProgramAndPipelines mGenerateFragmentShadingRateAttachment;
748 
749     vk::Sampler mPointSampler;
750     vk::Sampler mLinearSampler;
751 };
752 
753 // This class' responsibility is to create index buffers needed to support line loops in Vulkan.
754 // In the setup phase of drawing, the createIndexBuffer method should be called with the
755 // current draw call parameters. If an element array buffer is bound for an indexed draw, use
756 // createIndexBufferFromElementArrayBuffer.
757 //
758 // If the user wants to draw a loop between [v1, v2, v3], we will create an indexed buffer with
759 // these indexes: [0, 1, 2, 3, 0] to emulate the loop.
760 class LineLoopHelper final : angle::NonCopyable
761 {
762   public:
763     LineLoopHelper(vk::Renderer *renderer);
764     ~LineLoopHelper();
765 
766     angle::Result getIndexBufferForDrawArrays(ContextVk *contextVk,
767                                               uint32_t clampedVertexCount,
768                                               GLint firstVertex,
769                                               vk::BufferHelper **bufferOut);
770 
771     angle::Result getIndexBufferForElementArrayBuffer(ContextVk *contextVk,
772                                                       BufferVk *elementArrayBufferVk,
773                                                       gl::DrawElementsType glIndexType,
774                                                       int indexCount,
775                                                       intptr_t elementArrayOffset,
776                                                       vk::BufferHelper **bufferOut,
777                                                       uint32_t *indexCountOut);
778 
779     angle::Result streamIndices(ContextVk *contextVk,
780                                 gl::DrawElementsType glIndexType,
781                                 GLsizei indexCount,
782                                 const uint8_t *srcPtr,
783                                 vk::BufferHelper **bufferOut,
784                                 uint32_t *indexCountOut);
785 
786     angle::Result streamIndicesIndirect(ContextVk *contextVk,
787                                         gl::DrawElementsType glIndexType,
788                                         vk::BufferHelper *indexBuffer,
789                                         vk::BufferHelper *indirectBuffer,
790                                         VkDeviceSize indirectBufferOffset,
791                                         vk::BufferHelper **indexBufferOut,
792                                         vk::BufferHelper **indirectBufferOut);
793 
794     angle::Result streamArrayIndirect(ContextVk *contextVk,
795                                       size_t vertexCount,
796                                       vk::BufferHelper *arrayIndirectBuffer,
797                                       VkDeviceSize arrayIndirectBufferOffset,
798                                       vk::BufferHelper **indexBufferOut,
799                                       vk::BufferHelper **indexIndirectBufferOut);
800 
801     void release(ContextVk *contextVk);
802     void destroy(vk::Renderer *renderer);
803 
getCurrentIndexBuffer()804     vk::BufferHelper *getCurrentIndexBuffer() { return mDynamicIndexBuffer.getBuffer(); }
805 
Draw(uint32_t count,uint32_t baseVertex,vk::RenderPassCommandBuffer * commandBuffer)806     static void Draw(uint32_t count,
807                      uint32_t baseVertex,
808                      vk::RenderPassCommandBuffer *commandBuffer)
809     {
810         // Our first index is always 0 because that's how we set it up in createIndexBuffer*.
811         commandBuffer->drawIndexedBaseVertex(count, baseVertex);
812     }
813 
814   private:
815     ConversionBuffer mDynamicIndexBuffer;
816     ConversionBuffer mDynamicIndirectBuffer;
817 };
818 }  // namespace rx
819 
820 #endif  // LIBANGLE_RENDERER_VULKAN_UTILSVK_H_
821