X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fllvmpipe%2Flp_screen.c;h=1e65a91fc67e35ba2a60db3648ebaa98c7d4ea14;hb=4418a493c2466e734e1ca5ace51535d1dbcf8a46;hp=5f50446f8463c469c3b1af02e7c905fb28aa2c88;hpb=e121a73d629856240a9676a4f0dff832d95c90c3;p=mesa.git diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c index 5f50446f846..1e65a91fc67 100644 --- a/src/gallium/drivers/llvmpipe/lp_screen.c +++ b/src/gallium/drivers/llvmpipe/lp_screen.c @@ -34,6 +34,7 @@ #include "pipe/p_defines.h" #include "pipe/p_screen.h" +#include "gallivm/lp_bld_limits.h" #include "lp_texture.h" #include "lp_fence.h" #include "lp_jit.h" @@ -42,6 +43,7 @@ #include "lp_debug.h" #include "lp_public.h" #include "lp_limits.h" +#include "lp_rast.h" #include "state_tracker/sw_winsys.h" @@ -49,20 +51,19 @@ int LP_DEBUG = 0; static const struct debug_named_value lp_debug_flags[] = { - { "pipe", DEBUG_PIPE }, - { "tgsi", DEBUG_TGSI }, - { "tex", DEBUG_TEX }, - { "asm", DEBUG_ASM }, - { "setup", DEBUG_SETUP }, - { "rast", DEBUG_RAST }, - { "query", DEBUG_QUERY }, - { "screen", DEBUG_SCREEN }, - { "jit", DEBUG_JIT }, - { "show_tiles", DEBUG_SHOW_TILES }, - { "show_subtiles", DEBUG_SHOW_SUBTILES }, - { "counters", DEBUG_COUNTERS }, - { "nopt", DEBUG_NO_LLVM_OPT }, - {NULL, 0} + { "pipe", DEBUG_PIPE, NULL }, + { "tgsi", DEBUG_TGSI, NULL }, + { "tex", DEBUG_TEX, NULL }, + { "setup", DEBUG_SETUP, NULL }, + { "rast", DEBUG_RAST, NULL }, + { "query", DEBUG_QUERY, NULL }, + { "screen", DEBUG_SCREEN, NULL }, + { "show_tiles", DEBUG_SHOW_TILES, NULL }, + { "show_subtiles", DEBUG_SHOW_SUBTILES, NULL }, + { "counters", DEBUG_COUNTERS, NULL }, + { "scene", DEBUG_SCENE, NULL }, + { "fence", DEBUG_FENCE, NULL }, + DEBUG_NAMED_VALUE_END }; #endif @@ -82,13 +83,20 @@ llvmpipe_get_name(struct pipe_screen *screen) static int -llvmpipe_get_param(struct pipe_screen *screen, int param) +llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param) { switch (param) { case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: return PIPE_MAX_SAMPLERS; case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS: - return 0; + /* At this time, the draw module and llvmpipe driver only + * support vertex shader texture lookups when LLVM is enabled in + * the draw module. + */ + if (debug_get_bool_option("DRAW_USE_LLVM", TRUE)) + return PIPE_MAX_VERTEX_SAMPLERS; + else + return 0; case PIPE_CAP_MAX_COMBINED_SAMPLERS: return PIPE_MAX_SAMPLERS + PIPE_MAX_VERTEX_SAMPLERS; case PIPE_CAP_NPOT_TEXTURES: @@ -107,12 +115,16 @@ llvmpipe_get_param(struct pipe_screen *screen, int param) return PIPE_MAX_COLOR_BUFS; case PIPE_CAP_OCCLUSION_QUERY: return 1; + case PIPE_CAP_TIMER_QUERY: + return 0; case PIPE_CAP_TEXTURE_MIRROR_CLAMP: return 1; case PIPE_CAP_TEXTURE_MIRROR_REPEAT: return 1; case PIPE_CAP_TEXTURE_SHADOW_MAP: return 1; + case PIPE_CAP_TEXTURE_SWIZZLE: + return 1; case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: return LP_MAX_TEXTURE_2D_LEVELS; case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: @@ -124,7 +136,7 @@ llvmpipe_get_param(struct pipe_screen *screen, int param) case PIPE_CAP_BLEND_EQUATION_SEPARATE: return 1; case PIPE_CAP_INDEP_BLEND_ENABLE: - return 0; + return 1; case PIPE_CAP_INDEP_BLEND_FUNC: return 0; case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: @@ -133,14 +145,50 @@ llvmpipe_get_param(struct pipe_screen *screen, int param) case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: return 0; + case PIPE_CAP_MAX_VS_INSTRUCTIONS: + case PIPE_CAP_MAX_FS_INSTRUCTIONS: + case PIPE_CAP_MAX_VS_ALU_INSTRUCTIONS: + case PIPE_CAP_MAX_FS_ALU_INSTRUCTIONS: + case PIPE_CAP_MAX_VS_TEX_INSTRUCTIONS: + case PIPE_CAP_MAX_FS_TEX_INSTRUCTIONS: + case PIPE_CAP_MAX_VS_TEX_INDIRECTIONS: + case PIPE_CAP_MAX_FS_TEX_INDIRECTIONS: + /* There is no limit in number of instructions beyond available memory */ + return 32768; + case PIPE_CAP_MAX_VS_CONTROL_FLOW_DEPTH: + case PIPE_CAP_MAX_FS_CONTROL_FLOW_DEPTH: + return LP_MAX_TGSI_NESTING; + case PIPE_CAP_MAX_VS_INPUTS: + case PIPE_CAP_MAX_FS_INPUTS: + return PIPE_MAX_ATTRIBS; + case PIPE_CAP_MAX_FS_CONSTS: + case PIPE_CAP_MAX_VS_CONSTS: + /* There is no limit in number of constants beyond available memory */ + return 32768; + case PIPE_CAP_MAX_VS_TEMPS: + case PIPE_CAP_MAX_FS_TEMPS: + return LP_MAX_TGSI_TEMPS; + case PIPE_CAP_MAX_VS_ADDRS: + case PIPE_CAP_MAX_FS_ADDRS: + return LP_MAX_TGSI_ADDRS; + case PIPE_CAP_MAX_VS_PREDS: + case PIPE_CAP_MAX_FS_PREDS: + return LP_MAX_TGSI_PREDS; + case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE: + return 1; + case PIPE_CAP_GEOMETRY_SHADER4: + return 1; + case PIPE_CAP_DEPTH_CLAMP: + return 0; default: + assert(0); return 0; } } static float -llvmpipe_get_paramf(struct pipe_screen *screen, int param) +llvmpipe_get_paramf(struct pipe_screen *screen, enum pipe_cap param) { switch (param) { case PIPE_CAP_MAX_LINE_WIDTH: @@ -155,7 +203,13 @@ llvmpipe_get_paramf(struct pipe_screen *screen, int param) return 16.0; /* not actually signficant at this time */ case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: return 16.0; /* arbitrary */ + case PIPE_CAP_GUARD_BAND_LEFT: + case PIPE_CAP_GUARD_BAND_TOP: + case PIPE_CAP_GUARD_BAND_RIGHT: + case PIPE_CAP_GUARD_BAND_BOTTOM: + return 0.0; default: + assert(0); return 0; } } @@ -182,8 +236,10 @@ llvmpipe_is_format_supported( struct pipe_screen *_screen, if (!format_desc) return FALSE; - assert(target == PIPE_TEXTURE_1D || + assert(target == PIPE_BUFFER || + target == PIPE_TEXTURE_1D || target == PIPE_TEXTURE_2D || + target == PIPE_TEXTURE_RECT || target == PIPE_TEXTURE_3D || target == PIPE_TEXTURE_CUBE); @@ -253,16 +309,66 @@ llvmpipe_destroy_screen( struct pipe_screen *_screen ) struct llvmpipe_screen *screen = llvmpipe_screen(_screen); struct sw_winsys *winsys = screen->winsys; + if (screen->rast) + lp_rast_destroy(screen->rast); + lp_jit_screen_cleanup(screen); if(winsys->destroy) winsys->destroy(winsys); + pipe_mutex_destroy(screen->rast_mutex); + FREE(screen); } + +/** + * Fence reference counting. + */ +static void +llvmpipe_fence_reference(struct pipe_screen *screen, + struct pipe_fence_handle **ptr, + struct pipe_fence_handle *fence) +{ + struct lp_fence **old = (struct lp_fence **) ptr; + struct lp_fence *f = (struct lp_fence *) fence; + + lp_fence_reference(old, f); +} + + +/** + * Has the fence been executed/finished? + */ +static int +llvmpipe_fence_signalled(struct pipe_screen *screen, + struct pipe_fence_handle *fence, + unsigned flag) +{ + struct lp_fence *f = (struct lp_fence *) fence; + return lp_fence_signalled(f); +} + + +/** + * Wait for the fence to finish. + */ +static int +llvmpipe_fence_finish(struct pipe_screen *screen, + struct pipe_fence_handle *fence_handle, + unsigned flag) +{ + struct lp_fence *f = (struct lp_fence *) fence_handle; + + lp_fence_wait(f); + return 0; +} + + + /** * Create a new pipe_screen object * Note: we're not presently subclassing pipe_screen (no llvmpipe_screen). @@ -270,7 +376,16 @@ llvmpipe_destroy_screen( struct pipe_screen *_screen ) struct pipe_screen * llvmpipe_create_screen(struct sw_winsys *winsys) { - struct llvmpipe_screen *screen = CALLOC_STRUCT(llvmpipe_screen); + struct llvmpipe_screen *screen; + +#ifdef PIPE_ARCH_X86 + /* require SSE2 due to LLVM PR6960. */ + util_cpu_detect(); + if (!util_cpu_caps.has_sse2) + return NULL; +#endif + + screen = CALLOC_STRUCT(llvmpipe_screen); #ifdef DEBUG LP_DEBUG = debug_get_flags_option("LP_DEBUG", lp_debug_flags, 0 ); @@ -291,17 +406,14 @@ llvmpipe_create_screen(struct sw_winsys *winsys) 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; llvmpipe_init_screen_resource_funcs(&screen->base); - llvmpipe_init_screen_fence_funcs(&screen->base); lp_jit_screen_init(screen); -#ifdef PIPE_OS_WINDOWS - /* Multithreading not supported on windows until conditions and barriers are - * properly implemented. */ - screen->num_threads = 0; -#else #ifdef PIPE_OS_EMBEDDED screen->num_threads = 0; #else @@ -309,7 +421,14 @@ llvmpipe_create_screen(struct sw_winsys *winsys) #endif screen->num_threads = debug_get_num_option("LP_NUM_THREADS", screen->num_threads); screen->num_threads = MIN2(screen->num_threads, LP_MAX_THREADS); -#endif + + 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();