Рисование треугольников с помощью CUDA - PullRequest
7 голосов
/ 11 января 2010

Я пишу свою собственную графическую библиотеку (да, это домашнее задание :) и использую cuda для быстрого рендеринга и расчетов.

У меня проблема с рисованием заполненных треугольников. Я написал это так, чтобы один процесс нарисовал один треугольник. Он работает довольно хорошо, когда на сцене много маленьких треугольников, но полностью разрушает производительность, когда большие треугольники.

Моя идея - сделать два прохода. В первую очередь рассчитайте только вкладку с информацией о сканлайнах (рисуйте отсюда туда). Это будет вычисление треугольника на процесс, как в текущем алгоритме. А во втором проходе действительно нарисуйте линии развертки с более чем одним процессом на треугольник.

Но будет ли это достаточно быстро? Может быть, есть какое-то лучшее решение?

Ответы [ 3 ]

3 голосов
/ 14 января 2010

Вы можете проверить этот блог : конвейер рендеринга программного обеспечения в CUDA . Я не думаю, что это оптимальный способ сделать это, но, по крайней мере, автор делится некоторыми полезными источниками.

Во-вторых, прочитайте эту бумагу : Программируемая архитектура параллельной визуализации . Я думаю, что это одна из самых последних статей, и она также основана на CUDA.

Если бы мне пришлось это сделать, я бы пошел с Параллельным растрированием данных , как в Larrabee (который является TBR) или даже REYES, и адаптировал бы его к CUDA:

http://www.ddj.com/architect/217200602 http://home.comcast.net/~tom_forsyth/larrabee/Standford%20Forsyth%20Larrabee%202010.zip (см. Вторую часть презентации)

http://graphics.stanford.edu/papers/mprast/

0 голосов
/ 15 января 2010

Не хамить, но разве это не то, на что рассчитаны видеокарты? Похоже, использование стандартных API-интерфейсов OpenGL и Direct3D имело бы больше смысла.

Почему бы не использовать API для базового рендеринга, а не CUDA, который является гораздо более низким уровнем? Затем, если вы хотите выполнить дополнительные операции, которые не поддерживаются, вы можете использовать CUDA, чтобы применить их сверху. Или, может быть, реализовать их как шейдеры.

0 голосов
/ 13 января 2010

Я подозреваю, что у вас есть некоторые неправильные представления о CUDA и о том, как его использовать, тем более что вы ссылаетесь на «процесс», когда в терминологии CUDA такого нет.

Для большинства приложений CUDA для достижения хорошей производительности есть две важные вещи: оптимизация доступа к памяти и обеспечение того, чтобы каждый «активный» поток CUDA в деформации выполнял ту же операцию, что и другие активные потоки в деформации. Оба они звучат так, как будто они важны для вашего приложения.

Чтобы оптимизировать доступ к памяти, вы должны убедиться, что ваши чтения из глобальной памяти и ваши записи в глобальную память объединены. Вы можете прочитать больше об этом в руководстве по программированию CUDA, но это, по сути, означает, что смежные потоки в полусфере должны читать или записывать в смежные области памяти. Кроме того, каждый поток должен читать или записывать 4, 8 или 16 байтов за раз.

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

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

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

Таким образом, я бы рекомендовал каждому потоку проверять, находится ли его пиксель внутри заданного треугольника. Если нет, то ничего не должно делать. Если это так, он должен вычислить выходной цвет для этого пикселя.

Кроме того, я настоятельно рекомендую прочитать больше о CUDA, поскольку кажется, что вы прыгаете в глубокий конец, не имея хорошего понимания некоторых основных принципов.

...