Сценарии, которые вы разместили здесь, зависят от неустановленной и неизвестной информации, вещей, которые вы, вероятно, предполагаете о природе вашего процесса рендеринга, о которой вы не заявили, предполагая, что они не имеют значения.Хотя они очень сильно , как мы увидим здесь.
Итак, давайте начнем с этого.Если мы предположим, что вы отправляете вызовы рендеринга таким образом, что никакие два фрагмента никогда не будут иметь одинаковые значения gl_FragCoord
(и, следовательно, никакие два вызова шейдера никогда не будут пытаться записать в одно и то же место), тогда оба случая четко определены и не нуждаются в барьерах памяти.Да, действительно;из спецификации GLSL:
В пределах одного вызова шейдера видимость и порядок записей, сделанных этим вызовом, четко определены.
См. шейдерФункции memoryBarrier
и квалификаторы coherent
предназначены для чтения значений, записанных отдельными вызовами шейдеров.Чтение значения, записанного вашим вызовом, не является проблемой.Так что вам даже не нужно coherent
здесь, ни в том, ни в другом случае.
Отсюда и необходимость первоначального предположения.Потому что, если это предположение исчезнет, если когда-либо будет какое-либо перекрытие между фрагментами, так что два вызова будут пытаться записать в одно и то же место, оба случая равны undefined .И memoryBarrier
не изменит это .Почему?
Потому что два вызова с одной и той же стадии не имеют порядка между ними.GLSL не дает никаких гарантий относительно того, когда выполняются любые два вызова на одной и той же стадии.Они могут выполняться одновременно или фрагмент из более позднего примитива может выполняться раньше одного из более раннего, несмотря на то, что они вышли из строя, или что-то в этом роде.
memoryBarrier
и аналогичные функции имеет значение для случаев, когда вызовы шейдеров имеют некоторую зависимость порядка между ними .Это могут быть вычислительные шейдеры или управляющие тесселяцией вызовы barrier
, или это может быть вершинный шейдер, который записывает данные, которые читает фрагментный шейдер для примитива, связанного с этой вершиной, или другие случаи, когда между вызовами существует четкое упорядочение.
Два выполнения фрагментного шейдера в одной и той же команде рендеринга (или разных командах рендеринга для этого вещества) имеют без упорядочения между ними .Таким образом, барьеры не помогут.
Вы не хотите, чтобы несколько вызовов фрагментных шейдеров пытались записать в одну и ту же память.Нет, если они не находятся в разных командах рендеринга с правильным glMemoryBarrier
вызовом между ними.