Cuda и OpenGL Interop - PullRequest
       52

Cuda и OpenGL Interop

17 голосов
/ 26 июня 2011

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

Согласно руководству по программированию nvidia, это должно быть сделано следующим образом:

GLuint positionsVBO;
struct cudaGraphicsResource* positionsVBO_CUDA;

int main() {

    // Explicitly set device
    cudaGLSetGLDevice(0);
    // Initialize OpenGL and GLUT
    ...
    glutDisplayFunc(display);
    // Create buffer object and register it with CUDA
    glGenBuffers(1, positionsVBO);
    glBindBuffer(GL_ARRAY_BUFFER, &vbo);
    unsigned int size = width * height * 4 * sizeof(float);
    glBufferData(GL_ARRAY_BUFFER, size, 0, GL_DYNAMIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    cudaGraphicsGLRegisterBuffer(&positionsVBO_CUDA, positionsVBO, cudaGraphicsMapFlagsWriteDiscard);

    // Launch rendering loop
    glutMainLoop();
}
void display() {
    // Map buffer object for writing from CUDA
    float4* positions;
    cudaGraphicsMapResources(1, &positionsVBO_CUDA, 0);
    size_t num_bytes;
    cudaGraphicsResourceGetMappedPointer((void**)&positions, &num_bytes, positionsVBO_CUDA));
    // Execute kernel
    dim3 dimBlock(16, 16, 1);
    dim3 dimGrid(width / dimBlock.x, height / dimBlock.y, 1);
    createVertices<<<dimGrid, dimBlock>>>(positions, time, width, height);
    // Unmap buffer object
    cudaGraphicsUnmapResources(1, &positionsVBO_CUDA, 0);
    // Render from buffer object
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glBindBuffer(GL_ARRAY_BUFFER, positionsVBO);
    glVertexPointer(4, GL_FLOAT, 0, 0);
    glEnableClientState(GL_VERTEX_ARRAY);
    glDrawArrays(GL_POINTS, 0, width * height);
    glDisableClientState(GL_VERTEX_ARRAY);
    // Swap buffers
    glutSwapBuffers();
    glutPostRedisplay();
}
void deleteVBO() {
    cudaGraphicsUnregisterResource(positionsVBO_CUDA);
    glDeleteBuffers(1, &positionsVBO);
}

__global__ void createVertices(float4* positions, float time, unsigned int width, unsigned int height) { 
    // [....]
}

Есть ли способ передать пространство памяти, созданное cudaMalloc, непосредственно в OpenGL?У меня уже есть рабочий код, написанный на cuda, и я хочу поместить свой массив float4 прямо в OpenGL.

Скажите, если у вас уже есть код, подобный:

float4 *cd = (float4*) cudaMalloc(elements*sizeof(float4)). 
do_something<<<16,1>>>(cd);

И я хотел бы отобразить вывод do_something через OpenGL.

Примечание: почему функция cudaGraphicsResourceGetMappedPointerработать на каждом временном шаге?

Ответы [ 2 ]

12 голосов
/ 27 июня 2011

Начиная с CUDA 4.0, взаимодействие OpenGL является односторонним. Это означает, что для выполнения того, что вы хотите (запустить ядро ​​CUDA, которое записывает данные в буфер GL или изображение текстуры), вы должны сопоставить буфер с указателем устройства и передать этот указатель вашему ядру, как показано в вашем примере.

Что касается вашего примечания: cudaGraphicsResourceGetMappedPointer вызывается каждый раз, когда вызывается display (), потому что cudaGraphicsMapResource вызывается каждый кадр. Каждый раз, когда вы повторно сопоставляете ресурс, вы должны повторно получать сопоставленный указатель, потому что он мог измениться. Зачем заново отображать каждый кадр? Что ж, OpenGL иногда перемещает объекты буфера в памяти из соображений производительности (особенно в приложениях GL с интенсивным использованием памяти). Если вы все время оставляете ресурс подключенным, он не может этого сделать, и производительность может снизиться. Я полагаю, что способность GL и необходимость виртуализации объектов памяти также является одной из причин того, что текущий API взаимодействия GL является односторонним (GL не может перемещать распределения CUDA, и поэтому вы не можете отобразить указатель устройства, выделенный CUDA в буферный объект GL).

2 голосов
/ 12 мая 2015

Для примера того, как использовать взаимодействие CUDA-GL без необходимости переназначения каждого кадра, обратитесь к этому примеру:

https://github.com/nvpro-samples/gl_cuda_interop_pingpong_st

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...