copy image and process using CUDA
| 226 | |
| 227 | // copy image and process using CUDA |
| 228 | void generateCUDAImage() |
| 229 | { |
| 230 | // run the Cuda kernel |
| 231 | unsigned int *out_data; |
| 232 | |
| 233 | #ifdef USE_TEXSUBIMAGE2D |
| 234 | checkCudaErrors(cudaGraphicsMapResources(1, &cuda_pbo_dest_resource, 0)); |
| 235 | size_t num_bytes; |
| 236 | checkCudaErrors(cudaGraphicsResourceGetMappedPointer((void **)&out_data, &num_bytes, cuda_pbo_dest_resource)); |
| 237 | // printf("CUDA mapped pointer of pbo_out: May access %ld bytes, expected %d\n", |
| 238 | // num_bytes, size_tex_data); |
| 239 | #else |
| 240 | out_data = cuda_dest_resource; |
| 241 | #endif |
| 242 | // calculate grid size |
| 243 | dim3 block(16, 16, 1); |
| 244 | // dim3 block(16, 16, 1); |
| 245 | dim3 grid(image_width / block.x, image_height / block.y, 1); |
| 246 | // execute CUDA kernel |
| 247 | launch_cudaProcess(grid, block, 0, out_data, image_width); |
| 248 | |
| 249 | // CUDA generated data in cuda memory or in a mapped PBO made of BGRA 8 bits |
| 250 | // 2 solutions, here : |
| 251 | // - use glTexSubImage2D(), there is the potential to loose performance in |
| 252 | // possible hidden conversion |
| 253 | // - map the texture and blit the result thanks to CUDA API |
| 254 | #ifdef USE_TEXSUBIMAGE2D |
| 255 | checkCudaErrors(cudaGraphicsUnmapResources(1, &cuda_pbo_dest_resource, 0)); |
| 256 | glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pbo_dest); |
| 257 | |
| 258 | glBindTexture(GL_TEXTURE_2D, tex_cudaResult); |
| 259 | glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, image_width, image_height, GL_RGBA, GL_UNSIGNED_BYTE, NULL); |
| 260 | SDK_CHECK_ERROR_GL(); |
| 261 | glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0); |
| 262 | glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0); |
| 263 | #else |
| 264 | // We want to copy cuda_dest_resource data to the texture |
| 265 | // map buffer objects to get CUDA device pointers |
| 266 | cudaArray *texture_ptr; |
| 267 | checkCudaErrors(cudaGraphicsMapResources(1, &cuda_tex_result_resource, 0)); |
| 268 | checkCudaErrors(cudaGraphicsSubResourceGetMappedArray(&texture_ptr, cuda_tex_result_resource, 0, 0)); |
| 269 | |
| 270 | int num_texels = image_width * image_height; |
| 271 | int num_values = num_texels * 4; |
| 272 | int size_tex_data = sizeof(GLubyte) * num_values; |
| 273 | checkCudaErrors(cudaMemcpyToArray(texture_ptr, 0, 0, cuda_dest_resource, size_tex_data, cudaMemcpyDeviceToDevice)); |
| 274 | |
| 275 | checkCudaErrors(cudaGraphicsUnmapResources(1, &cuda_tex_result_resource, 0)); |
| 276 | #endif |
| 277 | } |
| 278 | |
| 279 | // display image to the screen as textured quad |
| 280 | void displayImage(GLuint texture) |