ПрограммированиеФорумГрафика

Синхронизации в Vulkan (комментарии) (2 стр)

Страницы: 1 2 3 Следующая »
#15
18:23, 26 фев 2019

перефразировал и добавил про порядок рисования

#16
18:31, 26 фев 2019

окей, статью я опубликовал

WTF?? Почему на главной целиком статья вместо кусочка??

#17
18:34, 26 фев 2019

@!!ex
Потому-что кто-то забыл про cut )

#18
20:31, 26 фев 2019

/A\
Спасибо за статью. Довольно глубоко описано.
>Командный буфер не создает никаких дополнительных синхронизаций, при переходе на следующий >командный буфер происходит только смена состояний (пайпалайны, дескрипторы и тд).
Меняются после vkEndCommandBuffer(cmd1) и vkBeginCommandBuffer(cmd2)
На что они меняются? Где об это почитать?

На своем опыте я заметил что при вызове vkBeginCommandBuffer нужно к примеру заново вызывать vkCmdBindPipeline и т.д. хотя Redudant API call можно избегать между vkBeginCommandBuffer/vkEndCommandBuffer

Почитаю дальше, может что еще напишу.

#19
20:39, 26 фев 2019

Andrey
> На своем опыте я заметил что при вызове vkBeginCommandBuffer нужно к примеру
> заново вызывать vkCmdBindPipeline и

заново заполнять command buffer ? а как иначе ?

#20
20:52, 26 фев 2019

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."

#21
20:54, 26 фев 2019

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.

#22
21:02, 26 фев 2019

/A\
> как раз начинается с "Each command buffer manages state independently of other
> command buffers."

твои слова "при переходе на следующий >командный буфер происходит только смена состояний (пайпалайны, дескрипторы и тд)."

понимаются как смена стейтов при вызове vkBeginCommandBuffer ?

#23
21:23, 26 фев 2019

innuendo
> понимаются как смена стейтов при вызове vkBeginCommandBuffer ?
Ну да, при вызове vkBeginCommandBuffer все состояния инвалидируются и их надо устанавливать заново.

#24
21:34, 26 фев 2019

/A\
> Ну да, при вызове vkBeginCommandBuffer все состояния инвалидируются и их надо
> устанавливать заново
Вот, я имел ввиду что инвалидация/сброс будет более правильно вместо "смена состояний", тем более на что меняется не сказано.

#25
21:36, 26 фев 2019

Andrey
> хотя Redudant API call можно избегать между
> vkBeginCommandBuffer/vkEndCommandBuffer

ты точно знаешь зачем secondary command buffer?

#26
21:44, 26 фев 2019

Andrey
> тем более на что меняется не сказано.
Когда пытаешься уместить всю документацию в одну страницу приходится многое не договаривать и больше ссылаться на документацию.

> Вот, я имел ввиду что инвалидация/сброс будет более правильно вместо "смена состояний"
Не совсем, это с точки зрения командного буфера его состояния сброшены при начале записи, а с точки зрения драйвера, которому пришел очередной командный буфер, это просто набор новых состояний и не важно валидны они или нет.

#27
7:46, 27 фев 2019

Andrey
> На своем опыте я заметил что при вызове vkBeginCommandBuffer нужно к примеру
> заново вызывать vkCmdBindPipeline и т.д. хотя Redudant API call можно избегать
> между vkBeginCommandBuffer/vkEndCommandBuffe

создай secondary command buffer - заполни его и делай vkCmdExecuteCommands без  Redudant API call

#28
22:59, 27 фев 2019

Решил тут проверить один момент.
Что будет если после записи идут две операции чтения, но с разными 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:

  • L1 data cache (read-write, for general buffer accesses)
  • Texture cache (read-only, for texture samplers)
  • Uniform cache (read-only, for dynamically-uniform access patterns (i.e. where every work item in a subgroup is expected to read from the same location))
  • 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 для текстур.

    #29
    2:25, 28 фев 2019

    /A\
    > barrier.srcAccessMask = 0;
    > barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
    ты уверен, что это — вообще валидный барьер?

    /A\
    > Я думаю, что надо при первом чтении инвалидировать все кэши, которые поддерживаются в usage буфера и в текущем layout для текстур.
    по-моему, нормальная идея. потому что инвалидировать одну и ту же память дважды, для разных кешей — это сомнительное веселье для будущей отладки, хотя теоретически и может дать какой-то буст. ключевое слово — теоретически.

    Страницы: 1 2 3 Следующая »
    ПрограммированиеФорумГрафика

    Тема в архиве.