Фрагментный шейдер использует два атомных счетчика. Он может увеличивать или не увеличивать первое и может увеличивать или не увеличивать второе (но не оба сразу). Однако перед таким изменением счетчиков всегда считываются их текущие значения и - если счетчики впоследствии изменяются - ранее считанные значения, используемые для некоторой настраиваемой логики. Все это происходит в цикле (скорее всего, неуправляемом).
Представьте себе поток примерно так:
- в каком-то небольшом неуправляемом цикле, скажем, FOR 0-20 (разрешимая константа во время компиляции) ...
- получить значения счетчиков для AC1 и AC2
- проверьте какое-то значение:
- если x: установить тексель в uimage1D_A по индексу AC1, увеличить AC1
- else: установить тексель в uimage1D_B по индексу (imgwidth-AC2-1), увеличить AC2
Вопрос: шейдер запрашивает текущее значение счетчика - всегда ли он получает «самое актуальное» значение? Теряю ли я здесь массовый параллелизм фрагментных шейдеров (если говорить только о графических процессорах и драйверах текущего и будущих поколений)?
Что касается ветвления (если x) - я сравниваю тексель в другом (readonly restrict uniform
) uimage1D
с (uniform
) uint
. Итак, один операнд определенно является однородным скаляром, а другой - imageLoad().x
, хотя изображение однородно - является ли этот вид ветвления все еще «полностью распараллеленным»? Вы можете видеть, что в обеих ветках есть ровно две, почти идентичные инструкции. Предполагая "идеально оптимизирующий" компилятор GLSL, может ли такое ветвление привести к остановке?