В настоящее время я работаю над Trail Renderer в пользовательском движке, используя Vulkan. Я застреваю, когда пытаюсь обновить буфер вершин из me sh, который я использую для следа. Я использую промежуточный буфер.
Ошибка обновления информации:
Эти промежуточные буферы, кажется, являются источником ошибки, ошибка проверки возвращает меня "Невозможно освободить VkBuffer 0x8838a700000004fe [], который используется с помощью буфера команд "когда я пытаюсь визуализировать me sh"
Для конвейера "update" я проверяю, что это не так, пока выполняется проход graphi c.
Вот код для обновления буфера вершин и индексного буфера
template <typename T>
void Initialize(const std::vector<T>& vertices, const std::vector<uint32_t>& indices = {})
{
static_assert(std::is_base_of<VertexMesh, T>::value, "T must derive from MeshVertex");
if (!vertices.empty()) {
std::vector<char> verticesData;
verticesData.resize(sizeof(T) * vertices.size());
std::memcpy(&verticesData[0], &vertices[0], sizeof(T) * vertices.size());
const auto vertexStaging = Buffer(
verticesData.size(),
VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
verticesData);
//Optional
vertexBuffer_.emplace(
sizeof(T) * vertices.
size(),
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
vertexCount_ = static_cast<uint32_t>(vertices.size());
auto commandBuffer = CommandBuffer();
VkBufferCopy copyRegion = {};
copyRegion.size = sizeof(T) * vertices.size();
vkCmdCopyBuffer(
commandBuffer,
vertexStaging.GetBuffer(),
vertexBuffer_->GetBuffer(),
1,
©Region);
commandBuffer.SubmitIdle();
}
if (!indices.empty()) {
const auto indexStaging = Buffer(
sizeof(uint32_t) * indices.size(),
VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
indices);
indexBuffer_.emplace(
sizeof(uint32_t) * indices.
size(),
VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
indexCount_ = static_cast<uint32_t>(indices.size());
auto commandBuffer = CommandBuffer();
VkBufferCopy copyRegion = {};
copyRegion.size = sizeof(uint32_t) * indices.size();
vkCmdCopyBuffer(
commandBuffer,
indexStaging.GetBuffer(),
indexBuffer_->GetBuffer(),
1,
©Region);
commandBuffer.SubmitIdle();
}
}
Эта же функция работает при загрузке при загрузке .obj или примитива
Конструктор для моего буфера команд: :
CommandBuffer(
bool begin = true,
VkQueueFlagBits queueType = VK_QUEUE_GRAPHICS_BIT,
VkCommandBufferLevel bufferLevel = VK_COMMAND_BUFFER_LEVEL_PRIMARY);
И функция SubmitIdle:
void CommandBuffer::SubmitIdle()
{
const auto queueSelected = GetQueue();
if (running_) { End(); }
VkSubmitInfo submitInfo = {};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &commandBuffer_;
//Code upadeted from Nicol Bolas tips
CheckVk(vkQueueSubmit(queueSelected, 1, &submitInfo, nullptr));
CheckVk(vkQueueWaitIdle(queueSelected));
}
Надеюсь, у вас есть все, чтобы видеть вещи более ясно, чем я!