chromium/third_party/angle/src/libANGLE/renderer/vulkan/vk_helpers.h

//
// Copyright 2018 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_helpers:
//   Helper utility classes that manage Vulkan resources.

#ifndef LIBANGLE_RENDERER_VULKAN_VK_HELPERS_H_
#define LIBANGLE_RENDERER_VULKAN_VK_HELPERS_H_

#include "common/MemoryBuffer.h"
#include "common/SimpleMutex.h"
#include "libANGLE/renderer/vulkan/MemoryTracking.h"
#include "libANGLE/renderer/vulkan/Suballocation.h"
#include "libANGLE/renderer/vulkan/vk_cache_utils.h"
#include "libANGLE/renderer/vulkan/vk_format_utils.h"
#include "libANGLE/renderer/vulkan/vk_ref_counted_event.h"

#include <functional>

namespace gl
{
class ImageIndex;
}  // namespace gl

namespace rx
{
namespace vk
{
constexpr VkBufferUsageFlags kVertexBufferUsageFlags =;
constexpr VkBufferUsageFlags kIndexBufferUsageFlags =;
constexpr VkBufferUsageFlags kIndirectBufferUsageFlags =;
constexpr size_t kVertexBufferAlignment   =;
constexpr size_t kIndexBufferAlignment    =;
constexpr size_t kIndirectBufferAlignment =;

constexpr VkBufferUsageFlags kStagingBufferFlags =;
constexpr size_t kStagingBufferSize =;

constexpr VkImageCreateFlags kVkImageCreateFlagsNone =;

// Most likely initial chroma filter mode given GL_TEXTURE_EXTERNAL_OES default
// min & mag filters are linear.
constexpr VkFilter kDefaultYCbCrChromaFilter =;

constexpr VkPipelineStageFlags kSwapchainAcquireImageWaitStageFlags =;                  // First use is a clear without scissor.

// For each level, write  layers that don't conflict in parallel.  The layer is hashed to
// `layer % kMaxParallelLayerWrites` and used to track whether that subresource is currently
// being written.  If so, a barrier is inserted; otherwise, the barrier is avoided.  If the updated
// layer count is greater than kMaxParallelLayerWrites, there will be a few unnecessary
// barriers.
constexpr uint32_t kMaxParallelLayerWrites =;
ImageLayerWriteMask;

StagingBufferOffsetArray;

// Imagine an image going through a few layout transitions:
//
//           srcStage 1    dstStage 2          srcStage 2     dstStage 3
//  Layout 1 ------Transition 1-----> Layout 2 ------Transition 2------> Layout 3
//           srcAccess 1  dstAccess 2          srcAccess 2   dstAccess 3
//   \_________________  ___________________/
//                     \/
//               A transition
//
// Every transition requires 6 pieces of information: from/to layouts, src/dst stage masks and
// src/dst access masks.  At the moment we decide to transition the image to Layout 2 (i.e.
// Transition 1), we need to have Layout 1, srcStage 1 and srcAccess 1 stored as history of the
// image.  To perform the transition, we need to know Layout 2, dstStage 2 and dstAccess 2.
// Additionally, we need to know srcStage 2 and srcAccess 2 to retain them for the next transition.
//
// That is, with the history kept, on every new transition we need 5 pieces of new information:
// layout/dstStage/dstAccess to transition into the layout, and srcStage/srcAccess for the future
// transition out from it.  Given the small number of possible combinations of these values, an
// enum is used were each value encapsulates these 5 pieces of information:
//
//                       +--------------------------------+
//           srcStage 1  | dstStage 2          srcStage 2 |   dstStage 3
//  Layout 1 ------Transition 1-----> Layout 2 ------Transition 2------> Layout 3
//           srcAccess 1 |dstAccess 2          srcAccess 2|  dstAccess 3
//                       +---------------  ---------------+
//                                       \/
//                                 One enum value
//
// Note that, while generally dstStage for the to-transition and srcStage for the from-transition
// are the same, they may occasionally be BOTTOM_OF_PIPE and TOP_OF_PIPE respectively.
enum class ImageLayout
{};

VkImageCreateFlags GetImageCreateFlags(gl::TextureType textureType);

ImageLayout GetImageLayoutFromGLImageLayout(Context *context, GLenum layout);

GLenum ConvertImageLayoutToGLImageLayout(ImageLayout imageLayout);

VkImageLayout ConvertImageLayoutToVkImageLayout(Renderer *renderer, ImageLayout imageLayout);

// A dynamic buffer is conceptually an infinitely long buffer. Each time you write to the buffer,
// you will always write to a previously unused portion. After a series of writes, you must flush
// the buffer data to the device. Buffer lifetime currently assumes that each new allocation will
// last as long or longer than each prior allocation.
//
// Dynamic buffers are used to implement a variety of data streaming operations in Vulkan, such
// as for immediate vertex array and element array data, uniform updates, and other dynamic data.
//
// Internally dynamic buffers keep a collection of VkBuffers. When we write past the end of a
// currently active VkBuffer we keep it until it is no longer in use. We then mark it available
// for future allocations in a free list.
class BufferHelper;
BufferHelperQueue;

class DynamicBuffer : angle::NonCopyable
{};

// Class DescriptorSetHelper. This is a wrapper of VkDescriptorSet with GPU resource use tracking.
class DescriptorSetHelper final : public Resource
{};
DescriptorSetList;

// Uses DescriptorPool to allocate descriptor sets as needed. If a descriptor pool becomes full, we
// allocate new pools internally as needed. Renderer takes care of the lifetime of the discarded
// pools. Note that we used a fixed layout for descriptor pools in ANGLE.

// Shared handle to a descriptor pool. Each helper is allocated from the dynamic descriptor pool.
// Can be used to share descriptor pools between multiple ProgramVks and the ContextVk.
class CommandBufferHelperCommon;

class DescriptorPoolHelper final : public Resource
{};

RefCountedDescriptorPoolBinding;

class DynamicDescriptorPool final : angle::NonCopyable
{};

RefCountedDescriptorPool;
DescriptorPoolPointer;

// Maps from a descriptor set layout (represented by DescriptorSetLayoutDesc) to a set of
// DynamicDescriptorPools. The purpose of the class is so multiple GL Programs can share descriptor
// set caches. We need to stratify the sets by the descriptor set layout to ensure compatibility.
class MetaDescriptorPool final : angle::NonCopyable
{};

template <typename Pool>
class DynamicallyGrowingPool : angle::NonCopyable
{};

// DynamicQueryPool allocates indices out of QueryPool as needed.  Once a QueryPool is exhausted,
// another is created.  The query pools live permanently, but are recycled as indices get freed.

// These are arbitrary default sizes for query pools.
constexpr uint32_t kDefaultOcclusionQueryPoolSize           =;
constexpr uint32_t kDefaultTimestampQueryPoolSize           =;
constexpr uint32_t kDefaultTransformFeedbackQueryPoolSize   =;
constexpr uint32_t kDefaultPrimitivesGeneratedQueryPoolSize =;

class QueryHelper;

class DynamicQueryPool final : public DynamicallyGrowingPool<QueryPool>
{};

// Stores the result of a Vulkan query call. XFB queries in particular store two result values.
class QueryResult final
{};

// Queries in Vulkan are identified by the query pool and an index for a query within that pool.
// Unlike other pools, such as descriptor pools where an allocation returns an independent object
// from the pool, the query allocations are not done through a Vulkan function and are only an
// integer index.
//
// Furthermore, to support arbitrarily large number of queries, DynamicQueryPool creates query pools
// of a fixed size as needed and allocates indices within those pools.
//
// The QueryHelper class below keeps the pool and index pair together.  For multiview, multiple
// consecutive query indices are implicitly written to by the driver, so the query count is
// additionally kept.
class QueryHelper final : public Resource
{};

// Semaphores that are allocated from the semaphore pool are encapsulated in a helper object,
// keeping track of where in the pool they are allocated from.
class SemaphoreHelper final : angle::NonCopyable
{};

// This defines enum for VkPipelineStageFlagBits so that we can use it to compare and index into
// array.
enum class PipelineStage : uint32_t
{};
PipelineStagesMask;

PipelineStage GetPipelineStage(gl::ShaderType stage);

struct ImageMemoryBarrierData
{};
// Initialize ImageLayout to ImageMemoryBarrierData mapping table.
void InitializeImageLayoutAndMemoryBarrierDataMap(
    angle::PackedEnumMap<ImageLayout, ImageMemoryBarrierData> *mapping,
    VkPipelineStageFlags supportedVulkanPipelineStageMask);
bool EventAndPipelineBarrierHaveMatchingStageFlags(
    const angle::PackedEnumMap<EventStage, VkPipelineStageFlags> &eventStageMap,
    const angle::PackedEnumMap<ImageLayout, ImageMemoryBarrierData> &barrierDataMap);

// This wraps data and API for vkCmdPipelineBarrier call
class PipelineBarrier : angle::NonCopyable
{};

class PipelineBarrierArray final
{};

enum class MemoryCoherency : uint8_t
{};
ANGLE_INLINE bool IsCached(MemoryCoherency coherency)
{}

class BufferPool;

class BufferHelper : public ReadWriteResource
{};

class BufferPool : angle::NonCopyable
{};
BufferPoolPointerArray;

// Stores clear value In packed attachment index
class PackedClearValuesArray final
{};

class ImageHelper;
ImageHelperPtr;

// Reference to a render pass attachment (color or depth/stencil) alongside render-pass-related
// tracking such as when the attachment is last written to or invalidated.  This is used to
// determine loadOp and storeOp of the attachment, and enables optimizations that need to know
// how the attachment has been used.
class RenderPassAttachment final
{};

// Stores RenderPassAttachment In packed attachment index
class PackedRenderPassAttachmentArray final
{};

class SecondaryCommandBufferCollector final
{};

struct CommandsState
{};

// How the ImageHelper object is being used by the renderpass
enum class RenderPassUsage
{};
RenderPassUsageFlags;
constexpr RenderPassUsageFlags kDepthStencilReadOnlyBits =;
constexpr RenderPassUsageFlags kDepthStencilFeedbackModeBits =;

// The following are used to help track the state of an invalidated attachment.
// This value indicates an "infinite" CmdCount that is not valid for comparing
constexpr uint32_t kInfiniteCmdCount =;

// CommandBufferHelperCommon and derivatives OutsideRenderPassCommandBufferHelper and
// RenderPassCommandBufferHelper wrap the outside/inside render pass secondary command buffers,
// together with other information such as barriers to issue before the command buffer, tracking of
// resource usages, etc.  When the asyncCommandQueue feature is enabled, objects of these classes
// are handed off to the worker thread to be executed on the primary command buffer.
class CommandBufferHelperCommon : angle::NonCopyable
{};

class SecondaryCommandBufferCollector;

class OutsideRenderPassCommandBufferHelper final : public CommandBufferHelperCommon
{};

enum class ImagelessFramebuffer
{};

enum class RenderPassSource
{};

class RenderPassFramebuffer : angle::NonCopyable
{};

class RenderPassCommandBufferHelper final : public CommandBufferHelperCommon
{};

// The following class helps support both Vulkan and ANGLE secondary command buffers by
// encapsulating their differences.
template <typename CommandBufferHelperT>
class CommandBufferRecycler
{};

// The source of update to an ImageHelper
enum class UpdateSource
{};

enum class ApplyImageUpdate
{};

constexpr VkImageAspectFlagBits IMAGE_ASPECT_DEPTH_STENCIL =;

bool FormatHasNecessaryFeature(Renderer *renderer,
                               angle::FormatID formatID,
                               VkImageTiling tilingMode,
                               VkFormatFeatureFlags featureBits);

bool CanCopyWithTransfer(Renderer *renderer,
                         angle::FormatID srcFormatID,
                         VkImageTiling srcTilingMode,
                         angle::FormatID dstFormatID,
                         VkImageTiling dstTilingMode);

class ImageViewHelper;
class ImageHelper final : public Resource, public angle::Subject
{};

ANGLE_INLINE bool RenderPassCommandBufferHelper::usesImage(const ImageHelper &image) const
{}

ANGLE_INLINE bool RenderPassCommandBufferHelper::startedAndUsesImageWithBarrier(
    const ImageHelper &image) const
{}

// A vector of image views, such as one per level or one per layer.
ImageViewVector;

// A vector of vector of image views.  Primary index is layer, secondary index is level.
LayerLevelImageViewVector;

// Address mode for layers: only possible to access either all layers, or up to
// IMPLEMENTATION_ANGLE_MULTIVIEW_MAX_VIEWS layers.  This enum uses 0 for all layers and the rest of
// the values conveniently alias the number of layers.
enum LayerMode
{};
static_assert;

LayerMode GetLayerMode(const vk::ImageHelper &image, uint32_t layerCount);

// Sampler decode mode indicating if an attachment needs to be decoded in linear colorspace or sRGB
enum class SrgbDecodeMode
{};

class ImageViewHelper final : angle::NonCopyable
{};

ImageSubresourceRange MakeImageSubresourceReadRange(gl::LevelIndex level,
                                                    uint32_t levelCount,
                                                    uint32_t layer,
                                                    LayerMode layerMode,
                                                    SrgbDecodeMode srgbDecodeMode,
                                                    gl::SrgbOverride srgbOverrideMode);
ImageSubresourceRange MakeImageSubresourceDrawRange(gl::LevelIndex level,
                                                    uint32_t layer,
                                                    LayerMode layerMode,
                                                    gl::SrgbWriteControlMode srgbWriteControlMode);

class BufferViewHelper final : public Resource
{};

// Context state that can affect a compute pipeline
ComputePipelineOptions;
static_assert;
ComputePipelineOptions GetComputePipelineOptions(vk::PipelineRobustness robustness,
                                                 vk::PipelineProtectedAccess protectedAccess);
ComputePipelineCache;

class ShaderProgramHelper : angle::NonCopyable
{};

// Tracks current handle allocation counts in the back-end. Useful for debugging and profiling.
// Note: not all handle types are currently implemented.
class ActiveHandleCounter final : angle::NonCopyable
{};

// Sometimes ANGLE issues a command internally, such as copies, draws and dispatches that do not
// directly correspond to the application draw/dispatch call.  Before the command is recorded in the
// command buffer, the render pass may need to be broken and/or appropriate barriers may need to be
// inserted.  The following struct aggregates all resources that such internal commands need.
struct CommandBufferBufferAccess
{};
struct CommandBufferImageAccess
{};
struct CommandBufferImageSubresourceAccess
{};
struct CommandBufferBufferExternalAcquireRelease
{};
struct CommandBufferResourceAccess
{};
class CommandBufferAccess : angle::NonCopyable
{};

enum class PresentMode
{};

VkPresentModeKHR ConvertPresentModeToVkPresentMode(PresentMode presentMode);
PresentMode ConvertVkPresentModeToPresentMode(VkPresentModeKHR vkPresentMode);
}  // namespace vk
}  // namespace rx

#endif  // LIBANGLE_RENDERER_VULKAN_VK_HELPERS_H_