Hey,

knowing that we're starting to have serious issues with figuring out what 
features the given device supports and what api's/extensions can be reasonably 
implemented on top of it I've spent the weekend trying to define feature 
levels. Feature levels were effectively defined by the Direct3D version 
numbers. 
Attached is a patch and documentation for the feature levels. I'm also 
attaching gallium_feature_levels.rst file which documents what each feature 
level means and what apis can be reasonably supported by each (I figured it's 
going to be easier to look at it outside the diff).

There's a few features that are a bit problematic, in no particular order:
- unnormalized coordinates, we don't even have a cap for those right now but 
since that feature doesn't exist in direct3d (all coords are always normalized 
in d3d) the support for it is hard to define in term of a feature level
- two-sided stencil - d3d supports it in d3d10 but tons of hardware supported 
it earlier
- extra mirror wrap modes - i don't think mirror repeat was ever supported and 
mirror clamp was removed in d3d10 but it seems that some hardware kept support 
for those
- shadow maps - it's more of an "researched guess" since it's largely based on 
a format support, but as far as i can tell all d3d10 hardware supports it, 
earlier it varies (e.g. nvidia did it for ages)

I think the other stuff is acceptable. Take a look at the docs and let me know 
what you think.

z
From 962994ad9f05b6ae219f839082d4743e7d2a70fe Mon Sep 17 00:00:00 2001
From: Zack Rusin <z...@kde.org>
Date: Mon, 11 Jan 2010 12:34:26 -0500
Subject: [PATCH] gallium: implement feature levels

a broader way of figuring out features of the hardware we're running on
---
 src/gallium/docs/source/gallium_feature_levels.rst |   69 ++++++++++++++++++++
 src/gallium/docs/source/screen.rst                 |    5 ++
 src/gallium/drivers/cell/ppu/cell_screen.c         |   27 ++------
 src/gallium/drivers/i915/i915_screen.c             |   21 ++----
 src/gallium/drivers/i965/brw_screen.c              |   21 ++----
 src/gallium/drivers/identity/id_screen.c           |   10 +++
 src/gallium/drivers/llvmpipe/lp_screen.c           |   28 ++------
 src/gallium/drivers/nv04/nv04_screen.c             |   29 ++------
 src/gallium/drivers/nv10/nv10_screen.c             |   25 ++-----
 src/gallium/drivers/nv20/nv20_screen.c             |   25 ++-----
 src/gallium/drivers/nv30/nv30_screen.c             |   29 ++------
 src/gallium/drivers/nv40/nv40_screen.c             |   28 ++------
 src/gallium/drivers/nv50/nv50_screen.c             |   28 ++------
 src/gallium/drivers/r300/r300_screen.c             |   60 +++--------------
 src/gallium/drivers/softpipe/sp_screen.c           |   28 ++------
 src/gallium/drivers/svga/svga_screen.c             |   28 ++------
 src/gallium/drivers/trace/tr_screen.c              |   20 ++++++
 src/gallium/include/pipe/p_defines.h               |   29 +++++----
 src/gallium/include/pipe/p_screen.h                |    5 ++
 src/mesa/state_tracker/st_cb_drawpixels.c          |    4 +-
 src/mesa/state_tracker/st_extensions.c             |   23 ++++---
 21 files changed, 231 insertions(+), 311 deletions(-)
 create mode 100644 src/gallium/docs/source/gallium_feature_levels.rst

diff --git a/src/gallium/docs/source/gallium_feature_levels.rst b/src/gallium/docs/source/gallium_feature_levels.rst
new file mode 100644
index 0000000..fcde68d
--- /dev/null
+++ b/src/gallium/docs/source/gallium_feature_levels.rst
@@ -0,0 +1,69 @@
+Profile                             7 (2009)        6 (2008)        5 (2006)        4 (2004)        3 (2003)        2 (2002)         1 (2000)
+
+API Support                         DX11            DX10.1          DX10/GL3.2      DX9.2           DX9.1           DX9.0            DX7.0
+                                    GL4.0           GL3.2+          GL3.2           GL3.0           GL2.x           GL2.x            GL2.x
+                                    VG              VG              VG              VG              VG              VG               VG
+                                    CL1.0           CL1.0           CL1.0
+
+Shader Model	                    5.0	            4.x	            4.0	            2.0             2.0             2.0              1.0
+                                                                                    4_0_level_9_3   4_0_level_9_1   4_0_level_9_1
+
+Fragment Shader                     Yes             Yes             Yes             Yes             Yes             Yes              Yes
+Vertex Shader                       Yes             Yes             Yes             Yes             Yes             Yes              No
+Geometry Shader	                    Yes	            Yes	            Yes	            No              No              No               No
+Stream Out	                    Yes	            Yes	            Yes	            No	            No	            No               No
+Compute Shader	                    Yes	            Optional	    Optional	    No	            No	            No               No
+Hull and Domain Shaders	            Yes	            No	            No	            No	            No	            No               No
+Texture Resource Arrays	            Yes	            Yes	            Yes	            No	            No	            No               No
+Cubemap Resource Arrays	            Yes	            Yes	            No	            No	            No	            No               No
+BC4/BC5 Compression	            Yes	            Yes	            Yes	            No	            No	            No               No
+BC6H/BC7 Compression	            Yes	            No	            No	            No	            No	            No               No
+Alpha-to-coverage	            Yes	            Yes	            Yes	            No	            No	            No               No
+Extended Formats*(BGRA, etc.)	    Yes	            Optional	    Optional	    Yes	            Yes	            Yes              No
+10-bit XR High Color Format	    Yes	            Optional	    Optional	    N/A	            N/A	            N/A              N/A
+Max Texture Dimension	            16384	    8192	    8192	    4096	    2048	    2048             2048
+Max Cubemap Dimension	            16384	    8192	    8192	    4096	    512	            512              512
+Max Volume Extent	            2048	    2048	    2048	    256	            256	            256              256
+Max Texture Repeat	            16384	    8192	    8192	    8192	    2048	    128              128
+Max Anisotropy	                    16	            16	            16	            16	            16	            2                0
+Max Primitive Count	            2^32	    2^32	    2^32	    1048575	    1048575	    65535            65535
+Simultaneous Render Targets	    8	            8	            8	            4	            1	            1                1
+Occlusion Queries	            Yes	            Yes	            Yes	            Yes	            Yes	            No               No
+Separate Alpha Blend	            Yes	            Yes	            Yes	            Yes	            Yes	            No               No
+Mirror Once	                    Yes	            Yes	            Yes	            Yes	            Yes	            No               No
+Overlapping Vertex Elements	    Yes	            Yes	            Yes	            Yes	            Yes	            No               No
+Independent Write Masks	            Yes	            Yes	            Yes	            Yes	            No	            No               No
+Instancing	                    Yes	            Yes	            Yes	            Yes	            No	            No               No
+Independent blend modes             Yes             Yes             No              No              No              No               No
+Dual-source blending                Yes             Yes             Yes             No              No              No               No
+Two sided stencil                   Yes             Yes             Yes             No              No              No               No
+Cube textures dimensions pot        No              No              No              Yes             Yes             Yes              Yes
+2D textures pot if MipCount >1      No              No              No              No              Yes             Yes              Yes
+DXTC / S3TC (*1)                    Yes             Yes             Yes             Yes             Yes             Yes              Yes
+Point Sprites                       No              No              No              Yes             Yes             Yes              Yes
+Unnormalized texture coordinates    N/A             N/A             N/A             N/A             N/A             N/A              N/A
+Triangle fans                       No              No              No              Yes             Yes             Yes              Yes
+Occlusion query                     Yes             Yes             Yes             Yes             Yes             Yes              No
+Shadow maps (*2)                    Yes             Yes             Yes             No              No              No               No
+Guard band clipping (*3)            N/A             N/A             N/A             N/A             N/A             N/A              N/A
+Texture mirror clamp                No              No              No              Yes             Yes             Yes              No
+Texture mirror repeat               No              No              No              No              No              No               No
+
+
+
+*1) There is no distinction between pre-multiplied alpha or non-premultiplied 
+alpha in Direct3D 10. DXT formats have been replaced by BC formats, so DXT1 == BC1,
+DXT2,DXT3 == BC2 and DXT4,DXT5 == BC3 (bc for block compression)
+*2) There's lots of ways of performing shadow mapping but what we refer to is simply 
+the ability to sample & filter from a depth texture. This ability is format dependent
+and therefore doesn't strickly adhere to the feature levels but all major vendors
+(NVIDIA, AMD, Intel) seem to support it in their DX10 level GPUs.
+*3) It's part of the functionality a driver can support or not. At least for DX9 level
+drivers. I'm not sure what happened with it afterwards.
+
+References:
+http://msdn.microsoft.com/en-us/library/ee422086(VS.85).aspx#Overview
+http://msdn.microsoft.com/en-us/library/ee416168(VS.85).aspx
+http://msdn.microsoft.com/en-us/library/ee416166(VS.85).aspx
+http://msdn.microsoft.com/en-us/library/ee415655(VS.85).aspx
+http://msdn.microsoft.com/en-us/library/ms792615.aspx
diff --git a/src/gallium/docs/source/screen.rst b/src/gallium/docs/source/screen.rst
index 9631e69..7571445 100644
--- a/src/gallium/docs/source/screen.rst
+++ b/src/gallium/docs/source/screen.rst
@@ -18,6 +18,11 @@ get_vendor
 
 Returns the screen vendor.
 
+feature_level
+^^^^^^^^^^
+
+Returns the latest feature level supported by the device.
+
 get_param
 ^^^^^^^^^
 
diff --git a/src/gallium/drivers/cell/ppu/cell_screen.c b/src/gallium/drivers/cell/ppu/cell_screen.c
index d185c6b..545ab58 100644
--- a/src/gallium/drivers/cell/ppu/cell_screen.c
+++ b/src/gallium/drivers/cell/ppu/cell_screen.c
@@ -51,6 +51,12 @@ cell_get_name(struct pipe_screen *screen)
    return "Cell";
 }
 
+static const enum pipe_feature_level
+cell_feature_level(struct pipe_screen *screen)
+{
+   return PIPE_FEATURE_LEVEL_3;
+}
+
 
 static int
 cell_get_param(struct pipe_screen *screen, int param)
@@ -58,34 +64,14 @@ cell_get_param(struct pipe_screen *screen, int param)
    switch (param) {
    case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
       return CELL_MAX_SAMPLERS;
-   case PIPE_CAP_NPOT_TEXTURES:
-      return 1;
-   case PIPE_CAP_TWO_SIDED_STENCIL:
-      return 1;
-   case PIPE_CAP_GLSL:
-      return 1;
-   case PIPE_CAP_ANISOTROPIC_FILTER:
-      return 0;
-   case PIPE_CAP_POINT_SPRITE:
-      return 1;
    case PIPE_CAP_MAX_RENDER_TARGETS:
       return 1;
-   case PIPE_CAP_OCCLUSION_QUERY:
-      return 1;
-   case PIPE_CAP_TEXTURE_SHADOW_MAP:
-      return 10;
    case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
       return CELL_MAX_TEXTURE_LEVELS;
    case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
       return 8;  /* max 128x128x128 */
    case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
       return CELL_MAX_TEXTURE_LEVELS;
-   case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
-      return 1; /* XXX not really true */
-   case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
-      return 0; /* XXX to do */
-   case PIPE_CAP_TGSI_CONT_SUPPORTED:
-      return 1;
    default:
       return 0;
    }
@@ -165,6 +151,7 @@ cell_create_screen(struct pipe_winsys *winsys)
 
    screen->get_name = cell_get_name;
    screen->get_vendor = cell_get_vendor;
+   screen->feature_level = cell_feature_level;
    screen->get_param = cell_get_param;
    screen->get_paramf = cell_get_paramf;
    screen->is_format_supported = cell_is_format_supported;
diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c
index d4ee8f5..519c0a3 100644
--- a/src/gallium/drivers/i915/i915_screen.c
+++ b/src/gallium/drivers/i915/i915_screen.c
@@ -89,28 +89,20 @@ i915_get_name(struct pipe_screen *screen)
    return buffer;
 }
 
+static const enum pipe_feature_level
+i915_feature_level(struct pipe_screen *screen)
+{
+   return PIPE_FEATURE_LEVEL_1;
+}
+
 static int
 i915_get_param(struct pipe_screen *screen, int param)
 {
    switch (param) {
    case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
       return 8;
-   case PIPE_CAP_NPOT_TEXTURES:
-      return 1;
-   case PIPE_CAP_TWO_SIDED_STENCIL:
-      return 1;
-   case PIPE_CAP_GLSL:
-      return 0;
-   case PIPE_CAP_ANISOTROPIC_FILTER:
-      return 0;
-   case PIPE_CAP_POINT_SPRITE:
-      return 0;
    case PIPE_CAP_MAX_RENDER_TARGETS:
       return 1;
-   case PIPE_CAP_OCCLUSION_QUERY:
-      return 0;
-   case PIPE_CAP_TEXTURE_SHADOW_MAP:
-      return 1;
    case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
       return 11; /* max 1024x1024 */
    case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
@@ -284,6 +276,7 @@ i915_create_screen(struct intel_winsys *iws, uint pci_id)
 
    is->base.get_name = i915_get_name;
    is->base.get_vendor = i915_get_vendor;
+   is->base.feature_level = i915_feature_level;
    is->base.get_param = i915_get_param;
    is->base.get_paramf = i915_get_paramf;
    is->base.is_format_supported = i915_is_format_supported;
diff --git a/src/gallium/drivers/i965/brw_screen.c b/src/gallium/drivers/i965/brw_screen.c
index 0ecacac..de5a060 100644
--- a/src/gallium/drivers/i965/brw_screen.c
+++ b/src/gallium/drivers/i965/brw_screen.c
@@ -144,28 +144,20 @@ brw_get_name(struct pipe_screen *screen)
    return buffer;
 }
 
+static const enum pipe_feature_level
+brw_feature_level(struct pipe_screen *screen)
+{
+   return PIPE_FEATURE_LEVEL_4;
+}
+
 static int
 brw_get_param(struct pipe_screen *screen, int param)
 {
    switch (param) {
    case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
       return 8;
-   case PIPE_CAP_NPOT_TEXTURES:
-      return 1;
-   case PIPE_CAP_TWO_SIDED_STENCIL:
-      return 1;
-   case PIPE_CAP_GLSL:
-      return 0;
-   case PIPE_CAP_ANISOTROPIC_FILTER:
-      return 0;
-   case PIPE_CAP_POINT_SPRITE:
-      return 0;
    case PIPE_CAP_MAX_RENDER_TARGETS:
       return 1;
-   case PIPE_CAP_OCCLUSION_QUERY:
-      return 0;
-   case PIPE_CAP_TEXTURE_SHADOW_MAP:
-      return 1;
    case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
       return 11; /* max 1024x1024 */
    case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
@@ -385,6 +377,7 @@ brw_create_screen(struct brw_winsys_screen *sws, uint pci_id)
    bscreen->base.destroy = brw_destroy_screen;
    bscreen->base.get_name = brw_get_name;
    bscreen->base.get_vendor = brw_get_vendor;
+   bscreen->base.feature_level = brw_feature_level;
    bscreen->base.get_param = brw_get_param;
    bscreen->base.get_paramf = brw_get_paramf;
    bscreen->base.is_format_supported = brw_is_format_supported;
diff --git a/src/gallium/drivers/identity/id_screen.c b/src/gallium/drivers/identity/id_screen.c
index 53eae3e..dd8422a 100644
--- a/src/gallium/drivers/identity/id_screen.c
+++ b/src/gallium/drivers/identity/id_screen.c
@@ -64,6 +64,15 @@ identity_screen_get_vendor(struct pipe_screen *_screen)
    return screen->get_vendor(screen);
 }
 
+static const enum pipe_feature_level
+identity_screen_feature_level(struct pipe_screen *_screen)
+{
+   struct identity_screen *id_screen = identity_screen(_screen);
+   struct pipe_screen *screen = id_screen->screen;
+
+   return screen->feature_level(screen);
+}
+
 static int
 identity_screen_get_param(struct pipe_screen *_screen,
                           int param)
@@ -475,6 +484,7 @@ identity_screen_create(struct pipe_screen *screen)
    id_screen->base.destroy = identity_screen_destroy;
    id_screen->base.get_name = identity_screen_get_name;
    id_screen->base.get_vendor = identity_screen_get_vendor;
+   id_screen->base.feature_level = identity_screen_feature_level;
    id_screen->base.get_param = identity_screen_get_param;
    id_screen->base.get_paramf = identity_screen_get_paramf;
    id_screen->base.is_format_supported = identity_screen_is_format_supported;
diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c
index 9b47415..bd785a3 100644
--- a/src/gallium/drivers/llvmpipe/lp_screen.c
+++ b/src/gallium/drivers/llvmpipe/lp_screen.c
@@ -69,6 +69,11 @@ llvmpipe_get_name(struct pipe_screen *screen)
    return "llvmpipe";
 }
 
+static const enum pipe_feature_level
+llvmpipe_feature_level(struct pipe_screen *screen)
+{
+   return PIPE_FEATURE_LEVEL_4;
+}
 
 static int
 llvmpipe_get_param(struct pipe_screen *screen, int param)
@@ -80,36 +85,14 @@ llvmpipe_get_param(struct pipe_screen *screen, int param)
       return PIPE_MAX_VERTEX_SAMPLERS;
    case PIPE_CAP_MAX_COMBINED_SAMPLERS:
       return PIPE_MAX_SAMPLERS + PIPE_MAX_VERTEX_SAMPLERS;
-   case PIPE_CAP_NPOT_TEXTURES:
-      return 1;
-   case PIPE_CAP_TWO_SIDED_STENCIL:
-      return 1;
-   case PIPE_CAP_GLSL:
-      return 1;
-   case PIPE_CAP_ANISOTROPIC_FILTER:
-      return 0;
-   case PIPE_CAP_POINT_SPRITE:
-      return 1;
    case PIPE_CAP_MAX_RENDER_TARGETS:
       return PIPE_MAX_COLOR_BUFS;
-   case PIPE_CAP_OCCLUSION_QUERY:
-      return 1;
-   case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
-      return 1;
-   case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
-      return 1;
-   case PIPE_CAP_TEXTURE_SHADOW_MAP:
-      return 1;
    case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
       return 13; /* max 4Kx4K */
    case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
       return 9;  /* max 256x256x256 */
    case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
       return 13; /* max 4Kx4K */
-   case PIPE_CAP_TGSI_CONT_SUPPORTED:
-      return 1;
-   case PIPE_CAP_BLEND_EQUATION_SEPARATE:
-      return 1;
    default:
       return 0;
    }
@@ -290,6 +273,7 @@ llvmpipe_create_screen(struct llvmpipe_winsys *winsys)
 
    screen->base.get_name = llvmpipe_get_name;
    screen->base.get_vendor = llvmpipe_get_vendor;
+   screen->base.feature_level = llvmpipe_feature_level;
    screen->base.get_param = llvmpipe_get_param;
    screen->base.get_paramf = llvmpipe_get_paramf;
    screen->base.is_format_supported = llvmpipe_is_format_supported;
diff --git a/src/gallium/drivers/nv04/nv04_screen.c b/src/gallium/drivers/nv04/nv04_screen.c
index 7c5b6e8..2d289d5 100644
--- a/src/gallium/drivers/nv04/nv04_screen.c
+++ b/src/gallium/drivers/nv04/nv04_screen.c
@@ -4,28 +4,20 @@
 #include "nv04_context.h"
 #include "nv04_screen.h"
 
+static const enum pipe_feature_level
+nv04_screen_feature_level(struct pipe_screen *screen)
+{
+   return PIPE_FEATURE_LEVEL_1;
+}
+
 static int
 nv04_screen_get_param(struct pipe_screen *screen, int param)
 {
 	switch (param) {
 	case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
 		return 1;
-	case PIPE_CAP_NPOT_TEXTURES:
-		return 0;
-	case PIPE_CAP_TWO_SIDED_STENCIL:
-		return 0;
-	case PIPE_CAP_GLSL:
-		return 0;
-	case PIPE_CAP_ANISOTROPIC_FILTER:
-		return 0;
-	case PIPE_CAP_POINT_SPRITE:
-		return 0;
 	case PIPE_CAP_MAX_RENDER_TARGETS:
 		return 1;
-	case PIPE_CAP_OCCLUSION_QUERY:
-		return 0;
-	case PIPE_CAP_TEXTURE_SHADOW_MAP:
-		return 0;
 	case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
 		return 10;
 	case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
@@ -34,14 +26,6 @@ nv04_screen_get_param(struct pipe_screen *screen, int param)
 		return 0;
 	case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
 		return 0;
-	case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
-		return 0;
-	case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
-		return 1;
-	case PIPE_CAP_TGSI_CONT_SUPPORTED:
-		return 0;
-	case PIPE_CAP_BLEND_EQUATION_SEPARATE:
-		return 0;
 	case NOUVEAU_CAP_HW_VTXBUF:
 	case NOUVEAU_CAP_HW_IDXBUF:
 		return 0;
@@ -154,6 +138,7 @@ nv04_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
 
 	pscreen->winsys = ws;
 	pscreen->destroy = nv04_screen_destroy;
+        pscreen->feature_level = nv04_screen_feature_level;
 	pscreen->get_param = nv04_screen_get_param;
 	pscreen->get_paramf = nv04_screen_get_paramf;
 	pscreen->is_format_supported = nv04_screen_is_format_supported;
diff --git a/src/gallium/drivers/nv10/nv10_screen.c b/src/gallium/drivers/nv10/nv10_screen.c
index 69a6dab..ed6e2be 100644
--- a/src/gallium/drivers/nv10/nv10_screen.c
+++ b/src/gallium/drivers/nv10/nv10_screen.c
@@ -3,28 +3,20 @@
 #include "nv10_context.h"
 #include "nv10_screen.h"
 
+static const enum pipe_feature_level
+nv10_screen_feature_level(struct pipe_screen *screen)
+{
+   return PIPE_FEATURE_LEVEL_1;
+}
+
 static int
 nv10_screen_get_param(struct pipe_screen *screen, int param)
 {
 	switch (param) {
 	case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
 		return 2;
-	case PIPE_CAP_NPOT_TEXTURES:
-		return 0;
-	case PIPE_CAP_TWO_SIDED_STENCIL:
-		return 0;
-	case PIPE_CAP_GLSL:
-		return 0;
-	case PIPE_CAP_ANISOTROPIC_FILTER:
-		return 1;
-	case PIPE_CAP_POINT_SPRITE:
-		return 0;
 	case PIPE_CAP_MAX_RENDER_TARGETS:
 		return 1;
-	case PIPE_CAP_OCCLUSION_QUERY:
-		return 0;
-	case PIPE_CAP_TEXTURE_SHADOW_MAP:
-		return 0;
 	case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
 		return 12;
 	case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
@@ -33,10 +25,6 @@ nv10_screen_get_param(struct pipe_screen *screen, int param)
 		return 12;
 	case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
 		return 0;
-	case PIPE_CAP_TGSI_CONT_SUPPORTED:
-		return 0;
-	case PIPE_CAP_BLEND_EQUATION_SEPARATE:
-		return 0;
 	case NOUVEAU_CAP_HW_VTXBUF:
 	case NOUVEAU_CAP_HW_IDXBUF:
 		return 0;
@@ -152,6 +140,7 @@ nv10_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
 
 	pscreen->winsys = ws;
 	pscreen->destroy = nv10_screen_destroy;
+        pscreen->feature_level = nv10_screen_feature_level;
 	pscreen->get_param = nv10_screen_get_param;
 	pscreen->get_paramf = nv10_screen_get_paramf;
 	pscreen->is_format_supported = nv10_screen_is_format_supported;
diff --git a/src/gallium/drivers/nv20/nv20_screen.c b/src/gallium/drivers/nv20/nv20_screen.c
index d091335..fe52fc8 100644
--- a/src/gallium/drivers/nv20/nv20_screen.c
+++ b/src/gallium/drivers/nv20/nv20_screen.c
@@ -3,28 +3,20 @@
 #include "nv20_context.h"
 #include "nv20_screen.h"
 
+static const enum pipe_feature_level
+nv20_screen_feature_level(struct pipe_screen *screen)
+{
+   return PIPE_FEATURE_LEVEL_1;
+}
+
 static int
 nv20_screen_get_param(struct pipe_screen *screen, int param)
 {
 	switch (param) {
 	case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
 		return 2;
-	case PIPE_CAP_NPOT_TEXTURES:
-		return 0;
-	case PIPE_CAP_TWO_SIDED_STENCIL:
-		return 0;
-	case PIPE_CAP_GLSL:
-		return 0;
-	case PIPE_CAP_ANISOTROPIC_FILTER:
-		return 1;
-	case PIPE_CAP_POINT_SPRITE:
-		return 0;
 	case PIPE_CAP_MAX_RENDER_TARGETS:
 		return 1;
-	case PIPE_CAP_OCCLUSION_QUERY:
-		return 0;
-	case PIPE_CAP_TEXTURE_SHADOW_MAP:
-		return 0;
 	case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
 		return 12;
 	case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
@@ -33,10 +25,6 @@ nv20_screen_get_param(struct pipe_screen *screen, int param)
 		return 12;
 	case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
 		return 0;
-	case PIPE_CAP_TGSI_CONT_SUPPORTED:
-		return 0;
-	case PIPE_CAP_BLEND_EQUATION_SEPARATE:
-		return 0;
 	case NOUVEAU_CAP_HW_VTXBUF:
 	case NOUVEAU_CAP_HW_IDXBUF:
 		return 0;
@@ -152,6 +140,7 @@ nv20_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
 
 	pscreen->winsys = ws;
 	pscreen->destroy = nv20_screen_destroy;
+        pscreen->feature_level = nv20_screen_feature_level;
 	pscreen->get_param = nv20_screen_get_param;
 	pscreen->get_paramf = nv20_screen_get_paramf;
 	pscreen->is_format_supported = nv20_screen_is_format_supported;
diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c
index 9ed4817..dca6271 100644
--- a/src/gallium/drivers/nv30/nv30_screen.c
+++ b/src/gallium/drivers/nv30/nv30_screen.c
@@ -26,44 +26,28 @@ struct nouveau_winsys {
 	struct pipe_surface *front;
 };
 
+static const enum pipe_feature_level
+nv30_screen_feature_level(struct pipe_screen *screen)
+{
+   return PIPE_FEATURE_LEVEL_1;
+}
+
 static int
 nv30_screen_get_param(struct pipe_screen *pscreen, int param)
 {
 	switch (param) {
 	case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
 		return 16;
-	case PIPE_CAP_NPOT_TEXTURES:
-		return 0;
-	case PIPE_CAP_TWO_SIDED_STENCIL:
-		return 1;
-	case PIPE_CAP_GLSL:
-		return 0;
-	case PIPE_CAP_ANISOTROPIC_FILTER:
-		return 1;
-	case PIPE_CAP_POINT_SPRITE:
-		return 1;
 	case PIPE_CAP_MAX_RENDER_TARGETS:
 		return 2;
-	case PIPE_CAP_OCCLUSION_QUERY:
-		return 1;
-	case PIPE_CAP_TEXTURE_SHADOW_MAP:
-		return 1;
 	case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
 		return 13;
 	case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
 		return 10;
 	case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
 		return 13;
-	case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
-		return 0;
-	case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
-		return 1;
 	case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
 		return 0;
-	case PIPE_CAP_TGSI_CONT_SUPPORTED:
-		return 0;
-	case PIPE_CAP_BLEND_EQUATION_SEPARATE:
-		return 0;
 	case NOUVEAU_CAP_HW_VTXBUF:
 	case NOUVEAU_CAP_HW_IDXBUF:
 		return 1;
@@ -199,6 +183,7 @@ nv30_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
 
 	pscreen->winsys = ws;
 	pscreen->destroy = nv30_screen_destroy;
+        pscreen->feature_level = nv30_screen_feature_level;
 	pscreen->get_param = nv30_screen_get_param;
 	pscreen->get_paramf = nv30_screen_get_paramf;
 	pscreen->is_format_supported = nv30_screen_surface_format_supported;
diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c
index 9e55e5a..c22f2d1 100644
--- a/src/gallium/drivers/nv40/nv40_screen.c
+++ b/src/gallium/drivers/nv40/nv40_screen.c
@@ -7,6 +7,12 @@
 #define NV4X_GRCLASS4497_CHIPSETS 0x00005450
 #define NV6X_GRCLASS4497_CHIPSETS 0x00000088
 
+static const enum pipe_feature_level
+nv40_screen_feature_level(struct pipe_screen *screen)
+{
+   return PIPE_FEATURE_LEVEL_2;
+}
+
 static int
 nv40_screen_get_param(struct pipe_screen *pscreen, int param)
 {
@@ -15,37 +21,16 @@ nv40_screen_get_param(struct pipe_screen *pscreen, int param)
 	switch (param) {
 	case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
 		return 16;
-	case PIPE_CAP_NPOT_TEXTURES:
-		return 1;
-	case PIPE_CAP_TWO_SIDED_STENCIL:
-		return 1;
-	case PIPE_CAP_GLSL:
-		return 0;
-	case PIPE_CAP_ANISOTROPIC_FILTER:
-		return 1;
-	case PIPE_CAP_POINT_SPRITE:
-		return 1;
 	case PIPE_CAP_MAX_RENDER_TARGETS:
 		return 4;
-	case PIPE_CAP_OCCLUSION_QUERY:
-		return 1;
-	case PIPE_CAP_TEXTURE_SHADOW_MAP:
-		return 1;
 	case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
 		return 13;
 	case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
 		return 10;
 	case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
 		return 13;
-	case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
-	case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
-		return 1;
 	case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
 		return 0; /* We have 4 - but unsupported currently */
-	case PIPE_CAP_TGSI_CONT_SUPPORTED:
-		return 0;
-	case PIPE_CAP_BLEND_EQUATION_SEPARATE:
-		return 1;
 	case NOUVEAU_CAP_HW_VTXBUF:
 		return 1;
 	case NOUVEAU_CAP_HW_IDXBUF:
@@ -183,6 +168,7 @@ nv40_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
 
 	pscreen->winsys = ws;
 	pscreen->destroy = nv40_screen_destroy;
+        pscreen->feature_level = nv40_screen_feature_level;
 	pscreen->get_param = nv40_screen_get_param;
 	pscreen->get_paramf = nv40_screen_get_paramf;
 	pscreen->is_format_supported = nv40_screen_surface_format_supported;
diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c
index 28e2b35..8f85337 100644
--- a/src/gallium/drivers/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nv50/nv50_screen.c
@@ -92,6 +92,12 @@ nv50_screen_is_format_supported(struct pipe_screen *pscreen,
 	return FALSE;
 }
 
+static const enum pipe_feature_level
+nv50_screen_feature_level(struct pipe_screen *screen)
+{
+   return PIPE_FEATURE_LEVEL_2;
+}
+
 static int
 nv50_screen_get_param(struct pipe_screen *pscreen, int param)
 {
@@ -102,35 +108,14 @@ nv50_screen_get_param(struct pipe_screen *pscreen, int param)
 		return 32;
 	case PIPE_CAP_MAX_COMBINED_SAMPLERS:
 		return 64;
-	case PIPE_CAP_NPOT_TEXTURES:
-		return 1;
-	case PIPE_CAP_TWO_SIDED_STENCIL:
-		return 1;
-	case PIPE_CAP_GLSL:
-		return 0;
-	case PIPE_CAP_ANISOTROPIC_FILTER:
-		return 1;
-	case PIPE_CAP_POINT_SPRITE:
-		return 1;
 	case PIPE_CAP_MAX_RENDER_TARGETS:
 		return 8;
-	case PIPE_CAP_OCCLUSION_QUERY:
-		return 1;
-	case PIPE_CAP_TEXTURE_SHADOW_MAP:
-		return 1;
 	case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
 		return 13;
 	case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
 		return 10;
 	case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
 		return 13;
-	case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
-	case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
-		return 1;
-	case PIPE_CAP_TGSI_CONT_SUPPORTED:
-		return 1;
-	case PIPE_CAP_BLEND_EQUATION_SEPARATE:
-		return 1;
 	case NOUVEAU_CAP_HW_VTXBUF:
 		return 1;
 	case NOUVEAU_CAP_HW_IDXBUF:
@@ -237,6 +222,7 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
 	pscreen->destroy = nv50_screen_destroy;
 	pscreen->get_param = nv50_screen_get_param;
 	pscreen->get_paramf = nv50_screen_get_paramf;
+        pscreen->feature_level = nv50_screen_feature_level;
 	pscreen->is_format_supported = nv50_screen_is_format_supported;
 	screen->base.pre_pipebuffer_map_callback = nv50_pre_pipebuffer_map;
 
diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c
index 287664b..c73b683 100644
--- a/src/gallium/drivers/r300/r300_screen.c
+++ b/src/gallium/drivers/r300/r300_screen.c
@@ -77,6 +77,16 @@ static const char* r300_get_name(struct pipe_screen* pscreen)
     return chip_families[r300screen->caps->family];
 }
 
+static const enum pipe_feature_level r300_feature_level(
+   struct pipe_screen* pscreen)
+{
+   if (r300screen->caps->is_r500) {
+      return PIPE_FEATURE_LEVEL_2;
+   } else {
+      return PIPE_FEATURE_LEVEL_1;
+   }
+}
+
 static int r300_get_param(struct pipe_screen* pscreen, int param)
 {
     struct r300_screen* r300screen = r300_screen(pscreen);
@@ -86,43 +96,8 @@ static int r300_get_param(struct pipe_screen* pscreen, int param)
         case PIPE_CAP_MAX_COMBINED_SAMPLERS:
             /* XXX I'm told this goes up to 16 */
             return 8;
-        case PIPE_CAP_NPOT_TEXTURES:
-            /* XXX enable now to get GL2.1 API,
-             * figure out later how to emulate this */
-            return 1;
-        case PIPE_CAP_TWO_SIDED_STENCIL:
-            if (r300screen->caps->is_r500) {
-                return 1;
-            } else {
-                return 0;
-            }
-        case PIPE_CAP_GLSL:
-            /* I'll be frank. This is a lie.
-             *
-             * We don't truly support GLSL on any of this driver's chipsets.
-             * To be fair, no chipset supports the full GLSL specification
-             * to the best of our knowledge, but some of the less esoteric
-             * features are still missing here.
-             *
-             * Rather than cripple ourselves intentionally, I'm going to set
-             * this flag, and as Gallium's interface continues to change, I
-             * hope that this single monolithic GLSL enable can slowly get
-             * split down into many different pieces and the state tracker
-             * will handle fallbacks transparently, like it should.
-             *
-             * ~ C.
-             */
-            return 1;
-        case PIPE_CAP_ANISOTROPIC_FILTER:
-            return 1;
-        case PIPE_CAP_POINT_SPRITE:
-            return 1;
         case PIPE_CAP_MAX_RENDER_TARGETS:
             return 4;
-        case PIPE_CAP_OCCLUSION_QUERY:
-            return 1;
-        case PIPE_CAP_TEXTURE_SHADOW_MAP:
-            return 1;
         case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
         case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
         case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
@@ -133,22 +108,8 @@ static int r300_get_param(struct pipe_screen* pscreen, int param)
                 /* 12 == 2048 */
                 return 12;
             }
-        case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
-            return 1;
-        case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
-            return 1;
         case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
             return 0;
-        case PIPE_CAP_TGSI_CONT_SUPPORTED:
-            return 0;
-        case PIPE_CAP_BLEND_EQUATION_SEPARATE:
-            return 1;
-        case PIPE_CAP_SM3:
-            if (r300screen->caps->is_r500) {
-                return 1;
-            } else {
-                return 0;
-            }
         default:
             debug_printf("r300: Implementation error: Bad param %d\n",
                 param);
@@ -403,6 +364,7 @@ struct pipe_screen* r300_create_screen(struct radeon_winsys* radeon_winsys)
     r300screen->screen.destroy = r300_destroy_screen;
     r300screen->screen.get_name = r300_get_name;
     r300screen->screen.get_vendor = r300_get_vendor;
+    r300screen->screen.feature_level = r300_feature_level;
     r300screen->screen.get_param = r300_get_param;
     r300screen->screen.get_paramf = r300_get_paramf;
     r300screen->screen.is_format_supported = r300_is_format_supported;
diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c
index bd3532d..0a0cd15 100644
--- a/src/gallium/drivers/softpipe/sp_screen.c
+++ b/src/gallium/drivers/softpipe/sp_screen.c
@@ -50,6 +50,11 @@ softpipe_get_name(struct pipe_screen *screen)
    return "softpipe";
 }
 
+static const enum pipe_feature_level
+softpipe_feature_level(struct pipe_screen *screen)
+{
+   return PIPE_FEATURE_LEVEL_5;
+}
 
 static int
 softpipe_get_param(struct pipe_screen *screen, int param)
@@ -61,36 +66,14 @@ softpipe_get_param(struct pipe_screen *screen, int param)
       return PIPE_MAX_VERTEX_SAMPLERS;
    case PIPE_CAP_MAX_COMBINED_SAMPLERS:
       return PIPE_MAX_SAMPLERS + PIPE_MAX_VERTEX_SAMPLERS;
-   case PIPE_CAP_NPOT_TEXTURES:
-      return 1;
-   case PIPE_CAP_TWO_SIDED_STENCIL:
-      return 1;
-   case PIPE_CAP_GLSL:
-      return 1;
-   case PIPE_CAP_ANISOTROPIC_FILTER:
-      return 0;
-   case PIPE_CAP_POINT_SPRITE:
-      return 1;
    case PIPE_CAP_MAX_RENDER_TARGETS:
       return PIPE_MAX_COLOR_BUFS;
-   case PIPE_CAP_OCCLUSION_QUERY:
-      return 1;
-   case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
-      return 1;
-   case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
-      return 1;
-   case PIPE_CAP_TEXTURE_SHADOW_MAP:
-      return 1;
    case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
       return 13; /* max 4Kx4K */
    case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
       return 9;  /* max 256x256x256 */
    case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
       return 13; /* max 4Kx4K */
-   case PIPE_CAP_TGSI_CONT_SUPPORTED:
-      return 1;
-   case PIPE_CAP_BLEND_EQUATION_SEPARATE:
-      return 1;
    default:
       return 0;
    }
@@ -188,6 +171,7 @@ softpipe_create_screen(struct pipe_winsys *winsys)
 
    screen->base.get_name = softpipe_get_name;
    screen->base.get_vendor = softpipe_get_vendor;
+   screen->base.feature_level = softpipe_feature_level;
    screen->base.get_param = softpipe_get_param;
    screen->base.get_paramf = softpipe_get_paramf;
    screen->base.is_format_supported = softpipe_is_format_supported;
diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c
index fc1b3c9..317f387 100644
--- a/src/gallium/drivers/svga/svga_screen.c
+++ b/src/gallium/drivers/svga/svga_screen.c
@@ -81,8 +81,11 @@ svga_get_name( struct pipe_screen *pscreen )
 #endif
 }
 
-
-
+static const enum pipe_feature_level
+svga_feature_level(struct pipe_screen *screen)
+{
+   return PIPE_FEATURE_LEVEL_4;
+}
 
 static float
 svga_get_paramf(struct pipe_screen *screen, int param)
@@ -113,26 +116,12 @@ svga_get_paramf(struct pipe_screen *screen, int param)
 
    case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
       return 16;
-   case PIPE_CAP_NPOT_TEXTURES:
-      return 1;
-   case PIPE_CAP_TWO_SIDED_STENCIL:
-      return 1;
-   case PIPE_CAP_GLSL:
-      return svgascreen->use_ps30 && svgascreen->use_vs30;
-   case PIPE_CAP_ANISOTROPIC_FILTER:
-      return 1;
-   case PIPE_CAP_POINT_SPRITE:
-      return 1;
    case PIPE_CAP_MAX_RENDER_TARGETS:
       if(!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_RENDER_TARGETS, &result))
          return 1;
       if(!result.u)
          return 1;
       return MIN2(result.u, PIPE_MAX_COLOR_BUFS);
-   case PIPE_CAP_OCCLUSION_QUERY:
-      return 1;
-   case PIPE_CAP_TEXTURE_SHADOW_MAP:
-      return 1;
    case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
       return SVGA_MAX_TEXTURE_LEVELS;
    case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
@@ -140,12 +129,6 @@ svga_get_paramf(struct pipe_screen *screen, int param)
    case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
       return SVGA_MAX_TEXTURE_LEVELS;
 
-   case PIPE_CAP_TEXTURE_MIRROR_REPEAT: /* req. for GL 1.4 */
-      return 1;
-
-   case PIPE_CAP_BLEND_EQUATION_SEPARATE: /* req. for GL 1.5 */
-      return 1;
-
    default:
       return 0;
    }
@@ -358,6 +341,7 @@ svga_screen_create(struct svga_winsys_screen *sws)
    screen->destroy = svga_destroy_screen;
    screen->get_name = svga_get_name;
    screen->get_vendor = svga_get_vendor;
+   screen->feature_level = svga_feature_level;
    screen->get_param = svga_get_param;
    screen->get_paramf = svga_get_paramf;
    screen->is_format_supported = svga_is_format_supported;
diff --git a/src/gallium/drivers/trace/tr_screen.c b/src/gallium/drivers/trace/tr_screen.c
index 117503a..ef5db76 100644
--- a/src/gallium/drivers/trace/tr_screen.c
+++ b/src/gallium/drivers/trace/tr_screen.c
@@ -83,6 +83,25 @@ trace_screen_get_vendor(struct pipe_screen *_screen)
    return result;
 }
 
+static const enum pipe_feature_level
+trace_screen_feature_level(struct pipe_screen *_screen)
+{
+   struct trace_screen *tr_scr = trace_screen(_screen);
+   struct pipe_screen *screen = tr_scr->screen;
+   enum pipe_feature_level result;
+
+   trace_dump_call_begin("pipe_screen", "feature_level");
+
+   trace_dump_arg(ptr, screen);
+
+   result = screen->feature_level(screen);
+
+   trace_dump_ret(int, result);
+
+   trace_dump_call_end();
+
+   return result;
+}
 
 static int
 trace_screen_get_param(struct pipe_screen *_screen,
@@ -901,6 +920,7 @@ trace_screen_create(struct pipe_screen *screen)
    tr_scr->base.destroy = trace_screen_destroy;
    tr_scr->base.get_name = trace_screen_get_name;
    tr_scr->base.get_vendor = trace_screen_get_vendor;
+   tr_scr->base.feature_level = trace_screen_feature_level;
    tr_scr->base.get_param = trace_screen_get_param;
    tr_scr->base.get_paramf = trace_screen_get_paramf;
    tr_scr->base.is_format_supported = trace_screen_is_format_supported;
diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h
index 35f3830..a1e8ea7 100644
--- a/src/gallium/include/pipe/p_defines.h
+++ b/src/gallium/include/pipe/p_defines.h
@@ -374,15 +374,7 @@ enum pipe_transfer_usage {
  * pipe_screen::get_param() and pipe_screen::get_paramf().
  */
 #define PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS 1
-#define PIPE_CAP_NPOT_TEXTURES           2
-#define PIPE_CAP_TWO_SIDED_STENCIL       3
-#define PIPE_CAP_GLSL                    4  /* XXX need something better */
-#define PIPE_CAP_S3TC                    5  /* XXX: deprecated; cap determined via supported sampler formats */
-#define PIPE_CAP_ANISOTROPIC_FILTER      6
-#define PIPE_CAP_POINT_SPRITE            7
 #define PIPE_CAP_MAX_RENDER_TARGETS      8
-#define PIPE_CAP_OCCLUSION_QUERY         9
-#define PIPE_CAP_TEXTURE_SHADOW_MAP      10
 #define PIPE_CAP_MAX_TEXTURE_2D_LEVELS   11
 #define PIPE_CAP_MAX_TEXTURE_3D_LEVELS   12
 #define PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS 13
@@ -396,16 +388,27 @@ enum pipe_transfer_usage {
 #define PIPE_CAP_GUARD_BAND_TOP          21  /*< float */
 #define PIPE_CAP_GUARD_BAND_RIGHT        22  /*< float */
 #define PIPE_CAP_GUARD_BAND_BOTTOM       23  /*< float */
-#define PIPE_CAP_TEXTURE_MIRROR_CLAMP    24
-#define PIPE_CAP_TEXTURE_MIRROR_REPEAT   25
 #define PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS 26
-#define PIPE_CAP_TGSI_CONT_SUPPORTED     27
-#define PIPE_CAP_BLEND_EQUATION_SEPARATE 28
-#define PIPE_CAP_SM3                     29  /*< Shader Model 3 supported */
 #define PIPE_CAP_MAX_PREDICATE_REGISTERS 30
 #define PIPE_CAP_MAX_COMBINED_SAMPLERS   31  /*< Maximum texture image units accessible from vertex
                                                  and fragment shaders combined */
 
+/**
+ * Feature levels and their meaning are documented
+ * in gallium_feature_levels.rst file.
+ *
+ * They describe features the driver is capable of supporting
+ */
+enum pipe_feature_level
+{
+   PIPE_FEATURE_LEVEL_1,
+   PIPE_FEATURE_LEVEL_2,
+   PIPE_FEATURE_LEVEL_3,
+   PIPE_FEATURE_LEVEL_4,
+   PIPE_FEATURE_LEVEL_5,
+   PIPE_FEATURE_LEVEL_6,
+   PIPE_FEATURE_LEVEL_7
+};
 
 /**
  * Referenced query flags.
diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h
index b8e001a..cef7e12 100644
--- a/src/gallium/include/pipe/p_screen.h
+++ b/src/gallium/include/pipe/p_screen.h
@@ -75,6 +75,11 @@ struct pipe_screen {
    const char *(*get_vendor)( struct pipe_screen * );
 
    /**
+    * Query the feature level supported by this driver.
+    */
+   const enum pipe_feature_level (*feature_level)( struct pipe_screen * );
+
+   /**
     * Query an integer-valued capability/parameter/limit
     * \param param  one of PIPE_CAP_x
     */
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
index 7c66426..bcb7e21 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -328,7 +328,7 @@ make_texture(struct st_context *st,
    /* Need to use POT texture? */
    ptw = width;
    pth = height;
-   if (!screen->get_param(screen, PIPE_CAP_NPOT_TEXTURES)) {
+   if (screen->feature_level(screen) == PIPE_FEATURE_LEVEL_1) {
       int l2pt, maxSize;
 
       l2pt = util_logbase2(width);
@@ -1024,7 +1024,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
    /* Need to use POT texture? */
    ptw = width;
    pth = height;
-   if (!screen->get_param(screen, PIPE_CAP_NPOT_TEXTURES)) {
+   if (screen->feature_level(screen) == PIPE_FEATURE_LEVEL_1) {
       int l2pt, maxSize;
 
       l2pt = util_logbase2(width);
diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c
index 35e0874..80a7b8e 100644
--- a/src/mesa/state_tracker/st_extensions.c
+++ b/src/mesa/state_tracker/st_extensions.c
@@ -128,7 +128,7 @@ void st_init_limits(struct st_context *st)
    /* Is TGSI_OPCODE_CONT supported? */
    /* XXX separate query for early function return? */
    st->ctx->Shader.EmitContReturn =
-      screen->get_param(screen, PIPE_CAP_TGSI_CONT_SUPPORTED);
+      screen->feature_level(screen) >= PIPE_FEATURE_LEVEL_5;
 }
 
 
@@ -197,7 +197,7 @@ void st_init_extensions(struct st_context *st)
       ctx->Extensions.ARB_draw_buffers = GL_TRUE;
    }
 
-   if (screen->get_param(screen, PIPE_CAP_GLSL)) {
+   if (screen->feature_level(screen) >= PIPE_FEATURE_LEVEL_4) {
       ctx->Extensions.ARB_fragment_shader = GL_TRUE;
       ctx->Extensions.ARB_vertex_shader = GL_TRUE;
       ctx->Extensions.ARB_shader_objects = GL_TRUE;
@@ -205,19 +205,20 @@ void st_init_extensions(struct st_context *st)
       ctx->Extensions.ARB_shading_language_120 = GL_TRUE;
    }
 
-   if (screen->get_param(screen, PIPE_CAP_TEXTURE_MIRROR_REPEAT) > 0) {
+   if (screen->feature_level(screen) > PIPE_FEATURE_LEVEL_1) {
       ctx->Extensions.ARB_texture_mirrored_repeat = GL_TRUE;
    }
 
-   if (screen->get_param(screen, PIPE_CAP_BLEND_EQUATION_SEPARATE)) {
+   if (screen->feature_level(screen) >= PIPE_FEATURE_LEVEL_3) {
       ctx->Extensions.EXT_blend_equation_separate = GL_TRUE;
    }
 
-   if (screen->get_param(screen, PIPE_CAP_TEXTURE_MIRROR_CLAMP) > 0) {
+   if (screen->feature_level(screen) >= PIPE_FEATURE_LEVEL_1 &&
+       screen->feature_level(screen) < PIPE_FEATURE_LEVEL_5) {
       ctx->Extensions.EXT_texture_mirror_clamp = GL_TRUE;
    }
 
-   if (screen->get_param(screen, PIPE_CAP_NPOT_TEXTURES)) {
+   if (screen->feature_level(screen) > PIPE_FEATURE_LEVEL_1) {
       ctx->Extensions.ARB_texture_non_power_of_two = GL_TRUE;
       ctx->Extensions.NV_texture_rectangle = GL_TRUE;
    }
@@ -226,27 +227,27 @@ void st_init_extensions(struct st_context *st)
       ctx->Extensions.ARB_multitexture = GL_TRUE;
    }
 
-   if (screen->get_param(screen, PIPE_CAP_TWO_SIDED_STENCIL)) {
+   if (screen->feature_level(screen) > PIPE_FEATURE_LEVEL_3) {
       ctx->Extensions.ATI_separate_stencil = GL_TRUE;
       ctx->Extensions.EXT_stencil_two_side = GL_TRUE;
    }
 
-   if (screen->get_param(screen, PIPE_CAP_ANISOTROPIC_FILTER)) {
+   if (screen->feature_level(screen) > PIPE_FEATURE_LEVEL_2) {
       ctx->Extensions.EXT_texture_filter_anisotropic = GL_TRUE;
    }
 
-   if (screen->get_param(screen, PIPE_CAP_POINT_SPRITE)) {
+   if (screen->feature_level(screen) < PIPE_FEATURE_LEVEL_5) {
       ctx->Extensions.ARB_point_sprite = GL_TRUE;
       /* GL_NV_point_sprite is not supported by gallium because we don't
        * support the GL_POINT_SPRITE_R_MODE_NV option.
        */
    }
 
-   if (screen->get_param(screen, PIPE_CAP_OCCLUSION_QUERY)) {
+   if (screen->feature_level(screen) >= PIPE_FEATURE_LEVEL_3) {
       ctx->Extensions.ARB_occlusion_query = GL_TRUE;
    }
 
-   if (screen->get_param(screen, PIPE_CAP_TEXTURE_SHADOW_MAP)) {
+   if (screen->feature_level(screen) >= PIPE_FEATURE_LEVEL_5) {
       ctx->Extensions.ARB_depth_texture = GL_TRUE;
       ctx->Extensions.ARB_shadow = GL_TRUE;
       ctx->Extensions.EXT_shadow_funcs = GL_TRUE;
-- 
1.6.6

Profile                             7 (2009)        6 (2008)        5 (2006)    
    4 (2004)        3 (2003)        2 (2002)         1 (2000)

API Support                         DX11            DX10.1          DX10/GL3.2  
    DX9.2           DX9.1           DX9.0            DX7.0
                                    GL4.0           GL3.2+          GL3.2       
    GL3.0           GL2.x           GL2.x            GL2.x
                                    VG              VG              VG          
    VG              VG              VG               VG
                                    CL1.0           CL1.0           CL1.0

Shader Model                        5.0             4.x             4.0         
    2.0             2.0             2.0              1.0
                                                                                
    4_0_level_9_3   4_0_level_9_1   4_0_level_9_1

Fragment Shader                     Yes             Yes             Yes         
    Yes             Yes             Yes              Yes
Vertex Shader                       Yes             Yes             Yes         
    Yes             Yes             Yes              No
Geometry Shader                     Yes             Yes             Yes         
    No              No              No               No
Stream Out                          Yes             Yes             Yes         
    No              No              No               No
Compute Shader                      Yes             Optional        Optional    
    No              No              No               No
Hull and Domain Shaders             Yes             No              No          
    No              No              No               No
Texture Resource Arrays             Yes             Yes             Yes         
    No              No              No               No
Cubemap Resource Arrays             Yes             Yes             No          
    No              No              No               No
BC4/BC5 Compression                 Yes             Yes             Yes         
    No              No              No               No
BC6H/BC7 Compression                Yes             No              No          
    No              No              No               No
Alpha-to-coverage                   Yes             Yes             Yes         
    No              No              No               No
Extended Formats*(BGRA, etc.)       Yes             Optional        Optional    
    Yes             Yes             Yes              No
10-bit XR High Color Format         Yes             Optional        Optional    
    N/A             N/A             N/A              N/A
Max Texture Dimension               16384           8192            8192        
    4096            2048            2048             2048
Max Cubemap Dimension               16384           8192            8192        
    4096            512             512              512
Max Volume Extent                   2048            2048            2048        
    256             256             256              256
Max Texture Repeat                  16384           8192            8192        
    8192            2048            128              128
Max Anisotropy                      16              16              16          
    16              16              2                0
Max Primitive Count                 2^32            2^32            2^32        
    1048575         1048575         65535            65535
Simultaneous Render Targets         8               8               8           
    4               1               1                1
Occlusion Queries                   Yes             Yes             Yes         
    Yes             Yes             No               No
Separate Alpha Blend                Yes             Yes             Yes         
    Yes             Yes             No               No
Mirror Once                         Yes             Yes             Yes         
    Yes             Yes             No               No
Overlapping Vertex Elements         Yes             Yes             Yes         
    Yes             Yes             No               No
Independent Write Masks             Yes             Yes             Yes         
    Yes             No              No               No
Instancing                          Yes             Yes             Yes         
    Yes             No              No               No
Independent blend modes             Yes             Yes             No          
    No              No              No               No
Dual-source blending                Yes             Yes             Yes         
    No              No              No               No
Two sided stencil                   Yes             Yes             Yes         
    No              No              No               No
Cube textures dimensions pot        No              No              No          
    Yes             Yes             Yes              Yes
2D textures pot if MipCount >1      No              No              No          
    No              Yes             Yes              Yes
DXTC / S3TC (*1)                    Yes             Yes             Yes         
    Yes             Yes             Yes              Yes
Point Sprites                       No              No              No          
    Yes             Yes             Yes              Yes
Unnormalized texture coordinates    N/A             N/A             N/A         
    N/A             N/A             N/A              N/A
Triangle fans                       No              No              No          
    Yes             Yes             Yes              Yes
Occlusion query                     Yes             Yes             Yes         
    Yes             Yes             Yes              No
Shadow maps (*2)                    Yes             Yes             Yes         
    No              No              No               No
Guard band clipping (*3)            N/A             N/A             N/A         
    N/A             N/A             N/A              N/A
Texture mirror clamp                No              No              No          
    Yes             Yes             Yes              No
Texture mirror repeat               No              No              No          
    No              No              No               No



*1) There is no distinction between pre-multiplied alpha or non-premultiplied 
alpha in Direct3D 10. DXT formats have been replaced by BC formats, so DXT1 == 
BC1,
DXT2,DXT3 == BC2 and DXT4,DXT5 == BC3 (bc for block compression)
*2) There's lots of ways of performing shadow mapping but what we refer to is 
simply 
the ability to sample & filter from a depth texture. This ability is format 
dependent
and therefore doesn't strickly adhere to the feature levels but all major 
vendors
(NVIDIA, AMD, Intel) seem to support it in their DX10 level GPUs.
*3) It's part of the functionality a driver can support or not. At least for 
DX9 level
drivers. I'm not sure what happened with it afterwards.

References:
http://msdn.microsoft.com/en-us/library/ee422086(VS.85).aspx#Overview
http://msdn.microsoft.com/en-us/library/ee416168(VS.85).aspx
http://msdn.microsoft.com/en-us/library/ee416166(VS.85).aspx
http://msdn.microsoft.com/en-us/library/ee415655(VS.85).aspx
http://msdn.microsoft.com/en-us/library/ms792615.aspx
------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev 
_______________________________________________
Mesa3d-dev mailing list
Mesa3d-dev@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mesa3d-dev

Reply via email to