Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit fe36a64

Browse files
cclaoCommit Bot
authored and
Commit Bot
committed
Vulkan: Add driverUniform's buffer to mResourceUseList
There is a bug with mDriverUniforms' dynamicBuffer that we never add it to context's mResourceUseList to let it hold onto it until GPU completes. This causes old buffer gets recycled prematurely and gets overwritten, result in rendering corruption. This CL adds current buffer to the mResourceUseList so that it will be waited properly before gets recycled. Bug: b/160777679 Change-Id: I7707442e0f5ba408f5f28337422274e0c23b6bfb Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2288325 Commit-Queue: Charlie Lao <[email protected]> Reviewed-by: Shahbaz Youssefi <[email protected]> Reviewed-by: Ian Elliott <[email protected]>
1 parent f61272f commit fe36a64

File tree

4 files changed

+51
-4
lines changed

4 files changed

+51
-4
lines changed

src/libANGLE/renderer/vulkan/ContextVk.cpp

+27-4
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ EventName GetTraceEventName(const char *title, uint32_t counter)
284284
} // anonymous namespace
285285

286286
ContextVk::DriverUniformsDescriptorSet::DriverUniformsDescriptorSet()
287-
: descriptorSet(VK_NULL_HANDLE), dynamicOffset(0)
287+
: descriptorSet(VK_NULL_HANDLE), dynamicOffset(0), referenced(false)
288288
{}
289289

290290
ContextVk::DriverUniformsDescriptorSet::~DriverUniformsDescriptorSet() = default;
@@ -914,6 +914,9 @@ angle::Result ContextVk::setupDraw(const gl::Context *context,
914914
DirtyBits dirtyBitMask,
915915
vk::CommandBuffer **commandBufferOut)
916916
{
917+
// Mark it as been used so that we will add current buffer to mResourceUseList
918+
mDriverUniforms[PipelineType::Graphics].referenced = true;
919+
917920
// Set any dirty bits that depend on draw call parameters or other objects.
918921
if (mode != mCurrentDrawMode)
919922
{
@@ -1175,6 +1178,9 @@ angle::Result ContextVk::setupLineLoopDraw(const gl::Context *context,
11751178
angle::Result ContextVk::setupDispatch(const gl::Context *context,
11761179
vk::CommandBuffer **commandBufferOut)
11771180
{
1181+
// Mark it as been used so that we will add current buffer to mResourceUseList
1182+
mDriverUniforms[PipelineType::Compute].referenced = true;
1183+
11781184
// |setupDispatch| and |setupDraw| are special in that they flush dirty bits. Therefore they
11791185
// don't use the same APIs to record commands as the functions outside ContextVk.
11801186
// The following ensures prior commands are flushed before we start processing dirty bits.
@@ -3661,9 +3667,6 @@ angle::Result ContextVk::allocateDriverUniforms(size_t driverUniformsSize,
36613667
uint8_t **ptrOut,
36623668
bool *newBufferOut)
36633669
{
3664-
// Release any previously retained buffers.
3665-
driverUniforms->dynamicBuffer.releaseInFlightBuffers(this);
3666-
36673670
// Allocate a new region in the dynamic buffer.
36683671
VkDeviceSize offset;
36693672
ANGLE_TRY(driverUniforms->dynamicBuffer.allocate(this, driverUniformsSize, ptrOut, bufferOut,
@@ -3913,6 +3916,26 @@ angle::Result ContextVk::flushImpl(const vk::Semaphore *signalSemaphore)
39133916
}
39143917
ANGLE_TRY(flushOutsideRenderPassCommands());
39153918

3919+
// We must add the per context dynamic buffers into mResourceUseList before submission so that
3920+
// they get retained properly until GPU completes
3921+
for (DriverUniformsDescriptorSet &driverUniform : mDriverUniforms)
3922+
{
3923+
driverUniform.dynamicBuffer.releaseInFlightBuffersToResourceUseList(this);
3924+
3925+
if (driverUniform.referenced)
3926+
{
3927+
// We always have to retain the current buffer. Even if data has not changed, current
3928+
// buffer may still be referenced by this command buffer.
3929+
vk::BufferHelper *currentBuffer = driverUniform.dynamicBuffer.getCurrentBuffer();
3930+
if (currentBuffer)
3931+
{
3932+
currentBuffer->retain(&mResourceUseList);
3933+
}
3934+
3935+
driverUniform.referenced = false;
3936+
}
3937+
}
3938+
39163939
if (mRenderer->getFeatures().enableCommandProcessingThread.enabled)
39173940
{
39183941
// Worker thread must complete adding any commands that were just flushed above to the

src/libANGLE/renderer/vulkan/ContextVk.h

+1
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,7 @@ class ContextVk : public ContextImpl, public vk::Context
615615
vk::DynamicBuffer dynamicBuffer;
616616
VkDescriptorSet descriptorSet;
617617
uint32_t dynamicOffset;
618+
bool referenced; // True if it has been used by current submission
618619
vk::BindingPointer<vk::DescriptorSetLayout> descriptorSetLayout;
619620
vk::RefCountedDescriptorPoolBinding descriptorPoolBinding;
620621

src/libANGLE/renderer/vulkan/vk_helpers.cpp

+20
Original file line numberDiff line numberDiff line change
@@ -1121,6 +1121,26 @@ void DynamicBuffer::release(RendererVk *renderer)
11211121
}
11221122
}
11231123

1124+
void DynamicBuffer::releaseInFlightBuffersToResourceUseList(ContextVk *contextVk)
1125+
{
1126+
ResourceUseList *resourceUseList = &contextVk->getResourceUseList();
1127+
for (BufferHelper *bufferHelper : mInFlightBuffers)
1128+
{
1129+
bufferHelper->retain(resourceUseList);
1130+
1131+
// If the dynamic buffer was resized we cannot reuse the retained buffer.
1132+
if (bufferHelper->getSize() < mSize)
1133+
{
1134+
bufferHelper->release(contextVk->getRenderer());
1135+
}
1136+
else
1137+
{
1138+
mBufferFreeList.push_back(bufferHelper);
1139+
}
1140+
}
1141+
mInFlightBuffers.clear();
1142+
}
1143+
11241144
void DynamicBuffer::releaseInFlightBuffers(ContextVk *contextVk)
11251145
{
11261146
for (BufferHelper *toRelease : mInFlightBuffers)

src/libANGLE/renderer/vulkan/vk_helpers.h

+3
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ class DynamicBuffer : angle::NonCopyable
102102
// This releases all the buffers that have been allocated since this was last called.
103103
void releaseInFlightBuffers(ContextVk *contextVk);
104104

105+
// This adds inflight buffers to the context's mResourceUseList and then releases them
106+
void releaseInFlightBuffersToResourceUseList(ContextVk *contextVk);
107+
105108
// This frees resources immediately.
106109
void destroy(RendererVk *renderer);
107110

0 commit comments

Comments
 (0)