Hash :
968041b5
Author :
Date :
2022-08-19T12:11:23
Metal: Optimized BufferSubData per device Adds a staging buffer path which means there are 4 paths for bufferSubData. 1. direct copy * get a pointer to the buffer * copy the new data to the buffer * if the buffer is managed, tell metal which part was updated 2. use a shadow copy * copy the data to a shadow copy * copy the entire shadow to a new buffer * start using the new buffer 3. use a new buffer * get a new buffer (or unused) * put the new data in the new buffer * blit any unchanged data from the old buffer to the new buffer * start using the new buffer 4. use a staging buffer * get a staging buffer * put the new data in the staging buffer * blit from the staging buffer to the existing buffer. Further, there are 3 types of memory storage modes. Managed, Staged, Private. Based on the GPU type different storage modes and different paths in different sitatutions are more performant. So, add feature flags to select paths by GPU. Bug: angleproject:7544 Change-Id: I741dd1874201043416374194bd2001ded8dbd9b4 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3842641 Reviewed-by: Kyle Piddington <kpiddington@apple.com> Reviewed-by: Kenneth Russell <kbr@chromium.org> Reviewed-by: Quyen Le <lehoangquyen@chromium.org> Commit-Queue: Gregg Tavares <gman@chromium.org>
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
//
// Copyright 2022 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.
//
// mtl_buffer_manager.h:
// BufferManager manages buffers across all contexts for a single
// device.
//
#ifndef LIBANGLE_RENDERER_METAL_MTL_BUFFER_MANAGER_H_
#define LIBANGLE_RENDERER_METAL_MTL_BUFFER_MANAGER_H_
#include "common/FixedVector.h"
#include "libANGLE/renderer/metal/mtl_resources.h"
#include <vector>
namespace rx
{
class ContextMtl;
namespace mtl
{
// GL buffers are backed by Metal buffers. Which metal
// buffer is backing a particular GL buffer is fluid.
// The case being optimized is a loop of something like
//
// for 1..4
// glBufferSubData
// glDrawXXX
//
// You can't update a buffer in the middle of a render pass
// in metal so instead we'd end up using multiple buffers.
//
// Simple case, the call to `glBufferSubData` updates the
// entire buffer. In this case we'd end up with each call
// to `glBufferSubData` getting a new buffer from this
// BufferManager and copying the new data to it. We'd
// end up submitting this renderpass
//
// draw with buf1
// draw with buf2
// draw with buf3
// draw with buf4
//
// The GL buffer now references buf4. And buf1, buf2, buf3 and
// buf0 (the buffer that was previously referenced by the GL buffer)
// are all added to the inuse-list
//
// This macro enables showing the running totals of the various
// buckets of unused buffers.
// #define ANGLE_MTL_TRACK_BUFFER_MEM
class BufferManager
{
public:
BufferManager();
static constexpr size_t kMaxStagingBufferSize = 1024 * 1024;
static constexpr size_t kMaxSizePowerOf2 = 64;
angle::Result queueBlitCopyDataToBuffer(ContextMtl *contextMtl,
const void *srcPtr,
size_t sizeToCopy,
size_t offset,
mtl::BufferRef &dstMetalBuffer);
angle::Result getBuffer(ContextMtl *contextMtl,
size_t size,
bool useSharedMem,
mtl::BufferRef &bufferRef);
void returnBuffer(ContextMtl *contextMtl, mtl::BufferRef &bufferRef);
private:
typedef std::vector<mtl::BufferRef> BufferList;
void freeUnusedBuffers(ContextMtl *contextMtl);
void addBufferRefToFreeLists(mtl::BufferRef &bufferRef);
BufferList mInUseBuffers;
angle::FixedVector<BufferList, kMaxSizePowerOf2> mFreeBuffers[2];
#ifdef ANGLE_MTL_TRACK_BUFFER_MEM
angle::FixedVector<size_t, kMaxSizePowerOf2> mAllocations;
size_t mTotalMem = 0;
#endif
};
} // namespace mtl
} // namespace rx
#endif /* LIBANGLE_RENDERER_METAL_MTL_BUFFER_MANAGER_H_ */