Exemplo n.º 1
0
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
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
/**
 * 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;
}
Exemplo n.º 4
0
/**
 * 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;
}
Exemplo n.º 5
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
}
Exemplo n.º 6
0
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
}
Exemplo n.º 7
0
/**
 * \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;
}
Exemplo n.º 8
0
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);
}
Exemplo n.º 9
0
Arquivo: xm_api.c Projeto: ideak/mesa
/**
 * 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;
}
Exemplo n.º 10
0
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
}
Exemplo n.º 11
0
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 );
   }
}
Exemplo n.º 12
0
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
}
Exemplo n.º 13
0
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
}
Exemplo n.º 14
0
/**
 * 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();
}
Exemplo n.º 15
0
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;
}
Exemplo n.º 16
0
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
}
Exemplo n.º 17
0
static void message( const char *msg )
{
   if (_mesa_getenv("MESA_DEBUG")) {
      _mesa_debug( NULL, "%s", msg );
   }
}
Exemplo n.º 18
0
Arquivo: xm_api.c Projeto: ideak/mesa
/*
 * 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;
}
Exemplo n.º 19
0
/**
 * 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;
}
Exemplo n.º 20
0
/**
 * 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;
}
Exemplo n.º 21
0
Arquivo: xm_api.c Projeto: RAOF/mesa
/*
 * 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;
}
Exemplo n.º 22
0
Arquivo: xm_api.c Projeto: RAOF/mesa
/**
 * 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;
}
Exemplo n.º 23
0
/**
 * 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;
}