summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Pouzenc <ludovic@pouzenc.fr>2013-03-10 21:36:01 +0000
committerLudovic Pouzenc <ludovic@pouzenc.fr>2013-03-10 21:36:01 +0000
commitbec8869883710493ddf2fd88ae79c3befe41dc9b (patch)
tree44334361f538d0ed285a88bda5e1cc09e1bc4878
parent149388bfe5069aaefe7bbcd43cca59703e42531d (diff)
download2013-gpudataviz-bec8869883710493ddf2fd88ae79c3befe41dc9b.tar.gz
2013-gpudataviz-bec8869883710493ddf2fd88ae79c3befe41dc9b.tar.bz2
2013-gpudataviz-bec8869883710493ddf2fd88ae79c3befe41dc9b.zip
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...) git-svn-id: file:///var/svn/2013-gpudataviz/trunk@22 371a6b4a-a258-45f8-9dcc-bdd82ce0ac9d
-rwxr-xr-xsrc/compil.sh6
-rw-r--r--src/gpudataviz.cpp61
-rw-r--r--src/my_gtk_gl_scene_widget.hpp4
-rw-r--r--src/opencl_mesh_kit.cpp44
-rw-r--r--src/opencl_mesh_kit.hpp10
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<Gdk::GL::Config> &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<Gdk::GL::Window> 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<MyGTK
public:
MyGTKGLSceneWidget(Glib::RefPtr<Gdk::GL::Config> &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<MyGTK
private:
OpenCLMeshKit clKit;
struct camera_params { float rx; float ry; float tz; } camera;
+ float time;
+ bool need_recompute;
};
#endif /*MY_GTK_GL_SCENE_H*/
diff --git a/src/opencl_mesh_kit.cpp b/src/opencl_mesh_kit.cpp
index abdf04d..8ad18b3 100644
--- a/src/opencl_mesh_kit.cpp
+++ b/src/opencl_mesh_kit.cpp
@@ -157,13 +157,13 @@ cl_int OpenCLMeshKit::compileKernels(std::list<std::string> 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<std::string,cl_kernel>::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);
}