copy image and process using CUDA
| 355 | |
| 356 | // copy image and process using CUDA |
| 357 | void processImage() |
| 358 | { |
| 359 | // run the Cuda kernel |
| 360 | process(image_width, image_height, blur_radius); |
| 361 | |
| 362 | // CUDA generated data in cuda memory or in a mapped PBO made of BGRA 8 bits |
| 363 | // 2 solutions, here : |
| 364 | // - use glTexSubImage2D(), there is the potential to loose performance in |
| 365 | // possible hidden conversion |
| 366 | // - map the texture and blit the result thanks to CUDA API |
| 367 | #ifdef USE_TEXSUBIMAGE2D |
| 368 | glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pbo_dest); |
| 369 | |
| 370 | glBindTexture(GL_TEXTURE_2D, tex_cudaResult); |
| 371 | glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, image_width, image_height, GL_RGBA, GL_UNSIGNED_BYTE, NULL); |
| 372 | SDK_CHECK_ERROR_GL(); |
| 373 | glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0); |
| 374 | glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0); |
| 375 | #else |
| 376 | // We want to copy cuda_dest_resource data to the texture |
| 377 | // map buffer objects to get CUDA device pointers |
| 378 | cudaArray *texture_ptr; |
| 379 | checkCudaErrors(cudaGraphicsMapResources(1, &cuda_tex_result_resource, 0)); |
| 380 | checkCudaErrors(cudaGraphicsSubResourceGetMappedArray(&texture_ptr, cuda_tex_result_resource, 0, 0)); |
| 381 | |
| 382 | int num_texels = image_width * image_height; |
| 383 | int num_values = num_texels * 4; |
| 384 | int size_tex_data = sizeof(GLubyte) * num_values; |
| 385 | checkCudaErrors(cudaMemcpyToArray(texture_ptr, 0, 0, cuda_dest_resource, size_tex_data, cudaMemcpyDeviceToDevice)); |
| 386 | |
| 387 | checkCudaErrors(cudaGraphicsUnmapResources(1, &cuda_tex_result_resource, 0)); |
| 388 | #endif |
| 389 | } |
| 390 | |
| 391 | // display image to the screen as textured quad |
| 392 | void displayImage(GLuint texture) |