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