Hash :
74f74b63
Author :
Date :
2024-11-14T10:07:34
Vulkan: Add ContextVk::onFramebufferBoundary() function This makes a more formal API to track frame boundary. Also adds a uint32_t mCurrentFrameCount to track the total number of frames rendered so that we could use for heuristic purpose. Bug: angleproject:372268711 Change-Id: I153497403ed0d8fde18f1786186ce600df60c514 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/6022549 Reviewed-by: Yuxin Hu <yuxinhu@google.com> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Commit-Queue: Charlie Lao <cclao@google.com>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
//
// Copyright 2023 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.
//
// ShareGroupVk.h:
// Defines the class interface for ShareGroupVk, implementing ShareGroupImpl.
//
#ifndef LIBANGLE_RENDERER_VULKAN_SHAREGROUPVK_H_
#define LIBANGLE_RENDERER_VULKAN_SHAREGROUPVK_H_
#include "libANGLE/renderer/ShareGroupImpl.h"
#include "libANGLE/renderer/vulkan/vk_cache_utils.h"
#include "libANGLE/renderer/vulkan/vk_helpers.h"
#include "libANGLE/renderer/vulkan/vk_resource.h"
#include "libANGLE/renderer/vulkan/vk_utils.h"
namespace rx
{
constexpr VkDeviceSize kMaxTotalEmptyBufferBytes = 16 * 1024 * 1024;
class TextureUpload
{
public:
TextureUpload() { mPrevUploadedMutableTexture = nullptr; }
~TextureUpload() { resetPrevTexture(); }
angle::Result onMutableTextureUpload(ContextVk *contextVk, TextureVk *newTexture);
void onTextureRelease(TextureVk *textureVk);
void resetPrevTexture() { mPrevUploadedMutableTexture = nullptr; }
private:
// Keep track of the previously stored texture. Used to flush mutable textures.
TextureVk *mPrevUploadedMutableTexture;
};
class ShareGroupVk : public ShareGroupImpl
{
public:
ShareGroupVk(const egl::ShareGroupState &state, vk::Renderer *renderer);
void onDestroy(const egl::Display *display) override;
void onContextAdd() override;
FramebufferCache &getFramebufferCache() { return mFramebufferCache; }
bool hasAnyContextWithRobustness() const { return mState.hasAnyContextWithRobustness(); }
// PipelineLayoutCache and DescriptorSetLayoutCache can be shared between multiple threads
// accessing them via shared contexts. The ShareGroup locks around gl entrypoints ensuring
// synchronous update to the caches.
PipelineLayoutCache &getPipelineLayoutCache() { return mPipelineLayoutCache; }
DescriptorSetLayoutCache &getDescriptorSetLayoutCache() { return mDescriptorSetLayoutCache; }
const egl::ContextMap &getContexts() const { return mState.getContexts(); }
vk::DescriptorSetArray<vk::MetaDescriptorPool> &getMetaDescriptorPools()
{
return mMetaDescriptorPools;
}
// Used to flush the mutable textures more often.
angle::Result onMutableTextureUpload(ContextVk *contextVk, TextureVk *newTexture);
vk::BufferPool *getDefaultBufferPool(VkDeviceSize size,
uint32_t memoryTypeIndex,
BufferUsageType usageType);
void calculateTotalBufferCount(size_t *bufferCount, VkDeviceSize *totalSize) const;
void logBufferPools() const;
// Temporary workaround until VkSemaphore(s) will be used between different priorities.
angle::Result unifyContextsPriority(ContextVk *newContextVk);
// Temporary workaround until VkSemaphore(s) will be used between different priorities.
angle::Result lockDefaultContextsPriority(ContextVk *contextVk);
UpdateDescriptorSetsBuilder *getUpdateDescriptorSetsBuilder()
{
return &mUpdateDescriptorSetsBuilder;
}
void onTextureRelease(TextureVk *textureVk);
VertexInputGraphicsPipelineCache *getVertexInputGraphicsPipelineCache()
{
return &mVertexInputGraphicsPipelineCache;
}
FragmentOutputGraphicsPipelineCache *getFragmentOutputGraphicsPipelineCache()
{
return &mFragmentOutputGraphicsPipelineCache;
}
angle::Result scheduleMonolithicPipelineCreationTask(
ContextVk *contextVk,
vk::WaitableMonolithicPipelineCreationTask *taskOut);
void waitForCurrentMonolithicPipelineCreationTask();
vk::RefCountedEventsGarbageRecycler *getRefCountedEventsGarbageRecycler()
{
return &mRefCountedEventsGarbageRecycler;
}
void cleanupRefCountedEventGarbage() { mRefCountedEventsGarbageRecycler.cleanup(mRenderer); }
void cleanupExcessiveRefCountedEventGarbage()
{
// TODO: b/336844257 needs tune.
constexpr size_t kExcessiveGarbageCountThreshold = 256;
if (mRefCountedEventsGarbageRecycler.getGarbageCount() > kExcessiveGarbageCountThreshold)
{
mRefCountedEventsGarbageRecycler.cleanup(mRenderer);
}
}
void onFramebufferBoundary();
uint32_t getCurrentFrameCount() const { return mCurrentFrameCount; }
private:
angle::Result updateContextsPriority(ContextVk *contextVk, egl::ContextPriority newPriority);
void pruneDefaultBufferPools();
bool isDueForBufferPoolPrune();
vk::Renderer *mRenderer;
// Tracks the total number of frames rendered.
uint32_t mCurrentFrameCount;
// VkFramebuffer caches
FramebufferCache mFramebufferCache;
void resetPrevTexture() { mTextureUpload.resetPrevTexture(); }
// ANGLE uses a PipelineLayout cache to store compatible pipeline layouts.
PipelineLayoutCache mPipelineLayoutCache;
// DescriptorSetLayouts are also managed in a cache.
DescriptorSetLayoutCache mDescriptorSetLayoutCache;
// Descriptor set caches
vk::DescriptorSetArray<vk::MetaDescriptorPool> mMetaDescriptorPools;
// Priority of all Contexts in the context set
egl::ContextPriority mContextsPriority;
bool mIsContextsPriorityLocked;
// Storage for vkUpdateDescriptorSets
UpdateDescriptorSetsBuilder mUpdateDescriptorSetsBuilder;
// The per shared group buffer pools that all buffers should sub-allocate from.
vk::BufferPoolPointerArray mDefaultBufferPools;
// The system time when last pruneEmptyBuffer gets called.
double mLastPruneTime;
// Used when VK_EXT_graphics_pipeline_library is available, the vertex input and fragment output
// partial pipelines are created in the following caches. These caches are in the share group
// because linked pipelines using these pipeline libraries are referenced from
// ProgramExecutableVk, and as such must stay alive as long as the program may be alive.
VertexInputGraphicsPipelineCache mVertexInputGraphicsPipelineCache;
FragmentOutputGraphicsPipelineCache mFragmentOutputGraphicsPipelineCache;
// The system time when the last monolithic pipeline creation job was launched. This is
// rate-limited to avoid hogging all cores and interfering with the application threads. A
// single pipeline creation job is currently supported.
double mLastMonolithicPipelineJobTime;
std::shared_ptr<angle::WaitableEvent> mMonolithicPipelineCreationEvent;
// Texture update manager used to flush uploaded mutable textures.
TextureUpload mTextureUpload;
// Holds RefCountedEvent that are free and ready to reuse
vk::RefCountedEventsGarbageRecycler mRefCountedEventsGarbageRecycler;
};
} // namespace rx
#endif // LIBANGLE_RENDERER_VULKAN_SHAREGROUPVK_H_