🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

DX12 Expanding a vertex buffer

Started by
2 comments, last by ddlox 3 years, 8 months ago

Coming back to an old project I noticed a memory leak while expanding the vertex buffer. The reason why I need to expand my vertex buffer is that some of my 3D objects grow to be more complex over time (and I can't tell beforehand which of them will grow). So, to expand the buffer I essentially create a larger buffer, copy the content from the old resource, and switch to the new one instead. See below for the sharpDX / pseudo code.

It's not the most efficient way I'm sure but it works. Notice that I do dispose my oldResource after copying. At first I just unmapped it and thought that it would be enough. It wasn't. It was leaking memory. After adding the Dispose command I got rid of the leak, although I started to experience crashes every now and then. It crashes because the device was removed (DXGI_ERROR_DEVICE_HUNG) at various locations in my code. Why?

After expanding the buffer I recreate the bundles etc, so they should all refer to the new location. Is some kind of fence needed? Then why did it work before adding the Dispose line?

Maybe I have just missed to update some part of the code about this new memory location.

If you have a proper way of expanding a vertex buffer “in flight” I'm all ears ?.

Resource newVertexBuffer = device.CreateCommittedResource(
	new HeapProperties(HeapType.Default), 
	HeapFlags.None, 
	ResourceDescription.Buffer(newBufferSize),
	ResourceStates.CopyDestination);

copyCommandList.CopyBufferRegion(
	newVertexBuffer, 0, oldResource, 0, oldBufferSize);

copyCommandList.Close();
copyCommandQueue.ExecuteCommandList(copyCommandList);
copyCommandList.Reset(copyCommandAllocator, pipelineState);
WaitForCopy();

oldResource.Unmap(0);
oldResource.Dispose(); // <-- NOTE THIS ONE

oldResource = newVertexBuffer;

bufferView.BufferLocation = newVertexBuffer.GPUVirtualAddress;
bufferView.SizeInBytes = newBufferSize;
Advertisement

are you accessing oldResource from more than 1 thread at the same time?

if yes, then yes you'll need to protect this resource with a mutex (or fence if u wish), because u r getting rid of it while another thread could potentially be trying to read from it;

if no then yr problem could be elsewhere, at first, i don't see what could be wrong here… maybe waitForCopy( ) does something weird?…

have u caught the crash in your debugger? where does the line of execution take you to or stop at ? … in threaded environments, what u see is not always what u had … etc… but i mean those are things I would check…

Until then ?

That makes sense of course. I solved the situation by setting up two lists of outdated resources (current list and previous list), and only disposing those in the previous list after an update, hanging on to the current resources until I know that they not used any more.

Thanks!

well done!

you're welcome ?

This topic is closed to new replies.

Advertisement