перефразировал и добавил про порядок рисования
окей, статью я опубликовал
WTF?? Почему на главной целиком статья вместо кусочка??
@!!ex
Потому-что кто-то забыл про cut )
/A\
Спасибо за статью. Довольно глубоко описано.
>Командный буфер не создает никаких дополнительных синхронизаций, при переходе на следующий >командный буфер происходит только смена состояний (пайпалайны, дескрипторы и тд).
Меняются после vkEndCommandBuffer(cmd1) и vkBeginCommandBuffer(cmd2)
На что они меняются? Где об это почитать?
На своем опыте я заметил что при вызове vkBeginCommandBuffer нужно к примеру заново вызывать vkCmdBindPipeline и т.д. хотя Redudant API call можно избегать между vkBeginCommandBuffer/vkEndCommandBuffer
Почитаю дальше, может что еще напишу.
Andrey
> На своем опыте я заметил что при вызове vkBeginCommandBuffer нужно к примеру
> заново вызывать vkCmdBindPipeline и
заново заполнять command buffer ? а как иначе ?
Andrey
> На что они меняются? Где об это почитать?
Да вроде в доках все написано)
https://www.khronos.org/registry/vulkan/specs/1.1/html/chap5.html… ommandbuffers
3й параграф, как раз начинается с "Each command buffer manages state independently of other command buffers."
Andrey
> Где об это почитать?
https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html… ommandbuffers
Recording
vkBeginCommandBuffer changes the state of a command buffer from the initial state to the recording state. Once a command buffer is in the recording state, vkCmd* commands can be used to record to the command buffer.
/A\
> как раз начинается с "Each command buffer manages state independently of other
> command buffers."
твои слова "при переходе на следующий >командный буфер происходит только смена состояний (пайпалайны, дескрипторы и тд)."
понимаются как смена стейтов при вызове vkBeginCommandBuffer ?
innuendo
> понимаются как смена стейтов при вызове vkBeginCommandBuffer ?
Ну да, при вызове vkBeginCommandBuffer все состояния инвалидируются и их надо устанавливать заново.
/A\
> Ну да, при вызове vkBeginCommandBuffer все состояния инвалидируются и их надо
> устанавливать заново
Вот, я имел ввиду что инвалидация/сброс будет более правильно вместо "смена состояний", тем более на что меняется не сказано.
Andrey
> хотя Redudant API call можно избегать между
> vkBeginCommandBuffer/vkEndCommandBuffer
ты точно знаешь зачем secondary command buffer?
Andrey
> тем более на что меняется не сказано.
Когда пытаешься уместить всю документацию в одну страницу приходится многое не договаривать и больше ссылаться на документацию.
> Вот, я имел ввиду что инвалидация/сброс будет более правильно вместо "смена состояний"
Не совсем, это с точки зрения командного буфера его состояния сброшены при начале записи, а с точки зрения драйвера, которому пришел очередной командный буфер, это просто набор новых состояний и не важно валидны они или нет.
Andrey
> На своем опыте я заметил что при вызове vkBeginCommandBuffer нужно к примеру
> заново вызывать vkCmdBindPipeline и т.д. хотя Redudant API call можно избегать
> между vkBeginCommandBuffer/vkEndCommandBuffe
создай secondary command buffer - заполни его и делай vkCmdExecuteCommands без Redudant API call
Решил тут проверить один момент.
Что будет если после записи идут две операции чтения, но с разными access mask?
Пойдем издалека...
Availability operations cause the values generated by specified memory write accesses to become available to a memory domain for future access.
availability это запись данных ИЗ кэша, что соответствует
srcAccessMask = *_WRITE;
dstAccessMask = 0;
Visibility operations cause values available to a memory domain to become visible to specified memory accesses.
visibility это только инвалидация кэша, то есть
srcAccessMask = 0;
dstAccessMask = *_READ;
Once written values are made visible to a particular type of memory access, they can be read or written by that type of memory access.
Это значит, что для всех других этапов (stages) кэш также инвалидируется.
https://github.com/philiptaylor/vulkan-sync/blob/master/memory.md
each CU also contains a number of different caches:
Additionally there are a number of ROPs (render output units / raster operations pipelines), which are responsible for all colour/depth/stencil framebuffer attachment accesses. They probably don't go through the L2 cache; instead they contain their own specialised caches for the attachments.
Получается как минимум 4 вида кэша, для каждого из них свой access mask.
In general, none of the GPU caches are coherent with each other - a write via one cache might not be seen by a later read from a different cache. They rely on invalidate/flush signals from software to maintain correct behaviour.
То есть каждый access mask затрагивает только свой кэш и ничего более.
Значит должно быть так:
vkCmdCopyBuffer(... ); // обновляем buffer VkBufferMemoryBarrier barrier; barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; barrier.dstAccessMask = VK_ACCESS_UNIFORM_READ_BIT; vkCmdPipelineBarrier( ... ); vkCmdDraw( ... ); // читаем как uniform buffer VkBufferMemoryBarrier barrier; barrier.srcAccessMask = 0; barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; vkCmdPipelineBarrier( ... ); vkCmdDispatch( ... ); // читаем как storage buffer
либо так:
vkCmdCopyBuffer(... ); // обновляем buffer VkBufferMemoryBarrier barrier; barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; barrier.dstAccessMask = VK_ACCESS_UNIFORM_READ_BIT | VK_ACCESS_SHADER_READ_BIT; vkCmdPipelineBarrier( ... ); vkCmdDraw( ... ); // читаем как uniform buffer ... vkCmdDispatch( ... ); // читаем как storage buffer
Решил посмотреть как это реализовано у других:
DiligentEngine - тут барьеры ставятся всегда, даже при чтении, никаких проверок нет, зато точно инвалидирует все кэши перед чтением.
Vulkan-EZ - после первого чтения участок данных больше не отслеживается, то есть другие типы кэша не будут инвалидированы.
Я думаю, что надо при первом чтении инвалидировать все кэши, которые поддерживаются в usage буфера и в текущем layout для текстур.
/A\
> barrier.srcAccessMask = 0;
> barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
ты уверен, что это — вообще валидный барьер?
/A\
> Я думаю, что надо при первом чтении инвалидировать все кэши, которые поддерживаются в usage буфера и в текущем layout для текстур.
по-моему, нормальная идея. потому что инвалидировать одну и ту же память дважды, для разных кешей — это сомнительное веселье для будущей отладки, хотя теоретически и может дать какой-то буст. ключевое слово — теоретически.
Тема в архиве.