/** * Create a new pipe_screen object * Note: we're not presently subclassing pipe_screen (no llvmpipe_screen). */ struct pipe_screen * llvmpipe_create_screen(struct sw_winsys *winsys) { struct llvmpipe_screen *screen; util_cpu_detect(); #ifdef DEBUG LP_DEBUG = debug_get_flags_option("LP_DEBUG", lp_debug_flags, 0 ); #endif LP_PERF = debug_get_flags_option("LP_PERF", lp_perf_flags, 0 ); screen = CALLOC_STRUCT(llvmpipe_screen); if (!screen) return NULL; if (!lp_jit_screen_init(screen)) { FREE(screen); return NULL; } screen->winsys = winsys; screen->base.destroy = llvmpipe_destroy_screen; screen->base.get_name = llvmpipe_get_name; screen->base.get_vendor = llvmpipe_get_vendor; screen->base.get_param = llvmpipe_get_param; screen->base.get_shader_param = llvmpipe_get_shader_param; screen->base.get_paramf = llvmpipe_get_paramf; screen->base.is_format_supported = llvmpipe_is_format_supported; screen->base.context_create = llvmpipe_create_context; screen->base.flush_frontbuffer = llvmpipe_flush_frontbuffer; screen->base.fence_reference = llvmpipe_fence_reference; screen->base.fence_signalled = llvmpipe_fence_signalled; screen->base.fence_finish = llvmpipe_fence_finish; screen->base.get_timestamp = llvmpipe_get_timestamp; llvmpipe_init_screen_resource_funcs(&screen->base); screen->num_threads = util_cpu_caps.nr_cpus > 1 ? util_cpu_caps.nr_cpus : 0; #ifdef PIPE_SUBSYSTEM_EMBEDDED screen->num_threads = 0; #endif screen->num_threads = debug_get_num_option("LP_NUM_THREADS", screen->num_threads); screen->num_threads = MIN2(screen->num_threads, LP_MAX_THREADS); screen->rast = lp_rast_create(screen->num_threads); if (!screen->rast) { lp_jit_screen_cleanup(screen); FREE(screen); return NULL; } pipe_mutex_init(screen->rast_mutex); util_format_s3tc_init(); return &screen->base; }
void lp_build_init(void) { #ifdef DEBUG gallivm_debug = debug_get_option_gallivm_debug(); #endif lp_set_target_options(); LLVMInitializeNativeTarget(); LLVMLinkInJIT(); if (!lp_build_module) lp_build_module = LLVMModuleCreateWithName("gallivm"); if (!lp_build_provider) lp_build_provider = LLVMCreateModuleProviderForExistingModule(lp_build_module); if (!lp_build_engine) { enum LLVM_CodeGenOpt_Level optlevel; char *error = NULL; if (gallivm_debug & GALLIVM_DEBUG_NO_OPT) { optlevel = None; } else { optlevel = Default; } if (LLVMCreateJITCompiler(&lp_build_engine, lp_build_provider, (unsigned)optlevel, &error)) { _debug_printf("%s\n", error); LLVMDisposeMessage(error); assert(0); } #if defined(DEBUG) || defined(PROFILE) lp_register_oprofile_jit_event_listener(lp_build_engine); #endif } if (!lp_build_target) lp_build_target = LLVMGetExecutionEngineTargetData(lp_build_engine); if (!lp_build_pass) { lp_build_pass = LLVMCreateFunctionPassManager(lp_build_provider); LLVMAddTargetData(lp_build_target, lp_build_pass); if ((gallivm_debug & GALLIVM_DEBUG_NO_OPT) == 0) { /* These are the passes currently listed in llvm-c/Transforms/Scalar.h, * but there are more on SVN. */ /* TODO: Add more passes */ LLVMAddCFGSimplificationPass(lp_build_pass); LLVMAddPromoteMemoryToRegisterPass(lp_build_pass); LLVMAddConstantPropagationPass(lp_build_pass); if(util_cpu_caps.has_sse4_1) { /* FIXME: There is a bug in this pass, whereby the combination of fptosi * and sitofp (necessary for trunc/floor/ceil/round implementation) * somehow becomes invalid code. */ LLVMAddInstructionCombiningPass(lp_build_pass); } LLVMAddGVNPass(lp_build_pass); } else { /* We need at least this pass to prevent the backends to fail in * unexpected ways. */ LLVMAddPromoteMemoryToRegisterPass(lp_build_pass); } } util_cpu_detect(); #if 0 /* For simulating less capable machines */ util_cpu_caps.has_sse3 = 0; util_cpu_caps.has_ssse3 = 0; util_cpu_caps.has_sse4_1 = 0; #endif }