Как я могу профилировать скорость моих вершинных и фрагментных шейдеров отдельно?

11

Я хотел бы знать, как я могу проверить, является ли моя вершина или мой фрагментный шейдер узким местом в моем конвейере рендеринга.

Я читал об использовании glQueryCounterс GL_TIMESTAMPцелью для получения контрольных точек часов между командами OpenGL, но они не различают различные типы шейдеров.

Например, если для рендеринга одного кадра в GPU потребовалось 8 мс, могу ли я сказать, что вершинный шейдер занял 7 мс, а фрагментный шейдер - 1 мс?

Тайлер
источник

Ответы:

12

Вершинные и фрагментные шейдеры работают одновременно, а не последовательно, и графический процессор автоматически балансирует нагрузку между ними, поэтому невозможно целенаправленно назначить конкретные моменты времени, например, 7 мс для одной и 1 мс для другой.

Однако вы можете выполнить простой эксперимент, чтобы измерить, где находится узкое место: установить матрицу проекции вида на все нули для всех ваших вызовов отрисовки. Это заставляет все вершины выводить ноль для их положений и делает все треугольники вырожденными; поэтому он закорачивает всю растеризацию и затенение фрагментов, сохраняя при этом всю работу вершинного шейдера (компилятор шейдера не может ничего оптимизировать, поскольку он не знает, что матрица будет установлена ​​в ноль во время выполнения).

Когда вы измеряете производительность с обнуленными матрицами, вы будете видеть количество времени, необходимое для запуска только вершинных шейдеров, без какой-либо одновременной работы по растеризации или затенению фрагментов в графическом процессоре. Затем вы можете сравнить это с количеством времени, необходимым для обычного рендеринга для каждого прохода. Если два раза похожи, проход, вероятно, сильно привязан к вершине; если рендеринг с нулевой матрицей выполняется значительно быстрее, он, вероятно, связан с пикселями. Также возможно получить промежуточный результат, указывающий, что работа распределена примерно поровну между двумя.

Натан Рид
источник