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