Merge branch '7.8' into master
[mesa.git] / src / mesa / drivers / dri / common / utils.c
index 2a1ded3871ded9899a16ab5f3fa4ee02e8c7f763..0dd879abc968e3912709fd1ed2591e56c2b6de6d 100644 (file)
 #include <string.h>
 #include <stdlib.h>
 #include "main/mtypes.h"
+#include "main/cpuinfo.h"
 #include "main/extensions.h"
-#include "glapi/dispatch.h"
 #include "utils.h"
 
-int driDispatchRemapTable[ driDispatchRemapTable_size ];
 
-#if defined(USE_X86_ASM)
-#include "x86/common_x86_asm.h"
-#endif
+/**
+ * Print message to \c stderr if the \c LIBGL_DEBUG environment variable
+ * is set. 
+ * 
+ * Is called from the drivers.
+ * 
+ * \param f \c printf like format string.
+ */
+void
+__driUtilMessage(const char *f, ...)
+{
+    va_list args;
+
+    if (getenv("LIBGL_DEBUG")) {
+        fprintf(stderr, "libGL: ");
+        va_start(args, f);
+        vfprintf(stderr, f, args);
+        va_end(args);
+        fprintf(stderr, "\n");
+    }
+}
 
-#if defined(USE_PPC_ASM)
-#include "ppc/common_ppc_features.h"
-#endif
 
 unsigned
 driParseDebugString( const char * debug, 
@@ -93,12 +107,8 @@ unsigned
 driGetRendererString( char * buffer, const char * hardware_name,
                      const char * driver_date, GLuint agp_mode )
 {
-#define MAX_INFO   4
-   const char * cpu[MAX_INFO];
-   unsigned   next = 0;
-   unsigned   i;
-   unsigned   offset;
-
+   unsigned offset;
+   char *cpu;
 
    offset = sprintf( buffer, "Mesa DRI %s %s", hardware_name, driver_date );
 
@@ -118,59 +128,10 @@ driGetRendererString( char * buffer, const char * hardware_name,
 
    /* Append any CPU-specific information.
     */
-#ifdef USE_X86_ASM
-   if ( _mesa_x86_cpu_features ) {
-      cpu[next] = " x86";
-      next++;
-   }
-# ifdef USE_MMX_ASM
-   if ( cpu_has_mmx ) {
-      cpu[next] = (cpu_has_mmxext) ? "/MMX+" : "/MMX";
-      next++;
-   }
-# endif
-# ifdef USE_3DNOW_ASM
-   if ( cpu_has_3dnow ) {
-      cpu[next] = (cpu_has_3dnowext) ? "/3DNow!+" : "/3DNow!";
-      next++;
-   }
-# endif
-# ifdef USE_SSE_ASM
-   if ( cpu_has_xmm ) {
-      cpu[next] = (cpu_has_xmm2) ? "/SSE2" : "/SSE";
-      next++;
-   }
-# endif
-
-#elif defined(USE_SPARC_ASM)
-
-   cpu[0] = " SPARC";
-   next = 1;
-
-#elif defined(USE_PPC_ASM)
-   if ( _mesa_ppc_cpu_features ) {
-      cpu[next] = (cpu_has_64) ? " PowerPC 64" : " PowerPC";
-      next++;
-   }
-
-# ifdef USE_VMX_ASM
-   if ( cpu_has_vmx ) {
-      cpu[next] = "/Altivec";
-      next++;
-   }
-# endif
-
-   if ( ! cpu_has_fpu ) {
-      cpu[next] = "/No FPU";
-      next++;
-   }
-#endif
-
-   for ( i = 0 ; i < next ; i++ ) {
-      const size_t len = strlen( cpu[i] );
-
-      strncpy( & buffer[ offset ], cpu[i], len );
-      offset += len;
+   cpu = _mesa_get_cpu_string();
+   if (cpu) {
+      offset += sprintf(buffer + offset, " %s", cpu);
+      free(cpu);
    }
 
    return offset;
@@ -179,13 +140,18 @@ driGetRendererString( char * buffer, const char * hardware_name,
 
 
 
+#define need_GL_ARB_draw_buffers
 #define need_GL_ARB_multisample
+#define need_GL_ARB_texture_compression
 #define need_GL_ARB_transpose_matrix
+#define need_GL_ARB_vertex_buffer_object
 #define need_GL_ARB_window_pos
 #define need_GL_EXT_compiled_vertex_array
+#define need_GL_EXT_multi_draw_arrays
 #define need_GL_EXT_polygon_offset
 #define need_GL_EXT_texture_object
 #define need_GL_EXT_vertex_array
+#define need_GL_IBM_multimode_draw_arrays
 #define need_GL_MESA_window_pos
 
 /* These are needed in *all* drivers because Mesa internally implements
@@ -195,17 +161,22 @@ driGetRendererString( char * buffer, const char * hardware_name,
 #define need_GL_EXT_blend_func_separate
 #define need_GL_NV_vertex_program
 
-#include "extension_helper.h"
+#include "main/remap_helper.h"
 
 static const struct dri_extension all_mesa_extensions[] = {
+   { "GL_ARB_draw_buffers",          GL_ARB_draw_buffers_functions },
    { "GL_ARB_multisample",           GL_ARB_multisample_functions },
+   { "GL_ARB_texture_compression",   GL_ARB_texture_compression_functions },
    { "GL_ARB_transpose_matrix",      GL_ARB_transpose_matrix_functions },
+   { "GL_ARB_vertex_buffer_object",  GL_ARB_vertex_buffer_object_functions},
    { "GL_ARB_window_pos",            GL_ARB_window_pos_functions },
    { "GL_EXT_blend_func_separate",   GL_EXT_blend_func_separate_functions },
    { "GL_EXT_compiled_vertex_array", GL_EXT_compiled_vertex_array_functions },
+   { "GL_EXT_multi_draw_arrays",     GL_EXT_multi_draw_arrays_functions },
    { "GL_EXT_polygon_offset",        GL_EXT_polygon_offset_functions },
    { "GL_EXT_texture_object",        GL_EXT_texture_object_functions },
    { "GL_EXT_vertex_array",          GL_EXT_vertex_array_functions },
+   { "GL_IBM_multimode_draw_arrays", GL_IBM_multimode_draw_arrays_functions },
    { "GL_MESA_window_pos",           GL_MESA_window_pos_functions },
    { "GL_NV_vertex_program",         GL_NV_vertex_program_functions },
    { NULL,                           NULL }
@@ -213,8 +184,12 @@ static const struct dri_extension all_mesa_extensions[] = {
 
 
 /**
- * Enable extensions supported by the driver.
+ * Enable and map extensions supported by the driver.
  * 
+ * When ctx is NULL, extensions are not enabled, but their functions
+ * are still mapped.  When extensions_to_enable is NULL, all static
+ * functions known to mesa core are mapped.
+ *
  * \bug
  * ARB_imaging isn't handled properly.  In Mesa, enabling ARB_imaging also
  * enables all the sub-extensions that are folded into it.  This means that
@@ -229,18 +204,23 @@ void driInitExtensions( GLcontext * ctx,
    unsigned   i;
 
    if ( first_time ) {
-      for ( i = 0 ; i < driDispatchRemapTable_size ; i++ ) {
-        driDispatchRemapTable[i] = -1;
-      }
-
       first_time = 0;
-      driInitExtensions( ctx, all_mesa_extensions, GL_FALSE );
+      driInitExtensions( NULL, all_mesa_extensions, GL_FALSE );
    }
 
    if ( (ctx != NULL) && enable_imaging ) {
       _mesa_enable_imaging_extensions( ctx );
    }
 
+   /* The caller is too lazy to list any extension */
+   if ( extensions_to_enable == NULL ) {
+      /* Map the static functions.  Together with those mapped by remap
+       * table, this should cover everything mesa core knows.
+       */
+      _mesa_map_static_functions();
+      return;
+   }
+
    for ( i = 0 ; extensions_to_enable[i].name != NULL ; i++ ) {
        driInitSingleExtension( ctx, & extensions_to_enable[i] );
    }
@@ -250,80 +230,18 @@ void driInitExtensions( GLcontext * ctx,
 
 
 /**
- * Enable and add dispatch functions for a single extension
+ * Enable and map functions for a single extension
  * 
  * \param ctx  Context where extension is to be enabled.
  * \param ext  Extension that is to be enabled.
  * 
- * \sa driInitExtensions, _mesa_enable_extension, _glapi_add_entrypoint
- *
- * \todo
- * Determine if it would be better to use \c strlen instead of the hardcoded
- * for-loops.
+ * \sa driInitExtensions, _mesa_enable_extension, _mesa_map_function_array
  */
 void driInitSingleExtension( GLcontext * ctx,
                             const struct dri_extension * ext )
 {
-    unsigned i;
-
-
     if ( ext->functions != NULL ) {
-       for ( i = 0 ; ext->functions[i].strings != NULL ; i++ ) {
-           const char * functions[16];
-           const char * parameter_signature;
-           const char * str = ext->functions[i].strings;
-           unsigned j;
-           unsigned offset;
-
-
-           /* Separate the parameter signature from the rest of the string.
-            * If the parameter signature is empty (i.e., the string starts
-            * with a NUL character), then the function has a void parameter
-            * list.
-            */
-           parameter_signature = str;
-           while ( str[0] != '\0' ) {
-               str++;
-           }
-           str++;
-
-
-           /* Divide the string into the substrings that name each
-            * entry-point for the function.
-            */
-           for ( j = 0 ; j < 16 ; j++ ) {
-               if ( str[0] == '\0' ) {
-                   functions[j] = NULL;
-                   break;
-               }
-
-               functions[j] = str;
-
-               while ( str[0] != '\0' ) {
-                   str++;
-               }
-               str++;
-           }
-
-
-           /* Add each entry-point to the dispatch table.
-            */
-           offset = _glapi_add_dispatch( functions, parameter_signature );
-           if (offset == -1) {
-#if 0 /* this causes noise with egl */
-               fprintf(stderr, "DISPATCH ERROR! _glapi_add_dispatch failed "
-                       "to add %s!\n", functions[0]);
-#endif
-           }
-           else if (ext->functions[i].remap_index != -1) {
-               driDispatchRemapTable[ ext->functions[i].remap_index ] = 
-                 offset;
-           }
-           else if (ext->functions[i].offset != offset) {
-               fprintf(stderr, "DISPATCH ERROR! %s -> %u != %u\n",
-                       functions[0], offset, ext->functions[i].offset);
-           }
-       }
+       _mesa_map_function_array(ext->functions);
     }
 
     if ( ctx != NULL ) {
@@ -335,9 +253,6 @@ void driInitSingleExtension( GLcontext * ctx,
 /**
  * Utility function used by drivers to test the verions of other components.
  *
- * If one of the version requirements is not met, a message is logged using
- * \c __driUtilMessage.
- *
  * \param driver_name  Name of the driver.  Used in error messages.
  * \param driActual    Actual DRI version supplied __driCreateNewScreen.
  * \param driExpected  Minimum DRI version required by the driver.
@@ -349,7 +264,7 @@ void driInitSingleExtension( GLcontext * ctx,
  * \returns \c GL_TRUE if all version requirements are met.  Otherwise,
  *          \c GL_FALSE is returned.
  * 
- * \sa __driCreateNewScreen, driCheckDriDdxDrmVersions2, __driUtilMessage
+ * \sa __driCreateNewScreen, driCheckDriDdxDrmVersions2
  *
  * \todo
  * Now that the old \c driCheckDriDdxDrmVersions function is gone, this
@@ -380,10 +295,9 @@ driCheckDriDdxDrmVersions3(const char * driver_name,
    }
 
    /* Check that the DDX driver version is compatible */
-   /* for miniglx we pass in -1 so we can ignore the DDX version */
-   if ( (ddxActual->major != -1) && ((ddxActual->major < ddxExpected->major_min)
+   if ( (ddxActual->major < ddxExpected->major_min)
        || (ddxActual->major > ddxExpected->major_max)
-       || (ddxActual->minor < ddxExpected->minor)) ) {
+       || (ddxActual->minor < ddxExpected->minor) ) {
       fprintf(stderr, format2, driver_name, "DDX",
                       ddxExpected->major_min, ddxExpected->major_max, ddxExpected->minor,
                       ddxActual->major, ddxActual->minor, ddxActual->patch);
@@ -529,7 +443,8 @@ driCreateConfigs(GLenum fb_format, GLenum fb_type,
                 const uint8_t * depth_bits, const uint8_t * stencil_bits,
                 unsigned num_depth_stencil_bits,
                 const GLenum * db_modes, unsigned num_db_modes,
-                const u_int8_t * msaa_samples, unsigned num_msaa_modes)
+                const uint8_t * msaa_samples, unsigned num_msaa_modes,
+                GLboolean enable_accum)
 {
    static const uint8_t bits_table[4][4] = {
      /* R  G  B  A */
@@ -591,7 +506,7 @@ driCreateConfigs(GLenum fb_format, GLenum fb_type,
    __GLcontextModes *modes;
    unsigned i, j, k, h;
    unsigned num_modes;
-   unsigned num_accum_bits = 2;
+   unsigned num_accum_bits = (enable_accum) ? 2 : 1;
 
    switch ( fb_type ) {
       case GL_UNSIGNED_BYTE_3_3_2:
@@ -663,7 +578,7 @@ driCreateConfigs(GLenum fb_format, GLenum fb_type,
    }
 
    num_modes = num_depth_stencil_bits * num_db_modes * num_accum_bits * num_msaa_modes;
-   configs = _mesa_calloc((num_modes + 1) * sizeof *configs);
+   configs = calloc(1, (num_modes + 1) * sizeof *configs);
    if (configs == NULL)
        return NULL;
 
@@ -672,7 +587,7 @@ driCreateConfigs(GLenum fb_format, GLenum fb_type,
        for ( i = 0 ; i < num_db_modes ; i++ ) {
            for ( h = 0 ; h < num_msaa_modes; h++ ) {
                for ( j = 0 ; j < num_accum_bits ; j++ ) {
-                   *c = _mesa_malloc (sizeof **c);
+                   *c = malloc (sizeof **c);
                    modes = &(*c)->modes;
                    c++;
 
@@ -730,11 +645,10 @@ driCreateConfigs(GLenum fb_format, GLenum fb_type,
                    modes->bindToTextureRgb = GL_TRUE;
                    modes->bindToTextureRgba = GL_TRUE;
                    modes->bindToMipmapTexture = GL_FALSE;
-                   modes->bindToTextureTargets = modes->rgbMode ?
-                       __DRI_ATTRIB_TEXTURE_1D_BIT |
-                       __DRI_ATTRIB_TEXTURE_2D_BIT |
-                       __DRI_ATTRIB_TEXTURE_RECTANGLE_BIT :
-                       0;
+                   modes->bindToTextureTargets =
+                       __DRI_ATTRIB_TEXTURE_1D_BIT |
+                       __DRI_ATTRIB_TEXTURE_2D_BIT |
+                       __DRI_ATTRIB_TEXTURE_RECTANGLE_BIT;
                }
            }
        }
@@ -744,9 +658,10 @@ driCreateConfigs(GLenum fb_format, GLenum fb_type,
     return configs;
 }
 
-const __DRIconfig **driConcatConfigs(__DRIconfig **a, __DRIconfig **b)
+__DRIconfig **driConcatConfigs(__DRIconfig **a,
+                              __DRIconfig **b)
 {
-    const __DRIconfig **all;
+    __DRIconfig **all;
     int i, j, index;
 
     i = 0;
@@ -756,7 +671,7 @@ const __DRIconfig **driConcatConfigs(__DRIconfig **a, __DRIconfig **b)
     while (b[j] != NULL)
        j++;
    
-    all = _mesa_malloc((i + j + 1) * sizeof *all);
+    all = malloc((i + j + 1) * sizeof *all);
     index = 0;
     for (i = 0; a[i] != NULL; i++)
        all[index++] = a[i];
@@ -764,8 +679,8 @@ const __DRIconfig **driConcatConfigs(__DRIconfig **a, __DRIconfig **b)
        all[index++] = b[j];
     all[index++] = NULL;
 
-    _mesa_free(a);
-    _mesa_free(b);
+    free(a);
+    free(b);
 
     return all;
 }
@@ -830,10 +745,7 @@ driGetConfigAttribIndex(const __DRIconfig *config,
 {
     switch (attribMap[index].attrib) {
     case __DRI_ATTRIB_RENDER_TYPE:
-       if (config->modes.rgbMode)
-           *value = __DRI_ATTRIB_RGBA_BIT;
-       else
-           *value = __DRI_ATTRIB_COLOR_INDEX_BIT;
+       *value = __DRI_ATTRIB_RGBA_BIT;
        break;
     case __DRI_ATTRIB_CONFIG_CAVEAT:
        if (config->modes.visualRating == GLX_NON_CONFORMANT_CONFIG)