CUDA et OpenGL Interop

j'ai lu la documentation de CUDA et il me semble que chaque tampon qui doit s'interfacer avec OpenGL doit être créé dans le glBuffer.

<!-Selon le guide de programmation de nvidia, cela doit être fait comme ceci:

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) { 
    // [....]
}

y a-t-il un moyen de donner directement à OpenGL l'espace mémoire créé par cudaMalloc? J'ai déjà le code de travail écrit sur cuda et je veux mettre mon tableau float4 directement dans OpenGL.

dire si vous avez ai déjà le code de la forme:

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

et je voulais afficher la sortie de do_something via OpenGL.

<!-Note: pourquoi la fonction cudaGraphicsResourceGetMappedPointer est-elle exécutée à chaque pas?

17
demandé sur Pascal 2011-06-26 03:22:33

2 réponses

à partir de CUDA 4.0, OpenGL interop est à Sens Unique. Cela signifie que pour faire ce que vous voulez (exécuter un noyau CUDA qui écrit des données dans un tampon GL ou une image de texture), vous devez mapper le tampon à un pointeur de périphérique, et passer ce pointeur à votre noyau, comme indiqué dans votre exemple.

comme pour votre côté note: cudaGraphicsResourceGetMappedPointer est appelé chaque fois que display() est appelé parce que cudaGraphicsMapResource est appelé chaque frame. Chaque fois que vous re-carte une ressource vous devriez re-obtenir le pointeur cartographié, parce qu'il peut avoir changé. Pourquoi refaire chaque image? Eh bien, OpenGL déplace parfois des objets tampons en mémoire, pour des raisons de performance (en particulier dans les applications GL à forte intensité de mémoire). Si vous laissez la ressource cartographiée tout le temps, elle ne peut pas le faire, et la performance peut en souffrir. Je pense que la capacité et le besoin de virtualiser les objets de mémoire de GL est aussi l'une des raisons pour lesquelles l'API actuelle interop de GL est à Sens Unique (le GL n'est pas autorisé à déplacer les allocations CUDA, et donc vous ne pouvez pas mapper un pointeur de périphérique alloué à CUDA dans un objet GL buffer).

12
répondu harrism 2011-06-27 01:09:08

pour un exemple d'utilisation de CUDA-GL interop sans avoir à re-mapper chaque image, référez-vous à cet exemple:

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

2
répondu bigD 2015-05-12 18:26:00