1 // This is brl/bseg/boxm2/ocl/pro/processes/boxm2_ocl_render_gl_view_dep_app_expected_color_process .cxx
2 //:
3 // \file
4 // \brief  A process for rendering the scene.
5 //
6 // \author Vishal Jain
7 // \date Mar 10, 2011
8 
9 #include <fstream>
10 #include <iostream>
11 #include <algorithm>
12 #include <bprb/bprb_func_process.h>
13 
14 #ifdef _MSC_VER
15 #  include "vcl_msvc_warnings.h"
16 #endif
17 #include <boxm2/ocl/boxm2_opencl_cache.h>
18 #include <boxm2/boxm2_scene.h>
19 #include <boxm2/boxm2_block.h>
20 #include <boxm2/boxm2_data_base.h>
21 #include <boxm2/ocl/boxm2_ocl_util.h>
22 //brdb stuff
23 #include <brdb/brdb_value.h>
24 #include <boxm2/boxm2_util.h>
25 //directory utility
26 #include <vcl_where_root_dir.h>
27 #include <bocl/bocl_device.h>
28 #include <bocl/bocl_kernel.h>
29 #include <boxm2/ocl/algo/boxm2_ocl_render_expected_image_function.h>
30 
31 namespace boxm2_ocl_render_gl_view_dep_app_expected_color_process_globals
32 {
33   constexpr unsigned n_inputs_ = 10;
34   constexpr unsigned n_outputs_ = 1;
35   std::size_t     lthreads[2] = {8,8};
36 
37   static std::map<std::string,std::vector<bocl_kernel*> > kernels;
38 
compile_kernel(const bocl_device_sptr & device,std::vector<bocl_kernel * > & vec_kernels,const std::string & opts)39   void compile_kernel(const bocl_device_sptr& device,std::vector<bocl_kernel*> & vec_kernels, const std::string& opts)
40   {
41     //gather all render sources... seems like a lot for rendering...
42     std::vector<std::string> src_paths;
43     std::string source_dir = boxm2_ocl_util::ocl_src_root();
44     src_paths.push_back(source_dir + "scene_info.cl");
45     src_paths.push_back(source_dir + "pixel_conversion.cl");
46     src_paths.push_back(source_dir + "bit/bit_tree_library_functions.cl");
47     src_paths.push_back(source_dir + "backproject.cl");
48     src_paths.push_back(source_dir + "statistics_library_functions.cl");
49     src_paths.push_back(source_dir + "ray_bundle_library_opt.cl");
50     src_paths.push_back(source_dir + "view_dep_app_color_helper_functions.cl");
51     src_paths.push_back(source_dir + "bit/render_view_dep_rgb.cl");
52     src_paths.push_back(source_dir + "bit/cast_ray_bit.cl");
53 
54     //set kernel options
55     //#define STEP_CELL step_cell_render(mixture_array, alpha_array, data_ptr, d, &vis, &expected_int);
56     std::string options = opts + " -D RENDER_VIEW_DEP ";
57     options += " -D DETERMINISTIC ";
58     options += " -D STEP_CELL=step_cell_render(aux_args,data_ptr,d*linfo->block_len)";
59 
60     //have kernel construct itself using the context and device
61     auto * ray_trace_kernel=new bocl_kernel();
62     ray_trace_kernel->create_kernel( &device->context(),
63                                      device->device_id(),
64                                      src_paths,
65                                      "render_bit_scene",   //kernel name
66                                      options,              //options
67                                      "boxm2 opencl render gl color"); //kernel identifier (for error checking)
68     vec_kernels.push_back(ray_trace_kernel);
69 
70     //create normalize image kernel
71     std::vector<std::string> norm_src_paths;
72     norm_src_paths.push_back(source_dir + "pixel_conversion.cl");
73     norm_src_paths.push_back(source_dir + "bit/normalize_kernels.cl");
74     auto * normalize_render_kernel=new bocl_kernel();
75     normalize_render_kernel->create_kernel( &device->context(),
76                                             device->device_id(),
77                                             norm_src_paths,
78                                             "normalize_render_kernel_rgb_gl",   //kernel name
79                                             " -D NORMALIZE_RENDER_GL ",              //options
80                                             "normalize render kernel"); //kernel identifier (for error checking)
81 
82     vec_kernels.push_back(normalize_render_kernel);
83   }
84 }
85 
boxm2_ocl_render_gl_view_dep_app_expected_color_process_cons(bprb_func_process & pro)86 bool boxm2_ocl_render_gl_view_dep_app_expected_color_process_cons(bprb_func_process& pro)
87 {
88   using namespace boxm2_ocl_render_gl_view_dep_app_expected_color_process_globals;
89 
90   //process takes 1 input
91   std::vector<std::string> input_types_(n_inputs_);
92   input_types_[0] = "bocl_device_sptr";
93   input_types_[1] = "boxm2_scene_sptr";
94   input_types_[2] = "boxm2_opencl_cache_sptr";
95   input_types_[3] = "vpgl_camera_double_sptr";
96   input_types_[4] = "unsigned";
97   input_types_[5] = "unsigned";
98   input_types_[6] = "bocl_mem_sptr"; // exp image buffer;
99   input_types_[7] = "bocl_mem_sptr"; // exp image dimensions buffer;
100   input_types_[8] = "vcl_string";  //identifier
101   input_types_[9] = "bool"; // exp image dimensions buffer;
102 
103   //default last two args
104   brdb_value_sptr idx = new brdb_value_t<std::string>("");
105   pro.set_input(8, idx);
106   brdb_value_sptr brdb_is_bw = new brdb_value_t<bool>(false);
107   pro.set_input(9, brdb_is_bw);
108 
109   //set output types
110   std::vector<std::string> output_types_(n_outputs_);
111   output_types_[0] = "float";
112 
113   return pro.set_input_types(input_types_) && pro.set_output_types(output_types_);
114 }
115 
boxm2_ocl_render_gl_view_dep_app_expected_color_process(bprb_func_process & pro)116 bool boxm2_ocl_render_gl_view_dep_app_expected_color_process (bprb_func_process& pro)
117 {
118   using namespace boxm2_ocl_render_gl_view_dep_app_expected_color_process_globals;
119   if ( pro.n_inputs() < n_inputs_ ) {
120     std::cout << pro.name() << ": The input number should be " << n_inputs_<< std::endl;
121     return false;
122   }
123   //get the inputs
124   unsigned i = 0;
125   bocl_device_sptr        device = pro.get_input<bocl_device_sptr>(i++);
126   boxm2_scene_sptr        scene = pro.get_input<boxm2_scene_sptr>(i++);
127   boxm2_opencl_cache_sptr opencl_cache = pro.get_input<boxm2_opencl_cache_sptr>(i++);
128   vpgl_camera_double_sptr cam = pro.get_input<vpgl_camera_double_sptr>(i++);
129   auto                ni = pro.get_input<unsigned>(i++);
130   auto                nj = pro.get_input<unsigned>(i++);
131   bocl_mem_sptr           exp_image = pro.get_input<bocl_mem_sptr>(i++);
132   bocl_mem_sptr           exp_img_dim = pro.get_input<bocl_mem_sptr>(i++);
133   std::string              ident = pro.get_input<std::string>(i++);
134   bool                    is_bw = pro.get_input<bool>(i++);
135 
136 
137   std::string data_type;
138   int apptypesize;
139   std::vector<std::string> valid_types;
140   valid_types.push_back(boxm2_data_traits<BOXM2_GAUSS_RGB_VIEW>::prefix());
141   valid_types.push_back(boxm2_data_traits<BOXM2_GAUSS_RGB_VIEW_COMPACT>::prefix());
142   if ( !boxm2_util::verify_appearance( *scene, valid_types, data_type, apptypesize ) ) {
143     std::cout<<"boxm2_ocl_render_gl_view_dep_app_expected_image_process ERROR: scene doesn't have BOXM2_MOG6_VIEW data type"<<std::endl;
144     return false;
145   }
146   std::string options = boxm2_ocl_util::mog_options(data_type);
147 
148   std::cout << options << " " << data_type << " " << apptypesize << std::endl;
149   // create a command queue.
150   int status=0;
151   cl_command_queue queue = clCreateCommandQueue(device->context(),*(device->device_id()),
152                                                 CL_QUEUE_PROFILING_ENABLE,&status);
153   if (status!=0) return false;
154   std::string identifier=device->device_identifier()+options;
155 
156   // compile the kernel
157   if (kernels.find(identifier)==kernels.end())
158   {
159     std::cout<<"===========Compiling kernels==========="<<std::endl;
160     std::vector<bocl_kernel*> ks;
161     compile_kernel(device,ks,options);
162     kernels[identifier]=ks;
163   }
164 
165   unsigned cl_ni=RoundUp(ni,lthreads[0]);
166   unsigned cl_nj=RoundUp(nj,lthreads[1]);
167 
168   //create float4 image here
169   auto* buff = new float[4*cl_ni*cl_nj];
170   std::fill(buff, buff + 4*cl_ni*cl_nj, 0.0f);
171   bocl_mem_sptr exp_color = new bocl_mem(device->context(), buff, 4*cl_ni*cl_nj*sizeof(float), "color im buffer (float4) buffer");
172   exp_color->create_buffer(CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR);
173 
174   // visibility image
175   auto* vis_buff = new float[cl_ni*cl_nj];
176   std::fill(vis_buff, vis_buff + cl_ni*cl_nj, 1.0f);
177   bocl_mem_sptr vis_image = new bocl_mem(device->context(), vis_buff, cl_ni*cl_nj*sizeof(float), "vis image (single float) buffer");
178   vis_image->create_buffer(CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR);
179 
180   auto* max_omega_buff = new float[cl_ni*cl_nj];
181   std::fill(max_omega_buff, max_omega_buff + cl_ni*cl_nj, 0.0f);
182   bocl_mem_sptr max_omega_image = new bocl_mem(device->context(), max_omega_buff, cl_ni*cl_nj*sizeof(float), "max_omega_image image (single float) buffer");
183   max_omega_image->create_buffer(CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR);
184 
185   // run expected image function
186   float tnearfar[2] = { 0.0f, 1000000} ;
187   bocl_mem_sptr tnearfar_mem_ptr = opencl_cache->alloc_mem(2*sizeof(float), tnearfar, "tnearfar  buffer");
188   tnearfar_mem_ptr->create_buffer(CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR);
189   float time = render_expected_image(scene, device, opencl_cache, queue,
190                                      cam, exp_color, vis_image, max_omega_image, exp_img_dim,
191                                      data_type, kernels[identifier][0], lthreads, cl_ni, cl_nj,apptypesize,tnearfar_mem_ptr);
192 
193   // normalize and write image to GL buffer
194   {
195     cl_bool isbw[1] = { is_bw };
196     bocl_mem_sptr is_bw_sptr = new bocl_mem(device->context(), isbw, sizeof(cl_bool), "is bw hack buffer");
197     is_bw_sptr->create_buffer(CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR);
198 
199     std::size_t gThreads[] = {cl_ni,cl_nj};
200     bocl_kernel* norm_rgb_gl = kernels[identifier][1];
201     norm_rgb_gl->set_arg( exp_color.ptr() );
202     norm_rgb_gl->set_arg( vis_image.ptr() );
203     norm_rgb_gl->set_arg( exp_img_dim.ptr());
204     norm_rgb_gl->set_arg( exp_image.ptr() );
205     norm_rgb_gl->set_arg( is_bw_sptr.ptr() ) ;
206     norm_rgb_gl->execute( queue, 2, lthreads, gThreads);
207     clFinish(queue);
208     norm_rgb_gl->clear_args();
209     time += norm_rgb_gl->exec_time();
210   }
211 
212   //delete visibilty image
213   delete[] vis_buff;
214   delete[] buff;
215 
216   // read out expected image
217   clReleaseCommandQueue(queue);
218 
219   // store scene smart pointer
220   int argIdx = 0;
221   pro.set_output_val<float>(argIdx, time);
222   return true;
223 }
224