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