From bec8869883710493ddf2fd88ae79c3befe41dc9b Mon Sep 17 00:00:00 2001 From: Ludovic Pouzenc Date: Sun, 10 Mar 2013 21:36:01 +0000 Subject: Debut implementation du refresh automatique (style game loop) si demandé (mouse1 down) compil.sh : -lrt est nécessaire pour avoir des infos précises sur le timing (kernel exec time...) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: file:///var/svn/2013-gpudataviz/trunk@22 371a6b4a-a258-45f8-9dcc-bdd82ce0ac9d --- src/compil.sh | 6 ++--- src/gpudataviz.cpp | 61 ++++++++++++++++++++++++++++++++---------- src/my_gtk_gl_scene_widget.hpp | 4 +++ src/opencl_mesh_kit.cpp | 44 ++++++++++++++++-------------- src/opencl_mesh_kit.hpp | 10 +++---- 5 files changed, 83 insertions(+), 42 deletions(-) diff --git a/src/compil.sh b/src/compil.sh index b0a1bad..d913674 100755 --- a/src/compil.sh +++ b/src/compil.sh @@ -10,7 +10,7 @@ AMDAPP_PATH="/opt/AMDAPP" DEFINES="" INCLUDES="" -LIBS="" +LIBS="-lrt" # OpenCL if [ -d "$AMDAPP_PATH/include" ] @@ -32,8 +32,8 @@ fi #set +x function build_cxx() { - echo "$PS4$CXX \$DEFINES \$INCLUDES -o $BUILD_PATH/$1 -c $2" - $CXX $DEFINES $INCLUDES -o $BUILD_PATH/$1 -c $2 + echo "$PS4$CXX \$DEFINES \$INCLUDES -o $BUILD_PATH/$1 -c $2 \$LIBS" + $CXX $DEFINES $INCLUDES -o $BUILD_PATH/$1 -c $2 $LIBS } function link_cxx() { diff --git a/src/gpudataviz.cpp b/src/gpudataviz.cpp index 91ef5fa..a9ddfae 100644 --- a/src/gpudataviz.cpp +++ b/src/gpudataviz.cpp @@ -42,7 +42,22 @@ int main(int argc, char* argv[]) { GTKWinMain gtkwinmain(glScene); // Run the app - gtkKit.run(gtkwinmain); + //gtkKit.run(gtkwinmain); + + //FIXME : handle main loop quit, maybe do that logic inside MyGTKGLSceneWidget, find bug with multiple mouse button release + while ( true ) { + while ( Gtk::Main::events_pending() ) { + Gtk::Main::iteration(false); + } + if ( glScene.continuous_play ) { + glScene.step(); + glScene.queue_draw(); + std::cout << "." << std::flush; + } else { + Gtk::Main::iteration(true); + std::cout << "!" << std::flush; + } + } return 0; } @@ -56,7 +71,8 @@ MyGTKGLSceneWidget::MyGTKGLSceneWidget(Glib::RefPtr &glconfig) | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK \ | Gdk::SCROLL_MASK; set_events(mask); // The containing window should have those attributes too - this->camera.rx = -64.0f; this->camera.ry = -16.0f; this->camera.tz = -1.0f; + this->camera.rx = -64.0f; this->camera.ry = -16.0f; this->camera.tz = -2.0f; + need_recompute=false; time=0.0f; continuous_play=false; } MyGTKGLSceneWidget::~MyGTKGLSceneWidget() { } @@ -118,18 +134,20 @@ void MyGTKGLSceneWidget::on_realize() { /* calculate uv coordinates of the mesh point [0.0;1.0] */ float u = nx / (float) width; float v = ny / (float) height; - /* calculate centered coordinates [-1.0;1.0] */ + /* calculate centered normalized coordinates [-1.0;1.0] */ float x = u*2.0-1.0; float y = v*2.0-1.0; - /* We only use normalized quaterinons here */ - float w = 1.0; /* Calculate the desirated value of the mesh point */ float freq = 8.0 * 3.14; float amp = 1.0 / 10.0; /* 0.1 does NOT works ! WTF !!! */ float speed = 1.0; float dist = sqrt(x*x+y*y); - float z = amp * sin( freq * dist - speed * time ) / dist ; - + float z; + //for(int i = 0; i < 40000; i++){ + z = amp * sin( freq * dist - speed * time ) / dist ; + //} + /* We only use normalized quaterinons here */ + float w = 1.0; /* Write output vertex (centered) */ pos[ny*width+nx] = (float4)(x, y, z, w); } @@ -180,6 +198,16 @@ bool MyGTKGLSceneWidget::on_expose_event(GdkEventExpose* event) { Glib::RefPtr glwindow = get_gl_window(); + // *** OpenCL BEGIN + if (this->need_recompute) { + this->need_recompute=false; +// std::cout << "execKernel(\"water1\", " << this->time << ");" << std::endl; + int res = this->clKit.execKernel("water1", this->time); + if ( res !=0 ) std::cerr << "execKernel() has returned " << res << std::endl; +// std::cout << " -> " << res << std::endl; + } + // *** OpenCL END + // *** OpenGL BEGIN *** if (!glwindow->gl_begin(get_gl_context())) { std::cerr << "Oups : glwindow->gl_begin(get_gl_context())" << std::endl; @@ -212,6 +240,11 @@ bool MyGTKGLSceneWidget::on_expose_event(GdkEventExpose* event) { return true; } +void MyGTKGLSceneWidget::step() { + this->time += 0.01f; + this->need_recompute = true; +} + bool MyGTKGLSceneWidget::on_motion_notify_event (GdkEventMotion *event) { return do_mouse_logic(event->type, event->state, event->x, event->y); } @@ -283,7 +316,7 @@ bool MyGTKGLSceneWidget::do_mouse_logic(GdkEventType type, guint state, guint x, */ static GdkEventType prev_type = GDK_NOTHING; // Static variable to hold previous mouse button event static guint drag_x=0, drag_y=0; // Static for DRAGING displacement calculus - static float t=0.0f; // XXX Just for playing with time + bool recompute=false; // Setting it to true will call OpenCL on next redraw bool redraw=false; // Setting it to true will queue a redraw to the widget (invalidate) // For event filter debug (display all events) @@ -330,14 +363,13 @@ bool MyGTKGLSceneWidget::do_mouse_logic(GdkEventType type, guint state, guint x, redraw=true; }*/ - MOUSE_DRAGING(GDK_BUTTON1_MASK) { - t+=0.1f; - std::cout << "execKernel(\"water1\", " << t << ");" << std::endl; - int res = this->clKit.execKernel("water1", t); - std::cout << " -> " << res << std::endl; - redraw=true; + MOUSE_DRAG_START(GDK_BUTTON1_MASK) { + this->continuous_play=true; } + MOUSE_DRAG_END(GDK_BUTTON1_MASK) { + this->continuous_play=false; + } // Demo filters MOUSE_CLIC(GDK_BUTTON1_MASK, GDK_SHIFT_MASK, GDK_CONTROL_MASK) { @@ -356,5 +388,6 @@ bool MyGTKGLSceneWidget::do_mouse_logic(GdkEventType type, guint state, guint x, } if ( redraw ) queue_draw(); + if ( recompute ) this->need_recompute=true; return true; } diff --git a/src/my_gtk_gl_scene_widget.hpp b/src/my_gtk_gl_scene_widget.hpp index 2c3cc89..6196ae8 100644 --- a/src/my_gtk_gl_scene_widget.hpp +++ b/src/my_gtk_gl_scene_widget.hpp @@ -14,6 +14,8 @@ class MyGTKGLSceneWidget : public Gtk::DrawingArea, public Gtk::GL::Widget &glconfig); virtual ~MyGTKGLSceneWidget(); + void step(); + bool continuous_play; protected: virtual void on_size_request(Gtk::Requisition* requisition); @@ -29,6 +31,8 @@ class MyGTKGLSceneWidget : public Gtk::DrawingArea, public Gtk::GL::Widget names, const char so cl_int OpenCLMeshKit::execKernel(std::string kernelName, float karg_time) { - cl_int res; + //cl_int res; cl_event eventND[1]; size_t globalWorkSize[2], localWorkSize[2]; cl_kernel kernel; - struct timespec before, after; + //struct timespec before, after; - clock_gettime(CLOCK_MONOTONIC_RAW, &before); + //clock_gettime(CLOCK_MONOTONIC_RAW, &before); std::map::iterator ii=this->kernels.find(kernelName); if ( ii==this->kernels.end() ) { @@ -180,32 +180,36 @@ cl_int OpenCLMeshKit::execKernel(std::string kernelName, float karg_time) { localWorkSize[0]=this->groupSize; localWorkSize[1]=1; - res=clEnqueueAcquireGLObjects(this->cl_cq, 1, &(this->cl_vbo), 0, 0, NULL); + CL_RETURN_VAL_IF_FAIL(1, + clEnqueueAcquireGLObjects(this->cl_cq, 1, &(this->cl_vbo), 0, 0, NULL) + ); - res=clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&(this->cl_vbo)); // float4 *pos - res=clSetKernelArg(kernel, 1, sizeof(cl_uint), (void *)&(this->meshWidth)); - res=clSetKernelArg(kernel, 2, sizeof(cl_uint), (void *)&(this->meshHeight)); - res=clSetKernelArg(kernel, 3, sizeof(float), (void *)&karg_time); + clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&(this->cl_vbo)); // float4 *pos + clSetKernelArg(kernel, 1, sizeof(cl_uint), (void *)&(this->meshWidth)); + clSetKernelArg(kernel, 2, sizeof(cl_uint), (void *)&(this->meshHeight)); + clSetKernelArg(kernel, 3, sizeof(float), (void *)&karg_time); // Execute kernel on given device - res=clEnqueueNDRangeKernel(this->cl_cq, kernel, 2, NULL, globalWorkSize, localWorkSize, 0, NULL, eventND); - if ( res != CL_SUCCESS ) { - std::cerr << "clEnqueueNDRangeKernel() failed" << std::endl; - return 1; - } + CL_RETURN_VAL_IF_FAIL(2, + clEnqueueNDRangeKernel(this->cl_cq, kernel, 2, NULL, globalWorkSize, localWorkSize, 0, NULL, eventND) + ); //TODO : return values checking - res=clFlush(this->cl_cq); + CL_RETURN_VAL_IF_FAIL(3, + clFlush(this->cl_cq) + ); // (CPU) Wait until GPU kernel execution end - res=clWaitForEvents(1,eventND); //XXX: SimpleGL utilise une attente active, pourquoi ? - res=clReleaseEvent(eventND[0]); - res=clEnqueueReleaseGLObjects(this->cl_cq, 1, &(this->cl_vbo), 0, 0, 0); - res=clFinish(this->cl_cq); + CL_RETURN_VAL_IF_FAIL(4, clWaitForEvents(1,eventND) ); //XXX: SimpleGL utilise une attente active, pourquoi ? + CL_RETURN_VAL_IF_FAIL(5, clReleaseEvent(eventND[0]) ); + CL_RETURN_VAL_IF_FAIL(6, + clEnqueueReleaseGLObjects(this->cl_cq, 1, &(this->cl_vbo), 0, 0, 0) + ); + CL_RETURN_VAL_IF_FAIL(7, clFinish(this->cl_cq) ); - clock_gettime(CLOCK_MONOTONIC_RAW, &after); + //clock_gettime(CLOCK_MONOTONIC_RAW, &after); //TODO : remove this debug hint - std::cout << "execTime : " << after.tv_nsec - before.tv_nsec << std::cout; + //std::cout << "kernel exec time : " << after.tv_nsec - before.tv_nsec << std::endl; return CL_SUCCESS; } diff --git a/src/opencl_mesh_kit.hpp b/src/opencl_mesh_kit.hpp index ee6bfa5..ac3cf46 100644 --- a/src/opencl_mesh_kit.hpp +++ b/src/opencl_mesh_kit.hpp @@ -56,13 +56,13 @@ const char kernel_src_zero_z[]=STRINGIFY( /* calculate uv coordinates of the mesh point [0.0;1.0] */ float u = nx / (float) width; float v = ny / (float) height; - /* calculate centered coordinates [-0.5;0.5] */ - float x = (u*2-1)/2; - float y = (v*2-1)/2; - /* We only use normalized quaterinons here */ - float w = 1.0f; + /* calculate centered normalized coordinates [-1.0;1.0] */ + float x = u*2.0-1.0; + float y = v*2.0-1.0; /* Calculate the desirated value of the mesh point */ float z = 0.0f; + /* We only use normalized quaterinons here */ + float w = 1.0f; /* Write output vertex (centered) */ pos[ny*width+nx] = (float4)(x, y, z, w); } -- cgit v1.2.3