• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2019 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 // vk_wrapper:
7 //    Wrapper classes around Vulkan objects. In an ideal world we could generate this
8 //    from vk.xml. Or reuse the generator in the vkhpp tool. For now this is manually
9 //    generated and we must add missing functions and objects as we need them.
10 
11 #ifndef LIBANGLE_RENDERER_VULKAN_VK_WRAPPER_H_
12 #define LIBANGLE_RENDERER_VULKAN_VK_WRAPPER_H_
13 
14 #include "volk.h"
15 
16 #include "libANGLE/renderer/renderer_utils.h"
17 #include "libANGLE/renderer/vulkan/vk_mem_alloc_wrapper.h"
18 
19 namespace rx
20 {
21 namespace vk
22 {
23 // Helper macros that apply to all the wrapped object types.
24 // Unimplemented handle types:
25 // Instance
26 // PhysicalDevice
27 // Device
28 // Queue
29 // DescriptorSet
30 
31 #define ANGLE_HANDLE_TYPES_X(FUNC) \
32     FUNC(Buffer)                   \
33     FUNC(BufferView)               \
34     FUNC(CommandPool)              \
35     FUNC(DescriptorPool)           \
36     FUNC(DescriptorSetLayout)      \
37     FUNC(DeviceMemory)             \
38     FUNC(Event)                    \
39     FUNC(Fence)                    \
40     FUNC(Framebuffer)              \
41     FUNC(Image)                    \
42     FUNC(ImageView)                \
43     FUNC(Pipeline)                 \
44     FUNC(PipelineCache)            \
45     FUNC(PipelineLayout)           \
46     FUNC(QueryPool)                \
47     FUNC(RenderPass)               \
48     FUNC(Sampler)                  \
49     FUNC(Semaphore)                \
50     FUNC(ShaderModule)             \
51     FUNC(Allocation)
52 
53 #define ANGLE_COMMA_SEP_FUNC(TYPE) TYPE,
54 
55 enum class HandleType
56 {
57     Invalid,
58     CommandBuffer,
59     ANGLE_HANDLE_TYPES_X(ANGLE_COMMA_SEP_FUNC)
60 };
61 
62 #undef ANGLE_COMMA_SEP_FUNC
63 
64 #define ANGLE_PRE_DECLARE_CLASS_FUNC(TYPE) class TYPE;
ANGLE_HANDLE_TYPES_X(ANGLE_PRE_DECLARE_CLASS_FUNC)65 ANGLE_HANDLE_TYPES_X(ANGLE_PRE_DECLARE_CLASS_FUNC)
66 namespace priv
67 {
68 class CommandBuffer;
69 }  // namespace priv
70 #undef ANGLE_PRE_DECLARE_CLASS_FUNC
71 
72 // Returns the HandleType of a Vk Handle.
73 template <typename T>
74 struct HandleTypeHelper;
75 
76 #define ANGLE_HANDLE_TYPE_HELPER_FUNC(TYPE)                         \
77     template <>                                                     \
78     struct HandleTypeHelper<TYPE>                                   \
79     {                                                               \
80         constexpr static HandleType kHandleType = HandleType::TYPE; \
81     };
82 
83 ANGLE_HANDLE_TYPES_X(ANGLE_HANDLE_TYPE_HELPER_FUNC)
84 template <>
85 struct HandleTypeHelper<priv::CommandBuffer>
86 {
87     constexpr static HandleType kHandleType = HandleType::CommandBuffer;
88 };
89 
90 #undef ANGLE_HANDLE_TYPE_HELPER_FUNC
91 
92 // Base class for all wrapped vulkan objects. Implements several common helper routines.
93 template <typename DerivedT, typename HandleT>
94 class WrappedObject : angle::NonCopyable
95 {
96   public:
97     HandleT getHandle() const { return mHandle; }
98     void setHandle(HandleT handle) { mHandle = handle; }
99     bool valid() const { return (mHandle != VK_NULL_HANDLE); }
100 
101     const HandleT *ptr() const { return &mHandle; }
102 
103     HandleT release()
104     {
105         HandleT handle = mHandle;
106         mHandle        = VK_NULL_HANDLE;
107         return handle;
108     }
109 
110   protected:
111     WrappedObject() : mHandle(VK_NULL_HANDLE) {}
112     ~WrappedObject() { ASSERT(!valid()); }
113 
114     WrappedObject(WrappedObject &&other) : mHandle(other.mHandle)
115     {
116         other.mHandle = VK_NULL_HANDLE;
117     }
118 
119     // Only works to initialize empty objects, since we don't have the device handle.
120     WrappedObject &operator=(WrappedObject &&other)
121     {
122         ASSERT(!valid());
123         std::swap(mHandle, other.mHandle);
124         return *this;
125     }
126 
127     HandleT mHandle;
128 };
129 
130 class CommandPool final : public WrappedObject<CommandPool, VkCommandPool>
131 {
132   public:
133     CommandPool() = default;
134 
135     void destroy(VkDevice device);
136     VkResult reset(VkDevice device, VkCommandPoolResetFlags flags);
137     void freeCommandBuffers(VkDevice device,
138                             uint32_t commandBufferCount,
139                             const VkCommandBuffer *commandBuffers);
140 
141     VkResult init(VkDevice device, const VkCommandPoolCreateInfo &createInfo);
142 };
143 
144 class Pipeline final : public WrappedObject<Pipeline, VkPipeline>
145 {
146   public:
147     Pipeline() = default;
148     void destroy(VkDevice device);
149 
150     VkResult initGraphics(VkDevice device,
151                           const VkGraphicsPipelineCreateInfo &createInfo,
152                           const PipelineCache &pipelineCacheVk);
153     VkResult initCompute(VkDevice device,
154                          const VkComputePipelineCreateInfo &createInfo,
155                          const PipelineCache &pipelineCacheVk);
156 };
157 
158 namespace priv
159 {
160 
161 // Helper class that wraps a Vulkan command buffer.
162 class CommandBuffer : public WrappedObject<CommandBuffer, VkCommandBuffer>
163 {
164   public:
165     CommandBuffer() = default;
166 
167     VkCommandBuffer releaseHandle();
168 
169     // This is used for normal pool allocated command buffers. It reset the handle.
170     void destroy(VkDevice device);
171 
172     // This is used in conjunction with VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT.
173     void destroy(VkDevice device, const CommandPool &commandPool);
174 
175     VkResult init(VkDevice device, const VkCommandBufferAllocateInfo &createInfo);
176 
177     // There is no way to know if the command buffer contains any commands.
178     static bool CanKnowIfEmpty() { return false; }
179     bool empty() const { return false; }
180 
181     using WrappedObject::operator=;
182 
183     static bool SupportsQueries(const VkPhysicalDeviceFeatures &features)
184     {
185         return (features.inheritedQueries == VK_TRUE);
186     }
187 
188     // Vulkan command buffers are executed as secondary command buffers within a primary command
189     // buffer.
190     static constexpr bool ExecutesInline() { return false; }
191 
192     VkResult begin(const VkCommandBufferBeginInfo &info);
193 
194     void beginQuery(const QueryPool &queryPool, uint32_t query, VkQueryControlFlags flags);
195 
196     void beginRenderPass(const VkRenderPassBeginInfo &beginInfo, VkSubpassContents subpassContents);
197 
198     void bindDescriptorSets(const PipelineLayout &layout,
199                             VkPipelineBindPoint pipelineBindPoint,
200                             uint32_t firstSet,
201                             uint32_t descriptorSetCount,
202                             const VkDescriptorSet *descriptorSets,
203                             uint32_t dynamicOffsetCount,
204                             const uint32_t *dynamicOffsets);
205     void bindGraphicsPipeline(const Pipeline &pipeline);
206     void bindComputePipeline(const Pipeline &pipeline);
207     void bindPipeline(VkPipelineBindPoint pipelineBindPoint, const Pipeline &pipeline);
208 
209     void bindIndexBuffer(const Buffer &buffer, VkDeviceSize offset, VkIndexType indexType);
210     void bindVertexBuffers(uint32_t firstBinding,
211                            uint32_t bindingCount,
212                            const VkBuffer *buffers,
213                            const VkDeviceSize *offsets);
214 
215     void blitImage(const Image &srcImage,
216                    VkImageLayout srcImageLayout,
217                    const Image &dstImage,
218                    VkImageLayout dstImageLayout,
219                    uint32_t regionCount,
220                    const VkImageBlit *regions,
221                    VkFilter filter);
222 
223     void clearColorImage(const Image &image,
224                          VkImageLayout imageLayout,
225                          const VkClearColorValue &color,
226                          uint32_t rangeCount,
227                          const VkImageSubresourceRange *ranges);
228     void clearDepthStencilImage(const Image &image,
229                                 VkImageLayout imageLayout,
230                                 const VkClearDepthStencilValue &depthStencil,
231                                 uint32_t rangeCount,
232                                 const VkImageSubresourceRange *ranges);
233 
234     void clearAttachments(uint32_t attachmentCount,
235                           const VkClearAttachment *attachments,
236                           uint32_t rectCount,
237                           const VkClearRect *rects);
238 
239     void copyBuffer(const Buffer &srcBuffer,
240                     const Buffer &destBuffer,
241                     uint32_t regionCount,
242                     const VkBufferCopy *regions);
243 
244     void copyBufferToImage(VkBuffer srcBuffer,
245                            const Image &dstImage,
246                            VkImageLayout dstImageLayout,
247                            uint32_t regionCount,
248                            const VkBufferImageCopy *regions);
249     void copyImageToBuffer(const Image &srcImage,
250                            VkImageLayout srcImageLayout,
251                            VkBuffer dstBuffer,
252                            uint32_t regionCount,
253                            const VkBufferImageCopy *regions);
254     void copyImage(const Image &srcImage,
255                    VkImageLayout srcImageLayout,
256                    const Image &dstImage,
257                    VkImageLayout dstImageLayout,
258                    uint32_t regionCount,
259                    const VkImageCopy *regions);
260 
261     void dispatch(uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ);
262     void dispatchIndirect(const Buffer &buffer, VkDeviceSize offset);
263 
264     void draw(uint32_t vertexCount,
265               uint32_t instanceCount,
266               uint32_t firstVertex,
267               uint32_t firstInstance);
268     void draw(uint32_t vertexCount, uint32_t firstVertex);
269     void drawInstanced(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex);
270     void drawInstancedBaseInstance(uint32_t vertexCount,
271                                    uint32_t instanceCount,
272                                    uint32_t firstVertex,
273                                    uint32_t firstInstance);
274     void drawIndexed(uint32_t indexCount,
275                      uint32_t instanceCount,
276                      uint32_t firstIndex,
277                      int32_t vertexOffset,
278                      uint32_t firstInstance);
279     void drawIndexed(uint32_t indexCount);
280     void drawIndexedBaseVertex(uint32_t indexCount, uint32_t vertexOffset);
281     void drawIndexedInstanced(uint32_t indexCount, uint32_t instanceCount);
282     void drawIndexedInstancedBaseVertex(uint32_t indexCount,
283                                         uint32_t instanceCount,
284                                         uint32_t vertexOffset);
285     void drawIndexedInstancedBaseVertexBaseInstance(uint32_t indexCount,
286                                                     uint32_t instanceCount,
287                                                     uint32_t firstIndex,
288                                                     int32_t vertexOffset,
289                                                     uint32_t firstInstance);
290     void drawIndexedIndirect(const Buffer &buffer,
291                              VkDeviceSize offset,
292                              uint32_t drawCount,
293                              uint32_t stride);
294     void drawIndirect(const Buffer &buffer,
295                       VkDeviceSize offset,
296                       uint32_t drawCount,
297                       uint32_t stride);
298 
299     VkResult end();
300     void endQuery(const QueryPool &queryPool, uint32_t query);
301     void endRenderPass();
302     void executeCommands(uint32_t commandBufferCount, const CommandBuffer *commandBuffers);
303 
304     void getMemoryUsageStats(size_t *usedMemoryOut, size_t *allocatedMemoryOut) const;
305 
306     void executionBarrier(VkPipelineStageFlags stageMask);
307 
308     void fillBuffer(const Buffer &dstBuffer,
309                     VkDeviceSize dstOffset,
310                     VkDeviceSize size,
311                     uint32_t data);
312 
313     void bufferBarrier(VkPipelineStageFlags srcStageMask,
314                        VkPipelineStageFlags dstStageMask,
315                        const VkBufferMemoryBarrier *bufferMemoryBarrier);
316 
317     void imageBarrier(VkPipelineStageFlags srcStageMask,
318                       VkPipelineStageFlags dstStageMask,
319                       const VkImageMemoryBarrier &imageMemoryBarrier);
320 
321     void memoryBarrier(VkPipelineStageFlags srcStageMask,
322                        VkPipelineStageFlags dstStageMask,
323                        const VkMemoryBarrier *memoryBarrier);
324 
325     void pipelineBarrier(VkPipelineStageFlags srcStageMask,
326                          VkPipelineStageFlags dstStageMask,
327                          VkDependencyFlags dependencyFlags,
328                          uint32_t memoryBarrierCount,
329                          const VkMemoryBarrier *memoryBarriers,
330                          uint32_t bufferMemoryBarrierCount,
331                          const VkBufferMemoryBarrier *bufferMemoryBarriers,
332                          uint32_t imageMemoryBarrierCount,
333                          const VkImageMemoryBarrier *imageMemoryBarriers);
334 
335     void pushConstants(const PipelineLayout &layout,
336                        VkShaderStageFlags flag,
337                        uint32_t offset,
338                        uint32_t size,
339                        const void *data);
340 
341     void setEvent(VkEvent event, VkPipelineStageFlags stageMask);
342     VkResult reset();
343     void resetEvent(VkEvent event, VkPipelineStageFlags stageMask);
344     void resetQueryPool(const QueryPool &queryPool, uint32_t firstQuery, uint32_t queryCount);
345     void resolveImage(const Image &srcImage,
346                       VkImageLayout srcImageLayout,
347                       const Image &dstImage,
348                       VkImageLayout dstImageLayout,
349                       uint32_t regionCount,
350                       const VkImageResolve *regions);
351     void waitEvents(uint32_t eventCount,
352                     const VkEvent *events,
353                     VkPipelineStageFlags srcStageMask,
354                     VkPipelineStageFlags dstStageMask,
355                     uint32_t memoryBarrierCount,
356                     const VkMemoryBarrier *memoryBarriers,
357                     uint32_t bufferMemoryBarrierCount,
358                     const VkBufferMemoryBarrier *bufferMemoryBarriers,
359                     uint32_t imageMemoryBarrierCount,
360                     const VkImageMemoryBarrier *imageMemoryBarriers);
361 
362     void writeTimestamp(VkPipelineStageFlagBits pipelineStage,
363                         const QueryPool &queryPool,
364                         uint32_t query);
365 
366     // VK_EXT_transform_feedback
367     void beginTransformFeedbackEXT(uint32_t firstCounterBuffer,
368                                    uint32_t counterBufferCount,
369                                    const VkBuffer *counterBuffers,
370                                    const VkDeviceSize *counterBufferOffsets);
371     void endTransformFeedbackEXT(uint32_t firstCounterBuffer,
372                                  uint32_t counterBufferCount,
373                                  const VkBuffer *counterBuffers,
374                                  const VkDeviceSize *counterBufferOffsets);
375     void bindTransformFeedbackBuffersEXT(uint32_t firstBinding,
376                                          uint32_t bindingCount,
377                                          const VkBuffer *buffers,
378                                          const VkDeviceSize *offsets,
379                                          const VkDeviceSize *sizes);
380 
381     // VK_EXT_debug_utils
382     void beginDebugUtilsLabelEXT(const VkDebugUtilsLabelEXT &labelInfo);
383     void endDebugUtilsLabelEXT();
384     void insertDebugUtilsLabelEXT(const VkDebugUtilsLabelEXT &labelInfo);
385 };
386 }  // namespace priv
387 
388 class Image final : public WrappedObject<Image, VkImage>
389 {
390   public:
391     Image() = default;
392 
393     // Use this method if the lifetime of the image is not controlled by ANGLE. (SwapChain)
394     void setHandle(VkImage handle);
395 
396     // Called on shutdown when the helper class *doesn't* own the handle to the image resource.
397     void reset();
398 
399     // Called on shutdown when the helper class *does* own the handle to the image resource.
400     void destroy(VkDevice device);
401 
402     VkResult init(VkDevice device, const VkImageCreateInfo &createInfo);
403 
404     void getMemoryRequirements(VkDevice device, VkMemoryRequirements *requirementsOut) const;
405     VkResult bindMemory(VkDevice device, const DeviceMemory &deviceMemory);
406 
407     void getSubresourceLayout(VkDevice device,
408                               VkImageAspectFlagBits aspectMask,
409                               uint32_t mipLevel,
410                               uint32_t arrayLayer,
411                               VkSubresourceLayout *outSubresourceLayout) const;
412 };
413 
414 class ImageView final : public WrappedObject<ImageView, VkImageView>
415 {
416   public:
417     ImageView() = default;
418     void destroy(VkDevice device);
419 
420     VkResult init(VkDevice device, const VkImageViewCreateInfo &createInfo);
421 };
422 
423 class Semaphore final : public WrappedObject<Semaphore, VkSemaphore>
424 {
425   public:
426     Semaphore() = default;
427     void destroy(VkDevice device);
428 
429     VkResult init(VkDevice device);
430 };
431 
432 class Framebuffer final : public WrappedObject<Framebuffer, VkFramebuffer>
433 {
434   public:
435     Framebuffer() = default;
436     void destroy(VkDevice device);
437 
438     // Use this method only in necessary cases. (RenderPass)
439     void setHandle(VkFramebuffer handle);
440 
441     VkResult init(VkDevice device, const VkFramebufferCreateInfo &createInfo);
442 };
443 
444 class DeviceMemory final : public WrappedObject<DeviceMemory, VkDeviceMemory>
445 {
446   public:
447     DeviceMemory() = default;
448     void destroy(VkDevice device);
449 
450     VkResult allocate(VkDevice device, const VkMemoryAllocateInfo &allocInfo);
451     VkResult map(VkDevice device,
452                  VkDeviceSize offset,
453                  VkDeviceSize size,
454                  VkMemoryMapFlags flags,
455                  uint8_t **mapPointer) const;
456     void unmap(VkDevice device) const;
457 };
458 
459 class Allocation final : public WrappedObject<Allocation, VmaAllocation>
460 {
461   public:
462     Allocation() = default;
463     void destroy(VmaAllocator allocator);
464 
465     VkResult createBufferAndMemory(VmaAllocator allocator,
466                                    const VkBufferCreateInfo *pBufferCreateInfo,
467                                    VkMemoryPropertyFlags requiredFlags,
468                                    VkMemoryPropertyFlags preferredFlags,
469                                    bool persistentlyMappedBuffers,
470                                    Buffer *buffer,
471                                    VkMemoryPropertyFlags *pMemPropertyOut);
472     VkResult map(VmaAllocator allocator, uint8_t **mapPointer) const;
473     void unmap(VmaAllocator allocator) const;
474     void flush(VmaAllocator allocator, VkDeviceSize offset, VkDeviceSize size);
475     void invalidate(VmaAllocator allocator, VkDeviceSize offset, VkDeviceSize size);
476 };
477 
478 class RenderPass final : public WrappedObject<RenderPass, VkRenderPass>
479 {
480   public:
481     RenderPass() = default;
482     void destroy(VkDevice device);
483 
484     VkResult init(VkDevice device, const VkRenderPassCreateInfo &createInfo);
485 };
486 
487 enum class StagingUsage
488 {
489     Read,
490     Write,
491     Both,
492 };
493 
494 class Buffer final : public WrappedObject<Buffer, VkBuffer>
495 {
496   public:
497     Buffer() = default;
498     void destroy(VkDevice device);
499 
500     VkResult init(VkDevice device, const VkBufferCreateInfo &createInfo);
501     VkResult bindMemory(VkDevice device, const DeviceMemory &deviceMemory);
502     void getMemoryRequirements(VkDevice device, VkMemoryRequirements *memoryRequirementsOut);
503 };
504 
505 class BufferView final : public WrappedObject<BufferView, VkBufferView>
506 {
507   public:
508     BufferView() = default;
509     void destroy(VkDevice device);
510 
511     VkResult init(VkDevice device, const VkBufferViewCreateInfo &createInfo);
512 };
513 
514 class ShaderModule final : public WrappedObject<ShaderModule, VkShaderModule>
515 {
516   public:
517     ShaderModule() = default;
518     void destroy(VkDevice device);
519 
520     VkResult init(VkDevice device, const VkShaderModuleCreateInfo &createInfo);
521 };
522 
523 class PipelineLayout final : public WrappedObject<PipelineLayout, VkPipelineLayout>
524 {
525   public:
526     PipelineLayout() = default;
527     void destroy(VkDevice device);
528 
529     VkResult init(VkDevice device, const VkPipelineLayoutCreateInfo &createInfo);
530 };
531 
532 class PipelineCache final : public WrappedObject<PipelineCache, VkPipelineCache>
533 {
534   public:
535     PipelineCache() = default;
536     void destroy(VkDevice device);
537 
538     VkResult init(VkDevice device, const VkPipelineCacheCreateInfo &createInfo);
539     VkResult getCacheData(VkDevice device, size_t *cacheSize, void *cacheData);
540     VkResult merge(VkDevice device,
541                    VkPipelineCache dstCache,
542                    uint32_t srcCacheCount,
543                    const VkPipelineCache *srcCaches);
544 };
545 
546 class DescriptorSetLayout final : public WrappedObject<DescriptorSetLayout, VkDescriptorSetLayout>
547 {
548   public:
549     DescriptorSetLayout() = default;
550     void destroy(VkDevice device);
551 
552     VkResult init(VkDevice device, const VkDescriptorSetLayoutCreateInfo &createInfo);
553 };
554 
555 class DescriptorPool final : public WrappedObject<DescriptorPool, VkDescriptorPool>
556 {
557   public:
558     DescriptorPool() = default;
559     void destroy(VkDevice device);
560 
561     VkResult init(VkDevice device, const VkDescriptorPoolCreateInfo &createInfo);
562 
563     VkResult allocateDescriptorSets(VkDevice device,
564                                     const VkDescriptorSetAllocateInfo &allocInfo,
565                                     VkDescriptorSet *descriptorSetsOut);
566     VkResult freeDescriptorSets(VkDevice device,
567                                 uint32_t descriptorSetCount,
568                                 const VkDescriptorSet *descriptorSets);
569 };
570 
571 class Sampler final : public WrappedObject<Sampler, VkSampler>
572 {
573   public:
574     Sampler() = default;
575     void destroy(VkDevice device);
576     VkResult init(VkDevice device, const VkSamplerCreateInfo &createInfo);
577 };
578 
579 class Event final : public WrappedObject<Event, VkEvent>
580 {
581   public:
582     Event() = default;
583     void destroy(VkDevice device);
584     using WrappedObject::operator=;
585 
586     VkResult init(VkDevice device, const VkEventCreateInfo &createInfo);
587     VkResult getStatus(VkDevice device) const;
588     VkResult set(VkDevice device) const;
589     VkResult reset(VkDevice device) const;
590 };
591 
592 class Fence final : public WrappedObject<Fence, VkFence>
593 {
594   public:
595     Fence() = default;
596     void destroy(VkDevice device);
597     using WrappedObject::operator=;
598 
599     VkResult init(VkDevice device, const VkFenceCreateInfo &createInfo);
600     VkResult reset(VkDevice device);
601     VkResult getStatus(VkDevice device) const;
602     VkResult wait(VkDevice device, uint64_t timeout) const;
603 };
604 
605 class QueryPool final : public WrappedObject<QueryPool, VkQueryPool>
606 {
607   public:
608     QueryPool() = default;
609     void destroy(VkDevice device);
610 
611     VkResult init(VkDevice device, const VkQueryPoolCreateInfo &createInfo);
612     VkResult getResults(VkDevice device,
613                         uint32_t firstQuery,
614                         uint32_t queryCount,
615                         size_t dataSize,
616                         void *data,
617                         VkDeviceSize stride,
618                         VkQueryResultFlags flags) const;
619 };
620 
621 // CommandPool implementation.
622 ANGLE_INLINE void CommandPool::destroy(VkDevice device)
623 {
624     if (valid())
625     {
626         vkDestroyCommandPool(device, mHandle, nullptr);
627         mHandle = VK_NULL_HANDLE;
628     }
629 }
630 
631 ANGLE_INLINE VkResult CommandPool::reset(VkDevice device, VkCommandPoolResetFlags flags)
632 {
633     ASSERT(valid());
634     return vkResetCommandPool(device, mHandle, flags);
635 }
636 
637 ANGLE_INLINE void CommandPool::freeCommandBuffers(VkDevice device,
638                                                   uint32_t commandBufferCount,
639                                                   const VkCommandBuffer *commandBuffers)
640 {
641     ASSERT(valid());
642     vkFreeCommandBuffers(device, mHandle, commandBufferCount, commandBuffers);
643 }
644 
645 ANGLE_INLINE VkResult CommandPool::init(VkDevice device, const VkCommandPoolCreateInfo &createInfo)
646 {
647     ASSERT(!valid());
648     return vkCreateCommandPool(device, &createInfo, nullptr, &mHandle);
649 }
650 
651 namespace priv
652 {
653 
654 // CommandBuffer implementation.
655 ANGLE_INLINE VkCommandBuffer CommandBuffer::releaseHandle()
656 {
657     VkCommandBuffer handle = mHandle;
658     mHandle                = nullptr;
659     return handle;
660 }
661 
662 ANGLE_INLINE VkResult CommandBuffer::init(VkDevice device,
663                                           const VkCommandBufferAllocateInfo &createInfo)
664 {
665     ASSERT(!valid());
666     return vkAllocateCommandBuffers(device, &createInfo, &mHandle);
667 }
668 
669 ANGLE_INLINE void CommandBuffer::blitImage(const Image &srcImage,
670                                            VkImageLayout srcImageLayout,
671                                            const Image &dstImage,
672                                            VkImageLayout dstImageLayout,
673                                            uint32_t regionCount,
674                                            const VkImageBlit *regions,
675                                            VkFilter filter)
676 {
677     ASSERT(valid() && srcImage.valid() && dstImage.valid());
678     ASSERT(regionCount == 1);
679     vkCmdBlitImage(mHandle, srcImage.getHandle(), srcImageLayout, dstImage.getHandle(),
680                    dstImageLayout, 1, regions, filter);
681 }
682 
683 ANGLE_INLINE VkResult CommandBuffer::begin(const VkCommandBufferBeginInfo &info)
684 {
685     ASSERT(valid());
686     return vkBeginCommandBuffer(mHandle, &info);
687 }
688 
689 ANGLE_INLINE VkResult CommandBuffer::end()
690 {
691     ASSERT(valid());
692     return vkEndCommandBuffer(mHandle);
693 }
694 
695 ANGLE_INLINE VkResult CommandBuffer::reset()
696 {
697     ASSERT(valid());
698     return vkResetCommandBuffer(mHandle, 0);
699 }
700 
701 ANGLE_INLINE void CommandBuffer::memoryBarrier(VkPipelineStageFlags srcStageMask,
702                                                VkPipelineStageFlags dstStageMask,
703                                                const VkMemoryBarrier *memoryBarrier)
704 {
705     ASSERT(valid());
706     vkCmdPipelineBarrier(mHandle, srcStageMask, dstStageMask, 0, 1, memoryBarrier, 0, nullptr, 0,
707                          nullptr);
708 }
709 
710 ANGLE_INLINE void CommandBuffer::pipelineBarrier(VkPipelineStageFlags srcStageMask,
711                                                  VkPipelineStageFlags dstStageMask,
712                                                  VkDependencyFlags dependencyFlags,
713                                                  uint32_t memoryBarrierCount,
714                                                  const VkMemoryBarrier *memoryBarriers,
715                                                  uint32_t bufferMemoryBarrierCount,
716                                                  const VkBufferMemoryBarrier *bufferMemoryBarriers,
717                                                  uint32_t imageMemoryBarrierCount,
718                                                  const VkImageMemoryBarrier *imageMemoryBarriers)
719 {
720     ASSERT(valid());
721     vkCmdPipelineBarrier(mHandle, srcStageMask, dstStageMask, dependencyFlags, memoryBarrierCount,
722                          memoryBarriers, bufferMemoryBarrierCount, bufferMemoryBarriers,
723                          imageMemoryBarrierCount, imageMemoryBarriers);
724 }
725 
726 ANGLE_INLINE void CommandBuffer::executionBarrier(VkPipelineStageFlags stageMask)
727 {
728     ASSERT(valid());
729     vkCmdPipelineBarrier(mHandle, stageMask, stageMask, 0, 0, nullptr, 0, nullptr, 0, nullptr);
730 }
731 
732 ANGLE_INLINE void CommandBuffer::bufferBarrier(VkPipelineStageFlags srcStageMask,
733                                                VkPipelineStageFlags dstStageMask,
734                                                const VkBufferMemoryBarrier *bufferMemoryBarrier)
735 {
736     ASSERT(valid());
737     vkCmdPipelineBarrier(mHandle, srcStageMask, dstStageMask, 0, 0, nullptr, 1, bufferMemoryBarrier,
738                          0, nullptr);
739 }
740 
741 ANGLE_INLINE void CommandBuffer::imageBarrier(VkPipelineStageFlags srcStageMask,
742                                               VkPipelineStageFlags dstStageMask,
743                                               const VkImageMemoryBarrier &imageMemoryBarrier)
744 {
745     ASSERT(valid());
746     vkCmdPipelineBarrier(mHandle, srcStageMask, dstStageMask, 0, 0, nullptr, 0, nullptr, 1,
747                          &imageMemoryBarrier);
748 }
749 
750 ANGLE_INLINE void CommandBuffer::destroy(VkDevice device)
751 {
752     releaseHandle();
753 }
754 
755 ANGLE_INLINE void CommandBuffer::destroy(VkDevice device, const vk::CommandPool &commandPool)
756 {
757     if (valid())
758     {
759         ASSERT(commandPool.valid());
760         vkFreeCommandBuffers(device, commandPool.getHandle(), 1, &mHandle);
761         mHandle = VK_NULL_HANDLE;
762     }
763 }
764 
765 ANGLE_INLINE void CommandBuffer::copyBuffer(const Buffer &srcBuffer,
766                                             const Buffer &destBuffer,
767                                             uint32_t regionCount,
768                                             const VkBufferCopy *regions)
769 {
770     ASSERT(valid() && srcBuffer.valid() && destBuffer.valid());
771     vkCmdCopyBuffer(mHandle, srcBuffer.getHandle(), destBuffer.getHandle(), regionCount, regions);
772 }
773 
774 ANGLE_INLINE void CommandBuffer::copyBufferToImage(VkBuffer srcBuffer,
775                                                    const Image &dstImage,
776                                                    VkImageLayout dstImageLayout,
777                                                    uint32_t regionCount,
778                                                    const VkBufferImageCopy *regions)
779 {
780     ASSERT(valid() && dstImage.valid());
781     ASSERT(srcBuffer != VK_NULL_HANDLE);
782     ASSERT(regionCount == 1);
783     vkCmdCopyBufferToImage(mHandle, srcBuffer, dstImage.getHandle(), dstImageLayout, 1, regions);
784 }
785 
786 ANGLE_INLINE void CommandBuffer::copyImageToBuffer(const Image &srcImage,
787                                                    VkImageLayout srcImageLayout,
788                                                    VkBuffer dstBuffer,
789                                                    uint32_t regionCount,
790                                                    const VkBufferImageCopy *regions)
791 {
792     ASSERT(valid() && srcImage.valid());
793     ASSERT(dstBuffer != VK_NULL_HANDLE);
794     ASSERT(regionCount == 1);
795     vkCmdCopyImageToBuffer(mHandle, srcImage.getHandle(), srcImageLayout, dstBuffer, 1, regions);
796 }
797 
798 ANGLE_INLINE void CommandBuffer::clearColorImage(const Image &image,
799                                                  VkImageLayout imageLayout,
800                                                  const VkClearColorValue &color,
801                                                  uint32_t rangeCount,
802                                                  const VkImageSubresourceRange *ranges)
803 {
804     ASSERT(valid());
805     ASSERT(rangeCount == 1);
806     vkCmdClearColorImage(mHandle, image.getHandle(), imageLayout, &color, 1, ranges);
807 }
808 
809 ANGLE_INLINE void CommandBuffer::clearDepthStencilImage(
810     const Image &image,
811     VkImageLayout imageLayout,
812     const VkClearDepthStencilValue &depthStencil,
813     uint32_t rangeCount,
814     const VkImageSubresourceRange *ranges)
815 {
816     ASSERT(valid());
817     ASSERT(rangeCount == 1);
818     vkCmdClearDepthStencilImage(mHandle, image.getHandle(), imageLayout, &depthStencil, 1, ranges);
819 }
820 
821 ANGLE_INLINE void CommandBuffer::clearAttachments(uint32_t attachmentCount,
822                                                   const VkClearAttachment *attachments,
823                                                   uint32_t rectCount,
824                                                   const VkClearRect *rects)
825 {
826     ASSERT(valid());
827     vkCmdClearAttachments(mHandle, attachmentCount, attachments, rectCount, rects);
828 }
829 
830 ANGLE_INLINE void CommandBuffer::copyImage(const Image &srcImage,
831                                            VkImageLayout srcImageLayout,
832                                            const Image &dstImage,
833                                            VkImageLayout dstImageLayout,
834                                            uint32_t regionCount,
835                                            const VkImageCopy *regions)
836 {
837     ASSERT(valid() && srcImage.valid() && dstImage.valid());
838     ASSERT(regionCount == 1);
839     vkCmdCopyImage(mHandle, srcImage.getHandle(), srcImageLayout, dstImage.getHandle(),
840                    dstImageLayout, 1, regions);
841 }
842 
843 ANGLE_INLINE void CommandBuffer::beginRenderPass(const VkRenderPassBeginInfo &beginInfo,
844                                                  VkSubpassContents subpassContents)
845 {
846     ASSERT(valid());
847     vkCmdBeginRenderPass(mHandle, &beginInfo, subpassContents);
848 }
849 
850 ANGLE_INLINE void CommandBuffer::endRenderPass()
851 {
852     ASSERT(mHandle != VK_NULL_HANDLE);
853     vkCmdEndRenderPass(mHandle);
854 }
855 
856 ANGLE_INLINE void CommandBuffer::bindIndexBuffer(const Buffer &buffer,
857                                                  VkDeviceSize offset,
858                                                  VkIndexType indexType)
859 {
860     ASSERT(valid());
861     vkCmdBindIndexBuffer(mHandle, buffer.getHandle(), offset, indexType);
862 }
863 
864 ANGLE_INLINE void CommandBuffer::bindDescriptorSets(const PipelineLayout &layout,
865                                                     VkPipelineBindPoint pipelineBindPoint,
866                                                     uint32_t firstSet,
867                                                     uint32_t descriptorSetCount,
868                                                     const VkDescriptorSet *descriptorSets,
869                                                     uint32_t dynamicOffsetCount,
870                                                     const uint32_t *dynamicOffsets)
871 {
872     ASSERT(valid() && layout.valid());
873     vkCmdBindDescriptorSets(mHandle, pipelineBindPoint, layout.getHandle(), firstSet,
874                             descriptorSetCount, descriptorSets, dynamicOffsetCount, dynamicOffsets);
875 }
876 
877 ANGLE_INLINE void CommandBuffer::executeCommands(uint32_t commandBufferCount,
878                                                  const CommandBuffer *commandBuffers)
879 {
880     ASSERT(valid());
881     vkCmdExecuteCommands(mHandle, commandBufferCount, commandBuffers[0].ptr());
882 }
883 
884 ANGLE_INLINE void CommandBuffer::getMemoryUsageStats(size_t *usedMemoryOut,
885                                                      size_t *allocatedMemoryOut) const
886 {
887     // No data available.
888     *usedMemoryOut      = 0;
889     *allocatedMemoryOut = 1;
890 }
891 
892 ANGLE_INLINE void CommandBuffer::fillBuffer(const Buffer &dstBuffer,
893                                             VkDeviceSize dstOffset,
894                                             VkDeviceSize size,
895                                             uint32_t data)
896 {
897     ASSERT(valid());
898     vkCmdFillBuffer(mHandle, dstBuffer.getHandle(), dstOffset, size, data);
899 }
900 
901 ANGLE_INLINE void CommandBuffer::pushConstants(const PipelineLayout &layout,
902                                                VkShaderStageFlags flag,
903                                                uint32_t offset,
904                                                uint32_t size,
905                                                const void *data)
906 {
907     ASSERT(valid() && layout.valid());
908     ASSERT(offset == 0);
909     vkCmdPushConstants(mHandle, layout.getHandle(), flag, 0, size, data);
910 }
911 
912 ANGLE_INLINE void CommandBuffer::setEvent(VkEvent event, VkPipelineStageFlags stageMask)
913 {
914     ASSERT(valid() && event != VK_NULL_HANDLE);
915     vkCmdSetEvent(mHandle, event, stageMask);
916 }
917 
918 ANGLE_INLINE void CommandBuffer::resetEvent(VkEvent event, VkPipelineStageFlags stageMask)
919 {
920     ASSERT(valid() && event != VK_NULL_HANDLE);
921     vkCmdResetEvent(mHandle, event, stageMask);
922 }
923 
924 ANGLE_INLINE void CommandBuffer::waitEvents(uint32_t eventCount,
925                                             const VkEvent *events,
926                                             VkPipelineStageFlags srcStageMask,
927                                             VkPipelineStageFlags dstStageMask,
928                                             uint32_t memoryBarrierCount,
929                                             const VkMemoryBarrier *memoryBarriers,
930                                             uint32_t bufferMemoryBarrierCount,
931                                             const VkBufferMemoryBarrier *bufferMemoryBarriers,
932                                             uint32_t imageMemoryBarrierCount,
933                                             const VkImageMemoryBarrier *imageMemoryBarriers)
934 {
935     ASSERT(valid());
936     vkCmdWaitEvents(mHandle, eventCount, events, srcStageMask, dstStageMask, memoryBarrierCount,
937                     memoryBarriers, bufferMemoryBarrierCount, bufferMemoryBarriers,
938                     imageMemoryBarrierCount, imageMemoryBarriers);
939 }
940 
941 ANGLE_INLINE void CommandBuffer::resetQueryPool(const QueryPool &queryPool,
942                                                 uint32_t firstQuery,
943                                                 uint32_t queryCount)
944 {
945     ASSERT(valid() && queryPool.valid());
946     vkCmdResetQueryPool(mHandle, queryPool.getHandle(), firstQuery, queryCount);
947 }
948 
949 ANGLE_INLINE void CommandBuffer::resolveImage(const Image &srcImage,
950                                               VkImageLayout srcImageLayout,
951                                               const Image &dstImage,
952                                               VkImageLayout dstImageLayout,
953                                               uint32_t regionCount,
954                                               const VkImageResolve *regions)
955 {
956     ASSERT(valid() && srcImage.valid() && dstImage.valid());
957     vkCmdResolveImage(mHandle, srcImage.getHandle(), srcImageLayout, dstImage.getHandle(),
958                       dstImageLayout, regionCount, regions);
959 }
960 
961 ANGLE_INLINE void CommandBuffer::beginQuery(const QueryPool &queryPool,
962                                             uint32_t query,
963                                             VkQueryControlFlags flags)
964 {
965     ASSERT(valid() && queryPool.valid());
966     vkCmdBeginQuery(mHandle, queryPool.getHandle(), query, flags);
967 }
968 
969 ANGLE_INLINE void CommandBuffer::endQuery(const QueryPool &queryPool, uint32_t query)
970 {
971     ASSERT(valid() && queryPool.valid());
972     vkCmdEndQuery(mHandle, queryPool.getHandle(), query);
973 }
974 
975 ANGLE_INLINE void CommandBuffer::writeTimestamp(VkPipelineStageFlagBits pipelineStage,
976                                                 const QueryPool &queryPool,
977                                                 uint32_t query)
978 {
979     ASSERT(valid());
980     vkCmdWriteTimestamp(mHandle, pipelineStage, queryPool.getHandle(), query);
981 }
982 
983 ANGLE_INLINE void CommandBuffer::draw(uint32_t vertexCount,
984                                       uint32_t instanceCount,
985                                       uint32_t firstVertex,
986                                       uint32_t firstInstance)
987 {
988     ASSERT(valid());
989     vkCmdDraw(mHandle, vertexCount, instanceCount, firstVertex, firstInstance);
990 }
991 
992 ANGLE_INLINE void CommandBuffer::draw(uint32_t vertexCount, uint32_t firstVertex)
993 {
994     ASSERT(valid());
995     vkCmdDraw(mHandle, vertexCount, 1, firstVertex, 0);
996 }
997 
998 ANGLE_INLINE void CommandBuffer::drawInstanced(uint32_t vertexCount,
999                                                uint32_t instanceCount,
1000                                                uint32_t firstVertex)
1001 {
1002     ASSERT(valid());
1003     vkCmdDraw(mHandle, vertexCount, instanceCount, firstVertex, 0);
1004 }
1005 
1006 ANGLE_INLINE void CommandBuffer::drawInstancedBaseInstance(uint32_t vertexCount,
1007                                                            uint32_t instanceCount,
1008                                                            uint32_t firstVertex,
1009                                                            uint32_t firstInstance)
1010 {
1011     ASSERT(valid());
1012     vkCmdDraw(mHandle, vertexCount, instanceCount, firstVertex, firstInstance);
1013 }
1014 
1015 ANGLE_INLINE void CommandBuffer::drawIndexed(uint32_t indexCount,
1016                                              uint32_t instanceCount,
1017                                              uint32_t firstIndex,
1018                                              int32_t vertexOffset,
1019                                              uint32_t firstInstance)
1020 {
1021     ASSERT(valid());
1022     vkCmdDrawIndexed(mHandle, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
1023 }
1024 
1025 ANGLE_INLINE void CommandBuffer::drawIndexed(uint32_t indexCount)
1026 {
1027     ASSERT(valid());
1028     vkCmdDrawIndexed(mHandle, indexCount, 1, 0, 0, 0);
1029 }
1030 
1031 ANGLE_INLINE void CommandBuffer::drawIndexedBaseVertex(uint32_t indexCount, uint32_t vertexOffset)
1032 {
1033     ASSERT(valid());
1034     vkCmdDrawIndexed(mHandle, indexCount, 1, 0, vertexOffset, 0);
1035 }
1036 
1037 ANGLE_INLINE void CommandBuffer::drawIndexedInstanced(uint32_t indexCount, uint32_t instanceCount)
1038 {
1039     ASSERT(valid());
1040     vkCmdDrawIndexed(mHandle, indexCount, instanceCount, 0, 0, 0);
1041 }
1042 
1043 ANGLE_INLINE void CommandBuffer::drawIndexedInstancedBaseVertex(uint32_t indexCount,
1044                                                                 uint32_t instanceCount,
1045                                                                 uint32_t vertexOffset)
1046 {
1047     ASSERT(valid());
1048     vkCmdDrawIndexed(mHandle, indexCount, instanceCount, 0, vertexOffset, 0);
1049 }
1050 
1051 ANGLE_INLINE void CommandBuffer::drawIndexedInstancedBaseVertexBaseInstance(uint32_t indexCount,
1052                                                                             uint32_t instanceCount,
1053                                                                             uint32_t firstIndex,
1054                                                                             int32_t vertexOffset,
1055                                                                             uint32_t firstInstance)
1056 {
1057     ASSERT(valid());
1058     vkCmdDrawIndexed(mHandle, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
1059 }
1060 
1061 ANGLE_INLINE void CommandBuffer::drawIndexedIndirect(const Buffer &buffer,
1062                                                      VkDeviceSize offset,
1063                                                      uint32_t drawCount,
1064                                                      uint32_t stride)
1065 {
1066     ASSERT(valid());
1067     vkCmdDrawIndexedIndirect(mHandle, buffer.getHandle(), offset, drawCount, stride);
1068 }
1069 
1070 ANGLE_INLINE void CommandBuffer::drawIndirect(const Buffer &buffer,
1071                                               VkDeviceSize offset,
1072                                               uint32_t drawCount,
1073                                               uint32_t stride)
1074 {
1075     ASSERT(valid());
1076     vkCmdDrawIndirect(mHandle, buffer.getHandle(), offset, drawCount, stride);
1077 }
1078 
1079 ANGLE_INLINE void CommandBuffer::dispatch(uint32_t groupCountX,
1080                                           uint32_t groupCountY,
1081                                           uint32_t groupCountZ)
1082 {
1083     ASSERT(valid());
1084     vkCmdDispatch(mHandle, groupCountX, groupCountY, groupCountZ);
1085 }
1086 
1087 ANGLE_INLINE void CommandBuffer::dispatchIndirect(const Buffer &buffer, VkDeviceSize offset)
1088 {
1089     ASSERT(valid());
1090     vkCmdDispatchIndirect(mHandle, buffer.getHandle(), offset);
1091 }
1092 
1093 ANGLE_INLINE void CommandBuffer::bindPipeline(VkPipelineBindPoint pipelineBindPoint,
1094                                               const Pipeline &pipeline)
1095 {
1096     ASSERT(valid() && pipeline.valid());
1097     vkCmdBindPipeline(mHandle, pipelineBindPoint, pipeline.getHandle());
1098 }
1099 
1100 ANGLE_INLINE void CommandBuffer::bindGraphicsPipeline(const Pipeline &pipeline)
1101 {
1102     ASSERT(valid() && pipeline.valid());
1103     vkCmdBindPipeline(mHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.getHandle());
1104 }
1105 
1106 ANGLE_INLINE void CommandBuffer::bindComputePipeline(const Pipeline &pipeline)
1107 {
1108     ASSERT(valid() && pipeline.valid());
1109     vkCmdBindPipeline(mHandle, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline.getHandle());
1110 }
1111 
1112 ANGLE_INLINE void CommandBuffer::bindVertexBuffers(uint32_t firstBinding,
1113                                                    uint32_t bindingCount,
1114                                                    const VkBuffer *buffers,
1115                                                    const VkDeviceSize *offsets)
1116 {
1117     ASSERT(valid());
1118     vkCmdBindVertexBuffers(mHandle, firstBinding, bindingCount, buffers, offsets);
1119 }
1120 
1121 ANGLE_INLINE void CommandBuffer::beginTransformFeedbackEXT(uint32_t firstCounterBuffer,
1122                                                            uint32_t counterBufferCount,
1123                                                            const VkBuffer *counterBuffers,
1124                                                            const VkDeviceSize *counterBufferOffsets)
1125 {
1126     ASSERT(valid());
1127     ASSERT(vkCmdBeginTransformFeedbackEXT);
1128     vkCmdBeginTransformFeedbackEXT(mHandle, firstCounterBuffer, counterBufferCount, counterBuffers,
1129                                    counterBufferOffsets);
1130 }
1131 
1132 ANGLE_INLINE void CommandBuffer::endTransformFeedbackEXT(uint32_t firstCounterBuffer,
1133                                                          uint32_t counterBufferCount,
1134                                                          const VkBuffer *counterBuffers,
1135                                                          const VkDeviceSize *counterBufferOffsets)
1136 {
1137     ASSERT(valid());
1138     ASSERT(vkCmdEndTransformFeedbackEXT);
1139     vkCmdEndTransformFeedbackEXT(mHandle, firstCounterBuffer, counterBufferCount, counterBuffers,
1140                                  counterBufferOffsets);
1141 }
1142 
1143 ANGLE_INLINE void CommandBuffer::bindTransformFeedbackBuffersEXT(uint32_t firstBinding,
1144                                                                  uint32_t bindingCount,
1145                                                                  const VkBuffer *buffers,
1146                                                                  const VkDeviceSize *offsets,
1147                                                                  const VkDeviceSize *sizes)
1148 {
1149     ASSERT(valid());
1150     ASSERT(vkCmdBindTransformFeedbackBuffersEXT);
1151     vkCmdBindTransformFeedbackBuffersEXT(mHandle, firstBinding, bindingCount, buffers, offsets,
1152                                          sizes);
1153 }
1154 
1155 ANGLE_INLINE void CommandBuffer::beginDebugUtilsLabelEXT(const VkDebugUtilsLabelEXT &labelInfo)
1156 {
1157     ASSERT(valid());
1158     ASSERT(vkCmdBeginDebugUtilsLabelEXT);
1159     vkCmdBeginDebugUtilsLabelEXT(mHandle, &labelInfo);
1160 }
1161 
1162 ANGLE_INLINE void CommandBuffer::endDebugUtilsLabelEXT()
1163 {
1164     ASSERT(valid());
1165     ASSERT(vkCmdEndDebugUtilsLabelEXT);
1166     vkCmdEndDebugUtilsLabelEXT(mHandle);
1167 }
1168 
1169 ANGLE_INLINE void CommandBuffer::insertDebugUtilsLabelEXT(const VkDebugUtilsLabelEXT &labelInfo)
1170 {
1171     ASSERT(valid());
1172     ASSERT(vkCmdInsertDebugUtilsLabelEXT);
1173     vkCmdInsertDebugUtilsLabelEXT(mHandle, &labelInfo);
1174 }
1175 }  // namespace priv
1176 
1177 // Image implementation.
1178 ANGLE_INLINE void Image::setHandle(VkImage handle)
1179 {
1180     mHandle = handle;
1181 }
1182 
1183 ANGLE_INLINE void Image::reset()
1184 {
1185     mHandle = VK_NULL_HANDLE;
1186 }
1187 
1188 ANGLE_INLINE void Image::destroy(VkDevice device)
1189 {
1190     if (valid())
1191     {
1192         vkDestroyImage(device, mHandle, nullptr);
1193         mHandle = VK_NULL_HANDLE;
1194     }
1195 }
1196 
1197 ANGLE_INLINE VkResult Image::init(VkDevice device, const VkImageCreateInfo &createInfo)
1198 {
1199     ASSERT(!valid());
1200     return vkCreateImage(device, &createInfo, nullptr, &mHandle);
1201 }
1202 
1203 ANGLE_INLINE void Image::getMemoryRequirements(VkDevice device,
1204                                                VkMemoryRequirements *requirementsOut) const
1205 {
1206     ASSERT(valid());
1207     vkGetImageMemoryRequirements(device, mHandle, requirementsOut);
1208 }
1209 
1210 ANGLE_INLINE VkResult Image::bindMemory(VkDevice device, const vk::DeviceMemory &deviceMemory)
1211 {
1212     ASSERT(valid() && deviceMemory.valid());
1213     return vkBindImageMemory(device, mHandle, deviceMemory.getHandle(), 0);
1214 }
1215 
1216 ANGLE_INLINE void Image::getSubresourceLayout(VkDevice device,
1217                                               VkImageAspectFlagBits aspectMask,
1218                                               uint32_t mipLevel,
1219                                               uint32_t arrayLayer,
1220                                               VkSubresourceLayout *outSubresourceLayout) const
1221 {
1222     VkImageSubresource subresource = {};
1223     subresource.aspectMask         = aspectMask;
1224     subresource.mipLevel           = mipLevel;
1225     subresource.arrayLayer         = arrayLayer;
1226 
1227     vkGetImageSubresourceLayout(device, getHandle(), &subresource, outSubresourceLayout);
1228 }
1229 
1230 // ImageView implementation.
1231 ANGLE_INLINE void ImageView::destroy(VkDevice device)
1232 {
1233     if (valid())
1234     {
1235         vkDestroyImageView(device, mHandle, nullptr);
1236         mHandle = VK_NULL_HANDLE;
1237     }
1238 }
1239 
1240 ANGLE_INLINE VkResult ImageView::init(VkDevice device, const VkImageViewCreateInfo &createInfo)
1241 {
1242     return vkCreateImageView(device, &createInfo, nullptr, &mHandle);
1243 }
1244 
1245 // Semaphore implementation.
1246 ANGLE_INLINE void Semaphore::destroy(VkDevice device)
1247 {
1248     if (valid())
1249     {
1250         vkDestroySemaphore(device, mHandle, nullptr);
1251         mHandle = VK_NULL_HANDLE;
1252     }
1253 }
1254 
1255 ANGLE_INLINE VkResult Semaphore::init(VkDevice device)
1256 {
1257     ASSERT(!valid());
1258 
1259     VkSemaphoreCreateInfo semaphoreInfo = {};
1260     semaphoreInfo.sType                 = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
1261     semaphoreInfo.flags                 = 0;
1262 
1263     return vkCreateSemaphore(device, &semaphoreInfo, nullptr, &mHandle);
1264 }
1265 
1266 // Framebuffer implementation.
1267 ANGLE_INLINE void Framebuffer::destroy(VkDevice device)
1268 {
1269     if (valid())
1270     {
1271         vkDestroyFramebuffer(device, mHandle, nullptr);
1272         mHandle = VK_NULL_HANDLE;
1273     }
1274 }
1275 
1276 ANGLE_INLINE VkResult Framebuffer::init(VkDevice device, const VkFramebufferCreateInfo &createInfo)
1277 {
1278     ASSERT(!valid());
1279     return vkCreateFramebuffer(device, &createInfo, nullptr, &mHandle);
1280 }
1281 
1282 ANGLE_INLINE void Framebuffer::setHandle(VkFramebuffer handle)
1283 {
1284     mHandle = handle;
1285 }
1286 
1287 // DeviceMemory implementation.
1288 ANGLE_INLINE void DeviceMemory::destroy(VkDevice device)
1289 {
1290     if (valid())
1291     {
1292         vkFreeMemory(device, mHandle, nullptr);
1293         mHandle = VK_NULL_HANDLE;
1294     }
1295 }
1296 
1297 ANGLE_INLINE VkResult DeviceMemory::allocate(VkDevice device, const VkMemoryAllocateInfo &allocInfo)
1298 {
1299     ASSERT(!valid());
1300     return vkAllocateMemory(device, &allocInfo, nullptr, &mHandle);
1301 }
1302 
1303 ANGLE_INLINE VkResult DeviceMemory::map(VkDevice device,
1304                                         VkDeviceSize offset,
1305                                         VkDeviceSize size,
1306                                         VkMemoryMapFlags flags,
1307                                         uint8_t **mapPointer) const
1308 {
1309     ASSERT(valid());
1310     return vkMapMemory(device, mHandle, offset, size, flags, reinterpret_cast<void **>(mapPointer));
1311 }
1312 
1313 ANGLE_INLINE void DeviceMemory::unmap(VkDevice device) const
1314 {
1315     ASSERT(valid());
1316     vkUnmapMemory(device, mHandle);
1317 }
1318 
1319 // Allocation implementation.
1320 ANGLE_INLINE void Allocation::destroy(VmaAllocator allocator)
1321 {
1322     if (valid())
1323     {
1324         vma::FreeMemory(allocator, mHandle);
1325         mHandle = VK_NULL_HANDLE;
1326     }
1327 }
1328 
1329 ANGLE_INLINE VkResult Allocation::createBufferAndMemory(VmaAllocator allocator,
1330                                                         const VkBufferCreateInfo *pBufferCreateInfo,
1331                                                         VkMemoryPropertyFlags requiredFlags,
1332                                                         VkMemoryPropertyFlags preferredFlags,
1333                                                         bool persistentlyMappedBuffers,
1334                                                         Buffer *buffer,
1335                                                         VkMemoryPropertyFlags *pMemPropertyOut)
1336 {
1337     ASSERT(!valid());
1338     VkResult result;
1339     uint32_t memoryTypeIndex;
1340     VkBuffer bufferHandle;
1341     result =
1342         vma::CreateBuffer(allocator, pBufferCreateInfo, requiredFlags, preferredFlags,
1343                           persistentlyMappedBuffers, &memoryTypeIndex, &bufferHandle, &mHandle);
1344     vma::GetMemoryTypeProperties(allocator, memoryTypeIndex, pMemPropertyOut);
1345     buffer->setHandle(bufferHandle);
1346 
1347     return result;
1348 }
1349 
1350 ANGLE_INLINE VkResult Allocation::map(VmaAllocator allocator, uint8_t **mapPointer) const
1351 {
1352     ASSERT(valid());
1353     return vma::MapMemory(allocator, mHandle, (void **)mapPointer);
1354 }
1355 
1356 ANGLE_INLINE void Allocation::unmap(VmaAllocator allocator) const
1357 {
1358     ASSERT(valid());
1359     vma::UnmapMemory(allocator, mHandle);
1360 }
1361 
1362 ANGLE_INLINE void Allocation::flush(VmaAllocator allocator, VkDeviceSize offset, VkDeviceSize size)
1363 {
1364     ASSERT(valid());
1365     vma::FlushAllocation(allocator, mHandle, offset, size);
1366 }
1367 
1368 ANGLE_INLINE void Allocation::invalidate(VmaAllocator allocator,
1369                                          VkDeviceSize offset,
1370                                          VkDeviceSize size)
1371 {
1372     ASSERT(valid());
1373     vma::InvalidateAllocation(allocator, mHandle, offset, size);
1374 }
1375 
1376 // RenderPass implementation.
1377 ANGLE_INLINE void RenderPass::destroy(VkDevice device)
1378 {
1379     if (valid())
1380     {
1381         vkDestroyRenderPass(device, mHandle, nullptr);
1382         mHandle = VK_NULL_HANDLE;
1383     }
1384 }
1385 
1386 ANGLE_INLINE VkResult RenderPass::init(VkDevice device, const VkRenderPassCreateInfo &createInfo)
1387 {
1388     ASSERT(!valid());
1389     return vkCreateRenderPass(device, &createInfo, nullptr, &mHandle);
1390 }
1391 
1392 // Buffer implementation.
1393 ANGLE_INLINE void Buffer::destroy(VkDevice device)
1394 {
1395     if (valid())
1396     {
1397         vkDestroyBuffer(device, mHandle, nullptr);
1398         mHandle = VK_NULL_HANDLE;
1399     }
1400 }
1401 
1402 ANGLE_INLINE VkResult Buffer::init(VkDevice device, const VkBufferCreateInfo &createInfo)
1403 {
1404     ASSERT(!valid());
1405     return vkCreateBuffer(device, &createInfo, nullptr, &mHandle);
1406 }
1407 
1408 ANGLE_INLINE VkResult Buffer::bindMemory(VkDevice device, const DeviceMemory &deviceMemory)
1409 {
1410     ASSERT(valid() && deviceMemory.valid());
1411     return vkBindBufferMemory(device, mHandle, deviceMemory.getHandle(), 0);
1412 }
1413 
1414 ANGLE_INLINE void Buffer::getMemoryRequirements(VkDevice device,
1415                                                 VkMemoryRequirements *memoryRequirementsOut)
1416 {
1417     ASSERT(valid());
1418     vkGetBufferMemoryRequirements(device, mHandle, memoryRequirementsOut);
1419 }
1420 
1421 // BufferView implementation.
1422 ANGLE_INLINE void BufferView::destroy(VkDevice device)
1423 {
1424     if (valid())
1425     {
1426         vkDestroyBufferView(device, mHandle, nullptr);
1427         mHandle = VK_NULL_HANDLE;
1428     }
1429 }
1430 
1431 ANGLE_INLINE VkResult BufferView::init(VkDevice device, const VkBufferViewCreateInfo &createInfo)
1432 {
1433     ASSERT(!valid());
1434     return vkCreateBufferView(device, &createInfo, nullptr, &mHandle);
1435 }
1436 
1437 // ShaderModule implementation.
1438 ANGLE_INLINE void ShaderModule::destroy(VkDevice device)
1439 {
1440     if (mHandle != VK_NULL_HANDLE)
1441     {
1442         vkDestroyShaderModule(device, mHandle, nullptr);
1443         mHandle = VK_NULL_HANDLE;
1444     }
1445 }
1446 
1447 ANGLE_INLINE VkResult ShaderModule::init(VkDevice device,
1448                                          const VkShaderModuleCreateInfo &createInfo)
1449 {
1450     ASSERT(!valid());
1451     return vkCreateShaderModule(device, &createInfo, nullptr, &mHandle);
1452 }
1453 
1454 // PipelineLayout implementation.
1455 ANGLE_INLINE void PipelineLayout::destroy(VkDevice device)
1456 {
1457     if (valid())
1458     {
1459         vkDestroyPipelineLayout(device, mHandle, nullptr);
1460         mHandle = VK_NULL_HANDLE;
1461     }
1462 }
1463 
1464 ANGLE_INLINE VkResult PipelineLayout::init(VkDevice device,
1465                                            const VkPipelineLayoutCreateInfo &createInfo)
1466 {
1467     ASSERT(!valid());
1468     return vkCreatePipelineLayout(device, &createInfo, nullptr, &mHandle);
1469 }
1470 
1471 // PipelineCache implementation.
1472 ANGLE_INLINE void PipelineCache::destroy(VkDevice device)
1473 {
1474     if (valid())
1475     {
1476         vkDestroyPipelineCache(device, mHandle, nullptr);
1477         mHandle = VK_NULL_HANDLE;
1478     }
1479 }
1480 
1481 ANGLE_INLINE VkResult PipelineCache::init(VkDevice device,
1482                                           const VkPipelineCacheCreateInfo &createInfo)
1483 {
1484     ASSERT(!valid());
1485     // Note: if we are concerned with memory usage of this cache, we should give it custom
1486     // allocators.  Also, failure of this function is of little importance.
1487     return vkCreatePipelineCache(device, &createInfo, nullptr, &mHandle);
1488 }
1489 
1490 ANGLE_INLINE VkResult PipelineCache::merge(VkDevice device,
1491                                            VkPipelineCache dstCache,
1492                                            uint32_t srcCacheCount,
1493                                            const VkPipelineCache *srcCaches)
1494 {
1495     ASSERT(valid());
1496     return vkMergePipelineCaches(device, dstCache, srcCacheCount, srcCaches);
1497 }
1498 
1499 ANGLE_INLINE VkResult PipelineCache::getCacheData(VkDevice device,
1500                                                   size_t *cacheSize,
1501                                                   void *cacheData)
1502 {
1503     ASSERT(valid());
1504 
1505     // Note: vkGetPipelineCacheData can return VK_INCOMPLETE if cacheSize is smaller than actual
1506     // size. There are two usages of this function.  One is with *cacheSize == 0 to query the size
1507     // of the cache, and one is with an appropriate buffer to retrieve the cache contents.
1508     // VK_INCOMPLETE in the first case is an expected output.  In the second case, VK_INCOMPLETE is
1509     // also acceptable and the resulting buffer will contain valid value by spec.  Angle currently
1510     // ensures *cacheSize to be either 0 or of enough size, therefore VK_INCOMPLETE is not expected.
1511     return vkGetPipelineCacheData(device, mHandle, cacheSize, cacheData);
1512 }
1513 
1514 // Pipeline implementation.
1515 ANGLE_INLINE void Pipeline::destroy(VkDevice device)
1516 {
1517     if (valid())
1518     {
1519         vkDestroyPipeline(device, mHandle, nullptr);
1520         mHandle = VK_NULL_HANDLE;
1521     }
1522 }
1523 
1524 ANGLE_INLINE VkResult Pipeline::initGraphics(VkDevice device,
1525                                              const VkGraphicsPipelineCreateInfo &createInfo,
1526                                              const PipelineCache &pipelineCacheVk)
1527 {
1528     ASSERT(!valid());
1529     return vkCreateGraphicsPipelines(device, pipelineCacheVk.getHandle(), 1, &createInfo, nullptr,
1530                                      &mHandle);
1531 }
1532 
1533 ANGLE_INLINE VkResult Pipeline::initCompute(VkDevice device,
1534                                             const VkComputePipelineCreateInfo &createInfo,
1535                                             const PipelineCache &pipelineCacheVk)
1536 {
1537     ASSERT(!valid());
1538     return vkCreateComputePipelines(device, pipelineCacheVk.getHandle(), 1, &createInfo, nullptr,
1539                                     &mHandle);
1540 }
1541 
1542 // DescriptorSetLayout implementation.
1543 ANGLE_INLINE void DescriptorSetLayout::destroy(VkDevice device)
1544 {
1545     if (valid())
1546     {
1547         vkDestroyDescriptorSetLayout(device, mHandle, nullptr);
1548         mHandle = VK_NULL_HANDLE;
1549     }
1550 }
1551 
1552 ANGLE_INLINE VkResult DescriptorSetLayout::init(VkDevice device,
1553                                                 const VkDescriptorSetLayoutCreateInfo &createInfo)
1554 {
1555     ASSERT(!valid());
1556     return vkCreateDescriptorSetLayout(device, &createInfo, nullptr, &mHandle);
1557 }
1558 
1559 // DescriptorPool implementation.
1560 ANGLE_INLINE void DescriptorPool::destroy(VkDevice device)
1561 {
1562     if (valid())
1563     {
1564         vkDestroyDescriptorPool(device, mHandle, nullptr);
1565         mHandle = VK_NULL_HANDLE;
1566     }
1567 }
1568 
1569 ANGLE_INLINE VkResult DescriptorPool::init(VkDevice device,
1570                                            const VkDescriptorPoolCreateInfo &createInfo)
1571 {
1572     ASSERT(!valid());
1573     return vkCreateDescriptorPool(device, &createInfo, nullptr, &mHandle);
1574 }
1575 
1576 ANGLE_INLINE VkResult
1577 DescriptorPool::allocateDescriptorSets(VkDevice device,
1578                                        const VkDescriptorSetAllocateInfo &allocInfo,
1579                                        VkDescriptorSet *descriptorSetsOut)
1580 {
1581     ASSERT(valid());
1582     return vkAllocateDescriptorSets(device, &allocInfo, descriptorSetsOut);
1583 }
1584 
1585 ANGLE_INLINE VkResult DescriptorPool::freeDescriptorSets(VkDevice device,
1586                                                          uint32_t descriptorSetCount,
1587                                                          const VkDescriptorSet *descriptorSets)
1588 {
1589     ASSERT(valid());
1590     ASSERT(descriptorSetCount > 0);
1591     return vkFreeDescriptorSets(device, mHandle, descriptorSetCount, descriptorSets);
1592 }
1593 
1594 // Sampler implementation.
1595 ANGLE_INLINE void Sampler::destroy(VkDevice device)
1596 {
1597     if (valid())
1598     {
1599         vkDestroySampler(device, mHandle, nullptr);
1600         mHandle = VK_NULL_HANDLE;
1601     }
1602 }
1603 
1604 ANGLE_INLINE VkResult Sampler::init(VkDevice device, const VkSamplerCreateInfo &createInfo)
1605 {
1606     ASSERT(!valid());
1607     return vkCreateSampler(device, &createInfo, nullptr, &mHandle);
1608 }
1609 
1610 // Event implementation.
1611 ANGLE_INLINE void Event::destroy(VkDevice device)
1612 {
1613     if (valid())
1614     {
1615         vkDestroyEvent(device, mHandle, nullptr);
1616         mHandle = VK_NULL_HANDLE;
1617     }
1618 }
1619 
1620 ANGLE_INLINE VkResult Event::init(VkDevice device, const VkEventCreateInfo &createInfo)
1621 {
1622     ASSERT(!valid());
1623     return vkCreateEvent(device, &createInfo, nullptr, &mHandle);
1624 }
1625 
1626 ANGLE_INLINE VkResult Event::getStatus(VkDevice device) const
1627 {
1628     ASSERT(valid());
1629     return vkGetEventStatus(device, mHandle);
1630 }
1631 
1632 ANGLE_INLINE VkResult Event::set(VkDevice device) const
1633 {
1634     ASSERT(valid());
1635     return vkSetEvent(device, mHandle);
1636 }
1637 
1638 ANGLE_INLINE VkResult Event::reset(VkDevice device) const
1639 {
1640     ASSERT(valid());
1641     return vkResetEvent(device, mHandle);
1642 }
1643 
1644 // Fence implementation.
1645 ANGLE_INLINE void Fence::destroy(VkDevice device)
1646 {
1647     if (valid())
1648     {
1649         vkDestroyFence(device, mHandle, nullptr);
1650         mHandle = VK_NULL_HANDLE;
1651     }
1652 }
1653 
1654 ANGLE_INLINE VkResult Fence::init(VkDevice device, const VkFenceCreateInfo &createInfo)
1655 {
1656     ASSERT(!valid());
1657     return vkCreateFence(device, &createInfo, nullptr, &mHandle);
1658 }
1659 
1660 ANGLE_INLINE VkResult Fence::reset(VkDevice device)
1661 {
1662     ASSERT(valid());
1663     return vkResetFences(device, 1, &mHandle);
1664 }
1665 
1666 ANGLE_INLINE VkResult Fence::getStatus(VkDevice device) const
1667 {
1668     ASSERT(valid());
1669     return vkGetFenceStatus(device, mHandle);
1670 }
1671 
1672 ANGLE_INLINE VkResult Fence::wait(VkDevice device, uint64_t timeout) const
1673 {
1674     ASSERT(valid());
1675     return vkWaitForFences(device, 1, &mHandle, true, timeout);
1676 }
1677 
1678 // QueryPool implementation.
1679 ANGLE_INLINE void QueryPool::destroy(VkDevice device)
1680 {
1681     if (valid())
1682     {
1683         vkDestroyQueryPool(device, mHandle, nullptr);
1684         mHandle = VK_NULL_HANDLE;
1685     }
1686 }
1687 
1688 ANGLE_INLINE VkResult QueryPool::init(VkDevice device, const VkQueryPoolCreateInfo &createInfo)
1689 {
1690     ASSERT(!valid());
1691     return vkCreateQueryPool(device, &createInfo, nullptr, &mHandle);
1692 }
1693 
1694 ANGLE_INLINE VkResult QueryPool::getResults(VkDevice device,
1695                                             uint32_t firstQuery,
1696                                             uint32_t queryCount,
1697                                             size_t dataSize,
1698                                             void *data,
1699                                             VkDeviceSize stride,
1700                                             VkQueryResultFlags flags) const
1701 {
1702     ASSERT(valid());
1703     return vkGetQueryPoolResults(device, mHandle, firstQuery, queryCount, dataSize, data, stride,
1704                                  flags);
1705 }
1706 }  // namespace vk
1707 }  // namespace rx
1708 
1709 #endif  // LIBANGLE_RENDERER_VULKAN_VK_WRAPPER_H_
1710