У меня проблема, когда я трансформирую (например, вращаю) объект (например, куб) в сцене, используя унифицированную матрицу MVP. Вращение не линейное, края объекта мерцают. Смотрите это https://drive.google.com/open?id=1L1Dx-LUdTdqvCQ23-o-vlI_yQK_t7l2_
Я использую 3 свопчейна изображения / фреймбуфера / буфера глубины, одну команду буфер на каждый буфер кадра. (Я также пробовал 2,4 и более изображений)
Я пытался использовать один унифицированный буфер для всех трех командных буферов и отдельные унифицированные буферы для каждого буфера команд.
Текущий режим - VK_PRESENT_MODE_IMMEDIATE_KHR (также я пробовал FIFO_KHR)
Обновление унифицированных буферов синхронизируется событиями в буфере команд и ожидающая очередь простаивает в цикле рисования, который блокирует мьютекс для обновления равномерный буфер. Данные обновляются для всех унифицированных буферов одновременно в одном вызове функции после цикла отрисовки разблокирует мьютекс а буфер команд уведомляет о завершении рисования.
Буферы команд подготавливаются только один раз для каждой программы запуска, потому что любые данные внутри являются постоянными (например, дескриптор установлен в единый буфер)
унифицированный буфер является видимым и согласованным для хоста, отображается во время создания
основной цикл рисования выполняет стандартные операции
Унифицированные буферы обновляются из основного потока по ключевым событиям. В течение нажмите кнопку Я увеличиваю угол Y на 1 градус после этого вызова glm :: повернуть с новым углом m_rot_prop.rotation = glm :: rotate (glm :: mat4 (1.0f), glm :: радианы (angle.y), glm :: vec3 (0.f, 1.0f, 0.f)); Рассчитать новую модель m_model = m_rot_prop.rotationm_trans_prop.transf ormm_scale_prop.scale; После этого эти данные копируются memcpy на единый указатель буфера.
Изначально цикл рисования и основная нить разделены. Но у меня также есть попытался найти их обоих в основном потоке.
Я ввел такие события:
1) в буфер команд добавлено следующее:
vkBeginCommandBuffer...
vkCmdWaitEvents(cmd_buf, 1, &m_data_update_event[image_number],
VK_PIPELINE_STAGE_HOST_BIT,
VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_HOST_BIT,
0, nullptr,
0, nullptr,
0, nullptr);
vkCmdSetEvent(cmd_buf, m_draw_progress_event[image_number],
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT | VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT);
vkCmdBeginRenderPass....
....
vkCmdEndRenderPass...
vkCmdResetEvent(cmd_buf, m_draw_progress_event[image_number], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT | VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT);
2) перед обновлением унифицированного буфера делаю
m_is_draw_paused = true;
for (uint32_t i = 0; i < m_choosen_swap_chain_details.imagesCount; i++)
{
vkResetEvent(m_logical_device, m_data_update_event[i]);
while (vkGetEventStatus(m_logical_device, m_draw_progress_event[i]) == VK_EVENT_SET)
{
boost::this_thread::sleep_for(boost::chrono::milli seconds(1));
}
}
3) обновить унифицированный буфер новой матрицей MVP (универсальный - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, VK_SHARING_MODE_EXCLUSIVE)
4) разрешить рендеринг
for (uint32_t i = 0; i < m_choosen_swap_chain_details.imagesCount; i++)
{
vkSetEvent(m_logical_device, m_data_update_event[i]);
}
Может кто знает причину мерцания?
Видео записывается со скоростью 30 кадров в секунду, но счетчик показывает 42 кадра в секунду. Это само по себе может вызвать некоторое заикание.
VkEvents может быть привередливым, чтобы получить права. Я бы попробовал обойтись без них. Крутиться на vkGetEventStatus
, наверное, плохая идея. Измерьте, не спит ли sleep_for
слишком много (некоторые платформы не могут справиться с такой небольшой дремотой). Использование Fences и QueueWaitIdle, вероятно, является излишним для управления цепочкой обмена. Использовать локальную память устройства явно вместо потоковой передачи унифицированного буфера.
"микростаттер" да, это можно так назвать. Но на видео видны микростатусы и большие сдвиги.
>> Видео записывается со скоростью 30 кадров в секунду, но счетчик показывает 42 кадра в секунду. Это само по себе может вызвать некоторое заикание. да. Но на самом деле и наблюдаются большие лаги, и видео их показывает.
>> Использовать локальную память устройства явно вместо потоковой передачи унифицированного буфера << Я пытался использовать локальную память устройства и копировать единое обновление из локальной памяти на устройство при каждом обновлении. Но это очень медленная операция и приносит больше лагов.
последнее обновление drive.google.com/open?id=1J7KaVd2YTVUZEW1wviguf1Ogd58C7Vwb
Я не вижу мерцания или мигания в прикрепленном видео. Вы имеете в виду микростаттер?