I want to add feature, which will delete mesh from the scene, so I am trying to perform a possibility of deleting vk::Buffer and vk::Memory while scene is running. Whenever the vertices data is nullptr, the recreation of a buffer causes an error: “Cannot call vkFreeMemory on VkDeviceMemory that is currently in use by a command buffer.”. However, when vertices data holds something, there is no error. Only if I call transferQueue.waitIdle() or device.waitIdle() before the recreation the error will disappear.
Pseudo-code of recreation:
auto temp = m_Buffer;
m_Buffer = Buffer(...);
temp.Cleanup(...);
The code of buffer:
void CopyBuffer(
const vk::Buffer& srcBuffer,
const vk::Buffer& dstBuffer,
const vk::DeviceSize& size,
const vk::Device& device,
const vk::CommandPool& transferPool,
const vk::Queue& transferQueue
)
{
const vk::CommandBufferAllocateInfo allocInfo(
transferPool,
vk::CommandBufferLevel::ePrimary,
1
);
const auto cBuffer = device.allocateCommandBuffers(allocInfo)[0];
const vk::CommandBufferBeginInfo beginInfo{vk::CommandBufferUsageFlagBits::eOneTimeSubmit};
GE_ASSERT_FN(cBuffer.begin(&beginInfo) == vk::Result::eSuccess, "cannot begin command buffer when copying buffer");
const vk::BufferCopy copy{0, 0, size};
cBuffer.copyBuffer(srcBuffer, dstBuffer, 1, ©);
cBuffer.end();
vk::SubmitInfo submitInfo{};
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &cBuffer;
GE_ASSERT_FN(transferQueue.submit(1, &submitInfo, nullptr) == vk::Result::eSuccess, "cannot submit on transfer queue");
transferQueue.waitIdle();
device.freeCommandBuffers(transferPool, 1, &cBuffer);
}
VertexBuffer::VertexBuffer(
const vk::Device& device,
const vk::PhysicalDevice& physicalDevice,
const QueueFamilyIndices& queueFamilyIndices,
const vk::CommandPool& transferPool,
const vk::Queue& transferQueue,
const void* data,
const uint& sizeOfAllData
)
{
m_Size = sizeOfAllData;
if(m_Size)
{
vk::BufferCreateInfo info{ vk::BufferCreateFlagBits(),
sizeOfAllData,
vk::BufferUsageFlagBits::eVertexBuffer | vk::BufferUsageFlagBits::eTransferDst
};
if(queueFamilyIndices.GetGraphicsFamily() != queueFamilyIndices.GetTransferFamily())
{
const uint uniqueIndices[] = { queueFamilyIndices.GetGraphicsFamily(), queueFamilyIndices.GetTransferFamily() };
info.queueFamilyIndexCount = 2;
info.pQueueFamilyIndices = uniqueIndices;
info.sharingMode = vk::SharingMode::eConcurrent;
}
else
info.sharingMode = vk::SharingMode::eExclusive;
m_Buffer = device.createBuffer(info);
const auto memRequirements = device.getBufferMemoryRequirements(m_Buffer);
vk::MemoryAllocateInfo allocInfo{
memRequirements.size,
IBuffer::FindMemoryType(
physicalDevice,
memRequirements.memoryTypeBits,
vk::MemoryPropertyFlagBits::eDeviceLocal
)
};
m_BufferMemory = device.allocateMemory(allocInfo);
device.bindBufferMemory(m_Buffer, m_BufferMemory, 0);
const auto stagingBuffer = StagingBuffer(device, physicalDevice, queueFamilyIndices, data, sizeOfAllData);
CopyBuffer(stagingBuffer.GetBuffer(), m_Buffer, m_Size, device, transferPool, transferQueue);
stagingBuffer.Cleanup(device);
}
}
So, why the error is thrown only when vertices data is nullptr?
PS: I am a beginner with Vulkan.
Misha Ryha is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.