gpu-info: Detect more info including architecture

The GPU info api previously told us a driver package name and a driver
vendor name, but now we have introduced detection for the gpu
architecture too and started to track architecture feature flags that
can tell us whether a gpu is a deferred or immediate mode renderer for
example or if a software rasterizer is being used.

This also adds support for checking more vendor names. We should now
detect the following cases:

Vendors: Intel, Imagination Technologies, ARM, Qualcomm, Nvidia, ATI
Architectures: Sandybridge, SGX, Mali
Architecture flags:
  - vertex tiled
  - vertex immediate mode
  - vertex software
  - fragment deferred
  - fragment immediate mode
  - fragment software

Reviewed-by: Neil Roberts <neil@linux.intel.com>

(cherry picked from commit b3803a0a7c9e663ed219e83626841895c7d95ad7)
This commit is contained in:
Robert Bragg 2012-05-14 09:58:25 +01:00
parent 37fbfffcd0
commit b8e380edc3
2 changed files with 328 additions and 11 deletions

View File

@ -26,10 +26,37 @@
#include "cogl-context.h" #include "cogl-context.h"
typedef enum _CoglGpuInfoArchitectureFlag
{
COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_IMMEDIATE_MODE,
COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_TILED,
COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_SOFTWARE,
COGL_GPU_INFO_ARCHITECTURE_FLAG_FRAGMENT_IMMEDIATE_MODE,
COGL_GPU_INFO_ARCHITECTURE_FLAG_FRAGMENT_DEFERRED,
COGL_GPU_INFO_ARCHITECTURE_FLAG_FRAGMENT_SOFTWARE
} CoglGpuInfoArchitectureFlag;
typedef enum _CoglGpuInfoArchitecture
{
COGL_GPU_INFO_ARCHITECTURE_UNKNOWN,
COGL_GPU_INFO_ARCHITECTURE_SANDYBRIDGE,
COGL_GPU_INFO_ARCHITECTURE_SGX,
COGL_GPU_INFO_ARCHITECTURE_MALI,
COGL_GPU_INFO_ARCHITECTURE_LLVMPIPE,
COGL_GPU_INFO_ARCHITECTURE_SOFTPIPE,
COGL_GPU_INFO_ARCHITECTURE_SWRAST
} CoglGpuInfoArchitecture;
typedef enum typedef enum
{ {
COGL_GPU_INFO_VENDOR_UNKNOWN, COGL_GPU_INFO_VENDOR_UNKNOWN,
COGL_GPU_INFO_VENDOR_INTEL COGL_GPU_INFO_VENDOR_INTEL,
COGL_GPU_INFO_VENDOR_IMAGINATION_TECHNOLOGIES,
COGL_GPU_INFO_VENDOR_ARM,
COGL_GPU_INFO_VENDOR_QUALCOMM,
COGL_GPU_INFO_VENDOR_NVIDIA,
COGL_GPU_INFO_VENDOR_ATI,
COGL_GPU_INFO_VENDOR_MESA
} CoglGpuInfoVendor; } CoglGpuInfoVendor;
typedef enum typedef enum
@ -61,6 +88,10 @@ struct _CoglGpuInfo
const char *driver_package_name; const char *driver_package_name;
int driver_package_version; int driver_package_version;
CoglGpuInfoArchitecture architecture;
const char *architecture_name;
CoglGpuInfoArchitectureFlag architecture_flags;
CoglGpuInfoDriverBug driver_bugs; CoglGpuInfoDriverBug driver_bugs;
}; };

View File

@ -39,11 +39,22 @@ typedef struct
const char *vendor_string; const char *vendor_string;
} CoglGpuInfoStrings; } CoglGpuInfoStrings;
typedef struct CoglGpuInfoArchitectureDescription
{
CoglGpuInfoArchitecture architecture;
const char *name;
CoglGpuInfoArchitectureFlag flags;
CoglBool (* check_function) (const CoglGpuInfoStrings *strings);
} CoglGpuInfoArchitectureDescription;
typedef struct typedef struct
{ {
CoglGpuInfoVendor vendor; CoglGpuInfoVendor vendor;
const char *name; const char *name;
CoglBool (* check_function) (const CoglGpuInfoStrings *strings); CoglBool (* check_function) (const CoglGpuInfoStrings *strings);
const CoglGpuInfoArchitectureDescription *architectures;
} CoglGpuInfoVendorDescription; } CoglGpuInfoVendorDescription;
typedef struct typedef struct
@ -94,42 +105,295 @@ _cogl_gpu_info_parse_version_string (const char *version_string,
} }
static CoglBool static CoglBool
check_intel_vendor (const CoglGpuInfoStrings *strings) match_phrase (const char *string, const char *phrase)
{ {
const char *intel_part = strstr (strings->renderer_string, "Intel(R)"); const char *part = strstr (string, phrase);
int len;
if (intel_part == NULL) if (part == NULL)
return FALSE; return FALSE;
/* The match must either be at the beginning of the string or /* The match must either be at the beginning of the string or
preceded by a space. Just in case there's a company called preceded by a space. */
IAmNotIntel (R) or something */ if (part > string && part[-1] != ' ')
if (intel_part > strings->renderer_string && intel_part[-1] != ' ') return FALSE;
/* Also match must either be at end of string or followed by a
* space. */
len = strlen (phrase);
if (part[len] != '\0' && part[len] != ' ')
return FALSE; return FALSE;
return TRUE; return TRUE;
} }
static CoglBool static CoglBool
check_unknown_vendor (const CoglGpuInfoStrings *strings) check_intel_vendor (const CoglGpuInfoStrings *strings)
{
return match_phrase (strings->renderer_string, "Intel(R)");
}
static CoglBool
check_imagination_technologies_vendor (const CoglGpuInfoStrings *strings)
{
if (strcmp (strings->vendor_string, "Imagination Technologies") != 0)
return FALSE;
return TRUE;
}
static CoglBool
check_arm_vendor (const CoglGpuInfoStrings *strings)
{
if (strcmp (strings->vendor_string, "ARM") != 0)
return FALSE;
return TRUE;
}
static CoglBool
check_qualcomm_vendor (const CoglGpuInfoStrings *strings)
{
if (strcmp (strings->vendor_string, "Qualcomm") != 0)
return FALSE;
return TRUE;
}
static CoglBool
check_nvidia_vendor (const CoglGpuInfoStrings *strings)
{
if (strcmp (strings->vendor_string, "NVIDIA") != 0)
return FALSE;
return TRUE;
}
static CoglBool
check_ati_vendor (const CoglGpuInfoStrings *strings)
{
if (strcmp (strings->vendor_string, "ATI") != 0)
return FALSE;
return TRUE;
}
static CoglBool
check_mesa_vendor (const CoglGpuInfoStrings *strings)
{
if (strcmp (strings->vendor_string, "Tungsten Graphics, Inc") == 0)
return TRUE;
else if (strcmp (strings->vendor_string, "VMware, Inc.") == 0)
return TRUE;
return FALSE;
}
static CoglBool
check_true (const CoglGpuInfoStrings *strings)
{ {
/* This is a last resort so it always matches */ /* This is a last resort so it always matches */
return TRUE; return TRUE;
} }
static CoglBool
check_sandybridge_architecture (const CoglGpuInfoStrings *strings)
{
return match_phrase (strings->renderer_string, "Sandybridge");
}
static CoglBool
check_llvmpipe_architecture (const CoglGpuInfoStrings *strings)
{
return match_phrase (strings->renderer_string, "llvmpipe");
}
static CoglBool
check_softpipe_architecture (const CoglGpuInfoStrings *strings)
{
return match_phrase (strings->renderer_string, "softpipe");
}
static CoglBool
check_swrast_architecture (const CoglGpuInfoStrings *strings)
{
return match_phrase (strings->renderer_string, "software rasterizer");
}
static CoglBool
check_sgx_architecture (const CoglGpuInfoStrings *strings)
{
if (strncmp (strings->renderer_string, "PowerVR SGX", 12) != 0)
return FALSE;
return TRUE;
}
static CoglBool
check_mali_architecture (const CoglGpuInfoStrings *strings)
{
if (strncmp (strings->renderer_string, "Mali-", 5) != 0)
return FALSE;
return TRUE;
}
static const CoglGpuInfoArchitectureDescription
intel_architectures[] =
{
{
COGL_GPU_INFO_ARCHITECTURE_SANDYBRIDGE,
"Sandybridge",
COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_IMMEDIATE_MODE |
COGL_GPU_INFO_ARCHITECTURE_FLAG_FRAGMENT_IMMEDIATE_MODE,
check_sandybridge_architecture
},
{
COGL_GPU_INFO_ARCHITECTURE_UNKNOWN,
"Unknown",
COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_IMMEDIATE_MODE |
COGL_GPU_INFO_ARCHITECTURE_FLAG_FRAGMENT_IMMEDIATE_MODE,
check_true
}
};
static const CoglGpuInfoArchitectureDescription
powervr_architectures[] =
{
{
COGL_GPU_INFO_ARCHITECTURE_SGX,
"SGX",
COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_TILED |
COGL_GPU_INFO_ARCHITECTURE_FLAG_FRAGMENT_DEFERRED,
check_sgx_architecture
},
{
COGL_GPU_INFO_ARCHITECTURE_UNKNOWN,
"Unknown",
COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_TILED |
COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_TILED,
check_true
}
};
static const CoglGpuInfoArchitectureDescription
arm_architectures[] =
{
{
COGL_GPU_INFO_ARCHITECTURE_MALI,
"Mali",
COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_TILED |
COGL_GPU_INFO_ARCHITECTURE_FLAG_FRAGMENT_IMMEDIATE_MODE,
check_mali_architecture
},
{
COGL_GPU_INFO_ARCHITECTURE_UNKNOWN,
"Unknown",
COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_TILED |
COGL_GPU_INFO_ARCHITECTURE_FLAG_FRAGMENT_IMMEDIATE_MODE,
check_true
}
};
static const CoglGpuInfoArchitectureDescription
mesa_architectures[] =
{
{
COGL_GPU_INFO_ARCHITECTURE_LLVMPIPE,
"LLVM Pipe",
COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_IMMEDIATE_MODE |
COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_SOFTWARE |
COGL_GPU_INFO_ARCHITECTURE_FLAG_FRAGMENT_IMMEDIATE_MODE |
COGL_GPU_INFO_ARCHITECTURE_FLAG_FRAGMENT_SOFTWARE,
check_llvmpipe_architecture
},
{
COGL_GPU_INFO_ARCHITECTURE_SOFTPIPE,
"Softpipe",
COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_IMMEDIATE_MODE |
COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_SOFTWARE |
COGL_GPU_INFO_ARCHITECTURE_FLAG_FRAGMENT_IMMEDIATE_MODE |
COGL_GPU_INFO_ARCHITECTURE_FLAG_FRAGMENT_SOFTWARE,
check_softpipe_architecture
},
{
COGL_GPU_INFO_ARCHITECTURE_SWRAST,
"SWRast",
COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_IMMEDIATE_MODE |
COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_SOFTWARE |
COGL_GPU_INFO_ARCHITECTURE_FLAG_FRAGMENT_IMMEDIATE_MODE |
COGL_GPU_INFO_ARCHITECTURE_FLAG_FRAGMENT_SOFTWARE,
check_swrast_architecture
},
{
COGL_GPU_INFO_ARCHITECTURE_UNKNOWN,
"Unknown",
COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_IMMEDIATE_MODE |
COGL_GPU_INFO_ARCHITECTURE_FLAG_FRAGMENT_IMMEDIATE_MODE,
check_true
}
};
static const CoglGpuInfoArchitectureDescription
unknown_architectures[] =
{
{
COGL_GPU_INFO_ARCHITECTURE_UNKNOWN,
"Unknown",
COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_IMMEDIATE_MODE |
COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_IMMEDIATE_MODE,
check_true
}
};
static const CoglGpuInfoVendorDescription static const CoglGpuInfoVendorDescription
_cogl_gpu_info_vendors[] = _cogl_gpu_info_vendors[] =
{ {
{ {
COGL_GPU_INFO_VENDOR_INTEL, COGL_GPU_INFO_VENDOR_INTEL,
"Intel", "Intel",
check_intel_vendor check_intel_vendor,
intel_architectures
},
{
COGL_GPU_INFO_VENDOR_IMAGINATION_TECHNOLOGIES,
"Imagination Technologies",
check_imagination_technologies_vendor,
powervr_architectures
},
{
COGL_GPU_INFO_VENDOR_ARM,
"ARM",
check_arm_vendor,
arm_architectures
},
{
COGL_GPU_INFO_VENDOR_QUALCOMM,
"Qualcomm",
check_qualcomm_vendor,
unknown_architectures
},
{
COGL_GPU_INFO_VENDOR_NVIDIA,
"Nvidia",
check_nvidia_vendor,
unknown_architectures
},
{
COGL_GPU_INFO_VENDOR_ATI,
"ATI",
check_ati_vendor,
unknown_architectures
}, },
/* Must be last */ /* Must be last */
{
COGL_GPU_INFO_VENDOR_MESA,
"Mesa",
check_mesa_vendor,
mesa_architectures
},
{ {
COGL_GPU_INFO_VENDOR_UNKNOWN, COGL_GPU_INFO_VENDOR_UNKNOWN,
"Unknown", "Unknown",
check_unknown_vendor check_true,
unknown_architectures
} }
}; };
@ -243,11 +507,33 @@ _cogl_gpu_info_init (CoglContext *ctx,
if (description->check_function (&strings)) if (description->check_function (&strings))
{ {
int j;
gpu->vendor = description->vendor; gpu->vendor = description->vendor;
gpu->vendor_name = description->name; gpu->vendor_name = description->name;
break;
for (j = 0; ; j++)
{
const CoglGpuInfoArchitectureDescription *architecture =
description->architectures + j;
if (architecture->check_function (&strings))
{
gpu->architecture = architecture->architecture;
gpu->architecture_name = architecture->name;
gpu->architecture_flags = architecture->flags;
goto probed;
} }
} }
}
}
probed:
COGL_NOTE (WINSYS, "Driver package = %s, vendor = %s, architecture = %s\n",
gpu->driver_package_name,
gpu->vendor_name,
gpu->architecture_name);
/* Determine the driver bugs */ /* Determine the driver bugs */