Как предоставить вычисленное количество рабочих групп для glDispatchComputeIndirect? - PullRequest
1 голос
/ 28 апреля 2020

Как glDispatchComputeIndirect должен работать, если вы хотите вычислить количество потоков второй отправки в первой?

У меня есть вычислительный шейдер, который работает над буфером, проверяет, является ли значение элемент действителен, а затем условно записывает индекс элемента в другой буфер с помощью счетчика atomi c. Как теперь я могу наиболее эффективно отправить второй вычислительный шейдер с одним потоком для каждого записанного индекса?

Вероятно, самое медленное решение - это прочитать значение n счетчика atomi c и glDispatchCompute ( n / workgroupSize, 1, 1).

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

Я мог бы также использовать атомный c «счетчик элементов» для считая количество записанных элементов, проверяйте возвращаемое значение в каждом потоке и увеличивайте еще один атоми c «счетчик рабочей группы» всякий раз, когда возвращаемое значение atomicAdd делится на размер рабочей группы. Это спасает меня от возврата к центральному процессору и третьей отправки, но за счет другого счетчика атомов c. Но сейчас я не могу придумать лучшего решения.

1 Ответ

2 голосов
/ 28 апреля 2020

Вам не нужно количество «потоков». Вам нужно количество рабочих групп. Поэтому вычислите то, что вам нужно вычислить.

Соотношение между количеством рабочих групп во втором вызове диспетчеризации и числом вычисляемых вами «потоков» очень просто: (threadCount / threadPerGroup), где threadPerGroup - это число вызовы в рабочей группе второго вычислительного шейдера.

Теперь вам не нужно вычислять все threadCount, чтобы вычислить это. Все, что вам действительно нужно сделать, - это увеличить счетчик c каждый раз, когда вы увеличиваете threadCount на кратное threadPerGroup раз. Что достаточно просто, поскольку atomicCounterIncrement возвращает предыдущее значение счетчика atomi c.

Таким образом, ваш код будет выглядеть так:

if(<I should add a thread>)
{
  uint oldThreadCount = atomicCounterIncrement(threadCount); //Returns old value
  if(oldThreadCount % threadPerGroup == 0) //That means `threadCount` is now in the next group.
    atomicCounterIncrement(groupCount);
}
...