Skip to content

Commit de309a4

Browse files
cclaoCommit Bot
authored andcommitted
Vulkan: Make staging buffer per context
Right now staging buffers are per BufferVk. This will make it per ContextVk so that it can be shared among all objects that needs a staging buffer. Bug: b/161846868 Change-Id: I9c436acdacaf429a43cbdfa216927df0796f7a28 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2310962 Reviewed-by: Tim Van Patten <timvp@google.com> Reviewed-by: Courtney Goeltzenleuchter <courtneygo@google.com> Reviewed-by: Ian Elliott <ianelliott@google.com> Reviewed-by: Jamie Madill <jmadill@chromium.org> Commit-Queue: Charlie Lao <cclao@google.com>
1 parent db88baa commit de309a4

File tree

4 files changed

+25
-65
lines changed

4 files changed

+25
-65
lines changed

src/libANGLE/renderer/vulkan/BufferVk.cpp

Lines changed: 9 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -33,33 +33,6 @@ static_assert(gl::isPow2(kBufferSizeGranularity), "use as alignment, must be pow
3333
// Start with a fairly small buffer size. We can increase this dynamically as we convert more data.
3434
constexpr size_t kConvertedArrayBufferInitialSize = 1024 * 8;
3535

36-
// Base size for all staging buffers
37-
constexpr size_t kStagingBufferBaseSize = 1024;
38-
// Fix the staging buffer size multiplier for unpack buffers, for now
39-
constexpr size_t kUnpackBufferStagingBufferMultiplier = 1024;
40-
41-
size_t CalculateStagingBufferSize(gl::BufferBinding target, size_t size, size_t alignment)
42-
{
43-
size_t alignedSize = rx::roundUp(size, alignment);
44-
int multiplier = std::max(gl::log2(alignedSize), 1);
45-
46-
switch (target)
47-
{
48-
case gl::BufferBinding::Array:
49-
case gl::BufferBinding::DrawIndirect:
50-
case gl::BufferBinding::ElementArray:
51-
case gl::BufferBinding::Uniform:
52-
return kStagingBufferBaseSize * multiplier;
53-
54-
case gl::BufferBinding::PixelUnpack:
55-
return std::max(alignedSize,
56-
(kStagingBufferBaseSize * kUnpackBufferStagingBufferMultiplier));
57-
58-
default:
59-
return kStagingBufferBaseSize;
60-
}
61-
}
62-
6336
// Buffers that have a static usage pattern will be allocated in
6437
// device local memory to speed up access to and from the GPU.
6538
// Dynamic usage patterns or that are frequently mapped
@@ -163,7 +136,6 @@ void BufferVk::destroy(const gl::Context *context)
163136
void BufferVk::release(ContextVk *contextVk)
164137
{
165138
RendererVk *renderer = contextVk->getRenderer();
166-
mStagingBuffer.release(renderer);
167139
mShadowBuffer.release();
168140
mBufferPool.release(renderer);
169141
mBuffer = nullptr;
@@ -174,18 +146,6 @@ void BufferVk::release(ContextVk *contextVk)
174146
}
175147
}
176148

177-
void BufferVk::initializeStagingBuffer(ContextVk *contextVk, gl::BufferBinding target, size_t size)
178-
{
179-
RendererVk *rendererVk = contextVk->getRenderer();
180-
181-
constexpr VkImageUsageFlags kBufferUsageFlags = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
182-
size_t alignment =
183-
static_cast<size_t>(rendererVk->getPhysicalDeviceProperties().limits.minMemoryMapAlignment);
184-
size_t stagingBufferSize = CalculateStagingBufferSize(target, size, alignment);
185-
186-
mStagingBuffer.init(rendererVk, kBufferUsageFlags, alignment, stagingBufferSize, true);
187-
}
188-
189149
angle::Result BufferVk::initializeShadowBuffer(ContextVk *contextVk,
190150
gl::BufferBinding target,
191151
size_t size)
@@ -258,9 +218,6 @@ angle::Result BufferVk::setData(const gl::Context *context,
258218

259219
ANGLE_TRY(acquireBufferHelper(contextVk, size, &mBuffer));
260220

261-
// Initialize the staging buffer
262-
initializeStagingBuffer(contextVk, target, size);
263-
264221
// Initialize the shadow buffer
265222
ANGLE_TRY(initializeShadowBuffer(contextVk, target, size));
266223
}
@@ -530,29 +487,23 @@ angle::Result BufferVk::stagedUpdate(ContextVk *contextVk,
530487
size_t offset)
531488
{
532489
// Acquire a "new" staging buffer
533-
bool needToReleasePreviousBuffers = false;
534-
uint8_t *mapPointer = nullptr;
535-
VkDeviceSize stagingBufferOffset = 0;
490+
uint8_t *mapPointer = nullptr;
491+
VkDeviceSize stagingBufferOffset = 0;
536492

537-
ANGLE_TRY(mStagingBuffer.allocate(contextVk, size, &mapPointer, nullptr, &stagingBufferOffset,
538-
&needToReleasePreviousBuffers));
539-
if (needToReleasePreviousBuffers)
540-
{
541-
// Release previous staging buffers
542-
mStagingBuffer.releaseInFlightBuffers(contextVk);
543-
}
493+
vk::DynamicBuffer *stagingBuffer = contextVk->getStagingBufferStorage();
494+
ANGLE_TRY(stagingBuffer->allocate(contextVk, size, &mapPointer, nullptr, &stagingBufferOffset,
495+
nullptr));
544496
ASSERT(mapPointer);
545497

546498
memcpy(mapPointer, data, size);
547-
ASSERT(!mStagingBuffer.isCoherent());
548-
ANGLE_TRY(mStagingBuffer.flush(contextVk));
549-
mStagingBuffer.getCurrentBuffer()->onExternalWrite(VK_ACCESS_HOST_WRITE_BIT);
499+
ASSERT(!stagingBuffer->isCoherent());
500+
ANGLE_TRY(stagingBuffer->flush(contextVk));
501+
stagingBuffer->getCurrentBuffer()->onExternalWrite(VK_ACCESS_HOST_WRITE_BIT);
550502

551503
// Enqueue a copy command on the GPU.
552504
VkBufferCopy copyRegion = {stagingBufferOffset, offset, size};
553505
ANGLE_TRY(
554-
mBuffer->copyFromBuffer(contextVk, mStagingBuffer.getCurrentBuffer(), 1, &copyRegion));
555-
mStagingBuffer.getCurrentBuffer()->retain(&contextVk->getResourceUseList());
506+
mBuffer->copyFromBuffer(contextVk, stagingBuffer->getCurrentBuffer(), 1, &copyRegion));
556507

557508
return angle::Result::Continue;
558509
}

src/libANGLE/renderer/vulkan/BufferVk.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,6 @@ class BufferVk : public BufferImpl
121121
bool hostVisible);
122122

123123
private:
124-
void initializeStagingBuffer(ContextVk *contextVk, gl::BufferBinding target, size_t size);
125124
angle::Result initializeShadowBuffer(ContextVk *contextVk,
126125
gl::BufferBinding target,
127126
size_t size);
@@ -182,9 +181,6 @@ class BufferVk : public BufferImpl
182181
// Pool of BufferHelpers for mBuffer to acquire from
183182
vk::DynamicBuffer mBufferPool;
184183

185-
// All staging buffer support is provided by a DynamicBuffer.
186-
vk::DynamicBuffer mStagingBuffer;
187-
188184
// For GPU-read only buffers glMap* latency is reduced by maintaining a copy
189185
// of the buffer which is writeable only by the CPU. The contents are updated on all
190186
// glData/glSubData/glCopy calls. With this, a glMap* call becomes a non-blocking

src/libANGLE/renderer/vulkan/ContextVk.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,7 @@ void ContextVk::onDestroy(const gl::Context *context)
752752

753753
mDefaultUniformStorage.release(mRenderer);
754754
mEmptyBuffer.release(mRenderer);
755+
mStagingBufferStorage.release(mRenderer);
755756

756757
for (vk::DynamicBuffer &defaultBuffer : mDefaultAttribBuffers)
757758
{
@@ -906,6 +907,13 @@ angle::Result ContextVk::initialize()
906907
constexpr VkMemoryPropertyFlags kMemoryType = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
907908
ANGLE_TRY(mEmptyBuffer.init(this, emptyBufferInfo, kMemoryType));
908909

910+
constexpr VkImageUsageFlags kStagingBufferUsageFlags = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
911+
size_t stagingBufferAlignment =
912+
static_cast<size_t>(mRenderer->getPhysicalDeviceProperties().limits.minMemoryMapAlignment);
913+
constexpr size_t kStagingBufferSize = 1024u * 1024u; // 1M
914+
mStagingBufferStorage.init(mRenderer, kStagingBufferUsageFlags, stagingBufferAlignment,
915+
kStagingBufferSize, true);
916+
909917
return angle::Result::Continue;
910918
}
911919

@@ -3972,6 +3980,7 @@ angle::Result ContextVk::flushImpl(const vk::Semaphore *signalSemaphore)
39723980
driverUniform.dynamicBuffer.releaseInFlightBuffersToResourceUseList(this);
39733981
}
39743982
mDefaultUniformStorage.releaseInFlightBuffersToResourceUseList(this);
3983+
mStagingBufferStorage.releaseInFlightBuffersToResourceUseList(this);
39753984

39763985
if (mRenderer->getFeatures().enableCommandProcessingThread.enabled)
39773986
{

src/libANGLE/renderer/vulkan/ContextVk.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,7 @@ class ContextVk : public ContextImpl, public vk::Context
591591
void setDefaultUniformBlocksMinSizeForTesting(size_t minSize);
592592

593593
vk::BufferHelper &getEmptyBuffer() { return mEmptyBuffer; }
594+
vk::DynamicBuffer *getStagingBufferStorage() { return &mStagingBufferStorage; }
594595

595596
private:
596597
// Dirty bits.
@@ -1065,15 +1066,18 @@ class ContextVk : public ContextImpl, public vk::Context
10651066

10661067
ShareGroupVk *mShareGroupVk;
10671068

1068-
// Storage for default uniforms of ProgramVks and ProgramPipelineVks.
1069-
vk::DynamicBuffer mDefaultUniformStorage;
1070-
10711069
// This is a special "empty" placeholder buffer for use when we just need a dummy buffer but not
10721070
// the data. Examples are shader that has no uniform or doesn't use all slots in the atomic
10731071
// counter buffer array, or places where there is no vertex buffer since Vulkan does not allow
10741072
// binding a null vertex buffer.
10751073
vk::BufferHelper mEmptyBuffer;
10761074

1075+
// Storage for default uniforms of ProgramVks and ProgramPipelineVks.
1076+
vk::DynamicBuffer mDefaultUniformStorage;
1077+
1078+
// All staging buffer support is provided by a DynamicBuffer.
1079+
vk::DynamicBuffer mStagingBufferStorage;
1080+
10771081
std::vector<std::string> mCommandBufferDiagnostics;
10781082
};
10791083

0 commit comments

Comments
 (0)