draw_llvm: fix segfaults on non-SSE2 CPUs where it is disabled (v2)

Changes in v2:
- Change function name

Currently draw_llvm refuses to create itself on non-SSE2 CPUs due to
an alleged LLVM bug.

However, this is implemented improperly, because other parts of draw
still attempt to access draw->llvm, resulting in segfaults.

Instead, put the check in debug_get_option_draw_use_llvm, check that
before calling draw_llvm_create, and then check whether draw->llvm is
non-null everywhere else.
This commit is contained in:
Luca Barbieri 2010-08-15 07:37:31 +02:00
parent c2da8e7702
commit f201217c1d
3 changed files with 32 additions and 17 deletions

View File

@ -34,6 +34,7 @@
#include "pipe/p_context.h"
#include "util/u_memory.h"
#include "util/u_math.h"
#include "util/u_cpu_detect.h"
#include "draw_context.h"
#include "draw_vs.h"
#include "draw_gs.h"
@ -41,6 +42,25 @@
#if HAVE_LLVM
#include "gallivm/lp_bld_init.h"
#include "draw_llvm.h"
static boolean
draw_get_option_use_llvm(void)
{
static boolean first = TRUE;
static boolean value;
if (first) {
first = FALSE;
value = debug_get_bool_option("DRAW_USE_LLVM", TRUE);
#ifdef PIPE_ARCH_X86
util_cpu_detect();
/* require SSE2 due to LLVM PR6960. */
if (!util_cpu_caps.has_sse2)
value = FALSE;
#endif
}
return value;
}
#endif
struct draw_context *draw_create( struct pipe_context *pipe )
@ -50,10 +70,13 @@ struct draw_context *draw_create( struct pipe_context *pipe )
goto fail;
#if HAVE_LLVM
lp_build_init();
assert(lp_build_engine);
draw->engine = lp_build_engine;
draw->llvm = draw_llvm_create(draw);
if(draw_get_option_use_llvm())
{
lp_build_init();
assert(lp_build_engine);
draw->engine = lp_build_engine;
draw->llvm = draw_llvm_create(draw);
}
#endif
if (!draw_init(draw))
@ -135,7 +158,8 @@ void draw_destroy( struct draw_context *draw )
draw_vs_destroy( draw );
draw_gs_destroy( draw );
#ifdef HAVE_LLVM
draw_llvm_destroy( draw->llvm );
if(draw->llvm)
draw_llvm_destroy( draw->llvm );
#endif
FREE( draw );
@ -659,7 +683,8 @@ draw_set_mapped_texture(struct draw_context *draw,
const void *data[DRAW_MAX_TEXTURE_LEVELS])
{
#ifdef HAVE_LLVM
draw_llvm_set_mapped_texture(draw,
if(draw->llvm)
draw_llvm_set_mapped_texture(draw,
sampler_idx,
width, height, depth, last_level,
row_stride, img_stride, data);

View File

@ -210,13 +210,6 @@ draw_llvm_create(struct draw_context *draw)
{
struct draw_llvm *llvm;
#ifdef PIPE_ARCH_X86
util_cpu_detect();
/* require SSE2 due to LLVM PR6960. */
if (!util_cpu_caps.has_sse2)
return NULL;
#endif
llvm = CALLOC_STRUCT( draw_llvm );
if (!llvm)
return NULL;

View File

@ -43,9 +43,6 @@
DEBUG_GET_ONCE_BOOL_OPTION(draw_fse, "DRAW_FSE", FALSE)
DEBUG_GET_ONCE_BOOL_OPTION(draw_no_fse, "DRAW_NO_FSE", FALSE)
#ifdef HAVE_LLVM
DEBUG_GET_ONCE_BOOL_OPTION(draw_use_llvm, "DRAW_USE_LLVM", TRUE)
#endif
/* Overall we split things into:
* - frontend -- prepare fetch_elts, draw_elts - eg vsplit
@ -140,7 +137,7 @@ boolean draw_pt_init( struct draw_context *draw )
return FALSE;
#if HAVE_LLVM
if (debug_get_option_draw_use_llvm())
if (draw->llvm)
draw->pt.middle.llvm = draw_pt_fetch_pipeline_or_emit_llvm( draw );
#endif