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