OSDN Git Service

new file: Integration/Tomography/Makefile.recent
[eos/hostdependX86LINUX64.git] / util / X86MAC64 / cuda / samples / 3_Imaging / simpleCUDA2GL / main.cpp
1 /*
2  * Copyright 1993-2013 NVIDIA Corporation.  All rights reserved.
3  *
4  * Please refer to the NVIDIA end user license agreement (EULA) associated
5  * with this source code for terms and conditions that govern your use of
6  * this software. Any use, reproduction, disclosure, or distribution of
7  * this software and related documentation outside the terms of the EULA
8  * is strictly prohibited.
9  *
10  */
11
12
13 // USE_TEXSUBIMAGE2D uses glTexSubImage2D() to update the final result
14 // commenting it will make the sample use the other way :
15 // map a texture in CUDA and blit the result into it
16 //#define USE_TEXSUBIMAGE2D
17
18 #ifdef _WIN32
19 #  define WINDOWS_LEAN_AND_MEAN
20 #  define NOMINMAX
21 #  include <windows.h>
22 #pragma warning(disable:4996)
23 #endif
24
25 // OpenGL Graphics includes
26 #include <GL/glew.h>
27 #if defined(__APPLE__) || defined(MACOSX)
28 #include <GLUT/glut.h>
29 // Sorry for Apple : unsigned int sampler is not available to you, yet...
30 // Let's switch to the use of PBO and glTexSubImage
31 #define USE_TEXSUBIMAGE2D
32 #else
33 #include <GL/freeglut.h>
34 #endif
35
36 // CUDA includes
37 #include <cuda_runtime.h>
38 #include <cuda_gl_interop.h>
39
40 // CUDA utilities and system includes
41 #include <helper_cuda.h>
42 #include <helper_cuda_gl.h>
43
44 #include <helper_functions.h>
45 #include <rendercheck_gl.h>
46
47 // Shared Library Test Functions
48 #define MAX_EPSILON 10
49 #define REFRESH_DELAY     10 //ms
50
51 const char *sSDKname = "simpleCUDA2GL";
52
53 unsigned int g_TotalErrors = 0;
54
55 // CheckFBO/BackBuffer class objects
56 CheckRender *g_CheckRender = NULL;
57
58 ////////////////////////////////////////////////////////////////////////////////
59 // constants / global variables
60 unsigned int window_width = 512;
61 unsigned int window_height = 512;
62 unsigned int image_width = 512;
63 unsigned int image_height = 512;
64 int iGLUTWindowHandle = 0;          // handle to the GLUT window
65
66 // pbo and fbo variables
67 #ifdef USE_TEXSUBIMAGE2D
68 GLuint pbo_dest;
69 struct cudaGraphicsResource *cuda_pbo_dest_resource;
70 #else
71 unsigned int *cuda_dest_resource;
72 GLuint shDrawTex;  // draws a texture
73 struct cudaGraphicsResource *cuda_tex_result_resource;
74 #endif
75
76 GLuint fbo_source;
77 struct cudaGraphicsResource *cuda_tex_screen_resource;
78
79 unsigned int size_tex_data;
80 unsigned int num_texels;
81 unsigned int num_values;
82
83 // (offscreen) render target fbo variables
84 GLuint tex_screen;      // where we render the image
85 GLuint tex_cudaResult;  // where we will copy the CUDA result
86
87 char *ref_file       = NULL;
88 bool enable_cuda     = true;
89
90 int   *pArgc = NULL;
91 char **pArgv = NULL;
92
93
94 // Timer
95 static int fpsCount = 0;
96 static int fpsLimit = 1;
97 StopWatchInterface *timer = NULL;
98
99 #ifndef USE_TEXTURE_RGBA8UI
100 #   pragma message("Note: Using Texture fmt GL_RGBA16F_ARB")
101 #else
102 // NOTE: the current issue with regular RGBA8 internal format of textures
103 // is that HW stores them as BGRA8. Therefore CUDA will see BGRA where users
104 // expected RGBA8. To prevent this issue, the driver team decided to prevent this to happen
105 // instead, use RGBA8UI which required the additional work of scaling the fragment shader
106 // output from 0-1 to 0-255. This is why we have some GLSL code, in this case
107 #   pragma message("Note: Using Texture RGBA8UI + GLSL for teapot rendering")
108 #endif
109 GLuint shDrawPot;  // colors the teapot
110
111 #ifdef WIN32
112 bool IsOpenGLAvailable(const char *appName)
113 {
114     return true;
115 }
116 #else
117 #if (defined(__APPLE__) || defined(MACOSX))
118 bool IsOpenGLAvailable(const char *appName)
119 {
120     return true;
121 }
122 #else
123 // check if this is a linux machine
124 #include <X11/Xlib.h>
125
126 bool IsOpenGLAvailable(const char *appName)
127 {
128     Display *Xdisplay = XOpenDisplay(NULL);
129
130     if (Xdisplay == NULL)
131     {
132         return false;
133     }
134     else
135     {
136         XCloseDisplay(Xdisplay);
137         return true;
138     }
139 }
140 #endif
141 #endif
142
143 ////////////////////////////////////////////////////////////////////////////////
144 extern "C" void
145 launch_cudaProcess(dim3 grid, dim3 block, int sbytes,
146                    unsigned int *g_odata,
147                    int imgw);
148
149 // Forward declarations
150 void runStdProgram(int argc, char **argv);
151 void FreeResource();
152 void Cleanup(int iExitCode);
153
154 // GL functionality
155 bool initCUDA(int argc, char **argv, bool bUseGL);
156 bool initGL(int *argc, char **argv);
157
158 #ifdef USE_TEXSUBIMAGE2D
159 void createPBO(GLuint *pbo, struct cudaGraphicsResource **pbo_resource);
160 void deletePBO(GLuint *pbo);
161 #endif
162
163 void createTextureDst(GLuint *tex_cudaResult, unsigned int size_x, unsigned int size_y);
164 void deleteTexture(GLuint *tex);
165
166 // rendering callbacks
167 void display();
168 void idle();
169 void keyboard(unsigned char key, int x, int y);
170 void reshape(int w, int h);
171 void mainMenu(int i);
172
173 #ifdef USE_TEXSUBIMAGE2D
174 ////////////////////////////////////////////////////////////////////////////////
175 //! Create PBO
176 ////////////////////////////////////////////////////////////////////////////////
177 void
178 createPBO(GLuint *pbo, struct cudaGraphicsResource **pbo_resource)
179 {
180     // set up vertex data parameter
181     num_texels = image_width * image_height;
182     num_values = num_texels * 4;
183     size_tex_data = sizeof(GLubyte) * num_values;
184     void *data = malloc(size_tex_data);
185
186     // create buffer object
187     glGenBuffers(1, pbo);
188     glBindBuffer(GL_ARRAY_BUFFER, *pbo);
189     glBufferData(GL_ARRAY_BUFFER, size_tex_data, data, GL_DYNAMIC_DRAW);
190     free(data);
191
192     glBindBuffer(GL_ARRAY_BUFFER, 0);
193
194     // register this buffer object with CUDA
195     checkCudaErrors(cudaGraphicsGLRegisterBuffer(pbo_resource, *pbo, cudaGraphicsMapFlagsNone));
196
197     SDK_CHECK_ERROR_GL();
198 }
199
200 void
201 deletePBO(GLuint *pbo)
202 {
203     glDeleteBuffers(1, pbo);
204     SDK_CHECK_ERROR_GL();
205     *pbo = 0;
206 }
207 #endif
208
209 const GLenum fbo_targets[] =
210 {
211     GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT,
212     GL_COLOR_ATTACHMENT2_EXT, GL_COLOR_ATTACHMENT3_EXT
213 };
214
215 #ifndef USE_TEXSUBIMAGE2D
216 static const char *glsl_drawtex_vertshader_src =
217     "void main(void)\n"
218     "{\n"
219     "   gl_Position = gl_Vertex;\n"
220     "   gl_TexCoord[0].xy = gl_MultiTexCoord0.xy;\n"
221     "}\n";
222
223 static const char *glsl_drawtex_fragshader_src =
224     "#version 130\n"
225     "uniform usampler2D texImage;\n"
226     "void main()\n"
227     "{\n"
228     "   vec4 c = texture(texImage, gl_TexCoord[0].xy);\n"
229     "   gl_FragColor = c / 255.0;\n"
230     "}\n";
231 #endif
232
233 static const char *glsl_drawpot_fragshader_src =
234     //WARNING: seems like the gl_FragColor doesn't want to output >1 colors...
235     //you need version 1.3 so you can define a uvec4 output...
236     //but MacOSX complains about not supporting 1.3 !!
237     // for now, the mode where we use RGBA8UI may not work properly for Apple : only RGBA16F works (default)
238 #if defined(__APPLE__) || defined(MACOSX)
239     "void main()\n"
240     "{"
241     "  gl_FragColor = vec4(gl_Color * 255.0);\n"
242     "}\n";
243 #else
244     "#version 130\n"
245     "out uvec4 FragColor;\n"
246     "void main()\n"
247     "{"
248     "  FragColor = uvec4(gl_Color.xyz * 255.0, 255.0);\n"
249     "}\n";
250 #endif
251
252 // copy image and process using CUDA
253 void generateCUDAImage()
254 {
255     // run the Cuda kernel
256     unsigned int *out_data;
257
258 #ifdef USE_TEXSUBIMAGE2D
259     checkCudaErrors(cudaGraphicsMapResources(1, &cuda_pbo_dest_resource, 0));
260     size_t num_bytes;
261     checkCudaErrors(cudaGraphicsResourceGetMappedPointer((void **)&out_data, &num_bytes,
262                                                          cuda_pbo_dest_resource));
263     //printf("CUDA mapped pointer of pbo_out: May access %ld bytes, expected %d\n", num_bytes, size_tex_data);
264 #else
265     out_data = cuda_dest_resource;
266 #endif
267     // calculate grid size
268     dim3 block(16, 16, 1);
269     //dim3 block(16, 16, 1);
270     dim3 grid(image_width / block.x, image_height / block.y, 1);
271     // execute CUDA kernel
272     launch_cudaProcess(grid, block, 0, out_data, image_width);
273
274
275     // CUDA generated data in cuda memory or in a mapped PBO made of BGRA 8 bits
276     // 2 solutions, here :
277     // - use glTexSubImage2D(), there is the potential to loose performance in possible hidden conversion
278     // - map the texture and blit the result thanks to CUDA API
279 #ifdef USE_TEXSUBIMAGE2D
280     checkCudaErrors(cudaGraphicsUnmapResources(1, &cuda_pbo_dest_resource, 0));
281     glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pbo_dest);
282
283     glBindTexture(GL_TEXTURE_2D, tex_cudaResult);
284     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
285                     image_width, image_height,
286                     GL_RGBA, GL_UNSIGNED_BYTE, NULL);
287     SDK_CHECK_ERROR_GL();
288     glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
289     glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
290 #else
291     // We want to copy cuda_dest_resource data to the texture
292     // map buffer objects to get CUDA device pointers
293     cudaArray *texture_ptr;
294     checkCudaErrors(cudaGraphicsMapResources(1, &cuda_tex_result_resource, 0));
295     checkCudaErrors(cudaGraphicsSubResourceGetMappedArray(&texture_ptr, cuda_tex_result_resource, 0, 0));
296
297     int num_texels = image_width * image_height;
298     int num_values = num_texels * 4;
299     int size_tex_data = sizeof(GLubyte) * num_values;
300     checkCudaErrors(cudaMemcpyToArray(texture_ptr, 0, 0, cuda_dest_resource, size_tex_data, cudaMemcpyDeviceToDevice));
301
302     checkCudaErrors(cudaGraphicsUnmapResources(1, &cuda_tex_result_resource, 0));
303 #endif
304 }
305
306 // display image to the screen as textured quad
307 void displayImage(GLuint texture)
308 {
309     glBindTexture(GL_TEXTURE_2D, texture);
310     glEnable(GL_TEXTURE_2D);
311     glDisable(GL_DEPTH_TEST);
312     glDisable(GL_LIGHTING);
313     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
314
315     glMatrixMode(GL_PROJECTION);
316     glPushMatrix();
317     glLoadIdentity();
318     glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
319
320     glMatrixMode(GL_MODELVIEW);
321     glLoadIdentity();
322
323     glViewport(0, 0, window_width, window_height);
324
325     // if the texture is a 8 bits UI, scale the fetch with a GLSL shader
326 #ifndef USE_TEXSUBIMAGE2D
327     glUseProgram(shDrawTex);
328     GLint id = glGetUniformLocation(shDrawTex, "texImage");
329     glUniform1i(id, 0); // texture unit 0 to "texImage"
330     SDK_CHECK_ERROR_GL();
331 #endif
332
333     glBegin(GL_QUADS);
334     glTexCoord2f(0.0, 0.0);
335     glVertex3f(-1.0, -1.0, 0.5);
336     glTexCoord2f(1.0, 0.0);
337     glVertex3f(1.0, -1.0, 0.5);
338     glTexCoord2f(1.0, 1.0);
339     glVertex3f(1.0, 1.0, 0.5);
340     glTexCoord2f(0.0, 1.0);
341     glVertex3f(-1.0, 1.0, 0.5);
342     glEnd();
343
344     glMatrixMode(GL_PROJECTION);
345     glPopMatrix();
346
347     glDisable(GL_TEXTURE_2D);
348
349 #ifndef USE_TEXSUBIMAGE2D
350     glUseProgram(0);
351 #endif
352     SDK_CHECK_ERROR_GL();
353 }
354
355 ////////////////////////////////////////////////////////////////////////////////
356 //! Display callback
357 ////////////////////////////////////////////////////////////////////////////////
358 void
359 display()
360 {
361     sdkStartTimer(&timer);
362
363     if (enable_cuda)
364     {
365         generateCUDAImage();
366         displayImage(tex_cudaResult);
367     }
368
369     // NOTE: I needed to add this call so the timing is consistent.
370     // Need to investigate why
371     cudaDeviceSynchronize();
372     sdkStopTimer(&timer);
373
374     // flip backbuffer
375     glutSwapBuffers();
376
377     // If specified, Check rendering against reference,
378     if (ref_file && g_CheckRender && g_CheckRender->IsQAReadback())
379     {
380
381         static int pass = 0;
382
383         if (pass > 0)
384         {
385             g_CheckRender->readback(window_width, window_height);
386             char currentOutputPPM[256];
387             sprintf(currentOutputPPM, "kilt.ppm");
388             g_CheckRender->savePPM(currentOutputPPM, true, NULL);
389
390             if (!g_CheckRender->PPMvsPPM(currentOutputPPM, sdkFindFilePath(ref_file, pArgv[0]), MAX_EPSILON, 0.30f))
391             {
392                 g_TotalErrors++;
393             }
394
395             Cleanup((g_TotalErrors==0) ? EXIT_SUCCESS : EXIT_FAILURE);
396         }
397
398         pass++;
399     }
400
401     // Update fps counter, fps/title display and log
402     if (++fpsCount == fpsLimit)
403     {
404         char cTitle[256];
405         float fps = 1000.0f / sdkGetAverageTimerValue(&timer);
406         sprintf(cTitle, "CUDA GL Post Processing (%d x %d): %.1f fps", window_width, window_height, fps);
407         glutSetWindowTitle(cTitle);
408         //printf("%s\n", cTitle);
409         fpsCount = 0;
410         fpsLimit = (int)((fps > 1.0f) ? fps : 1.0f);
411         sdkResetTimer(&timer);
412     }
413 }
414
415 void timerEvent(int value)
416 {
417     glutPostRedisplay();
418     glutTimerFunc(REFRESH_DELAY, timerEvent, 0);
419 }
420
421 ////////////////////////////////////////////////////////////////////////////////
422 //! Keyboard events handler
423 ////////////////////////////////////////////////////////////////////////////////
424 void
425 keyboard(unsigned char key, int /*x*/, int /*y*/)
426 {
427     switch (key)
428     {
429         case (27) :
430             Cleanup(EXIT_SUCCESS);
431             break;
432
433         case ' ':
434             enable_cuda ^= 1;
435 #ifdef USE_TEXTURE_RGBA8UI
436
437             if (enable_cuda)
438             {
439                 glClearColorIuiEXT(128,128,128,255);
440             }
441             else
442             {
443                 glClearColor(0.5, 0.5, 0.5, 1.0);
444             }
445
446 #endif
447             break;
448
449     }
450 }
451
452 void reshape(int w, int h)
453 {
454     window_width = w;
455     window_height = h;
456 }
457
458 void mainMenu(int i)
459 {
460     keyboard((unsigned char) i, 0, 0);
461 }
462
463 ////////////////////////////////////////////////////////////////////////////////
464 //!
465 ////////////////////////////////////////////////////////////////////////////////
466 void
467 createTextureDst(GLuint *tex_cudaResult, unsigned int size_x, unsigned int size_y)
468 {
469     // create a texture
470     glGenTextures(1, tex_cudaResult);
471     glBindTexture(GL_TEXTURE_2D, *tex_cudaResult);
472
473     // set basic parameters
474     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
475     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
476     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
477     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
478
479 #ifdef USE_TEXSUBIMAGE2D
480     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, size_x, size_y, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
481     SDK_CHECK_ERROR_GL();
482 #else
483     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8UI_EXT, size_x, size_y, 0, GL_RGBA_INTEGER_EXT, GL_UNSIGNED_BYTE, NULL);
484     SDK_CHECK_ERROR_GL();
485     // register this texture with CUDA
486     checkCudaErrors(cudaGraphicsGLRegisterImage(&cuda_tex_result_resource, *tex_cudaResult,
487                                                 GL_TEXTURE_2D, cudaGraphicsMapFlagsWriteDiscard));
488 #endif
489 }
490
491 ////////////////////////////////////////////////////////////////////////////////
492 //!
493 ////////////////////////////////////////////////////////////////////////////////
494 void
495 deleteTexture(GLuint *tex)
496 {
497     glDeleteTextures(1, tex);
498     SDK_CHECK_ERROR_GL();
499
500     *tex = 0;
501 }
502
503 ////////////////////////////////////////////////////////////////////////////////
504 // Program main
505 ////////////////////////////////////////////////////////////////////////////////
506 int
507 main(int argc, char **argv)
508 {
509     printf("%s Starting...\n\n", argv[0]);
510
511     if (checkCmdLineFlag(argc, (const char **)argv, "file"))
512     {
513
514         getCmdLineArgumentString(argc, (const char **)argv, "file", &ref_file);
515     }
516
517     pArgc = &argc;
518     pArgv = argv;
519
520     // use command-line specified CUDA device, otherwise use device with highest Gflops/s
521     if (checkCmdLineFlag(argc, (const char **)argv, "device"))
522     {
523         printf("[%s]\n", argv[0]);
524         printf("   Does not explicitly support -device=n\n");
525         printf("   This sample requires OpenGL.  Only -file=<reference> are supported\n");
526         printf("exiting...\n");
527         exit(EXIT_WAIVED);
528     }
529
530     if (ref_file)
531     {
532         printf("(Test with OpenGL verification)\n");
533         runStdProgram(argc, argv);
534     }
535     else
536     {
537         printf("(Interactive OpenGL Demo)\n");
538         runStdProgram(argc, argv);
539     }
540
541     exit(EXIT_SUCCESS);
542 }
543
544 ////////////////////////////////////////////////////////////////////////////////
545 //!
546 ////////////////////////////////////////////////////////////////////////////////
547 void FreeResource()
548 {
549     sdkDeleteTimer(&timer);
550
551     // unregister this buffer object with CUDA
552 //    checkCudaErrors(cudaGraphicsUnregisterResource(cuda_tex_screen_resource));
553 #ifdef USE_TEXSUBIMAGE2D
554     checkCudaErrors(cudaGraphicsUnregisterResource(cuda_pbo_dest_resource));
555     deletePBO(&pbo_dest);
556 #else
557     cudaFree(cuda_dest_resource);
558 #endif
559     deleteTexture(&tex_screen);
560     deleteTexture(&tex_cudaResult);
561
562     cudaDeviceReset();
563
564     if (iGLUTWindowHandle)
565     {
566         glutDestroyWindow(iGLUTWindowHandle);
567     }
568
569     // finalize logs and leave
570     printf("postProcessGL.exe Exiting...\n");
571 }
572
573 void Cleanup(int iExitCode)
574 {
575     FreeResource();
576     printf("PPM Images are %s\n", (iExitCode == EXIT_SUCCESS) ? "Matching" : "Not Matching");
577     exit(iExitCode);
578 }
579
580
581 ////////////////////////////////////////////////////////////////////////////////
582 //!
583 ////////////////////////////////////////////////////////////////////////////////
584 GLuint compileGLSLprogram(const char *vertex_shader_src, const char *fragment_shader_src)
585 {
586     GLuint v, f, p = 0;
587
588     p = glCreateProgram();
589
590     if (vertex_shader_src)
591     {
592         v = glCreateShader(GL_VERTEX_SHADER);
593         glShaderSource(v, 1, &vertex_shader_src, NULL);
594         glCompileShader(v);
595
596         // check if shader compiled
597         GLint compiled = 0;
598         glGetShaderiv(v, GL_COMPILE_STATUS, &compiled);
599
600         if (!compiled)
601         {
602             //#ifdef NV_REPORT_COMPILE_ERRORS
603             char temp[256] = "";
604             glGetShaderInfoLog(v, 256, NULL, temp);
605             printf("Vtx Compile failed:\n%s\n", temp);
606             //#endif
607             glDeleteShader(v);
608             return 0;
609         }
610         else
611         {
612             glAttachShader(p,v);
613         }
614     }
615
616     if (fragment_shader_src)
617     {
618         f = glCreateShader(GL_FRAGMENT_SHADER);
619         glShaderSource(f, 1, &fragment_shader_src, NULL);
620         glCompileShader(f);
621
622         // check if shader compiled
623         GLint compiled = 0;
624         glGetShaderiv(f, GL_COMPILE_STATUS, &compiled);
625
626         if (!compiled)
627         {
628             //#ifdef NV_REPORT_COMPILE_ERRORS
629             char temp[256] = "";
630             glGetShaderInfoLog(f, 256, NULL, temp);
631             printf("frag Compile failed:\n%s\n", temp);
632             //#endif
633             glDeleteShader(f);
634             return 0;
635         }
636         else
637         {
638             glAttachShader(p,f);
639         }
640     }
641
642     glLinkProgram(p);
643
644     int infologLength = 0;
645     int charsWritten  = 0;
646
647     glGetProgramiv(p, GL_INFO_LOG_LENGTH, (GLint *)&infologLength);
648
649     if (infologLength > 0)
650     {
651         char *infoLog = (char *)malloc(infologLength);
652         glGetProgramInfoLog(p, infologLength, (GLsizei *)&charsWritten, infoLog);
653         printf("Shader compilation error: %s\n", infoLog);
654         free(infoLog);
655     }
656
657     return p;
658 }
659
660 ////////////////////////////////////////////////////////////////////////////////
661 //! Allocate the "render target" of CUDA
662 ////////////////////////////////////////////////////////////////////////////////
663 #ifndef USE_TEXSUBIMAGE2D
664 void initCUDABuffers()
665 {
666     // set up vertex data parameter
667     num_texels = image_width * image_height;
668     num_values = num_texels * 4;
669     size_tex_data = sizeof(GLubyte) * num_values;
670     checkCudaErrors(cudaMalloc((void **)&cuda_dest_resource, size_tex_data));
671     //checkCudaErrors(cudaHostAlloc((void**)&cuda_dest_resource, size_tex_data, ));
672 }
673 #endif
674
675 ////////////////////////////////////////////////////////////////////////////////
676 //!
677 ////////////////////////////////////////////////////////////////////////////////
678 void initGLBuffers()
679 {
680     // create pbo
681 #ifdef USE_TEXSUBIMAGE2D
682     createPBO(&pbo_dest, &cuda_pbo_dest_resource);
683 #endif
684     // create texture that will receive the result of CUDA
685     createTextureDst(&tex_cudaResult, image_width, image_height);
686     // load shader programs
687     shDrawPot = compileGLSLprogram(NULL, glsl_drawpot_fragshader_src);
688
689 #ifndef USE_TEXSUBIMAGE2D
690     shDrawTex = compileGLSLprogram(glsl_drawtex_vertshader_src, glsl_drawtex_fragshader_src);
691 #endif
692     SDK_CHECK_ERROR_GL();
693 }
694
695 ////////////////////////////////////////////////////////////////////////////////
696 //! Run standard demo loop with or without GL verification
697 ////////////////////////////////////////////////////////////////////////////////
698 void
699 runStdProgram(int argc, char **argv)
700 {
701     // First initialize OpenGL context, so we can properly set the GL for CUDA.
702     // This is necessary in order to achieve optimal performance with OpenGL/CUDA interop.
703     if (false == initGL(&argc, argv))
704     {
705         return;
706     }
707
708     // Now initialize CUDA context (GL context has been created already)
709     initCUDA(argc, argv, true);
710
711     sdkCreateTimer(&timer);
712     sdkResetTimer(&timer);
713
714     // register callbacks
715     glutDisplayFunc(display);
716     glutKeyboardFunc(keyboard);
717     glutReshapeFunc(reshape);
718     glutTimerFunc(REFRESH_DELAY, timerEvent, 0);
719
720     // create menu
721     glutCreateMenu(mainMenu);
722     glutAddMenuEntry("Quit (esc)", '\033');
723     glutAttachMenu(GLUT_RIGHT_BUTTON);
724
725     initGLBuffers();
726 #ifndef USE_TEXSUBIMAGE2D
727     initCUDABuffers();
728 #endif
729
730     // Creating the Auto-Validation Code
731     if (ref_file)
732     {
733         g_CheckRender = new CheckBackBuffer(window_width, window_height, 4);
734         g_CheckRender->setPixelFormat(GL_RGBA);
735         g_CheckRender->setExecPath(argv[0]);
736         g_CheckRender->EnableQAReadback(true);
737     }
738
739     printf("\n"
740            "\tControls\n"
741            "\t(right click mouse button for Menu)\n"
742            "\t[esc] - Quit\n\n"
743           );
744
745     // start rendering mainloop
746     glutMainLoop();
747
748     // Normally unused return path
749     Cleanup(EXIT_SUCCESS);
750 }
751
752 ////////////////////////////////////////////////////////////////////////////////
753 //! Initialize CUDA context
754 ////////////////////////////////////////////////////////////////////////////////
755 bool
756 initCUDA(int argc, char **argv, bool bUseGL)
757 {
758     if (bUseGL)
759     {
760         findCudaGLDevice(argc, (const char **)argv);
761     }
762     else
763     {
764         findCudaDevice(argc, (const char **)argv);
765     }
766
767     return true;
768 }
769
770 ////////////////////////////////////////////////////////////////////////////////
771 //! Initialize GL
772 ////////////////////////////////////////////////////////////////////////////////
773 bool
774 initGL(int *argc, char **argv)
775 {
776     if (IsOpenGLAvailable(sSDKname))
777     {
778         fprintf(stderr, "   OpenGL device is Available\n");
779     }
780     else
781     {
782         fprintf(stderr, "   OpenGL device is NOT Available, [%s] exiting...\n", sSDKname);
783         exit(EXIT_WAIVED);
784     }
785
786     // Create GL context
787     glutInit(argc, argv);
788     glutInitDisplayMode(GLUT_RGBA | GLUT_ALPHA | GLUT_DOUBLE | GLUT_DEPTH);
789     glutInitWindowSize(window_width, window_height);
790     iGLUTWindowHandle = glutCreateWindow("CUDA OpenGL post-processing");
791
792     // initialize necessary OpenGL extensions
793     glewInit();
794
795     if (! glewIsSupported(
796             "GL_VERSION_2_0 "
797             "GL_ARB_pixel_buffer_object "
798             "GL_EXT_framebuffer_object "
799         ))
800     {
801         printf("ERROR: Support for necessary OpenGL extensions missing.");
802         fflush(stderr);
803         return false;
804     }
805
806     // default initialization
807 #ifndef USE_TEXTURE_RGBA8UI
808     glClearColor(0.5, 0.5, 0.5, 1.0);
809 #else
810     glClearColorIuiEXT(128,128,128,255);
811 #endif
812     glDisable(GL_DEPTH_TEST);
813
814     // viewport
815     glViewport(0, 0, window_width, window_height);
816
817     // projection
818     glMatrixMode(GL_PROJECTION);
819     glLoadIdentity();
820     gluPerspective(60.0, (GLfloat)window_width / (GLfloat) window_height, 0.1f, 10.0f);
821
822     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
823
824     glEnable(GL_LIGHT0);
825     float red[] = { 1.0f, 0.1f, 0.1f, 1.0f };
826     float white[] = { 1.0f, 1.0f, 1.0f, 1.0f };
827     glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, red);
828     glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, white);
829     glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 60.0f);
830
831     SDK_CHECK_ERROR_GL();
832
833     return true;
834 }