/// Returns a std::string of stats, ended by a newline. /// Requires the current connector name as an argument. std::string Socket::Connection::getStats(std::string C){ return "S " + getHost() + " " + C + " " + uint2string(Util::epoch() - conntime) + " " + uint2string(up) + " " + uint2string(down) + "\n"; }
weak_ptr<opencl::kernel_object> oclraster_program::build_kernel(const kernel_spec& spec) { kernel_spec* new_spec = new kernel_spec(spec); compiled_kernels.emplace_back(new_spec); // if any device doesn't support doubles and the user tries to use a double image format, // fail immediately and return a null kernel (better here than crashing during compilation) if(!ocl->is_full_double_support()) { for(const auto& img_type : spec.image_spec) { if(img_type.data_type == IMAGE_TYPE::FLOAT_64) { oclr_error("can't use a double/FLOAT_64 image format when one or more opencl devices do not support doubles!"); kernels.emplace(new_spec, opencl::null_kernel_object); return opencl::null_kernel_object; } } } // build image defines string (image functions for each image type are #ifdef'ed) string image_defines = ""; set<string> img_types; for(const auto& img_type : spec.image_spec) { if(img_type.native) continue; img_types.insert(img_type.to_string()); } for(const auto& img_type : img_types) { image_defines += " -DOCLRASTER_IMAGE_" + core::str_to_upper(img_type); } // depth defines string framebuffer_options = ""; bool has_framebuffer_depth = false; for(size_t i = 0, img_count = images.image_names.size(); i < img_count; i++) { if(images.is_framebuffer[i] && images.image_types[i] == IMAGE_VAR_TYPE::DEPTH_IMAGE) { has_framebuffer_depth = true; break; } } if(!has_framebuffer_depth) framebuffer_options += " -DOCLRASTER_NO_DEPTH"; if(!spec.depth.depth_test) framebuffer_options += " -DOCLRASTER_NO_DEPTH_TEST"; if(spec.depth.depth_override) framebuffer_options += " -DOCLRASTER_DEPTH_OVERRIDE"; string depth_spec_str = ""; depth_spec_str += (spec.depth.depth_test ? ".depth_test" : ".no_depth_test"); depth_spec_str += "."; switch(spec.depth.depth_func) { case DEPTH_FUNCTION::NEVER: depth_spec_str += "never"; break; case DEPTH_FUNCTION::LESS: depth_spec_str += "less"; break; case DEPTH_FUNCTION::EQUAL: depth_spec_str += "equal"; break; case DEPTH_FUNCTION::LESS_OR_EQUAL: depth_spec_str += "lequal"; break; case DEPTH_FUNCTION::GREATER: depth_spec_str += "greater"; break; case DEPTH_FUNCTION::NOT_EQUAL: depth_spec_str += "nequal"; break; case DEPTH_FUNCTION::GREATER_OR_EQUAL: depth_spec_str += "gequal"; break; case DEPTH_FUNCTION::ALWAYS: depth_spec_str += "always"; break; case DEPTH_FUNCTION::CUSTOM: depth_spec_str += "custom"; break; } depth_spec_str += (spec.depth.depth_override ? ".depth_override" : ""); // finally: call the specialized processing function of inheriting classes/programs // note: this should inject the user code into their respective code templates const string program_code { specialized_processing(processed_code, *new_spec) }; // const string proj_spec_str = (spec.projection == PROJECTION::PERSPECTIVE ? "perspective" : "orthographic"); string img_spec_str = ""; for(const auto& type : spec.image_spec) { img_spec_str += "." + type.to_string(); } stringstream id_stream; id_stream << dec << this_thread::get_id(); const string identifier = ("USER_PROGRAM."+kernel_function_name+"."+entry_function+"."+ proj_spec_str+depth_spec_str+img_spec_str+"."+ ull2string(SDL_GetPerformanceCounter())+"."+id_stream.str()); weak_ptr<opencl::kernel_object> kernel = ocl->add_kernel_src(identifier, program_code, kernel_function_name, " -DBIN_SIZE="+uint2string(OCLRASTER_BIN_SIZE)+ " -DBATCH_SIZE="+uint2string(OCLRASTER_BATCH_SIZE)+ " -DOCLRASTER_PROJECTION_"+(spec.projection == PROJECTION::PERSPECTIVE ? "PERSPECTIVE" : "ORTHOGRAPHIC")+ image_defines+ framebuffer_options+ " "+build_options); //oclr_msg("%s:\n%s\n", identifier, program_code); #if defined(OCLRASTER_DEBUG) if(kernel.use_count() == 0) { oclr_debug("kernel source: %s", program_code); } #endif kernels.emplace(new_spec, kernel); return kernel; }
void transform_stage::transform(draw_state& state) { // oclraster_program::kernel_spec spec; if(!create_kernel_spec(state, *state.transform_prog, spec)) { return; } // -> 1D kernel, with max #work-items per work-group ocl->use_kernel(state.transform_prog->get_kernel(spec)); unsigned int argc = 0; if(!bind_user_buffers(state, *state.transform_prog, argc)) return; // internal buffer / kernel parameters ocl->set_kernel_argument(argc++, state.transformed_vertices_buffer); ocl->set_kernel_argument(argc++, state.camera_buffer); ocl->set_kernel_argument(argc++, state.vertex_count); ocl->set_kernel_argument(argc++, state.instance_count); ocl->set_kernel_range(ocl->compute_kernel_ranges(state.vertex_count * state.instance_count)); ocl->run_kernel(); // #if 0 static bool dumped = false; if(!dumped) { dumped = true; ocl->dump_buffer(state.transformed_vertices_buffer, oclraster::data_path("dump/tvbuffer.bin")); // unsigned int buffer_num = 0; const auto find_and_dump_buffer = [&](const string& name) -> void { const auto buffer = state.user_buffers.find(name); ocl->dump_buffer((opencl::buffer_object*)&buffer->second, oclraster::data_path("dump/tuser_"+uint2string(buffer_num)+".hex")); buffer_num++; }; for(const auto& user_struct : state.transform_prog->get_structs()) { if(user_struct->type != oclraster_program::STRUCT_TYPE::BUFFERS) { find_and_dump_buffer(user_struct->object_name); } else { for(size_t i = 0, buffer_entries = user_struct->variables.size(); i < buffer_entries; i++) { find_and_dump_buffer(user_struct->variables[i]); } } } } #endif }