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