1 #include <iostream>
2 #include <sstream>
3 #include "bstm_ocl_render_tableau.h"
4 //:
5 // \file
6 #include "vpgl/vpgl_perspective_camera.h"
7 #include "vgui/vgui_modifier.h"
8 #include "vgui/vgui_utils.h"
9 #ifdef _MSC_VER
10 #  include "vcl_msvc_warnings.h"
11 #endif
12 
13 #include <bocl/bocl_device.h>
14 #include <bocl/bocl_kernel.h>
15 
16 #include <boxm2/view/boxm2_view_utils.h>
17 
18 #include <brdb/brdb_value.h>
19 #include <brdb/brdb_selection.h>
20 
21 #include <bprb/bprb_batch_process_manager.h>
22 #include <bprb/bprb_parameters.h>
23 #include <bprb/bprb_macros.h>
24 #include <bprb/bprb_func_process.h>
25 
26 //: Constructor
bstm_ocl_render_tableau()27 bstm_ocl_render_tableau::bstm_ocl_render_tableau()
28 {
29   pbuffer_=0;
30   ni_=640;
31   nj_=480;
32   DECLARE_FUNC_CONS(bstm_ocl_render_gl_expected_image_process);
33   DECLARE_FUNC_CONS(bstm_ocl_render_gl_expected_color_process);
34   REG_PROCESS_FUNC_CONS(bprb_func_process, bprb_batch_process_manager, bstm_ocl_render_gl_expected_image_process, "bstmOclRenderGlExpectedImageProcess");
35   REG_PROCESS_FUNC_CONS(bprb_func_process, bprb_batch_process_manager, bstm_ocl_render_gl_expected_color_process, "bstmOclRenderGlExpectedColorProcess");
36 
37   REGISTER_DATATYPE(bstm_opencl_cache_sptr);
38   REGISTER_DATATYPE(bstm_scene_sptr);
39   REGISTER_DATATYPE(bocl_mem_sptr);
40   REGISTER_DATATYPE(float);
41 }
42 
43 //: initialize tableau properties
init(bocl_device_sptr device,bstm_opencl_cache_sptr opencl_cache,bstm_scene_sptr scene,unsigned ni,unsigned nj,vpgl_perspective_camera<double> * cam,vgui_slider_tableau_sptr slider)44 bool bstm_ocl_render_tableau::init(bocl_device_sptr device,
45                                     bstm_opencl_cache_sptr opencl_cache,
46                                     bstm_scene_sptr scene,
47                                     unsigned ni,
48                                     unsigned nj,
49                                     vpgl_perspective_camera<double> * cam,vgui_slider_tableau_sptr slider)
50 {
51     //set image dimensions, camera and scene
52     ni_ = ni;
53     nj_ = nj;
54 
55 
56     cam_   = (*cam);
57     default_cam_ = (*cam);
58 
59     default_stare_point_.set(scene->bounding_box().centroid().x(),
60                              scene->bounding_box().centroid().y(),
61                              scene->bounding_box().min_z());
62     stare_point_=default_stare_point_;
63     scale_ =scene->bounding_box().height();
64     //create the scene
65     scene_ = scene;
66     opencl_cache_=opencl_cache;
67     device_=device;
68     do_init_ocl=true;
69     render_trajectory_ = true;
70     render_label_ = false;
71     vgl_box_3d<double> bb= scene_->bounding_box();
72     bb.set_centroid_z(bb.centroid_z() - bb.depth()/4 );
73     trajectory_ = new boxm2_trajectory(20.0, 20, -1.0, bb, ni, nj);
74     cam_iter_ = trajectory_->begin();
75 
76     //set bb for time
77     scene->bounding_box_t(scene_min_t_,scene_max_t_);
78 
79     slider_ = slider;
80 
81     return true;
82 }
83 
84 
85 //: Handles tableau events (drawing and keys)
handle(vgui_event const & e)86 bool bstm_ocl_render_tableau::handle(vgui_event const &e)
87 {
88 
89   //toggle color - this is a hack to get color models to show as grey
90   if (e.type == vgui_KEY_PRESS) {
91     if (e.key == vgui_key('p')) {
92       //play...
93     }
94     if (e.key == vgui_key('l')) {
95       render_label_ = !render_label_;
96     }
97   }
98   else if (e.type == vgui_DRAW) //draw handler - called on post_draw()
99   {
100 
101     if (do_init_ocl) {
102       this->init_clgl();
103       do_init_ocl = false;
104     }
105     float gpu_time = this->render_frame();
106     this->setup_gl_matrices();
107     glClear(GL_COLOR_BUFFER_BIT);
108     glDisable(GL_DEPTH_TEST);
109     glRasterPos2i(0, 1);
110     vgui_utils::set_glPixelZoom(1,-1);
111     glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pbuffer_);
112     glDrawPixels(ni_, nj_, GL_RGBA, GL_UNSIGNED_BYTE, 0);
113     glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
114 
115     //calculate and write fps to status
116     std::stringstream str;
117     str<<".  rendering at ~ "<< (1000.0f / gpu_time) <<" fps ";
118     if (status_) {
119       status_->write(str.str().c_str());
120     }
121     return true;
122   }
123 
124   if (bstm_cam_tableau::handle(e))
125     return true;
126 
127 
128   return false;
129 }
130 
131 //: calls on ray manager to render frame into the pbuffer_
render_frame()132 float bstm_ocl_render_tableau::render_frame()
133 {
134     cl_int status = clEnqueueAcquireGLObjects( queue_, 1,&exp_img_->buffer(), 0, 0, 0);
135     exp_img_->zero_gpu_buffer( queue_ );
136     if (!check_val(status,CL_SUCCESS,"clEnqueueAcquireGLObjects failed. (gl_image)"+error_to_string(status)))
137         return -1.0f;
138 
139     double scaled_time = scene_min_t_ + time_ * (scene_max_t_ - scene_min_t_);
140 
141     //set up brdb_value_sptr arguments...
142     brdb_value_sptr brdb_device = new brdb_value_t<bocl_device_sptr>(device_);
143     brdb_value_sptr brdb_scene = new brdb_value_t<bstm_scene_sptr>(scene_);
144     brdb_value_sptr brdb_opencl_cache = new brdb_value_t<bstm_opencl_cache_sptr>(opencl_cache_);
145     vpgl_camera_double_sptr cam = new vpgl_perspective_camera<double>(cam_);
146     brdb_value_sptr brdb_cam = new brdb_value_t<vpgl_camera_double_sptr>(cam);
147     brdb_value_sptr brdb_ni = new brdb_value_t<unsigned>(ni_);
148     brdb_value_sptr brdb_nj = new brdb_value_t<unsigned>(nj_);
149     brdb_value_sptr exp_img = new brdb_value_t<bocl_mem_sptr>(exp_img_);
150     brdb_value_sptr exp_img_dim = new brdb_value_t<bocl_mem_sptr>(exp_img_dim_);
151     brdb_value_sptr brdb_time = new brdb_value_t<float>(scaled_time);
152     brdb_value_sptr brdb_render_label = new brdb_value_t<bool>(render_label_);
153 
154 
155     //if scene has RGB data type, use color render process
156     bool good = true;
157     if(scene_->has_data_type(bstm_data_traits<BSTM_GAUSS_RGB>::prefix()) )
158       good = bprb_batch_process_manager::instance()->init_process("bstmOclRenderGlExpectedColorProcess");
159     else
160       good = bprb_batch_process_manager::instance()->init_process("bstmOclRenderGlExpectedImageProcess");
161 
162     //set process args
163     good = good && bprb_batch_process_manager::instance()->set_input(0, brdb_device); // device
164     good = good && bprb_batch_process_manager::instance()->set_input(1, brdb_scene); //  scene
165     good = good && bprb_batch_process_manager::instance()->set_input(2, brdb_opencl_cache);
166     good = good && bprb_batch_process_manager::instance()->set_input(3, brdb_cam);// camera
167     good = good && bprb_batch_process_manager::instance()->set_input(4, brdb_ni);  // ni for rendered image
168     good = good && bprb_batch_process_manager::instance()->set_input(5, brdb_nj);   // nj for rendered image
169     good = good && bprb_batch_process_manager::instance()->set_input(6, exp_img);   // exp image ( gl buffer)
170     good = good && bprb_batch_process_manager::instance()->set_input(7, exp_img_dim);   // exp image dimensions
171     good = good && bprb_batch_process_manager::instance()->set_input(8, brdb_time);   // time
172     good = good && bprb_batch_process_manager::instance()->set_input(9, brdb_render_label);   // render_label?
173     good = good && bprb_batch_process_manager::instance()->run_process();
174 
175 
176     //grab float output from render gl process
177     unsigned int time_id = 0;
178     good = good && bprb_batch_process_manager::instance()->commit_output(0, time_id);
179     brdb_query_aptr Q = brdb_query_comp_new("id", brdb_query::EQ, time_id);
180     brdb_selection_sptr S = DATABASE->select("float_data", std::move(Q));
181     if (S->size()!=1){
182         std::cout << "in bprb_batch_process_manager::set_input_from_db(.) -"
183             << " no selections\n";
184     }
185     brdb_value_sptr value;
186     if (!S->get_value(std::string("value"), value)) {
187         std::cout << "in bprb_batch_process_manager::set_input_from_db(.) -"
188             << " didn't get value\n";
189     }
190     float time = value->val<float>();
191 
192     //release gl buffer
193     status = clEnqueueReleaseGLObjects(queue_, 1, &exp_img_->buffer(), 0, 0, 0);
194     clFinish( queue_ );
195 
196     return time;
197 }
198 
199 //: private helper method to init_clgl stuff (gpu processor)
init_clgl()200 bool bstm_ocl_render_tableau::init_clgl()
201 {
202   //get relevant blocks
203   std::cout<<"Data Path: "<<scene_->data_path()<<std::endl;
204   device_->context() = boxm2_view_utils::create_clgl_context(*(device_->device_id()));
205   opencl_cache_->set_context(device_->context());
206 
207   int status_queue=0;
208   queue_ =  clCreateCommandQueue(device_->context(),*(device_->device_id()),CL_QUEUE_PROFILING_ENABLE,&status_queue);
209 
210   // delete old buffer
211   if (pbuffer_) {
212       clReleaseMemObject(clgl_buffer_);
213       glDeleteBuffers(1, &pbuffer_);
214   }
215 
216   ////generate glBuffer, and bind to ray_mgr->image_gl_buf_
217   glGenBuffers(1, &pbuffer_);
218   glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbuffer_);
219   glBufferData(GL_PIXEL_UNPACK_BUFFER, ni_*nj_*sizeof(GLubyte)*4, 0, GL_STREAM_DRAW);
220   glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
221 
222   //create OpenCL buffer from GL PBO, and set kernel and arguments
223   int status = 0;
224   clgl_buffer_ = clCreateFromGLBuffer(device_->context(),
225                                       CL_MEM_WRITE_ONLY,
226                                       pbuffer_,
227                                       &status);
228   exp_img_ = new bocl_mem(device_->context(),  NULL, RoundUp(ni_,8)*RoundUp(nj_,8)*sizeof(GLubyte)*4, "exp image (gl) buffer");
229   exp_img_->set_gl_buffer(clgl_buffer_);
230 
231   int img_dim_buff[4];
232   img_dim_buff[0] = 0;   img_dim_buff[2] = ni_;
233   img_dim_buff[1] = 0;   img_dim_buff[3] = nj_;
234   exp_img_dim_=new bocl_mem(device_->context(), img_dim_buff, sizeof(int)*4, "image dims");
235   exp_img_dim_->create_buffer(CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR);
236   return true;
237 }
238