void _mesa_init_all_x86_transform_asm( void ) { _mesa_get_x86_features(); #ifdef USE_X86_ASM if ( _mesa_x86_cpu_features ) { _mesa_init_x86_transform_asm(); } #ifdef USE_MMX_ASM if ( cpu_has_mmx ) { if ( _mesa_getenv( "MESA_NO_MMX" ) == 0 ) { _mesa_debug(NULL, "MMX cpu detected.\n"); } else { _mesa_x86_cpu_features &= ~(X86_FEATURE_MMX); } } #endif #ifdef USE_3DNOW_ASM if ( cpu_has_3dnow ) { if ( _mesa_getenv( "MESA_NO_3DNOW" ) == 0 ) { _mesa_debug(NULL, "3DNow! cpu detected.\n"); _mesa_init_3dnow_transform_asm(); } else { _mesa_x86_cpu_features &= ~(X86_FEATURE_3DNOW); } } #endif #ifdef USE_SSE_ASM if ( cpu_has_xmm ) { if ( _mesa_getenv( "MESA_NO_SSE" ) == 0 ) { _mesa_debug(NULL, "SSE cpu detected.\n"); if ( _mesa_getenv( "MESA_FORCE_SSE" ) == 0 ) { _mesa_check_os_sse_support(); } if ( cpu_has_xmm ) { _mesa_init_sse_transform_asm(); } } else { _mesa_debug(NULL, "SSE cpu detected, but switched off by user.\n"); _mesa_x86_cpu_features &= ~(X86_FEATURE_XMM); } } #endif #endif }
static GLboolean st_get_s3tc_override(void) { const char *override = _mesa_getenv("force_s3tc_enable"); if (override && !strcmp(override, "true")) return GL_TRUE; return GL_FALSE; }
/** * Return mask of GLSL_x flags by examining the MESA_GLSL env var. */ static GLbitfield get_shader_flags(void) { GLbitfield flags = 0x0; const char *env = _mesa_getenv("MESA_GLSL"); if (env) { if (strstr(env, "dump")) flags |= GLSL_DUMP; if (strstr(env, "log")) flags |= GLSL_LOG; if (strstr(env, "nopvert")) flags |= GLSL_NOP_VERT; if (strstr(env, "nopfrag")) flags |= GLSL_NOP_FRAG; if (strstr(env, "nopt")) flags |= GLSL_NO_OPT; else if (strstr(env, "opt")) flags |= GLSL_OPT; if (strstr(env, "uniform")) flags |= GLSL_UNIFORMS; if (strstr(env, "useprog")) flags |= GLSL_USE_PROG; if (strstr(env, "errors")) flags |= GLSL_REPORT_ERRORS; } return flags; }
/** * Check for multisample env var override. */ int st_get_msaa(void) { const char *msaa = _mesa_getenv("__GL_FSAA_MODE"); if (msaa) return atoi(msaa); return 0; }
void _math_test_all_transform_functions( char *description ) { int psize, mtype; unsigned long benchmark_tab[4][7]; static int first_time = 1; if ( first_time ) { first_time = 0; mesa_profile = _mesa_getenv( "MESA_PROFILE" ); } #ifdef RUN_DEBUG_BENCHMARK if ( mesa_profile ) { if ( !counter_overhead ) { INIT_COUNTER(); _mesa_printf("counter overhead: %lu cycles\n\n", counter_overhead ); } _mesa_printf("transform results after hooking in %s functions:\n", description ); } #endif #ifdef RUN_DEBUG_BENCHMARK if ( mesa_profile ) { _mesa_printf("\n" ); for ( psize = 1 ; psize <= 4 ; psize++ ) { _mesa_printf(" p%d\t", psize ); } _mesa_printf("\n--------------------------------------------------------\n" ); } #endif for ( mtype = 0 ; mtype < 7 ; mtype++ ) { for ( psize = 1 ; psize <= 4 ; psize++ ) { transform_func func = _mesa_transform_tab[psize][mtypes[mtype]]; unsigned long *cycles = &(benchmark_tab[psize-1][mtype]); if ( test_transform_function( func, psize, mtype, cycles ) == 0 ) { char buf[100]; _mesa_sprintf(buf, "_mesa_transform_tab[0][%d][%s] failed test (%s)", psize, mstrings[mtype], description ); _mesa_problem( NULL, buf ); } #ifdef RUN_DEBUG_BENCHMARK if ( mesa_profile ) _mesa_printf(" %li\t", benchmark_tab[psize-1][mtype] ); #endif } #ifdef RUN_DEBUG_BENCHMARK if ( mesa_profile ) _mesa_printf(" | [%s]\n", mstrings[mtype] ); #endif } #ifdef RUN_DEBUG_BENCHMARK if ( mesa_profile ) _mesa_printf( "\n" ); #endif }
void _math_test_all_cliptest_functions( char *description ) { int np, psize; long benchmark_tab[2][4]; static int first_time = 1; if ( first_time ) { first_time = 0; mesa_profile = _mesa_getenv( "MESA_PROFILE" ); } #ifdef RUN_DEBUG_BENCHMARK if ( mesa_profile ) { if ( !counter_overhead ) { INIT_COUNTER(); printf( "counter overhead: %ld cycles\n\n", counter_overhead ); } printf( "cliptest results after hooking in %s functions:\n", description ); } #endif #ifdef RUN_DEBUG_BENCHMARK if ( mesa_profile ) { printf( "\n\t" ); for ( psize = 2 ; psize <= 4 ; psize++ ) { printf( " p%d\t", psize ); } printf( "\n--------------------------------------------------------\n\t" ); } #endif for ( np = 0 ; np < 2 ; np++ ) { for ( psize = 2 ; psize <= 4 ; psize++ ) { clip_func func = clip_tab[np][psize]; long *cycles = &(benchmark_tab[np][psize-1]); if ( test_cliptest_function( func, np, psize, cycles ) == 0 ) { char buf[100]; sprintf( buf, "%s[%d] failed test (%s)", cnames[np], psize, description ); _mesa_problem( NULL, "%s", buf ); } #ifdef RUN_DEBUG_BENCHMARK if ( mesa_profile ) printf( " %li\t", benchmark_tab[np][psize-1] ); #endif } #ifdef RUN_DEBUG_BENCHMARK if ( mesa_profile ) printf( " | [%s]\n\t", cstrings[np] ); #endif } #ifdef RUN_DEBUG_BENCHMARK if ( mesa_profile ) printf( "\n" ); #endif }
/** * \brief Apply the \c MESA_EXTENSION_OVERRIDE environment variable. * * \c MESA_EXTENSION_OVERRIDE is a space-separated list of extensions to * enable or disable. The list is processed thus: * - Enable recognized extension names that are prefixed with '+'. * - Disable recognized extension names that are prefixed with '-'. * - Enable recognized extension names that are not prefixed. * - Collect unrecognized extension names in a new string. * * \return Space-separated list of unrecognized extension names (which must * be freed). Does not return \c NULL. */ static char * get_extension_override( struct gl_context *ctx ) { const char *env_const = _mesa_getenv("MESA_EXTENSION_OVERRIDE"); char *env; char *ext; char *extra_exts; int len; if (env_const == NULL) { /* Return the empty string rather than NULL. This simplifies the logic * of client functions. */ return calloc(4, sizeof(char)); } /* extra_exts: List of unrecognized extensions. */ extra_exts = calloc(ALIGN(strlen(env_const) + 2, 4), sizeof(char)); /* Copy env_const because strtok() is destructive. */ env = strdup(env_const); for (ext = strtok(env, " "); ext != NULL; ext = strtok(NULL, " ")) { int enable; int recognized; switch (ext[0]) { case '+': enable = 1; ++ext; break; case '-': enable = 0; ++ext; break; default: enable = 1; break; } recognized = set_extension(ctx, ext, enable); if (!recognized) { strcat(extra_exts, ext); strcat(extra_exts, " "); } } free(env); /* Remove trailing space. */ len = strlen(extra_exts); if (len > 0 && extra_exts[len - 1] == ' ') extra_exts[len - 1] = '\0'; return extra_exts; }
void _mesa_init_debug( GLcontext *ctx ) { char *c; /* Dither disable */ ctx->NoDither = _mesa_getenv("MESA_NO_DITHER") ? GL_TRUE : GL_FALSE; if (ctx->NoDither) { if (_mesa_getenv("MESA_DEBUG")) { _mesa_debug(ctx, "MESA_NO_DITHER set - dithering disabled\n"); } ctx->Color.DitherFlag = GL_FALSE; } c = _mesa_getenv("MESA_DEBUG"); if (c) add_debug_flags(c); c = _mesa_getenv("MESA_VERBOSE"); if (c) add_debug_flags(c); }
/** * When a context is bound for the first time, we can finally finish * initializing the context's visual and buffer information. * \param v the XMesaVisual to initialize * \param b the XMesaBuffer to initialize (may be NULL) * \param rgb_flag TRUE = RGBA mode, FALSE = color index mode * \param window the window/pixmap we're rendering into * \param cmap the colormap associated with the window/pixmap * \return GL_TRUE=success, GL_FALSE=failure */ static GLboolean initialize_visual_and_buffer(XMesaVisual v, XMesaBuffer b, GLboolean rgb_flag, Drawable window, Colormap cmap) { ASSERT(!b || b->xm_visual == v); /* Save true bits/pixel */ v->BitsPerPixel = bits_per_pixel(v); assert(v->BitsPerPixel > 0); if (rgb_flag == GL_FALSE) { /* COLOR-INDEXED WINDOW: not supported*/ return GL_FALSE; } else { /* RGB WINDOW: * We support RGB rendering into almost any kind of visual. */ const int xclass = v->visualType; if (xclass != GLX_TRUE_COLOR && xclass == !GLX_DIRECT_COLOR) { _mesa_warning(NULL, "XMesa: RGB mode rendering not supported in given visual.\n"); return GL_FALSE; } v->mesa_visual.indexBits = 0; if (v->BitsPerPixel == 32) { /* We use XImages for all front/back buffers. If an X Window or * X Pixmap is 32bpp, there's no guarantee that the alpha channel * will be preserved. For XImages we're in luck. */ v->mesa_visual.alphaBits = 8; } } /* * If MESA_INFO env var is set print out some debugging info * which can help Brian figure out what's going on when a user * reports bugs. */ if (_mesa_getenv("MESA_INFO")) { printf("X/Mesa visual = %p\n", (void *) v); printf("X/Mesa level = %d\n", v->mesa_visual.level); printf("X/Mesa depth = %d\n", v->visinfo->depth); printf("X/Mesa bits per pixel = %d\n", v->BitsPerPixel); } return GL_TRUE; }
void _tnl_init_vertices( GLcontext *ctx, GLuint vb_size, GLuint max_vertex_size ) { struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); _tnl_install_attrs( ctx, NULL, 0, NULL, 0 ); vtx->need_extras = GL_TRUE; if (max_vertex_size > vtx->max_vertex_size) { _tnl_free_vertices( ctx ); vtx->max_vertex_size = max_vertex_size; vtx->vertex_buf = (GLubyte *)ALIGN_CALLOC(vb_size * max_vertex_size, 32 ); invalidate_funcs(vtx); } switch(CHAN_TYPE) { case GL_UNSIGNED_BYTE: vtx->chan_scale[0] = 255.0; vtx->chan_scale[1] = 255.0; vtx->chan_scale[2] = 255.0; vtx->chan_scale[3] = 255.0; break; case GL_UNSIGNED_SHORT: vtx->chan_scale[0] = 65535.0; vtx->chan_scale[1] = 65535.0; vtx->chan_scale[2] = 65535.0; vtx->chan_scale[3] = 65535.0; break; default: vtx->chan_scale[0] = 1.0; vtx->chan_scale[1] = 1.0; vtx->chan_scale[2] = 1.0; vtx->chan_scale[3] = 1.0; break; } vtx->identity[0] = 0.0; vtx->identity[1] = 0.0; vtx->identity[2] = 0.0; vtx->identity[3] = 1.0; vtx->codegen_emit = NULL; #ifdef USE_SSE_ASM if (!_mesa_getenv("MESA_NO_CODEGEN")) vtx->codegen_emit = _tnl_generate_sse_emit; #endif }
static void message( const char *msg ) { GLboolean debug; #ifdef DEBUG debug = GL_TRUE; #else if ( _mesa_getenv( "MESA_DEBUG" ) ) { debug = GL_TRUE; } else { debug = GL_FALSE; } #endif if ( debug ) { _mesa_debug( NULL, "%s", msg ); } }
void _math_test_all_normal_transform_functions( char *description ) { int mtype; long benchmark_tab[0xf]; static int first_time = 1; if ( first_time ) { first_time = 0; mesa_profile = _mesa_getenv( "MESA_PROFILE" ); } #ifdef RUN_DEBUG_BENCHMARK if ( mesa_profile ) { if ( !counter_overhead ) { INIT_COUNTER(); printf( "counter overhead: %ld cycles\n\n", counter_overhead ); } printf( "normal transform results after hooking in %s functions:\n", description ); printf( "\n-------------------------------------------------------\n" ); } #endif for ( mtype = 0 ; mtype < 8 ; mtype++ ) { normal_func func = _mesa_normal_tab[norm_types[mtype]]; long *cycles = &benchmark_tab[mtype]; if ( test_norm_function( func, mtype, cycles ) == 0 ) { char buf[100]; sprintf( buf, "_mesa_normal_tab[0][%s] failed test (%s)", norm_strings[mtype], description ); _mesa_problem( NULL, "%s", buf ); } #ifdef RUN_DEBUG_BENCHMARK if ( mesa_profile ) { printf( " %li\t", benchmark_tab[mtype] ); printf( " | [%s]\n", norm_strings[mtype] ); } #endif } #ifdef RUN_DEBUG_BENCHMARK if ( mesa_profile ) { printf( "\n" ); } #endif }
void _mesa_init_all_x86_64_transform_asm(void) { #ifdef USE_X86_64_ASM unsigned int regs[4]; if ( _mesa_getenv( "MESA_NO_ASM" ) ) { return; } message("Initializing x86-64 optimizations\n"); _mesa_transform_tab[4][MATRIX_GENERAL] = _mesa_x86_64_transform_points4_general; _mesa_transform_tab[4][MATRIX_IDENTITY] = _mesa_x86_64_transform_points4_identity; _mesa_transform_tab[4][MATRIX_3D] = _mesa_x86_64_transform_points4_3d; regs[0] = 0x80000001; regs[1] = 0x00000000; regs[2] = 0x00000000; regs[3] = 0x00000000; _mesa_x86_64_cpuid(regs); if (regs[3] & (1U << 31)) { message("3Dnow! detected\n"); _mesa_transform_tab[4][MATRIX_3D_NO_ROT] = _mesa_3dnow_transform_points4_3d_no_rot; _mesa_transform_tab[4][MATRIX_PERSPECTIVE] = _mesa_3dnow_transform_points4_perspective; _mesa_transform_tab[4][MATRIX_2D_NO_ROT] = _mesa_3dnow_transform_points4_2d_no_rot; _mesa_transform_tab[4][MATRIX_2D] = _mesa_3dnow_transform_points4_2d; } #ifdef DEBUG_MATH _math_test_all_transform_functions("x86_64"); _math_test_all_cliptest_functions("x86_64"); _math_test_all_normal_transform_functions("x86_64"); #endif #endif }
/** * Calls all the various one-time-init functions in Mesa. * * While holding a global mutex lock, calls several initialization functions, * and sets the glapi callbacks if the \c MESA_DEBUG environment variable is * defined. * * \sa _math_init(). */ static void one_time_init( GLcontext *ctx ) { static GLboolean alreadyCalled = GL_FALSE; (void) ctx; _glthread_LOCK_MUTEX(OneTimeLock); if (!alreadyCalled) { GLuint i; /* do some implementation tests */ assert( sizeof(GLbyte) == 1 ); assert( sizeof(GLubyte) == 1 ); assert( sizeof(GLshort) == 2 ); assert( sizeof(GLushort) == 2 ); assert( sizeof(GLint) == 4 ); assert( sizeof(GLuint) == 4 ); _mesa_get_cpu_features(); _mesa_init_remap_table(); _mesa_init_sqrt_table(); for (i = 0; i < 256; i++) { _mesa_ubyte_to_float_color_tab[i] = (float) i / 255.0F; } if (_mesa_getenv("MESA_DEBUG")) { _glapi_noop_enable_warnings(GL_TRUE); _glapi_set_warning_func( (_glapi_warning_func) _mesa_warning ); } else { _glapi_noop_enable_warnings(GL_FALSE); } #if defined(DEBUG) && defined(__DATE__) && defined(__TIME__) _mesa_debug(ctx, "Mesa %s DEBUG build %s %s\n", MESA_VERSION_STRING, __DATE__, __TIME__); #endif alreadyCalled = GL_TRUE; } _glthread_UNLOCK_MUTEX(OneTimeLock); dummy_enum_func(); }
struct vertex_fetch *vf_create( GLboolean allow_viewport_emits ) { struct vertex_fetch *vf = CALLOC_STRUCT(vertex_fetch); GLuint i; for (i = 0; i < VF_ATTRIB_MAX; i++) vf->attr[i].vf = vf; vf->allow_viewport_emits = allow_viewport_emits; switch(CHAN_TYPE) { case GL_UNSIGNED_BYTE: vf->chan_scale[0] = 255.0; vf->chan_scale[1] = 255.0; vf->chan_scale[2] = 255.0; vf->chan_scale[3] = 255.0; break; case GL_UNSIGNED_SHORT: vf->chan_scale[0] = 65535.0; vf->chan_scale[1] = 65535.0; vf->chan_scale[2] = 65535.0; vf->chan_scale[3] = 65535.0; break; default: vf->chan_scale[0] = 1.0; vf->chan_scale[1] = 1.0; vf->chan_scale[2] = 1.0; vf->chan_scale[3] = 1.0; break; } vf->identity[0] = 0.0; vf->identity[1] = 0.0; vf->identity[2] = 0.0; vf->identity[3] = 1.0; vf->codegen_emit = NULL; #ifdef USE_SSE_ASM if (!_mesa_getenv("MESA_NO_CODEGEN")) vf->codegen_emit = vf_generate_sse_emit; #endif return vf; }
void _mesa_init_all_x86_64_transform_asm(void) { #ifdef USE_X86_64_ASM if ( _mesa_getenv( "MESA_NO_ASM" ) ) { return; } message("Initializing x86-64 optimizations\n"); ASSIGN_XFORM_GROUP( x86_64, 4 ); /* _mesa_transform_tab[4][MATRIX_GENERAL] = _mesa_x86_64_transform_points4_general; _mesa_transform_tab[4][MATRIX_IDENTITY] = _mesa_x86_64_transform_points4_identity; _mesa_transform_tab[4][MATRIX_3D] = _mesa_x86_64_transform_points4_3d; _mesa_transform_tab[4][MATRIX_3D_NO_ROT] = _mesa_x86_64_transform_points4_3d_no_rot; _mesa_transform_tab[4][MATRIX_PERSPECTIVE] = _mesa_x86_64_transform_points4_perspective; _mesa_transform_tab[4][MATRIX_2D_NO_ROT] = _mesa_x86_64_transform_points4_2d_no_rot; _mesa_transform_tab[4][MATRIX_2D] = _mesa_x86_64_transform_points4_2d; */ #ifdef DEBUG_MATH _math_test_all_transform_functions("x86_64"); _math_test_all_cliptest_functions("x86_64"); _math_test_all_normal_transform_functions("x86_64"); #endif #endif }
static void message( const char *msg ) { if (_mesa_getenv("MESA_DEBUG")) { _mesa_debug( NULL, "%s", msg ); } }
/* * Create a new X/Mesa visual. * Input: display - X11 display * visinfo - an XVisualInfo pointer * rgb_flag - GL_TRUE = RGB mode, * GL_FALSE = color index mode * alpha_flag - alpha buffer requested? * db_flag - GL_TRUE = double-buffered, * GL_FALSE = single buffered * stereo_flag - stereo visual? * ximage_flag - GL_TRUE = use an XImage for back buffer, * GL_FALSE = use an off-screen pixmap for back buffer * depth_size - requested bits/depth values, or zero * stencil_size - requested bits/stencil values, or zero * accum_red_size - requested bits/red accum values, or zero * accum_green_size - requested bits/green accum values, or zero * accum_blue_size - requested bits/blue accum values, or zero * accum_alpha_size - requested bits/alpha accum values, or zero * num_samples - number of samples/pixel if multisampling, or zero * level - visual level, usually 0 * visualCaveat - ala the GLX extension, usually GLX_NONE * Return; a new XMesaVisual or 0 if error. */ PUBLIC XMesaVisual XMesaCreateVisual( Display *display, XVisualInfo * visinfo, GLboolean rgb_flag, GLboolean alpha_flag, GLboolean db_flag, GLboolean stereo_flag, GLboolean ximage_flag, GLint depth_size, GLint stencil_size, GLint accum_red_size, GLint accum_green_size, GLint accum_blue_size, GLint accum_alpha_size, GLint num_samples, GLint level, GLint visualCaveat ) { XMesaDisplay xmdpy = xmesa_init_display(display); XMesaVisual v; GLint red_bits, green_bits, blue_bits, alpha_bits; if (!xmdpy) return NULL; /* For debugging only */ if (_mesa_getenv("MESA_XSYNC")) { /* This makes debugging X easier. * In your debugger, set a breakpoint on _XError to stop when an * X protocol error is generated. */ XSynchronize( display, 1 ); } v = (XMesaVisual) CALLOC_STRUCT(xmesa_visual); if (!v) { return NULL; } v->display = display; /* Save a copy of the XVisualInfo struct because the user may Xfree() * the struct but we may need some of the information contained in it * at a later time. */ v->visinfo = (XVisualInfo *) malloc(sizeof(*visinfo)); if (!v->visinfo) { free(v); return NULL; } memcpy(v->visinfo, visinfo, sizeof(*visinfo)); v->ximage_flag = ximage_flag; v->mesa_visual.redMask = visinfo->red_mask; v->mesa_visual.greenMask = visinfo->green_mask; v->mesa_visual.blueMask = visinfo->blue_mask; v->visualID = visinfo->visualid; v->screen = visinfo->screen; #if !(defined(__cplusplus) || defined(c_plusplus)) v->visualType = xmesa_convert_from_x_visual_type(visinfo->class); #else v->visualType = xmesa_convert_from_x_visual_type(visinfo->c_class); #endif v->mesa_visual.visualRating = visualCaveat; if (alpha_flag) v->mesa_visual.alphaBits = 8; (void) initialize_visual_and_buffer( v, NULL, rgb_flag, 0, 0 ); { const int xclass = v->visualType; if (xclass == GLX_TRUE_COLOR || xclass == GLX_DIRECT_COLOR) { red_bits = _mesa_bitcount(GET_REDMASK(v)); green_bits = _mesa_bitcount(GET_GREENMASK(v)); blue_bits = _mesa_bitcount(GET_BLUEMASK(v)); } else { /* this is an approximation */ int depth; depth = v->visinfo->depth; red_bits = depth / 3; depth -= red_bits; green_bits = depth / 2; depth -= green_bits; blue_bits = depth; alpha_bits = 0; assert( red_bits + green_bits + blue_bits == v->visinfo->depth ); } alpha_bits = v->mesa_visual.alphaBits; } /* initialize visual */ { struct gl_config *vis = &v->mesa_visual; vis->rgbMode = GL_TRUE; vis->doubleBufferMode = db_flag; vis->stereoMode = stereo_flag; vis->redBits = red_bits; vis->greenBits = green_bits; vis->blueBits = blue_bits; vis->alphaBits = alpha_bits; vis->rgbBits = red_bits + green_bits + blue_bits; vis->indexBits = 0; vis->depthBits = depth_size; vis->stencilBits = stencil_size; vis->accumRedBits = accum_red_size; vis->accumGreenBits = accum_green_size; vis->accumBlueBits = accum_blue_size; vis->accumAlphaBits = accum_alpha_size; vis->haveAccumBuffer = accum_red_size > 0; vis->haveDepthBuffer = depth_size > 0; vis->haveStencilBuffer = stencil_size > 0; vis->numAuxBuffers = 0; vis->level = 0; vis->sampleBuffers = 0; vis->samples = 0; } v->stvis.buffer_mask = ST_ATTACHMENT_FRONT_LEFT_MASK; if (db_flag) v->stvis.buffer_mask |= ST_ATTACHMENT_BACK_LEFT_MASK; if (stereo_flag) { v->stvis.buffer_mask |= ST_ATTACHMENT_FRONT_RIGHT_MASK; if (db_flag) v->stvis.buffer_mask |= ST_ATTACHMENT_BACK_RIGHT_MASK; } v->stvis.color_format = choose_pixel_format(v); if (v->stvis.color_format == PIPE_FORMAT_NONE) { free(v->visinfo); free(v); return NULL; } v->stvis.depth_stencil_format = choose_depth_stencil_format(xmdpy, depth_size, stencil_size); v->stvis.accum_format = (accum_red_size + accum_green_size + accum_blue_size + accum_alpha_size) ? PIPE_FORMAT_R16G16B16A16_SNORM : PIPE_FORMAT_NONE; v->stvis.samples = num_samples; v->stvis.render_buffer = ST_ATTACHMENT_INVALID; /* XXX minor hack */ v->mesa_visual.level = level; return v; }
/** * Initialize a GLcontext struct (rendering context). * * This includes allocating all the other structs and arrays which hang off of * the context by pointers. * Note that the driver needs to pass in its dd_function_table here since * we need to at least call driverFunctions->NewTextureObject to create the * default texture objects. * * Called by _mesa_create_context(). * * Performs the imports and exports callback tables initialization, and * miscellaneous one-time initializations. If no shared context is supplied one * is allocated, and increase its reference count. Setups the GL API dispatch * tables. Initialize the TNL module. Sets the maximum Z buffer depth. * Finally queries the \c MESA_DEBUG and \c MESA_VERBOSE environment variables * for debug flags. * * \param ctx the context to initialize * \param visual describes the visual attributes for this context * \param share_list points to context to share textures, display lists, * etc with, or NULL * \param driverFunctions table of device driver functions for this context * to use * \param driverContext pointer to driver-specific context data */ GLboolean _mesa_initialize_context(GLcontext *ctx, const GLvisual *visual, GLcontext *share_list, const struct dd_function_table *driverFunctions, void *driverContext) { struct gl_shared_state *shared; /*ASSERT(driverContext);*/ assert(driverFunctions->NewTextureObject); assert(driverFunctions->FreeTexImageData); /* misc one-time initializations */ one_time_init(ctx); ctx->Visual = *visual; ctx->DrawBuffer = NULL; ctx->ReadBuffer = NULL; ctx->WinSysDrawBuffer = NULL; ctx->WinSysReadBuffer = NULL; /* Plug in driver functions and context pointer here. * This is important because when we call alloc_shared_state() below * we'll call ctx->Driver.NewTextureObject() to create the default * textures. */ ctx->Driver = *driverFunctions; ctx->DriverCtx = driverContext; if (share_list) { /* share state with another context */ shared = share_list->Shared; } else { /* allocate new, unshared state */ shared = _mesa_alloc_shared_state(ctx); if (!shared) return GL_FALSE; } _glthread_LOCK_MUTEX(shared->Mutex); ctx->Shared = shared; shared->RefCount++; _glthread_UNLOCK_MUTEX(shared->Mutex); if (!init_attrib_groups( ctx )) { _mesa_free_shared_state(ctx, ctx->Shared); return GL_FALSE; } /* setup the API dispatch tables */ ctx->Exec = alloc_dispatch_table(); ctx->Save = alloc_dispatch_table(); if (!ctx->Exec || !ctx->Save) { _mesa_free_shared_state(ctx, ctx->Shared); if (ctx->Exec) _mesa_free(ctx->Exec); return GL_FALSE; } #if FEATURE_dispatch _mesa_init_exec_table(ctx->Exec); #endif ctx->CurrentDispatch = ctx->Exec; #if FEATURE_dlist _mesa_init_save_table(ctx->Save); _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt ); #endif /* Neutral tnl module stuff */ _mesa_init_exec_vtxfmt( ctx ); ctx->TnlModule.Current = NULL; ctx->TnlModule.SwapCount = 0; ctx->FragmentProgram._MaintainTexEnvProgram = (_mesa_getenv("MESA_TEX_PROG") != NULL); ctx->VertexProgram._MaintainTnlProgram = (_mesa_getenv("MESA_TNL_PROG") != NULL); if (ctx->VertexProgram._MaintainTnlProgram) { /* this is required... */ ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE; } #ifdef FEATURE_extra_context_init _mesa_initialize_context_extra(ctx); #endif ctx->FirstTimeCurrent = GL_TRUE; return GL_TRUE; }
/** * Bind the given context to the given drawBuffer and readBuffer and * make it the current context for the calling thread. * We'll render into the drawBuffer and read pixels from the * readBuffer (i.e. glRead/CopyPixels, glCopyTexImage, etc). * * We check that the context's and framebuffer's visuals are compatible * and return immediately if they're not. * * \param newCtx the new GL context. If NULL then there will be no current GL * context. * \param drawBuffer the drawing framebuffer * \param readBuffer the reading framebuffer */ GLboolean _mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer, GLframebuffer *readBuffer ) { if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(newCtx, "_mesa_make_current()\n"); /* Check that the context's and framebuffer's visuals are compatible. */ if (newCtx && drawBuffer && newCtx->WinSysDrawBuffer != drawBuffer) { if (!check_compatible(newCtx, drawBuffer)) { _mesa_warning(newCtx, "MakeCurrent: incompatible visuals for context and drawbuffer"); return GL_FALSE; } } if (newCtx && readBuffer && newCtx->WinSysReadBuffer != readBuffer) { if (!check_compatible(newCtx, readBuffer)) { _mesa_warning(newCtx, "MakeCurrent: incompatible visuals for context and readbuffer"); return GL_FALSE; } } /* We used to call _glapi_check_multithread() here. Now do it in drivers */ _glapi_set_context((void *) newCtx); ASSERT(_mesa_get_current_context() == newCtx); if (!newCtx) { _glapi_set_dispatch(NULL); /* none current */ } else { _glapi_set_dispatch(newCtx->CurrentDispatch); if (drawBuffer && readBuffer) { /* TODO: check if newCtx and buffer's visual match??? */ ASSERT(drawBuffer->Name == 0); ASSERT(readBuffer->Name == 0); _mesa_reference_framebuffer(&newCtx->WinSysDrawBuffer, drawBuffer); _mesa_reference_framebuffer(&newCtx->WinSysReadBuffer, readBuffer); /* * Only set the context's Draw/ReadBuffer fields if they're NULL * or not bound to a user-created FBO. */ if (!newCtx->DrawBuffer || newCtx->DrawBuffer->Name == 0) { /* KW: merge conflict here, revisit. */ /* fix up the fb fields - these will end up wrong otherwise * if the DRIdrawable changes, and everything relies on them. * This is a bit messy (same as needed in _mesa_BindFramebufferEXT) */ unsigned int i; GLenum buffers[MAX_DRAW_BUFFERS]; _mesa_reference_framebuffer(&newCtx->DrawBuffer, drawBuffer); for(i = 0; i < newCtx->Const.MaxDrawBuffers; i++) { buffers[i] = newCtx->Color.DrawBuffer[i]; } _mesa_drawbuffers(newCtx, newCtx->Const.MaxDrawBuffers, buffers, NULL); } if (!newCtx->ReadBuffer || newCtx->ReadBuffer->Name == 0) { _mesa_reference_framebuffer(&newCtx->ReadBuffer, readBuffer); } /* XXX only set this flag if we're really changing the draw/read * framebuffer bindings. */ newCtx->NewState |= _NEW_BUFFERS; #if 1 /* We want to get rid of these lines: */ #if _HAVE_FULL_GL if (!drawBuffer->Initialized) { initialize_framebuffer_size(newCtx, drawBuffer); } if (readBuffer != drawBuffer && !readBuffer->Initialized) { initialize_framebuffer_size(newCtx, readBuffer); } _mesa_resizebuffers(newCtx); #endif #else /* We want the drawBuffer and readBuffer to be initialized by * the driver. * This generally means the Width and Height match the actual * window size and the renderbuffers (both hardware and software * based) are allocated to match. The later can generally be * done with a call to _mesa_resize_framebuffer(). * * It's theoretically possible for a buffer to have zero width * or height, but for now, assert check that the driver did what's * expected of it. */ ASSERT(drawBuffer->Width > 0); ASSERT(drawBuffer->Height > 0); #endif if (drawBuffer) { _mesa_check_init_viewport(newCtx, drawBuffer->Width, drawBuffer->Height); } } if (newCtx->FirstTimeCurrent) { check_context_limits(newCtx); /* We can use this to help debug user's problems. Tell them to set * the MESA_INFO env variable before running their app. Then the * first time each context is made current we'll print some useful * information. */ if (_mesa_getenv("MESA_INFO")) { _mesa_print_info(); } newCtx->FirstTimeCurrent = GL_FALSE; } } return GL_TRUE; }
/* * Create a new X/Mesa visual. * Input: display - X11 display * visinfo - an XVisualInfo pointer * rgb_flag - GL_TRUE = RGB mode, * GL_FALSE = color index mode * alpha_flag - alpha buffer requested? * db_flag - GL_TRUE = double-buffered, * GL_FALSE = single buffered * stereo_flag - stereo visual? * ximage_flag - GL_TRUE = use an XImage for back buffer, * GL_FALSE = use an off-screen pixmap for back buffer * depth_size - requested bits/depth values, or zero * stencil_size - requested bits/stencil values, or zero * accum_red_size - requested bits/red accum values, or zero * accum_green_size - requested bits/green accum values, or zero * accum_blue_size - requested bits/blue accum values, or zero * accum_alpha_size - requested bits/alpha accum values, or zero * num_samples - number of samples/pixel if multisampling, or zero * level - visual level, usually 0 * visualCaveat - ala the GLX extension, usually GLX_NONE * Return; a new XMesaVisual or 0 if error. */ PUBLIC XMesaVisual XMesaCreateVisual( XMesaDisplay *display, XMesaVisualInfo visinfo, GLboolean rgb_flag, GLboolean alpha_flag, GLboolean db_flag, GLboolean stereo_flag, GLboolean ximage_flag, GLint depth_size, GLint stencil_size, GLint accum_red_size, GLint accum_green_size, GLint accum_blue_size, GLint accum_alpha_size, GLint num_samples, GLint level, GLint visualCaveat ) { char *gamma; XMesaVisual v; GLint red_bits, green_bits, blue_bits, alpha_bits; /* For debugging only */ if (_mesa_getenv("MESA_XSYNC")) { /* This makes debugging X easier. * In your debugger, set a breakpoint on _XError to stop when an * X protocol error is generated. */ XSynchronize( display, 1 ); } /* Color-index rendering not supported. */ if (!rgb_flag) return NULL; v = (XMesaVisual) CALLOC_STRUCT(xmesa_visual); if (!v) { return NULL; } v->display = display; /* Save a copy of the XVisualInfo struct because the user may Xfree() * the struct but we may need some of the information contained in it * at a later time. */ v->visinfo = (XVisualInfo *) malloc(sizeof(*visinfo)); if(!v->visinfo) { free(v); return NULL; } memcpy(v->visinfo, visinfo, sizeof(*visinfo)); /* check for MESA_GAMMA environment variable */ gamma = _mesa_getenv("MESA_GAMMA"); if (gamma) { v->RedGamma = v->GreenGamma = v->BlueGamma = 0.0; sscanf( gamma, "%f %f %f", &v->RedGamma, &v->GreenGamma, &v->BlueGamma ); if (v->RedGamma<=0.0) v->RedGamma = 1.0; if (v->GreenGamma<=0.0) v->GreenGamma = v->RedGamma; if (v->BlueGamma<=0.0) v->BlueGamma = v->RedGamma; } else { v->RedGamma = v->GreenGamma = v->BlueGamma = 1.0; } v->ximage_flag = ximage_flag; v->mesa_visual.redMask = visinfo->red_mask; v->mesa_visual.greenMask = visinfo->green_mask; v->mesa_visual.blueMask = visinfo->blue_mask; v->visualID = visinfo->visualid; v->screen = visinfo->screen; #if !(defined(__cplusplus) || defined(c_plusplus)) v->visualType = xmesa_convert_from_x_visual_type(visinfo->class); #else v->visualType = xmesa_convert_from_x_visual_type(visinfo->c_class); #endif v->mesa_visual.visualRating = visualCaveat; if (alpha_flag) v->mesa_visual.alphaBits = 8; (void) initialize_visual_and_buffer( v, NULL, 0, 0 ); { const int xclass = v->visualType; if (xclass == GLX_TRUE_COLOR || xclass == GLX_DIRECT_COLOR) { red_bits = _mesa_bitcount(GET_REDMASK(v)); green_bits = _mesa_bitcount(GET_GREENMASK(v)); blue_bits = _mesa_bitcount(GET_BLUEMASK(v)); } else { /* this is an approximation */ int depth; depth = GET_VISUAL_DEPTH(v); red_bits = depth / 3; depth -= red_bits; green_bits = depth / 2; depth -= green_bits; blue_bits = depth; alpha_bits = 0; assert( red_bits + green_bits + blue_bits == GET_VISUAL_DEPTH(v) ); } alpha_bits = v->mesa_visual.alphaBits; } if (!_mesa_initialize_visual(&v->mesa_visual, db_flag, stereo_flag, red_bits, green_bits, blue_bits, alpha_bits, depth_size, stencil_size, accum_red_size, accum_green_size, accum_blue_size, accum_alpha_size, 0)) { FREE(v); return NULL; } /* XXX minor hack */ v->mesa_visual.level = level; return v; }
/** * When a context is bound for the first time, we can finally finish * initializing the context's visual and buffer information. * \param v the XMesaVisual to initialize * \param b the XMesaBuffer to initialize (may be NULL) * \param rgb_flag TRUE = RGBA mode, FALSE = color index mode * \param window the window/pixmap we're rendering into * \param cmap the colormap associated with the window/pixmap * \return GL_TRUE=success, GL_FALSE=failure */ static GLboolean initialize_visual_and_buffer(XMesaVisual v, XMesaBuffer b, XMesaDrawable window, XMesaColormap cmap) { const int xclass = v->visualType; ASSERT(!b || b->xm_visual == v); /* Save true bits/pixel */ v->BitsPerPixel = bits_per_pixel(v); assert(v->BitsPerPixel > 0); /* RGB WINDOW: * We support RGB rendering into almost any kind of visual. */ if (xclass == GLX_TRUE_COLOR || xclass == GLX_DIRECT_COLOR) { setup_truecolor( v, b, cmap ); } else { _mesa_warning(NULL, "XMesa: RGB mode rendering not supported in given visual.\n"); return GL_FALSE; } v->mesa_visual.indexBits = 0; if (_mesa_getenv("MESA_NO_DITHER")) { v->dithered_pf = v->undithered_pf; } /* * If MESA_INFO env var is set print out some debugging info * which can help Brian figure out what's going on when a user * reports bugs. */ if (_mesa_getenv("MESA_INFO")) { printf("X/Mesa visual = %p\n", (void *) v); printf("X/Mesa dithered pf = %u\n", v->dithered_pf); printf("X/Mesa undithered pf = %u\n", v->undithered_pf); printf("X/Mesa level = %d\n", v->mesa_visual.level); printf("X/Mesa depth = %d\n", GET_VISUAL_DEPTH(v)); printf("X/Mesa bits per pixel = %d\n", v->BitsPerPixel); } if (b && window) { /* Do window-specific initializations */ /* these should have been set in create_xmesa_buffer */ ASSERT(b->frontxrb->drawable == window); ASSERT(b->frontxrb->pixmap == (XMesaPixmap) window); /* Setup for single/double buffering */ if (v->mesa_visual.doubleBufferMode) { /* Double buffered */ b->shm = check_for_xshm( v->display ); } /* X11 graphics contexts */ b->gc = XCreateGC( v->display, window, 0, NULL ); XMesaSetFunction( v->display, b->gc, GXcopy ); /* cleargc - for glClear() */ b->cleargc = XCreateGC( v->display, window, 0, NULL ); XMesaSetFunction( v->display, b->cleargc, GXcopy ); /* * Don't generate Graphics Expose/NoExpose events in swapbuffers(). * Patch contributed by Michael Pichler May 15, 1995. */ { XGCValues gcvalues; gcvalues.graphics_exposures = False; b->swapgc = XCreateGC(v->display, window, GCGraphicsExposures, &gcvalues); } XMesaSetFunction( v->display, b->swapgc, GXcopy ); } return GL_TRUE; }
/** * Initialize the _mesa_x86_cpu_features bitfield. * This is a no-op if called more than once. */ void _mesa_get_x86_features(void) { static int called = 0; if (called) return; called = 1; #ifdef USE_X86_ASM _mesa_x86_cpu_features = 0x0; if (_mesa_getenv( "MESA_NO_ASM")) { return; } if (!_mesa_x86_has_cpuid()) { _mesa_debug(NULL, "CPUID not detected\n"); } else { GLuint cpu_features, cpu_features_ecx; GLuint cpu_ext_features; GLuint cpu_ext_info; char cpu_vendor[13]; GLuint result; /* get vendor name */ _mesa_x86_cpuid(0, &result, (GLuint *)(cpu_vendor + 0), (GLuint *)(cpu_vendor + 8), (GLuint *)(cpu_vendor + 4)); cpu_vendor[12] = '\0'; if (detection_debug) _mesa_debug(NULL, "CPU vendor: %s\n", cpu_vendor); /* get cpu features */ cpu_features = _mesa_x86_cpuid_edx(1); cpu_features_ecx = _mesa_x86_cpuid_ecx(1); if (cpu_features & X86_CPU_FPU) _mesa_x86_cpu_features |= X86_FEATURE_FPU; if (cpu_features & X86_CPU_CMOV) _mesa_x86_cpu_features |= X86_FEATURE_CMOV; #ifdef USE_MMX_ASM if (cpu_features & X86_CPU_MMX) _mesa_x86_cpu_features |= X86_FEATURE_MMX; #endif #ifdef USE_SSE_ASM if (cpu_features & X86_CPU_XMM) _mesa_x86_cpu_features |= X86_FEATURE_XMM; if (cpu_features & X86_CPU_XMM2) _mesa_x86_cpu_features |= X86_FEATURE_XMM2; if (cpu_features_ecx & X86_CPU_SSE4_1) _mesa_x86_cpu_features |= X86_FEATURE_SSE4_1; #endif /* query extended cpu features */ if ((cpu_ext_info = _mesa_x86_cpuid_eax(0x80000000)) > 0x80000000) { if (cpu_ext_info >= 0x80000001) { cpu_ext_features = _mesa_x86_cpuid_edx(0x80000001); if (cpu_features & X86_CPU_MMX) { #ifdef USE_3DNOW_ASM if (cpu_ext_features & X86_CPUEXT_3DNOW) _mesa_x86_cpu_features |= X86_FEATURE_3DNOW; if (cpu_ext_features & X86_CPUEXT_3DNOW_EXT) _mesa_x86_cpu_features |= X86_FEATURE_3DNOWEXT; #endif #ifdef USE_MMX_ASM if (cpu_ext_features & X86_CPUEXT_MMX_EXT) _mesa_x86_cpu_features |= X86_FEATURE_MMXEXT; #endif } } /* query cpu name */ if (cpu_ext_info >= 0x80000002) { GLuint ofs; char cpu_name[49]; for (ofs = 0; ofs < 3; ofs++) _mesa_x86_cpuid(0x80000002+ofs, (GLuint *)(cpu_name + (16*ofs)+0), (GLuint *)(cpu_name + (16*ofs)+4), (GLuint *)(cpu_name + (16*ofs)+8), (GLuint *)(cpu_name + (16*ofs)+12)); cpu_name[48] = '\0'; /* the name should be NULL terminated, but just to be sure */ if (detection_debug) _mesa_debug(NULL, "CPU name: %s\n", cpu_name); } } } #ifdef USE_MMX_ASM if ( cpu_has_mmx ) { if ( _mesa_getenv( "MESA_NO_MMX" ) == 0 ) { if (detection_debug) _mesa_debug(NULL, "MMX cpu detected.\n"); } else { _mesa_x86_cpu_features &= ~(X86_FEATURE_MMX); } } #endif #ifdef USE_3DNOW_ASM if ( cpu_has_3dnow ) { if ( _mesa_getenv( "MESA_NO_3DNOW" ) == 0 ) { if (detection_debug) _mesa_debug(NULL, "3DNow! cpu detected.\n"); } else { _mesa_x86_cpu_features &= ~(X86_FEATURE_3DNOW); } } #endif #ifdef USE_SSE_ASM if ( cpu_has_xmm ) { if ( _mesa_getenv( "MESA_NO_SSE" ) == 0 ) { if (detection_debug) _mesa_debug(NULL, "SSE cpu detected.\n"); if ( _mesa_getenv( "MESA_FORCE_SSE" ) == 0 ) { _mesa_check_os_sse_support(); } } else { _mesa_debug(NULL, "SSE cpu detected, but switched off by user.\n"); _mesa_x86_cpu_features &= ~(X86_FEATURE_XMM); } } #endif #elif defined(USE_X86_64_ASM) { unsigned int uninitialized_var(eax), uninitialized_var(ebx), uninitialized_var(ecx), uninitialized_var(edx); /* Always available on x86-64. */ _mesa_x86_cpu_features |= X86_FEATURE_XMM | X86_FEATURE_XMM2; __get_cpuid(1, &eax, &ebx, &ecx, &edx); if (ecx & bit_SSE4_1) _mesa_x86_cpu_features |= X86_FEATURE_SSE4_1; } #endif /* USE_X86_64_ASM */ (void) detection_debug; }