//
// Copyright 2019 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// vk_wrapper:
//    Wrapper classes around Vulkan objects. In an ideal world we could generate this
//    from vk.xml. Or reuse the generator in the vkhpp tool. For now this is manually
//    generated and we must add missing functions and objects as we need them.

#ifndef LIBANGLE_RENDERER_VULKAN_VK_WRAPPER_H_
#define LIBANGLE_RENDERER_VULKAN_VK_WRAPPER_H_

#include <vulkan/vulkan.h>

#include "libANGLE/renderer/renderer_utils.h"

namespace rx
{
namespace vk
{
// Helper macros that apply to all the wrapped object types.
// Unimplemented handle types:
// Instance
// PhysicalDevice
// Device
// Queue
// DescriptorSet

#define ANGLE_HANDLE_TYPES_X(FUNC) \
    FUNC(Buffer)                   \
    FUNC(BufferView)               \
    FUNC(CommandPool)              \
    FUNC(DescriptorPool)           \
    FUNC(DescriptorSetLayout)      \
    FUNC(DeviceMemory)             \
    FUNC(Event)                    \
    FUNC(Fence)                    \
    FUNC(Framebuffer)              \
    FUNC(Image)                    \
    FUNC(ImageView)                \
    FUNC(Pipeline)                 \
    FUNC(PipelineCache)            \
    FUNC(PipelineLayout)           \
    FUNC(QueryPool)                \
    FUNC(RenderPass)               \
    FUNC(Sampler)                  \
    FUNC(Semaphore)                \
    FUNC(ShaderModule)

#define ANGLE_COMMA_SEP_FUNC(TYPE) TYPE,

enum class HandleType
{
    Invalid,
    CommandBuffer,
    ANGLE_HANDLE_TYPES_X(ANGLE_COMMA_SEP_FUNC)
};

#undef ANGLE_COMMA_SEP_FUNC

#define ANGLE_PRE_DECLARE_CLASS_FUNC(TYPE) class TYPE;
ANGLE_HANDLE_TYPES_X(ANGLE_PRE_DECLARE_CLASS_FUNC)
namespace priv
{
class CommandBuffer;
}  // namespace priv
#undef ANGLE_PRE_DECLARE_CLASS_FUNC

// Returns the HandleType of a Vk Handle.
template <typename T>
struct HandleTypeHelper;

#define ANGLE_HANDLE_TYPE_HELPER_FUNC(TYPE)                         \
    template <>                                                     \
    struct HandleTypeHelper<TYPE>                                   \
    {                                                               \
        constexpr static HandleType kHandleType = HandleType::TYPE; \
    };

ANGLE_HANDLE_TYPES_X(ANGLE_HANDLE_TYPE_HELPER_FUNC)
template <>
struct HandleTypeHelper<priv::CommandBuffer>
{
    constexpr static HandleType kHandleType = HandleType::CommandBuffer;
};

#undef ANGLE_HANDLE_TYPE_HELPER_FUNC

// Base class for all wrapped vulkan objects. Implements several common helper routines.
template <typename DerivedT, typename HandleT>
class WrappedObject : angle::NonCopyable
{
  public:
    HandleT getHandle() const { return mHandle; }
    bool valid() const { return (mHandle != VK_NULL_HANDLE); }

    const HandleT *ptr() const { return &mHandle; }

    HandleT release()
    {
        HandleT handle = mHandle;
        mHandle        = VK_NULL_HANDLE;
        return handle;
    }

  protected:
    WrappedObject() : mHandle(VK_NULL_HANDLE) {}
    ~WrappedObject() { ASSERT(!valid()); }

    WrappedObject(WrappedObject &&other) : mHandle(other.mHandle)
    {
        other.mHandle = VK_NULL_HANDLE;
    }

    // Only works to initialize empty objects, since we don't have the device handle.
    WrappedObject &operator=(WrappedObject &&other)
    {
        ASSERT(!valid());
        std::swap(mHandle, other.mHandle);
        return *this;
    }

    HandleT mHandle;
};

class CommandPool final : public WrappedObject<CommandPool, VkCommandPool>
{
  public:
    CommandPool() = default;

    void destroy(VkDevice device);
    VkResult reset(VkDevice device, VkCommandPoolResetFlags flags);

    VkResult init(VkDevice device, const VkCommandPoolCreateInfo &createInfo);
};

class Pipeline final : public WrappedObject<Pipeline, VkPipeline>
{
  public:
    Pipeline() = default;
    void destroy(VkDevice device);

    VkResult initGraphics(VkDevice device,
                          const VkGraphicsPipelineCreateInfo &createInfo,
                          const PipelineCache &pipelineCacheVk);
    VkResult initCompute(VkDevice device,
                         const VkComputePipelineCreateInfo &createInfo,
                         const PipelineCache &pipelineCacheVk);
};

namespace priv
{

// Helper class that wraps a Vulkan command buffer.
class CommandBuffer : public WrappedObject<CommandBuffer, VkCommandBuffer>
{
  public:
    CommandBuffer() = default;

    VkCommandBuffer releaseHandle();

    // This is used for normal pool allocated command buffers. It reset the handle.
    void destroy(VkDevice device);

    // This is used in conjunction with VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT.
    void destroy(VkDevice device, const CommandPool &commandPool);

    VkResult init(VkDevice device, const VkCommandBufferAllocateInfo &createInfo);

    // There is no way to know if the command buffer contains any commands.
    static bool CanKnowIfEmpty() { return false; }
    bool empty() const { return false; }

    using WrappedObject::operator=;

    static bool SupportsQueries(const VkPhysicalDeviceFeatures &features)
    {
        return (features.inheritedQueries == VK_TRUE);
    }

    // Vulkan command buffers are executed as secondary command buffers within a primary command
    // buffer.
    static constexpr bool ExecutesInline() { return false; }

    VkResult begin(const VkCommandBufferBeginInfo &info);

    void beginQuery(VkQueryPool queryPool, uint32_t query, VkQueryControlFlags flags);

    void beginRenderPass(const VkRenderPassBeginInfo &beginInfo, VkSubpassContents subpassContents);

    void bindDescriptorSets(const PipelineLayout &layout,
                            VkPipelineBindPoint pipelineBindPoint,
                            uint32_t firstSet,
                            uint32_t descriptorSetCount,
                            const VkDescriptorSet *descriptorSets,
                            uint32_t dynamicOffsetCount,
                            const uint32_t *dynamicOffsets);
    void bindGraphicsPipeline(const Pipeline &pipeline);
    void bindComputePipeline(const Pipeline &pipeline);
    void bindPipeline(VkPipelineBindPoint pipelineBindPoint, const Pipeline &pipeline);

    void bindIndexBuffer(const Buffer &buffer, VkDeviceSize offset, VkIndexType indexType);
    void bindVertexBuffers(uint32_t firstBinding,
                           uint32_t bindingCount,
                           const VkBuffer *buffers,
                           const VkDeviceSize *offsets);

    void blitImage(const Image &srcImage,
                   VkImageLayout srcImageLayout,
                   const Image &dstImage,
                   VkImageLayout dstImageLayout,
                   uint32_t regionCount,
                   const VkImageBlit *regions,
                   VkFilter filter);

    void clearColorImage(const Image &image,
                         VkImageLayout imageLayout,
                         const VkClearColorValue &color,
                         uint32_t rangeCount,
                         const VkImageSubresourceRange *ranges);
    void clearDepthStencilImage(const Image &image,
                                VkImageLayout imageLayout,
                                const VkClearDepthStencilValue &depthStencil,
                                uint32_t rangeCount,
                                const VkImageSubresourceRange *ranges);

    void clearAttachments(uint32_t attachmentCount,
                          const VkClearAttachment *attachments,
                          uint32_t rectCount,
                          const VkClearRect *rects);

    void copyBuffer(const Buffer &srcBuffer,
                    const Buffer &destBuffer,
                    uint32_t regionCount,
                    const VkBufferCopy *regions);

    void copyBufferToImage(VkBuffer srcBuffer,
                           const Image &dstImage,
                           VkImageLayout dstImageLayout,
                           uint32_t regionCount,
                           const VkBufferImageCopy *regions);
    void copyImageToBuffer(const Image &srcImage,
                           VkImageLayout srcImageLayout,
                           VkBuffer dstBuffer,
                           uint32_t regionCount,
                           const VkBufferImageCopy *regions);
    void copyImage(const Image &srcImage,
                   VkImageLayout srcImageLayout,
                   const Image &dstImage,
                   VkImageLayout dstImageLayout,
                   uint32_t regionCount,
                   const VkImageCopy *regions);

    void dispatch(uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ);
    void dispatchIndirect(const Buffer &buffer, VkDeviceSize offset);

    void draw(uint32_t vertexCount,
              uint32_t instanceCount,
              uint32_t firstVertex,
              uint32_t firstInstance);
    void draw(uint32_t vertexCount, uint32_t firstVertex);
    void drawInstanced(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex);
    void drawInstancedBaseInstance(uint32_t vertexCount,
                                   uint32_t instanceCount,
                                   uint32_t firstVertex,
                                   uint32_t firstInstance);
    void drawIndexed(uint32_t indexCount,
                     uint32_t instanceCount,
                     uint32_t firstIndex,
                     int32_t vertexOffset,
                     uint32_t firstInstance);
    void drawIndexed(uint32_t indexCount);
    void drawIndexedInstanced(uint32_t indexCount, uint32_t instanceCount);
    void drawIndexedInstancedBaseVertexBaseInstance(uint32_t indexCount,
                                                    uint32_t instanceCount,
                                                    uint32_t firstIndex,
                                                    int32_t vertexOffset,
                                                    uint32_t firstInstance);
    void drawIndexedIndirect(const Buffer &buffer,
                             VkDeviceSize offset,
                             uint32_t drawCount,
                             uint32_t stride);
    void drawIndirect(const Buffer &buffer,
                      VkDeviceSize offset,
                      uint32_t drawCount,
                      uint32_t stride);

    VkResult end();
    void endQuery(VkQueryPool queryPool, uint32_t query);
    void endRenderPass();
    void executeCommands(uint32_t commandBufferCount, const CommandBuffer *commandBuffers);

    void getMemoryUsageStats(size_t *usedMemoryOut, size_t *allocatedMemoryOut) const;

    void executionBarrier(VkPipelineStageFlags stageMask);

    void fillBuffer(const Buffer &dstBuffer,
                    VkDeviceSize dstOffset,
                    VkDeviceSize size,
                    uint32_t data);

    void imageBarrier(VkPipelineStageFlags srcStageMask,
                      VkPipelineStageFlags dstStageMask,
                      const VkImageMemoryBarrier *imageMemoryBarrier);

    void memoryBarrier(VkPipelineStageFlags srcStageMask,
                       VkPipelineStageFlags dstStageMask,
                       const VkMemoryBarrier *memoryBarrier);

    void pipelineBarrier(VkPipelineStageFlags srcStageMask,
                         VkPipelineStageFlags dstStageMask,
                         VkDependencyFlags dependencyFlags,
                         uint32_t memoryBarrierCount,
                         const VkMemoryBarrier *memoryBarriers,
                         uint32_t bufferMemoryBarrierCount,
                         const VkBufferMemoryBarrier *bufferMemoryBarriers,
                         uint32_t imageMemoryBarrierCount,
                         const VkImageMemoryBarrier *imageMemoryBarriers);

    void pushConstants(const PipelineLayout &layout,
                       VkShaderStageFlags flag,
                       uint32_t offset,
                       uint32_t size,
                       const void *data);

    void setEvent(VkEvent event, VkPipelineStageFlags stageMask);
    VkResult reset();
    void resetEvent(VkEvent event, VkPipelineStageFlags stageMask);
    void resetQueryPool(VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount);
    void resolveImage(const Image &srcImage,
                      VkImageLayout srcImageLayout,
                      const Image &dstImage,
                      VkImageLayout dstImageLayout,
                      uint32_t regionCount,
                      const VkImageResolve *regions);
    void waitEvents(uint32_t eventCount,
                    const VkEvent *events,
                    VkPipelineStageFlags srcStageMask,
                    VkPipelineStageFlags dstStageMask,
                    uint32_t memoryBarrierCount,
                    const VkMemoryBarrier *memoryBarriers,
                    uint32_t bufferMemoryBarrierCount,
                    const VkBufferMemoryBarrier *bufferMemoryBarriers,
                    uint32_t imageMemoryBarrierCount,
                    const VkImageMemoryBarrier *imageMemoryBarriers);

    void writeTimestamp(VkPipelineStageFlagBits pipelineStage,
                        VkQueryPool queryPool,
                        uint32_t query);
};
}  // namespace priv

class Image final : public WrappedObject<Image, VkImage>
{
  public:
    Image() = default;

    // Use this method if the lifetime of the image is not controlled by ANGLE. (SwapChain)
    void setHandle(VkImage handle);

    // Called on shutdown when the helper class *doesn't* own the handle to the image resource.
    void reset();

    // Called on shutdown when the helper class *does* own the handle to the image resource.
    void destroy(VkDevice device);

    VkResult init(VkDevice device, const VkImageCreateInfo &createInfo);

    void getMemoryRequirements(VkDevice device, VkMemoryRequirements *requirementsOut) const;
    VkResult bindMemory(VkDevice device, const DeviceMemory &deviceMemory);

    void getSubresourceLayout(VkDevice device,
                              VkImageAspectFlagBits aspectMask,
                              uint32_t mipLevel,
                              uint32_t arrayLayer,
                              VkSubresourceLayout *outSubresourceLayout) const;
};

class ImageView final : public WrappedObject<ImageView, VkImageView>
{
  public:
    ImageView() = default;
    void destroy(VkDevice device);

    VkResult init(VkDevice device, const VkImageViewCreateInfo &createInfo);
};

class Semaphore final : public WrappedObject<Semaphore, VkSemaphore>
{
  public:
    Semaphore() = default;
    void destroy(VkDevice device);

    VkResult init(VkDevice device);
};

class Framebuffer final : public WrappedObject<Framebuffer, VkFramebuffer>
{
  public:
    Framebuffer() = default;
    void destroy(VkDevice device);

    // Use this method only in necessary cases. (RenderPass)
    void setHandle(VkFramebuffer handle);

    VkResult init(VkDevice device, const VkFramebufferCreateInfo &createInfo);
};

class DeviceMemory final : public WrappedObject<DeviceMemory, VkDeviceMemory>
{
  public:
    DeviceMemory() = default;
    void destroy(VkDevice device);

    VkResult allocate(VkDevice device, const VkMemoryAllocateInfo &allocInfo);
    VkResult map(VkDevice device,
                 VkDeviceSize offset,
                 VkDeviceSize size,
                 VkMemoryMapFlags flags,
                 uint8_t **mapPointer) const;
    void unmap(VkDevice device) const;
};

class RenderPass final : public WrappedObject<RenderPass, VkRenderPass>
{
  public:
    RenderPass() = default;
    void destroy(VkDevice device);

    VkResult init(VkDevice device, const VkRenderPassCreateInfo &createInfo);
};

enum class StagingUsage
{
    Read,
    Write,
    Both,
};

class Buffer final : public WrappedObject<Buffer, VkBuffer>
{
  public:
    Buffer() = default;
    void destroy(VkDevice device);

    VkResult init(VkDevice device, const VkBufferCreateInfo &createInfo);
    VkResult bindMemory(VkDevice device, const DeviceMemory &deviceMemory);
    void getMemoryRequirements(VkDevice device, VkMemoryRequirements *memoryRequirementsOut);
};

class BufferView final : public WrappedObject<BufferView, VkBufferView>
{
  public:
    BufferView() = default;
    void destroy(VkDevice device);

    VkResult init(VkDevice device, const VkBufferViewCreateInfo &createInfo);
};

class ShaderModule final : public WrappedObject<ShaderModule, VkShaderModule>
{
  public:
    ShaderModule() = default;
    void destroy(VkDevice device);

    VkResult init(VkDevice device, const VkShaderModuleCreateInfo &createInfo);
};

class PipelineLayout final : public WrappedObject<PipelineLayout, VkPipelineLayout>
{
  public:
    PipelineLayout() = default;
    void destroy(VkDevice device);

    VkResult init(VkDevice device, const VkPipelineLayoutCreateInfo &createInfo);
};

class PipelineCache final : public WrappedObject<PipelineCache, VkPipelineCache>
{
  public:
    PipelineCache() = default;
    void destroy(VkDevice device);

    VkResult init(VkDevice device, const VkPipelineCacheCreateInfo &createInfo);
    VkResult getCacheData(VkDevice device, size_t *cacheSize, void *cacheData);
    VkResult merge(VkDevice device,
                   VkPipelineCache dstCache,
                   uint32_t srcCacheCount,
                   const VkPipelineCache *srcCaches);
};

class DescriptorSetLayout final : public WrappedObject<DescriptorSetLayout, VkDescriptorSetLayout>
{
  public:
    DescriptorSetLayout() = default;
    void destroy(VkDevice device);

    VkResult init(VkDevice device, const VkDescriptorSetLayoutCreateInfo &createInfo);
};

class DescriptorPool final : public WrappedObject<DescriptorPool, VkDescriptorPool>
{
  public:
    DescriptorPool() = default;
    void destroy(VkDevice device);

    VkResult init(VkDevice device, const VkDescriptorPoolCreateInfo &createInfo);

    VkResult allocateDescriptorSets(VkDevice device,
                                    const VkDescriptorSetAllocateInfo &allocInfo,
                                    VkDescriptorSet *descriptorSetsOut);
    VkResult freeDescriptorSets(VkDevice device,
                                uint32_t descriptorSetCount,
                                const VkDescriptorSet *descriptorSets);
};

class Sampler final : public WrappedObject<Sampler, VkSampler>
{
  public:
    Sampler() = default;
    void destroy(VkDevice device);
    VkResult init(VkDevice device, const VkSamplerCreateInfo &createInfo);
};

class Event final : public WrappedObject<Event, VkEvent>
{
  public:
    Event() = default;
    void destroy(VkDevice device);
    using WrappedObject::operator=;

    VkResult init(VkDevice device, const VkEventCreateInfo &createInfo);
    VkResult getStatus(VkDevice device) const;
    VkResult set(VkDevice device) const;
    VkResult reset(VkDevice device) const;
};

class Fence final : public WrappedObject<Fence, VkFence>
{
  public:
    Fence() = default;
    void destroy(VkDevice device);
    using WrappedObject::operator=;

    VkResult init(VkDevice device, const VkFenceCreateInfo &createInfo);
    VkResult reset(VkDevice device);
    VkResult getStatus(VkDevice device) const;
    VkResult wait(VkDevice device, uint64_t timeout) const;
};

class QueryPool final : public WrappedObject<QueryPool, VkQueryPool>
{
  public:
    QueryPool() = default;
    void destroy(VkDevice device);

    VkResult init(VkDevice device, const VkQueryPoolCreateInfo &createInfo);
    VkResult getResults(VkDevice device,
                        uint32_t firstQuery,
                        uint32_t queryCount,
                        size_t dataSize,
                        void *data,
                        VkDeviceSize stride,
                        VkQueryResultFlags flags) const;
};

// CommandPool implementation.
ANGLE_INLINE void CommandPool::destroy(VkDevice device)
{
    if (valid())
    {
        vkDestroyCommandPool(device, mHandle, nullptr);
        mHandle = VK_NULL_HANDLE;
    }
}

ANGLE_INLINE VkResult CommandPool::reset(VkDevice device, VkCommandPoolResetFlags flags)
{
    ASSERT(valid());
    return vkResetCommandPool(device, mHandle, flags);
}

ANGLE_INLINE VkResult CommandPool::init(VkDevice device, const VkCommandPoolCreateInfo &createInfo)
{
    ASSERT(!valid());
    return vkCreateCommandPool(device, &createInfo, nullptr, &mHandle);
}

namespace priv
{

// CommandBuffer implementation.
ANGLE_INLINE VkCommandBuffer CommandBuffer::releaseHandle()
{
    VkCommandBuffer handle = mHandle;
    mHandle                = nullptr;
    return handle;
}

ANGLE_INLINE VkResult CommandBuffer::init(VkDevice device,
                                          const VkCommandBufferAllocateInfo &createInfo)
{
    ASSERT(!valid());
    return vkAllocateCommandBuffers(device, &createInfo, &mHandle);
}

ANGLE_INLINE void CommandBuffer::blitImage(const Image &srcImage,
                                           VkImageLayout srcImageLayout,
                                           const Image &dstImage,
                                           VkImageLayout dstImageLayout,
                                           uint32_t regionCount,
                                           const VkImageBlit *regions,
                                           VkFilter filter)
{
    ASSERT(valid() && srcImage.valid() && dstImage.valid());
    ASSERT(regionCount == 1);
    vkCmdBlitImage(mHandle, srcImage.getHandle(), srcImageLayout, dstImage.getHandle(),
                   dstImageLayout, 1, regions, filter);
}

ANGLE_INLINE VkResult CommandBuffer::begin(const VkCommandBufferBeginInfo &info)
{
    ASSERT(valid());
    return vkBeginCommandBuffer(mHandle, &info);
}

ANGLE_INLINE VkResult CommandBuffer::end()
{
    ASSERT(valid());
    return vkEndCommandBuffer(mHandle);
}

ANGLE_INLINE VkResult CommandBuffer::reset()
{
    ASSERT(valid());
    return vkResetCommandBuffer(mHandle, 0);
}

ANGLE_INLINE void CommandBuffer::memoryBarrier(VkPipelineStageFlags srcStageMask,
                                               VkPipelineStageFlags dstStageMask,
                                               const VkMemoryBarrier *memoryBarrier)
{
    ASSERT(valid());
    vkCmdPipelineBarrier(mHandle, srcStageMask, dstStageMask, 0, 1, memoryBarrier, 0, nullptr, 0,
                         nullptr);
}

ANGLE_INLINE void CommandBuffer::pipelineBarrier(VkPipelineStageFlags srcStageMask,
                                                 VkPipelineStageFlags dstStageMask,
                                                 VkDependencyFlags dependencyFlags,
                                                 uint32_t memoryBarrierCount,
                                                 const VkMemoryBarrier *memoryBarriers,
                                                 uint32_t bufferMemoryBarrierCount,
                                                 const VkBufferMemoryBarrier *bufferMemoryBarriers,
                                                 uint32_t imageMemoryBarrierCount,
                                                 const VkImageMemoryBarrier *imageMemoryBarriers)
{
    ASSERT(valid());
    vkCmdPipelineBarrier(mHandle, srcStageMask, dstStageMask, dependencyFlags, memoryBarrierCount,
                         memoryBarriers, bufferMemoryBarrierCount, bufferMemoryBarriers,
                         imageMemoryBarrierCount, imageMemoryBarriers);
}

ANGLE_INLINE void CommandBuffer::executionBarrier(VkPipelineStageFlags stageMask)
{
    ASSERT(valid());
    vkCmdPipelineBarrier(mHandle, stageMask, stageMask, 0, 0, nullptr, 0, nullptr, 0, nullptr);
}

ANGLE_INLINE void CommandBuffer::imageBarrier(VkPipelineStageFlags srcStageMask,
                                              VkPipelineStageFlags dstStageMask,
                                              const VkImageMemoryBarrier *imageMemoryBarrier)
{
    ASSERT(valid());
    vkCmdPipelineBarrier(mHandle, srcStageMask, dstStageMask, 0, 0, nullptr, 0, nullptr, 1,
                         imageMemoryBarrier);
}

ANGLE_INLINE void CommandBuffer::destroy(VkDevice device)
{
    releaseHandle();
}

ANGLE_INLINE void CommandBuffer::destroy(VkDevice device, const vk::CommandPool &commandPool)
{
    if (valid())
    {
        ASSERT(commandPool.valid());
        vkFreeCommandBuffers(device, commandPool.getHandle(), 1, &mHandle);
        mHandle = VK_NULL_HANDLE;
    }
}

ANGLE_INLINE void CommandBuffer::copyBuffer(const Buffer &srcBuffer,
                                            const Buffer &destBuffer,
                                            uint32_t regionCount,
                                            const VkBufferCopy *regions)
{
    ASSERT(valid() && srcBuffer.valid() && destBuffer.valid());
    vkCmdCopyBuffer(mHandle, srcBuffer.getHandle(), destBuffer.getHandle(), regionCount, regions);
}

ANGLE_INLINE void CommandBuffer::copyBufferToImage(VkBuffer srcBuffer,
                                                   const Image &dstImage,
                                                   VkImageLayout dstImageLayout,
                                                   uint32_t regionCount,
                                                   const VkBufferImageCopy *regions)
{
    ASSERT(valid() && dstImage.valid());
    ASSERT(srcBuffer != VK_NULL_HANDLE);
    ASSERT(regionCount == 1);
    vkCmdCopyBufferToImage(mHandle, srcBuffer, dstImage.getHandle(), dstImageLayout, 1, regions);
}

ANGLE_INLINE void CommandBuffer::copyImageToBuffer(const Image &srcImage,
                                                   VkImageLayout srcImageLayout,
                                                   VkBuffer dstBuffer,
                                                   uint32_t regionCount,
                                                   const VkBufferImageCopy *regions)
{
    ASSERT(valid() && srcImage.valid());
    ASSERT(dstBuffer != VK_NULL_HANDLE);
    ASSERT(regionCount == 1);
    vkCmdCopyImageToBuffer(mHandle, srcImage.getHandle(), srcImageLayout, dstBuffer, 1, regions);
}

ANGLE_INLINE void CommandBuffer::clearColorImage(const Image &image,
                                                 VkImageLayout imageLayout,
                                                 const VkClearColorValue &color,
                                                 uint32_t rangeCount,
                                                 const VkImageSubresourceRange *ranges)
{
    ASSERT(valid());
    ASSERT(rangeCount == 1);
    vkCmdClearColorImage(mHandle, image.getHandle(), imageLayout, &color, 1, ranges);
}

ANGLE_INLINE void CommandBuffer::clearDepthStencilImage(
    const Image &image,
    VkImageLayout imageLayout,
    const VkClearDepthStencilValue &depthStencil,
    uint32_t rangeCount,
    const VkImageSubresourceRange *ranges)
{
    ASSERT(valid());
    ASSERT(rangeCount == 1);
    vkCmdClearDepthStencilImage(mHandle, image.getHandle(), imageLayout, &depthStencil, 1, ranges);
}

ANGLE_INLINE void CommandBuffer::clearAttachments(uint32_t attachmentCount,
                                                  const VkClearAttachment *attachments,
                                                  uint32_t rectCount,
                                                  const VkClearRect *rects)
{
    ASSERT(valid());
    vkCmdClearAttachments(mHandle, attachmentCount, attachments, rectCount, rects);
}

ANGLE_INLINE void CommandBuffer::copyImage(const Image &srcImage,
                                           VkImageLayout srcImageLayout,
                                           const Image &dstImage,
                                           VkImageLayout dstImageLayout,
                                           uint32_t regionCount,
                                           const VkImageCopy *regions)
{
    ASSERT(valid() && srcImage.valid() && dstImage.valid());
    ASSERT(regionCount == 1);
    vkCmdCopyImage(mHandle, srcImage.getHandle(), srcImageLayout, dstImage.getHandle(),
                   dstImageLayout, 1, regions);
}

ANGLE_INLINE void CommandBuffer::beginRenderPass(const VkRenderPassBeginInfo &beginInfo,
                                                 VkSubpassContents subpassContents)
{
    ASSERT(valid());
    vkCmdBeginRenderPass(mHandle, &beginInfo, subpassContents);
}

ANGLE_INLINE void CommandBuffer::endRenderPass()
{
    ASSERT(mHandle != VK_NULL_HANDLE);
    vkCmdEndRenderPass(mHandle);
}

ANGLE_INLINE void CommandBuffer::bindIndexBuffer(const Buffer &buffer,
                                                 VkDeviceSize offset,
                                                 VkIndexType indexType)
{
    ASSERT(valid());
    vkCmdBindIndexBuffer(mHandle, buffer.getHandle(), offset, indexType);
}

ANGLE_INLINE void CommandBuffer::bindDescriptorSets(const PipelineLayout &layout,
                                                    VkPipelineBindPoint pipelineBindPoint,
                                                    uint32_t firstSet,
                                                    uint32_t descriptorSetCount,
                                                    const VkDescriptorSet *descriptorSets,
                                                    uint32_t dynamicOffsetCount,
                                                    const uint32_t *dynamicOffsets)
{
    ASSERT(valid() && layout.valid());
    vkCmdBindDescriptorSets(mHandle, pipelineBindPoint, layout.getHandle(), firstSet,
                            descriptorSetCount, descriptorSets, dynamicOffsetCount, dynamicOffsets);
}

ANGLE_INLINE void CommandBuffer::executeCommands(uint32_t commandBufferCount,
                                                 const CommandBuffer *commandBuffers)
{
    ASSERT(valid());
    vkCmdExecuteCommands(mHandle, commandBufferCount, commandBuffers[0].ptr());
}

ANGLE_INLINE void CommandBuffer::getMemoryUsageStats(size_t *usedMemoryOut,
                                                     size_t *allocatedMemoryOut) const
{
    // No data available.
    *usedMemoryOut      = 0;
    *allocatedMemoryOut = 1;
}

ANGLE_INLINE void CommandBuffer::fillBuffer(const Buffer &dstBuffer,
                                            VkDeviceSize dstOffset,
                                            VkDeviceSize size,
                                            uint32_t data)
{
    ASSERT(valid());
    vkCmdFillBuffer(mHandle, dstBuffer.getHandle(), dstOffset, size, data);
}

ANGLE_INLINE void CommandBuffer::pushConstants(const PipelineLayout &layout,
                                               VkShaderStageFlags flag,
                                               uint32_t offset,
                                               uint32_t size,
                                               const void *data)
{
    ASSERT(valid() && layout.valid());
    ASSERT(offset == 0);
    vkCmdPushConstants(mHandle, layout.getHandle(), flag, 0, size, data);
}

ANGLE_INLINE void CommandBuffer::setEvent(VkEvent event, VkPipelineStageFlags stageMask)
{
    ASSERT(valid() && event != VK_NULL_HANDLE);
    vkCmdSetEvent(mHandle, event, stageMask);
}

ANGLE_INLINE void CommandBuffer::resetEvent(VkEvent event, VkPipelineStageFlags stageMask)
{
    ASSERT(valid() && event != VK_NULL_HANDLE);
    vkCmdResetEvent(mHandle, event, stageMask);
}

ANGLE_INLINE void CommandBuffer::waitEvents(uint32_t eventCount,
                                            const VkEvent *events,
                                            VkPipelineStageFlags srcStageMask,
                                            VkPipelineStageFlags dstStageMask,
                                            uint32_t memoryBarrierCount,
                                            const VkMemoryBarrier *memoryBarriers,
                                            uint32_t bufferMemoryBarrierCount,
                                            const VkBufferMemoryBarrier *bufferMemoryBarriers,
                                            uint32_t imageMemoryBarrierCount,
                                            const VkImageMemoryBarrier *imageMemoryBarriers)
{
    ASSERT(valid());
    vkCmdWaitEvents(mHandle, eventCount, events, srcStageMask, dstStageMask, memoryBarrierCount,
                    memoryBarriers, bufferMemoryBarrierCount, bufferMemoryBarriers,
                    imageMemoryBarrierCount, imageMemoryBarriers);
}

ANGLE_INLINE void CommandBuffer::resetQueryPool(VkQueryPool queryPool,
                                                uint32_t firstQuery,
                                                uint32_t queryCount)
{
    ASSERT(valid());
    vkCmdResetQueryPool(mHandle, queryPool, firstQuery, queryCount);
}

ANGLE_INLINE void CommandBuffer::resolveImage(const Image &srcImage,
                                              VkImageLayout srcImageLayout,
                                              const Image &dstImage,
                                              VkImageLayout dstImageLayout,
                                              uint32_t regionCount,
                                              const VkImageResolve *regions)
{
    ASSERT(valid() && srcImage.valid() && dstImage.valid());
    vkCmdResolveImage(mHandle, srcImage.getHandle(), srcImageLayout, dstImage.getHandle(),
                      dstImageLayout, regionCount, regions);
}

ANGLE_INLINE void CommandBuffer::beginQuery(VkQueryPool queryPool,
                                            uint32_t query,
                                            VkQueryControlFlags flags)
{
    ASSERT(valid());
    vkCmdBeginQuery(mHandle, queryPool, query, flags);
}

ANGLE_INLINE void CommandBuffer::endQuery(VkQueryPool queryPool, uint32_t query)
{
    ASSERT(valid());
    vkCmdEndQuery(mHandle, queryPool, query);
}

ANGLE_INLINE void CommandBuffer::writeTimestamp(VkPipelineStageFlagBits pipelineStage,
                                                VkQueryPool queryPool,
                                                uint32_t query)
{
    ASSERT(valid());
    vkCmdWriteTimestamp(mHandle, pipelineStage, queryPool, query);
}

ANGLE_INLINE void CommandBuffer::draw(uint32_t vertexCount,
                                      uint32_t instanceCount,
                                      uint32_t firstVertex,
                                      uint32_t firstInstance)
{
    ASSERT(valid());
    vkCmdDraw(mHandle, vertexCount, instanceCount, firstVertex, firstInstance);
}

ANGLE_INLINE void CommandBuffer::draw(uint32_t vertexCount, uint32_t firstVertex)
{
    ASSERT(valid());
    vkCmdDraw(mHandle, vertexCount, 1, firstVertex, 0);
}

ANGLE_INLINE void CommandBuffer::drawInstanced(uint32_t vertexCount,
                                               uint32_t instanceCount,
                                               uint32_t firstVertex)
{
    ASSERT(valid());
    vkCmdDraw(mHandle, vertexCount, instanceCount, firstVertex, 0);
}

ANGLE_INLINE void CommandBuffer::drawInstancedBaseInstance(uint32_t vertexCount,
                                                           uint32_t instanceCount,
                                                           uint32_t firstVertex,
                                                           uint32_t firstInstance)
{
    ASSERT(valid());
    vkCmdDraw(mHandle, vertexCount, instanceCount, firstVertex, firstInstance);
}

ANGLE_INLINE void CommandBuffer::drawIndexed(uint32_t indexCount,
                                             uint32_t instanceCount,
                                             uint32_t firstIndex,
                                             int32_t vertexOffset,
                                             uint32_t firstInstance)
{
    ASSERT(valid());
    vkCmdDrawIndexed(mHandle, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
}

ANGLE_INLINE void CommandBuffer::drawIndexed(uint32_t indexCount)
{
    ASSERT(valid());
    vkCmdDrawIndexed(mHandle, indexCount, 1, 0, 0, 0);
}

ANGLE_INLINE void CommandBuffer::drawIndexedInstanced(uint32_t indexCount, uint32_t instanceCount)
{
    ASSERT(valid());
    vkCmdDrawIndexed(mHandle, indexCount, instanceCount, 0, 0, 0);
}

ANGLE_INLINE void CommandBuffer::drawIndexedInstancedBaseVertexBaseInstance(uint32_t indexCount,
                                                                            uint32_t instanceCount,
                                                                            uint32_t firstIndex,
                                                                            int32_t vertexOffset,
                                                                            uint32_t firstInstance)
{
    ASSERT(valid());
    vkCmdDrawIndexed(mHandle, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
}

ANGLE_INLINE void CommandBuffer::drawIndexedIndirect(const Buffer &buffer,
                                                     VkDeviceSize offset,
                                                     uint32_t drawCount,
                                                     uint32_t stride)
{
    ASSERT(valid());
    vkCmdDrawIndexedIndirect(mHandle, buffer.getHandle(), offset, drawCount, stride);
}

ANGLE_INLINE void CommandBuffer::drawIndirect(const Buffer &buffer,
                                              VkDeviceSize offset,
                                              uint32_t drawCount,
                                              uint32_t stride)
{
    ASSERT(valid());
    vkCmdDrawIndirect(mHandle, buffer.getHandle(), offset, drawCount, stride);
}

ANGLE_INLINE void CommandBuffer::dispatch(uint32_t groupCountX,
                                          uint32_t groupCountY,
                                          uint32_t groupCountZ)
{
    ASSERT(valid());
    vkCmdDispatch(mHandle, groupCountX, groupCountY, groupCountZ);
}

ANGLE_INLINE void CommandBuffer::dispatchIndirect(const Buffer &buffer, VkDeviceSize offset)
{
    ASSERT(valid());
    vkCmdDispatchIndirect(mHandle, buffer.getHandle(), offset);
}

ANGLE_INLINE void CommandBuffer::bindPipeline(VkPipelineBindPoint pipelineBindPoint,
                                              const Pipeline &pipeline)
{
    ASSERT(valid() && pipeline.valid());
    vkCmdBindPipeline(mHandle, pipelineBindPoint, pipeline.getHandle());
}

ANGLE_INLINE void CommandBuffer::bindGraphicsPipeline(const Pipeline &pipeline)
{
    ASSERT(valid() && pipeline.valid());
    vkCmdBindPipeline(mHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.getHandle());
}

ANGLE_INLINE void CommandBuffer::bindComputePipeline(const Pipeline &pipeline)
{
    ASSERT(valid() && pipeline.valid());
    vkCmdBindPipeline(mHandle, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline.getHandle());
}

ANGLE_INLINE void CommandBuffer::bindVertexBuffers(uint32_t firstBinding,
                                                   uint32_t bindingCount,
                                                   const VkBuffer *buffers,
                                                   const VkDeviceSize *offsets)
{
    ASSERT(valid());
    vkCmdBindVertexBuffers(mHandle, firstBinding, bindingCount, buffers, offsets);
}

}  // namespace priv

// Image implementation.
ANGLE_INLINE void Image::setHandle(VkImage handle)
{
    mHandle = handle;
}

ANGLE_INLINE void Image::reset()
{
    mHandle = VK_NULL_HANDLE;
}

ANGLE_INLINE void Image::destroy(VkDevice device)
{
    if (valid())
    {
        vkDestroyImage(device, mHandle, nullptr);
        mHandle = VK_NULL_HANDLE;
    }
}

ANGLE_INLINE VkResult Image::init(VkDevice device, const VkImageCreateInfo &createInfo)
{
    ASSERT(!valid());
    return vkCreateImage(device, &createInfo, nullptr, &mHandle);
}

ANGLE_INLINE void Image::getMemoryRequirements(VkDevice device,
                                               VkMemoryRequirements *requirementsOut) const
{
    ASSERT(valid());
    vkGetImageMemoryRequirements(device, mHandle, requirementsOut);
}

ANGLE_INLINE VkResult Image::bindMemory(VkDevice device, const vk::DeviceMemory &deviceMemory)
{
    ASSERT(valid() && deviceMemory.valid());
    return vkBindImageMemory(device, mHandle, deviceMemory.getHandle(), 0);
}

ANGLE_INLINE void Image::getSubresourceLayout(VkDevice device,
                                              VkImageAspectFlagBits aspectMask,
                                              uint32_t mipLevel,
                                              uint32_t arrayLayer,
                                              VkSubresourceLayout *outSubresourceLayout) const
{
    VkImageSubresource subresource = {};
    subresource.aspectMask         = aspectMask;
    subresource.mipLevel           = mipLevel;
    subresource.arrayLayer         = arrayLayer;

    vkGetImageSubresourceLayout(device, getHandle(), &subresource, outSubresourceLayout);
}

// ImageView implementation.
ANGLE_INLINE void ImageView::destroy(VkDevice device)
{
    if (valid())
    {
        vkDestroyImageView(device, mHandle, nullptr);
        mHandle = VK_NULL_HANDLE;
    }
}

ANGLE_INLINE VkResult ImageView::init(VkDevice device, const VkImageViewCreateInfo &createInfo)
{
    return vkCreateImageView(device, &createInfo, nullptr, &mHandle);
}

// Semaphore implementation.
ANGLE_INLINE void Semaphore::destroy(VkDevice device)
{
    if (valid())
    {
        vkDestroySemaphore(device, mHandle, nullptr);
        mHandle = VK_NULL_HANDLE;
    }
}

ANGLE_INLINE VkResult Semaphore::init(VkDevice device)
{
    ASSERT(!valid());

    VkSemaphoreCreateInfo semaphoreInfo = {};
    semaphoreInfo.sType                 = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
    semaphoreInfo.flags                 = 0;

    return vkCreateSemaphore(device, &semaphoreInfo, nullptr, &mHandle);
}

// Framebuffer implementation.
ANGLE_INLINE void Framebuffer::destroy(VkDevice device)
{
    if (valid())
    {
        vkDestroyFramebuffer(device, mHandle, nullptr);
        mHandle = VK_NULL_HANDLE;
    }
}

ANGLE_INLINE VkResult Framebuffer::init(VkDevice device, const VkFramebufferCreateInfo &createInfo)
{
    ASSERT(!valid());
    return vkCreateFramebuffer(device, &createInfo, nullptr, &mHandle);
}

ANGLE_INLINE void Framebuffer::setHandle(VkFramebuffer handle)
{
    mHandle = handle;
}

// DeviceMemory implementation.
ANGLE_INLINE void DeviceMemory::destroy(VkDevice device)
{
    if (valid())
    {
        vkFreeMemory(device, mHandle, nullptr);
        mHandle = VK_NULL_HANDLE;
    }
}

ANGLE_INLINE VkResult DeviceMemory::allocate(VkDevice device, const VkMemoryAllocateInfo &allocInfo)
{
    ASSERT(!valid());
    return vkAllocateMemory(device, &allocInfo, nullptr, &mHandle);
}

ANGLE_INLINE VkResult DeviceMemory::map(VkDevice device,
                                        VkDeviceSize offset,
                                        VkDeviceSize size,
                                        VkMemoryMapFlags flags,
                                        uint8_t **mapPointer) const
{
    ASSERT(valid());
    return vkMapMemory(device, mHandle, offset, size, flags, reinterpret_cast<void **>(mapPointer));
}

ANGLE_INLINE void DeviceMemory::unmap(VkDevice device) const
{
    ASSERT(valid());
    vkUnmapMemory(device, mHandle);
}

// RenderPass implementation.
ANGLE_INLINE void RenderPass::destroy(VkDevice device)
{
    if (valid())
    {
        vkDestroyRenderPass(device, mHandle, nullptr);
        mHandle = VK_NULL_HANDLE;
    }
}

ANGLE_INLINE VkResult RenderPass::init(VkDevice device, const VkRenderPassCreateInfo &createInfo)
{
    ASSERT(!valid());
    return vkCreateRenderPass(device, &createInfo, nullptr, &mHandle);
}

// Buffer implementation.
ANGLE_INLINE void Buffer::destroy(VkDevice device)
{
    if (valid())
    {
        vkDestroyBuffer(device, mHandle, nullptr);
        mHandle = VK_NULL_HANDLE;
    }
}

ANGLE_INLINE VkResult Buffer::init(VkDevice device, const VkBufferCreateInfo &createInfo)
{
    ASSERT(!valid());
    return vkCreateBuffer(device, &createInfo, nullptr, &mHandle);
}

ANGLE_INLINE VkResult Buffer::bindMemory(VkDevice device, const DeviceMemory &deviceMemory)
{
    ASSERT(valid() && deviceMemory.valid());
    return vkBindBufferMemory(device, mHandle, deviceMemory.getHandle(), 0);
}

ANGLE_INLINE void Buffer::getMemoryRequirements(VkDevice device,
                                                VkMemoryRequirements *memoryRequirementsOut)
{
    ASSERT(valid());
    vkGetBufferMemoryRequirements(device, mHandle, memoryRequirementsOut);
}

// BufferView implementation.
ANGLE_INLINE void BufferView::destroy(VkDevice device)
{
    if (valid())
    {
        vkDestroyBufferView(device, mHandle, nullptr);
        mHandle = VK_NULL_HANDLE;
    }
}

ANGLE_INLINE VkResult BufferView::init(VkDevice device, const VkBufferViewCreateInfo &createInfo)
{
    ASSERT(!valid());
    return vkCreateBufferView(device, &createInfo, nullptr, &mHandle);
}

// ShaderModule implementation.
ANGLE_INLINE void ShaderModule::destroy(VkDevice device)
{
    if (mHandle != VK_NULL_HANDLE)
    {
        vkDestroyShaderModule(device, mHandle, nullptr);
        mHandle = VK_NULL_HANDLE;
    }
}

ANGLE_INLINE VkResult ShaderModule::init(VkDevice device,
                                         const VkShaderModuleCreateInfo &createInfo)
{
    ASSERT(!valid());
    return vkCreateShaderModule(device, &createInfo, nullptr, &mHandle);
}

// PipelineLayout implementation.
ANGLE_INLINE void PipelineLayout::destroy(VkDevice device)
{
    if (valid())
    {
        vkDestroyPipelineLayout(device, mHandle, nullptr);
        mHandle = VK_NULL_HANDLE;
    }
}

ANGLE_INLINE VkResult PipelineLayout::init(VkDevice device,
                                           const VkPipelineLayoutCreateInfo &createInfo)
{
    ASSERT(!valid());
    return vkCreatePipelineLayout(device, &createInfo, nullptr, &mHandle);
}

// PipelineCache implementation.
ANGLE_INLINE void PipelineCache::destroy(VkDevice device)
{
    if (valid())
    {
        vkDestroyPipelineCache(device, mHandle, nullptr);
        mHandle = VK_NULL_HANDLE;
    }
}

ANGLE_INLINE VkResult PipelineCache::init(VkDevice device,
                                          const VkPipelineCacheCreateInfo &createInfo)
{
    ASSERT(!valid());
    // Note: if we are concerned with memory usage of this cache, we should give it custom
    // allocators.  Also, failure of this function is of little importance.
    return vkCreatePipelineCache(device, &createInfo, nullptr, &mHandle);
}

ANGLE_INLINE VkResult PipelineCache::merge(VkDevice device,
                                           VkPipelineCache dstCache,
                                           uint32_t srcCacheCount,
                                           const VkPipelineCache *srcCaches)
{
    ASSERT(valid());
    return vkMergePipelineCaches(device, dstCache, srcCacheCount, srcCaches);
}

ANGLE_INLINE VkResult PipelineCache::getCacheData(VkDevice device,
                                                  size_t *cacheSize,
                                                  void *cacheData)
{
    ASSERT(valid());

    // Note: vkGetPipelineCacheData can return VK_INCOMPLETE if cacheSize is smaller than actual
    // size. There are two usages of this function.  One is with *cacheSize == 0 to query the size
    // of the cache, and one is with an appropriate buffer to retrieve the cache contents.
    // VK_INCOMPLETE in the first case is an expected output.  In the second case, VK_INCOMPLETE is
    // also acceptable and the resulting buffer will contain valid value by spec.  Angle currently
    // ensures *cacheSize to be either 0 or of enough size, therefore VK_INCOMPLETE is not expected.
    return vkGetPipelineCacheData(device, mHandle, cacheSize, cacheData);
}

// Pipeline implementation.
ANGLE_INLINE void Pipeline::destroy(VkDevice device)
{
    if (valid())
    {
        vkDestroyPipeline(device, mHandle, nullptr);
        mHandle = VK_NULL_HANDLE;
    }
}

ANGLE_INLINE VkResult Pipeline::initGraphics(VkDevice device,
                                             const VkGraphicsPipelineCreateInfo &createInfo,
                                             const PipelineCache &pipelineCacheVk)
{
    ASSERT(!valid());
    return vkCreateGraphicsPipelines(device, pipelineCacheVk.getHandle(), 1, &createInfo, nullptr,
                                     &mHandle);
}

ANGLE_INLINE VkResult Pipeline::initCompute(VkDevice device,
                                            const VkComputePipelineCreateInfo &createInfo,
                                            const PipelineCache &pipelineCacheVk)
{
    ASSERT(!valid());
    return vkCreateComputePipelines(device, pipelineCacheVk.getHandle(), 1, &createInfo, nullptr,
                                    &mHandle);
}

// DescriptorSetLayout implementation.
ANGLE_INLINE void DescriptorSetLayout::destroy(VkDevice device)
{
    if (valid())
    {
        vkDestroyDescriptorSetLayout(device, mHandle, nullptr);
        mHandle = VK_NULL_HANDLE;
    }
}

ANGLE_INLINE VkResult DescriptorSetLayout::init(VkDevice device,
                                                const VkDescriptorSetLayoutCreateInfo &createInfo)
{
    ASSERT(!valid());
    return vkCreateDescriptorSetLayout(device, &createInfo, nullptr, &mHandle);
}

// DescriptorPool implementation.
ANGLE_INLINE void DescriptorPool::destroy(VkDevice device)
{
    if (valid())
    {
        vkDestroyDescriptorPool(device, mHandle, nullptr);
        mHandle = VK_NULL_HANDLE;
    }
}

ANGLE_INLINE VkResult DescriptorPool::init(VkDevice device,
                                           const VkDescriptorPoolCreateInfo &createInfo)
{
    ASSERT(!valid());
    return vkCreateDescriptorPool(device, &createInfo, nullptr, &mHandle);
}

ANGLE_INLINE VkResult
DescriptorPool::allocateDescriptorSets(VkDevice device,
                                       const VkDescriptorSetAllocateInfo &allocInfo,
                                       VkDescriptorSet *descriptorSetsOut)
{
    ASSERT(valid());
    return vkAllocateDescriptorSets(device, &allocInfo, descriptorSetsOut);
}

ANGLE_INLINE VkResult DescriptorPool::freeDescriptorSets(VkDevice device,
                                                         uint32_t descriptorSetCount,
                                                         const VkDescriptorSet *descriptorSets)
{
    ASSERT(valid());
    ASSERT(descriptorSetCount > 0);
    return vkFreeDescriptorSets(device, mHandle, descriptorSetCount, descriptorSets);
}

// Sampler implementation.
ANGLE_INLINE void Sampler::destroy(VkDevice device)
{
    if (valid())
    {
        vkDestroySampler(device, mHandle, nullptr);
        mHandle = VK_NULL_HANDLE;
    }
}

ANGLE_INLINE VkResult Sampler::init(VkDevice device, const VkSamplerCreateInfo &createInfo)
{
    ASSERT(!valid());
    return vkCreateSampler(device, &createInfo, nullptr, &mHandle);
}

// Event implementation.
ANGLE_INLINE void Event::destroy(VkDevice device)
{
    if (valid())
    {
        vkDestroyEvent(device, mHandle, nullptr);
        mHandle = VK_NULL_HANDLE;
    }
}

ANGLE_INLINE VkResult Event::init(VkDevice device, const VkEventCreateInfo &createInfo)
{
    ASSERT(!valid());
    return vkCreateEvent(device, &createInfo, nullptr, &mHandle);
}

ANGLE_INLINE VkResult Event::getStatus(VkDevice device) const
{
    ASSERT(valid());
    return vkGetEventStatus(device, mHandle);
}

ANGLE_INLINE VkResult Event::set(VkDevice device) const
{
    ASSERT(valid());
    return vkSetEvent(device, mHandle);
}

ANGLE_INLINE VkResult Event::reset(VkDevice device) const
{
    ASSERT(valid());
    return vkResetEvent(device, mHandle);
}

// Fence implementation.
ANGLE_INLINE void Fence::destroy(VkDevice device)
{
    if (valid())
    {
        vkDestroyFence(device, mHandle, nullptr);
        mHandle = VK_NULL_HANDLE;
    }
}

ANGLE_INLINE VkResult Fence::init(VkDevice device, const VkFenceCreateInfo &createInfo)
{
    ASSERT(!valid());
    return vkCreateFence(device, &createInfo, nullptr, &mHandle);
}

ANGLE_INLINE VkResult Fence::reset(VkDevice device)
{
    ASSERT(valid());
    return vkResetFences(device, 1, &mHandle);
}

ANGLE_INLINE VkResult Fence::getStatus(VkDevice device) const
{
    ASSERT(valid());
    return vkGetFenceStatus(device, mHandle);
}

ANGLE_INLINE VkResult Fence::wait(VkDevice device, uint64_t timeout) const
{
    ASSERT(valid());
    return vkWaitForFences(device, 1, &mHandle, true, timeout);
}

// QueryPool implementation.
ANGLE_INLINE void QueryPool::destroy(VkDevice device)
{
    if (valid())
    {
        vkDestroyQueryPool(device, mHandle, nullptr);
        mHandle = VK_NULL_HANDLE;
    }
}

ANGLE_INLINE VkResult QueryPool::init(VkDevice device, const VkQueryPoolCreateInfo &createInfo)
{
    ASSERT(!valid());
    return vkCreateQueryPool(device, &createInfo, nullptr, &mHandle);
}

ANGLE_INLINE VkResult QueryPool::getResults(VkDevice device,
                                            uint32_t firstQuery,
                                            uint32_t queryCount,
                                            size_t dataSize,
                                            void *data,
                                            VkDeviceSize stride,
                                            VkQueryResultFlags flags) const
{
    ASSERT(valid());
    return vkGetQueryPoolResults(device, mHandle, firstQuery, queryCount, dataSize, data, stride,
                                 flags);
}
}  // namespace vk
}  // namespace rx

#endif  // LIBANGLE_RENDERER_VULKAN_VK_WRAPPER_H_
