[Mesa-dev] [PATCH 08/10] gallium: introduce get_shader_param (ALL DRIVERS CHANGED)

Luca Barbieri luca at luca-barbieri.com
Sun Sep 5 18:30:50 PDT 2010


Currently each shader cap has FS and VS versions.

However, we want a version of them for geometry, tessellation control,
and tessellation evaluation shaders, and want to be able to easily
query a given cap type for a given shader stage.

Since having 5 duplicates of each shader cap is unmanageable, add
a new get_shader_param function that takes both a shader cap from a
new enum and a shader stage.

Drivers with non-unified shaders will first switch on the shader
and, within each case, switch on the cap.

Drivers with unified shaders instead first check whether the shader
is supported, and then switch on the cap.

MAX_CONST_BUFFERS is now per-stage.
The geometry shader cap is removed in favor of checking whether the
limit of geometry shader instructions is greater than 0, which is also
used for tessellation shaders.

WARNING: all drivers changed and compiled but only nvfx tested
---
 src/gallium/auxiliary/draw/draw_context.h  |   13 +++
 src/gallium/auxiliary/tgsi/tgsi_exec.h     |   30 +++++++
 src/gallium/auxiliary/util/u_caps.c        |   29 ++++---
 src/gallium/auxiliary/util/u_caps.h        |    4 +
 src/gallium/auxiliary/util/u_inlines.h     |    1 -
 src/gallium/drivers/cell/ppu/cell_screen.c |   17 ++++-
 src/gallium/drivers/failover/fo_context.c  |    1 +
 src/gallium/drivers/galahad/glhd_context.c |    4 +-
 src/gallium/drivers/galahad/glhd_screen.c  |   12 +++
 src/gallium/drivers/i915/i915_screen.c     |   44 ++++++++++
 src/gallium/drivers/i965/brw_screen.c      |   44 ++++++++++
 src/gallium/drivers/identity/id_screen.c   |   14 +++-
 src/gallium/drivers/llvmpipe/lp_screen.c   |   50 ++++--------
 src/gallium/drivers/nv50/nv50_screen.c     |   64 ++++++++------
 src/gallium/drivers/nvfx/nvfx_screen.c     |  119 ++++++++++++++++----------
 src/gallium/drivers/r300/r300_screen.c     |   96 +++++++++++++--------
 src/gallium/drivers/r600/r600_screen.c     |   96 +++++++++++----------
 src/gallium/drivers/rbug/rbug_screen.c     |   12 +++
 src/gallium/drivers/softpipe/sp_screen.c   |   55 ++++---------
 src/gallium/drivers/svga/svga_screen.c     |  127 +++++++++++++++++-----------
 src/gallium/include/pipe/p_compiler.h      |    1 +
 src/gallium/include/pipe/p_defines.h       |   46 ++++-------
 src/gallium/include/pipe/p_screen.h        |    6 ++
 src/mesa/state_tracker/st_extensions.c     |   63 +++++++++-----
 24 files changed, 602 insertions(+), 346 deletions(-)

diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h
index 4c780e4..4f0d301 100644
--- a/src/gallium/auxiliary/draw/draw_context.h
+++ b/src/gallium/auxiliary/draw/draw_context.h
@@ -39,6 +39,7 @@
 
 
 #include "pipe/p_state.h"
+#include "tgsi/tgsi_exec.h"
 
 struct pipe_context;
 struct draw_context;
@@ -225,4 +226,16 @@ boolean draw_need_pipeline(const struct draw_context *draw,
                            const struct pipe_rasterizer_state *rasterizer,
                            unsigned prim );
 
+static INLINE int
+draw_get_shader_param(unsigned shader, enum pipe_cap param)
+{
+   switch(shader) {
+   case PIPE_SHADER_VERTEX:
+   case PIPE_SHADER_GEOMETRY:
+      return tgsi_exec_get_shader_param(param);
+   default:
+      return 0;
+   }
+}
+
 #endif /* DRAW_CONTEXT_H */
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.h b/src/gallium/auxiliary/tgsi/tgsi_exec.h
index 6dee362..9d62c1d 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.h
@@ -377,6 +377,36 @@ tgsi_exec_set_constant_buffers(struct tgsi_exec_machine *mach,
                                const unsigned *buf_sizes);
 
 
+static INLINE int
+tgsi_exec_get_shader_param(enum pipe_shader_cap param)
+{
+   switch(param) {
+   case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
+   case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
+   case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
+   case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
+      return INT_MAX;
+   case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
+      return TGSI_EXEC_MAX_NESTING;
+   case PIPE_SHADER_CAP_MAX_INPUTS:
+      return TGSI_EXEC_MAX_INPUT_ATTRIBS;
+   case PIPE_SHADER_CAP_MAX_CONSTS:
+      return TGSI_EXEC_MAX_CONST_BUFFER;
+   case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
+      return PIPE_MAX_CONSTANT_BUFFERS;
+   case PIPE_SHADER_CAP_MAX_TEMPS:
+      return TGSI_EXEC_NUM_TEMPS;
+   case PIPE_SHADER_CAP_MAX_ADDRS:
+      return TGSI_EXEC_NUM_ADDRS;
+   case PIPE_SHADER_CAP_MAX_PREDS:
+      return TGSI_EXEC_NUM_PREDS;
+   case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
+      return 1;
+   default:
+      return 0;
+   }
+}
+
 #if defined __cplusplus
 } /* extern "C" */
 #endif
diff --git a/src/gallium/auxiliary/util/u_caps.c b/src/gallium/auxiliary/util/u_caps.c
index 94d5bd3..f6a8786 100644
--- a/src/gallium/auxiliary/util/u_caps.c
+++ b/src/gallium/auxiliary/util/u_caps.c
@@ -75,6 +75,13 @@ util_check_caps_out(struct pipe_screen *screen, const unsigned *list, int *out)
             return FALSE;
          }
          break;
+      case UTIL_CAPS_CHECK_SHADER:
+         tmpi = screen->get_shader_param(screen, list[i] >> 24, list[i] & ((1 << 24) - 1));
+         ++i;
+         if (tmpi < (int)list[i++]) {
+            *out = i - 3;
+            return FALSE;
+         }
       case UTIL_CAPS_CHECK_UNIMPLEMENTED:
          *out = i - 1;
          return FALSE;
@@ -188,17 +195,17 @@ static unsigned caps_opengl_2_1[] = {
 
 /* Shader Model 3 */
 static unsigned caps_sm3[] = {
-    UTIL_CHECK_INT(MAX_FS_INSTRUCTIONS, 512),
-    UTIL_CHECK_INT(MAX_FS_INPUTS, 10),
-    UTIL_CHECK_INT(MAX_FS_TEMPS, 32),
-    UTIL_CHECK_INT(MAX_FS_ADDRS, 1),
-    UTIL_CHECK_INT(MAX_FS_CONSTS, 224),
+    UTIL_CHECK_SHADER(FRAGMENT, MAX_INSTRUCTIONS, 512),
+    UTIL_CHECK_SHADER(FRAGMENT, MAX_INPUTS, 10),
+    UTIL_CHECK_SHADER(FRAGMENT, MAX_TEMPS, 32),
+    UTIL_CHECK_SHADER(FRAGMENT, MAX_ADDRS, 1),
+    UTIL_CHECK_SHADER(FRAGMENT, MAX_CONSTS, 224),
 
-    UTIL_CHECK_INT(MAX_VS_INSTRUCTIONS, 512),
-    UTIL_CHECK_INT(MAX_VS_INPUTS, 16),
-    UTIL_CHECK_INT(MAX_VS_TEMPS, 32),
-    UTIL_CHECK_INT(MAX_VS_ADDRS, 2),
-    UTIL_CHECK_INT(MAX_VS_CONSTS, 256),
+    UTIL_CHECK_SHADER(VERTEX, MAX_INSTRUCTIONS, 512),
+    UTIL_CHECK_SHADER(VERTEX, MAX_INPUTS, 16),
+    UTIL_CHECK_SHADER(VERTEX, MAX_TEMPS, 32),
+    UTIL_CHECK_SHADER(VERTEX, MAX_ADDRS, 2),
+    UTIL_CHECK_SHADER(VERTEX, MAX_CONSTS, 256),
 
     UTIL_CHECK_TERMINATE
 };
diff --git a/src/gallium/auxiliary/util/u_caps.h b/src/gallium/auxiliary/util/u_caps.h
index b1074f9..7bd2380 100644
--- a/src/gallium/auxiliary/util/u_caps.h
+++ b/src/gallium/auxiliary/util/u_caps.h
@@ -38,6 +38,7 @@ enum u_caps_check_enum {
    UTIL_CAPS_CHECK_INT,
    UTIL_CAPS_CHECK_FLOAT,
    UTIL_CAPS_CHECK_FORMAT,
+   UTIL_CAPS_CHECK_SHADER,
    UTIL_CAPS_CHECK_UNIMPLEMENTED,
 };
 
@@ -54,6 +55,9 @@ enum u_caps_check_enum {
 #define UTIL_CHECK_FORMAT(format) \
    UTIL_CAPS_CHECK_FORMAT, PIPE_FORMAT_##format
 
+#define UTIL_CHECK_SHADER(shader, cap, higher) \
+   UTIL_CAPS_CHECK_SHADER, (PIPE_SHADER_##shader << 24) | PIPE_SHADER_CAP_##cap, (unsigned)(higher)
+
 #define UTIL_CHECK_UNIMPLEMENTED \
    UTIL_CAPS_CHECK_UNIMPLEMENTED
 
diff --git a/src/gallium/auxiliary/util/u_inlines.h b/src/gallium/auxiliary/util/u_inlines.h
index 78473bf..6ed3956 100644
--- a/src/gallium/auxiliary/util/u_inlines.h
+++ b/src/gallium/auxiliary/util/u_inlines.h
@@ -399,7 +399,6 @@ static INLINE boolean util_get_offset(
    }
 }
 
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/gallium/drivers/cell/ppu/cell_screen.c b/src/gallium/drivers/cell/ppu/cell_screen.c
index 0f12e06..8d2b4b9 100644
--- a/src/gallium/drivers/cell/ppu/cell_screen.c
+++ b/src/gallium/drivers/cell/ppu/cell_screen.c
@@ -90,8 +90,6 @@ cell_get_param(struct pipe_screen *screen, enum pipe_cap param)
       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;
    case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
    case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
       return 1;
@@ -105,6 +103,20 @@ cell_get_param(struct pipe_screen *screen, enum pipe_cap param)
    }
 }
 
+static int
+cell_get_shader_param(struct pipe_screen *screen, unsigned shader, enum pipe_shader_cap param)
+{
+   switch(shader)
+   {
+   case PIPE_SHADER_FRAGMENT:
+      return tgsi_exec_get_shader_param(param);
+   case PIPE_SHADER_VERTEX:
+   case PIPE_SHADER_GEOMETRY:
+      return draw_get_shader_param(shader, param);
+   default:
+      return 0;
+   }
+}
 
 static float
 cell_get_paramf(struct pipe_screen *screen, enum pipe_cap param)
@@ -200,6 +212,7 @@ cell_create_screen(struct sw_winsys *winsys)
    screen->base.get_name = cell_get_name;
    screen->base.get_vendor = cell_get_vendor;
    screen->base.get_param = cell_get_param;
+   screen->base.get_shader_param = cell_get_shader_param;
    screen->base.get_paramf = cell_get_paramf;
    screen->base.is_format_supported = cell_is_format_supported;
    screen->base.context_create = cell_create_context;
diff --git a/src/gallium/drivers/failover/fo_context.c b/src/gallium/drivers/failover/fo_context.c
index 761a0fc..ec36092 100644
--- a/src/gallium/drivers/failover/fo_context.c
+++ b/src/gallium/drivers/failover/fo_context.c
@@ -116,6 +116,7 @@ struct pipe_context *failover_create( struct pipe_context *hw,
    failover->pipe.get_name = hw->get_name;
    failover->pipe.get_vendor = hw->get_vendor;
    failover->pipe.get_param = hw->get_param;
+   failover->pipe.get_shader_param = hw->get_shader_param;
    failover->pipe.get_paramf = hw->get_paramf;
 #endif
 
diff --git a/src/gallium/drivers/galahad/glhd_context.c b/src/gallium/drivers/galahad/glhd_context.c
index 5b56a4d..ff6d2aa 100644
--- a/src/gallium/drivers/galahad/glhd_context.c
+++ b/src/gallium/drivers/galahad/glhd_context.c
@@ -469,11 +469,11 @@ galahad_set_constant_buffer(struct pipe_context *_pipe,
 
    if (index &&
       index >=
-         pipe->screen->get_param(pipe->screen, PIPE_CAP_MAX_CONST_BUFFERS)) {
+         pipe->screen->get_shader_param(pipe->screen, shader, PIPE_SHADER_CAP_MAX_CONST_BUFFERS)) {
       glhd_error("Access to constant buffer %u requested, "
          "but only %d are supported",
          index,
-         pipe->screen->get_param(pipe->screen, PIPE_CAP_MAX_CONST_BUFFERS));
+         pipe->screen->get_shader_param(pipe->screen, shader, PIPE_SHADER_CAP_MAX_CONST_BUFFERS));
    }
 
    /* XXX hmm? unwrap the input state */
diff --git a/src/gallium/drivers/galahad/glhd_screen.c b/src/gallium/drivers/galahad/glhd_screen.c
index 75e4c2d..288941b 100644
--- a/src/gallium/drivers/galahad/glhd_screen.c
+++ b/src/gallium/drivers/galahad/glhd_screen.c
@@ -79,6 +79,17 @@ galahad_screen_get_param(struct pipe_screen *_screen,
                             param);
 }
 
+static int
+galahad_screen_get_shader_param(struct pipe_screen *_screen,
+                          unsigned shader, enum pipe_shader_cap param)
+{
+   struct galahad_screen *glhd_screen = galahad_screen(_screen);
+   struct pipe_screen *screen = glhd_screen->screen;
+
+   return screen->get_shader_param(screen, shader,
+                            param);
+}
+
 static float
 galahad_screen_get_paramf(struct pipe_screen *_screen,
                            enum pipe_cap param)
@@ -341,6 +352,7 @@ galahad_screen_create(struct pipe_screen *screen)
    glhd_screen->base.get_name = galahad_screen_get_name;
    glhd_screen->base.get_vendor = galahad_screen_get_vendor;
    glhd_screen->base.get_param = galahad_screen_get_param;
+   glhd_screen->base.get_shader_param = galahad_screen_get_shader_param;
    glhd_screen->base.get_paramf = galahad_screen_get_paramf;
    glhd_screen->base.is_format_supported = galahad_screen_is_format_supported;
    glhd_screen->base.context_create = galahad_screen_context_create;
diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c
index 77345d5..34bd81f 100644
--- a/src/gallium/drivers/i915/i915_screen.c
+++ b/src/gallium/drivers/i915/i915_screen.c
@@ -139,6 +139,49 @@ i915_get_param(struct pipe_screen *screen, enum pipe_cap param)
    }
 }
 
+static int
+i915_get_shader_param(struct pipe_screen *screen, unsigned shader, enum pipe_shader_cap param)
+{
+   switch(shader) {
+   case PIPE_SHADER_VERTEX:
+      return draw_get_shader_param(shader, param);
+   case PIPE_SHADER_FRAGMENT:
+      break;
+   default:
+      return 0;
+   }
+
+   /* XXX: these are just shader model 2.0 values, fix this! */
+   switch(param) {
+      case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
+         return 96;
+      case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
+         return 64;
+      case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
+         return 32;
+      case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
+         return 8;
+      case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
+         return 0;
+      case PIPE_SHADER_CAP_MAX_INPUTS:
+         return 10;
+      case PIPE_SHADER_CAP_MAX_CONSTS:
+         return 32;
+      case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
+         return 1;
+      case PIPE_SHADER_CAP_MAX_TEMPS:
+         return 12; /* XXX: 12 -> 32 ? */
+      case PIPE_SHADER_CAP_MAX_ADDRS:
+         return 0;
+      case PIPE_SHADER_CAP_MAX_PREDS:
+         return 0;
+      case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
+         return 0;
+      default:
+              break;
+   }
+}
+
 static float
 i915_get_paramf(struct pipe_screen *screen, enum pipe_cap param)
 {
@@ -320,6 +363,7 @@ i915_screen_create(struct i915_winsys *iws)
    is->base.get_name = i915_get_name;
    is->base.get_vendor = i915_get_vendor;
    is->base.get_param = i915_get_param;
+   is->base.get_shader_param = i915_get_shader_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 bdfead7..2359980 100644
--- a/src/gallium/drivers/i965/brw_screen.c
+++ b/src/gallium/drivers/i965/brw_screen.c
@@ -197,6 +197,49 @@ brw_get_param(struct pipe_screen *screen, enum pipe_cap param)
    }
 }
 
+static int
+brw_get_shader_param(struct pipe_screen *screen, unsigned shader, enum pipe_shader_cap param)
+{
+   switch(shader) {
+   case PIPE_SHADER_VERTEX:
+   case PIPE_SHADER_FRAGMENT:
+   case PIPE_SHADER_GEOMETRY:
+      break;
+   default:
+      return 0;
+   }
+
+   /* XXX: these are just shader model 4.0 values, fix this! */
+   switch(param) {
+      case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
+         return 65536;
+      case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
+         return 65536;
+      case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
+         return 65536;
+      case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
+         return 65536;
+      case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
+         return 65536;
+      case PIPE_SHADER_CAP_MAX_INPUTS:
+         return 32;
+      case PIPE_SHADER_CAP_MAX_CONSTS:
+         return 4096;
+      case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
+         return PIPE_MAX_CONSTANT_BUFFERS;
+      case PIPE_SHADER_CAP_MAX_TEMPS:
+         return 4096;
+      case PIPE_SHADER_CAP_MAX_ADDRS:
+         return 0;
+      case PIPE_SHADER_CAP_MAX_PREDS:
+         return 0;
+      case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
+         return 1;
+      default:
+              break;
+      }
+}
+
 static float
 brw_get_paramf(struct pipe_screen *screen, enum pipe_cap param)
 {
@@ -410,6 +453,7 @@ brw_screen_create(struct brw_winsys_screen *sws)
    bscreen->base.get_name = brw_get_name;
    bscreen->base.get_vendor = brw_get_vendor;
    bscreen->base.get_param = brw_get_param;
+   bscreen->base.get_shader_param = brw_get_shader_param;
    bscreen->base.get_paramf = brw_get_paramf;
    bscreen->base.is_format_supported = brw_is_format_supported;
    bscreen->base.context_create = brw_create_context;
diff --git a/src/gallium/drivers/identity/id_screen.c b/src/gallium/drivers/identity/id_screen.c
index f71585e..c46d745 100644
--- a/src/gallium/drivers/identity/id_screen.c
+++ b/src/gallium/drivers/identity/id_screen.c
@@ -67,7 +67,7 @@ identity_screen_get_vendor(struct pipe_screen *_screen)
 
 static int
 identity_screen_get_param(struct pipe_screen *_screen,
-                          enum pipe_cap param)
+                          unsigned shader, enum pipe_cap param)
 {
    struct identity_screen *id_screen = identity_screen(_screen);
    struct pipe_screen *screen = id_screen->screen;
@@ -76,6 +76,17 @@ identity_screen_get_param(struct pipe_screen *_screen,
                             param);
 }
 
+static int
+identity_screen_get_shader_param(struct pipe_screen *_screen,
+                          unsigned shader, enum pipe_shader_cap param)
+{
+   struct identity_screen *id_screen = identity_screen(_screen);
+   struct pipe_screen *screen = id_screen->screen;
+
+   return screen->get_shader_param(screen, shader,
+                            param);
+}
+
 static float
 identity_screen_get_paramf(struct pipe_screen *_screen,
                            enum pipe_cap param)
@@ -304,6 +315,7 @@ identity_screen_create(struct pipe_screen *screen)
    id_screen->base.get_name = identity_screen_get_name;
    id_screen->base.get_vendor = identity_screen_get_vendor;
    id_screen->base.get_param = identity_screen_get_param;
+   id_screen->base.get_shader_param = identity_screen_get_shader_param;
    id_screen->base.get_paramf = identity_screen_get_paramf;
    id_screen->base.is_format_supported = identity_screen_is_format_supported;
    id_screen->base.context_create = identity_screen_context_create;
diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c
index 1e65a91..8fb52de 100644
--- a/src/gallium/drivers/llvmpipe/lp_screen.c
+++ b/src/gallium/drivers/llvmpipe/lp_screen.c
@@ -33,6 +33,7 @@
 #include "util/u_format_s3tc.h"
 #include "pipe/p_defines.h"
 #include "pipe/p_screen.h"
+#include "draw/draw_context.h"
 
 #include "gallivm/lp_bld_limits.h"
 #include "lp_texture.h"
@@ -131,8 +132,6 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
       return LP_MAX_TEXTURE_3D_LEVELS;
    case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
       return LP_MAX_TEXTURE_2D_LEVELS;
-   case PIPE_CAP_TGSI_CONT_SUPPORTED:
-      return 1;
    case PIPE_CAP_BLEND_EQUATION_SEPARATE:
       return 1;
    case PIPE_CAP_INDEP_BLEND_ENABLE:
@@ -145,47 +144,29 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
    case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
    case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
       return 0;
-   case PIPE_CAP_MAX_VS_INSTRUCTIONS:
-   case PIPE_CAP_MAX_FS_INSTRUCTIONS:
-   case PIPE_CAP_MAX_VS_ALU_INSTRUCTIONS:
-   case PIPE_CAP_MAX_FS_ALU_INSTRUCTIONS:
-   case PIPE_CAP_MAX_VS_TEX_INSTRUCTIONS:
-   case PIPE_CAP_MAX_FS_TEX_INSTRUCTIONS:
-   case PIPE_CAP_MAX_VS_TEX_INDIRECTIONS:
-   case PIPE_CAP_MAX_FS_TEX_INDIRECTIONS:
-      /* There is no limit in number of instructions beyond available memory */
-      return 32768;
-   case PIPE_CAP_MAX_VS_CONTROL_FLOW_DEPTH:
-   case PIPE_CAP_MAX_FS_CONTROL_FLOW_DEPTH:
-      return LP_MAX_TGSI_NESTING;
-   case PIPE_CAP_MAX_VS_INPUTS:
-   case PIPE_CAP_MAX_FS_INPUTS:
-      return PIPE_MAX_ATTRIBS;
-   case PIPE_CAP_MAX_FS_CONSTS:
-   case PIPE_CAP_MAX_VS_CONSTS:
-      /* There is no limit in number of constants beyond available memory */
-      return 32768;
-   case PIPE_CAP_MAX_VS_TEMPS:
-   case PIPE_CAP_MAX_FS_TEMPS:
-      return LP_MAX_TGSI_TEMPS;
-   case PIPE_CAP_MAX_VS_ADDRS:
-   case PIPE_CAP_MAX_FS_ADDRS:
-      return LP_MAX_TGSI_ADDRS;
-   case PIPE_CAP_MAX_VS_PREDS:
-   case PIPE_CAP_MAX_FS_PREDS:
-      return LP_MAX_TGSI_PREDS;
    case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
       return 1;
-   case PIPE_CAP_GEOMETRY_SHADER4:
-      return 1;
    case PIPE_CAP_DEPTH_CLAMP:
       return 0;
    default:
-      assert(0);
       return 0;
    }
 }
 
+static int
+llvmpipe_get_shader_param(struct pipe_screen *screen, unsigned shader, enum pipe_shader_cap param)
+{
+   switch(shader)
+   {
+   case PIPE_SHADER_FRAGMENT:
+      return tgsi_exec_get_shader_param(param);
+   case PIPE_SHADER_VERTEX:
+   case PIPE_SHADER_GEOMETRY:
+      return draw_get_shader_param(shader, param);
+   default:
+      return 0;
+   }
+}
 
 static float
 llvmpipe_get_paramf(struct pipe_screen *screen, enum pipe_cap param)
@@ -401,6 +382,7 @@ llvmpipe_create_screen(struct sw_winsys *winsys)
    screen->base.get_name = llvmpipe_get_name;
    screen->base.get_vendor = llvmpipe_get_vendor;
    screen->base.get_param = llvmpipe_get_param;
+   screen->base.get_shader_param = llvmpipe_get_shader_param;
    screen->base.get_paramf = llvmpipe_get_paramf;
    screen->base.is_format_supported = llvmpipe_is_format_supported;
 
diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c
index ca4b01b..f37dd07 100644
--- a/src/gallium/drivers/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nv50/nv50_screen.c
@@ -142,8 +142,6 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
 	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 PIPE_CAP_INDEP_BLEND_ENABLE:
@@ -158,38 +156,51 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
 	case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
 	case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
 		return 0;
-	case PIPE_CAP_MAX_VS_INSTRUCTIONS:
-	case PIPE_CAP_MAX_FS_INSTRUCTIONS:
-	case PIPE_CAP_MAX_VS_ALU_INSTRUCTIONS:
-	case PIPE_CAP_MAX_FS_ALU_INSTRUCTIONS:
-	case PIPE_CAP_MAX_VS_TEX_INSTRUCTIONS:
-	case PIPE_CAP_MAX_FS_TEX_INSTRUCTIONS:
-	case PIPE_CAP_MAX_VS_TEX_INDIRECTIONS:
-	case PIPE_CAP_MAX_FS_TEX_INDIRECTIONS: /* arbitrary limit */
+	case PIPE_CAP_DEPTH_CLAMP:
+		return 1;
+	default:
+		NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
+		return 0;
+	}
+}
+
+static int
+nv50_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader, enum pipe_shader_cap param)
+{
+	switch(shader)
+	{
+	case PIPE_SHADER_FRAGMENT:
+	case PIPE_SHADER_VERTEX:
+	case PIPE_SHADER_GEOMETRY:
+		break;
+	default:
+		return 0;
+	}
+
+	switch(param) {
+	case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
+	case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
+	case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
+	case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS: /* arbitrary limit */
 		return 16384;
-	case PIPE_CAP_MAX_VS_CONTROL_FLOW_DEPTH:
-	case PIPE_CAP_MAX_FS_CONTROL_FLOW_DEPTH: /* need stack bo */
+	case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: /* need stack bo */
 		return 4;
-	case PIPE_CAP_MAX_VS_INPUTS:
-		return 16;
-	case PIPE_CAP_MAX_FS_INPUTS: /* 128 / 4 with GP */
-		return 64 / 4;
-	case PIPE_CAP_MAX_VS_CONSTS:
-	case PIPE_CAP_MAX_FS_CONSTS:
+	case PIPE_SHADER_CAP_MAX_INPUTS: /* 128 / 4 with GP */
+		if(shader == PIPE_SHADER_GEOMETRY)
+			return 128 / 4;
+		else
+			return 64 / 4;
+	case PIPE_SHADER_CAP_MAX_CONSTS:
 		return 65536 / 16;
-	case PIPE_CAP_MAX_VS_ADDRS:
-	case PIPE_CAP_MAX_FS_ADDRS: /* no spilling atm */
+	case PIPE_SHADER_CAP_MAX_ADDRS: /* no spilling atm */
 		return 1;
-	case PIPE_CAP_MAX_VS_PREDS:
-	case PIPE_CAP_MAX_FS_PREDS: /* not yet handled */
+	case PIPE_SHADER_CAP_MAX_PREDS: /* not yet handled */
 		return 0;
-	case PIPE_CAP_MAX_VS_TEMPS:
-	case PIPE_CAP_MAX_FS_TEMPS: /* no spilling atm */
+	case PIPE_SHADER_CAP_MAX_TEMPS: /* no spilling atm */
 		return 128 / 4;
-	case PIPE_CAP_DEPTH_CLAMP:
+	case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
 		return 1;
 	default:
-		NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
 		return 0;
 	}
 }
@@ -315,6 +326,7 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
 	pscreen->winsys = ws;
 	pscreen->destroy = nv50_screen_destroy;
 	pscreen->get_param = nv50_screen_get_param;
+	pscreen->get_shader_param = nv50_screen_get_shader_param;
 	pscreen->get_paramf = nv50_screen_get_paramf;
 	pscreen->is_format_supported = nv50_screen_is_format_supported;
 	pscreen->context_create = nv50_create;
diff --git a/src/gallium/drivers/nvfx/nvfx_screen.c b/src/gallium/drivers/nvfx/nvfx_screen.c
index 0290370..3f177b7 100644
--- a/src/gallium/drivers/nvfx/nvfx_screen.c
+++ b/src/gallium/drivers/nvfx/nvfx_screen.c
@@ -58,8 +58,6 @@ nvfx_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
 		return 1;
 	case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
 		return 0; /* We have 4 on nv40 - but unsupported currently */
-	case PIPE_CAP_TGSI_CONT_SUPPORTED:
-		return 0;
 	case PIPE_CAP_BLEND_EQUATION_SEPARATE:
 		return screen->advertise_blend_equation_separate;
 	case PIPE_CAP_MAX_COMBINED_SAMPLERS:
@@ -77,49 +75,6 @@ nvfx_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
 	case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
 	case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
 		return 1;
-	case PIPE_CAP_MAX_FS_INSTRUCTIONS:
-	case PIPE_CAP_MAX_FS_ALU_INSTRUCTIONS:
-	case PIPE_CAP_MAX_FS_TEX_INSTRUCTIONS:
-	case PIPE_CAP_MAX_FS_TEX_INDIRECTIONS:
-		return 4096;
-	case PIPE_CAP_MAX_FS_CONTROL_FLOW_DEPTH:
-		/* FIXME: is it the dynamic (nv30:0/nv40:24) or the static
-		   value (nv30:0/nv40:4) ? */
-		return screen->use_nv4x ? 4 : 0;
-	case PIPE_CAP_MAX_FS_INPUTS:
-		return screen->use_nv4x ? 12 : 10;
-	case PIPE_CAP_MAX_FS_CONSTS:
-		return screen->use_nv4x ? 224 : 32;
-	case PIPE_CAP_MAX_FS_TEMPS:
-		return 32;
-	case PIPE_CAP_MAX_FS_ADDRS:
-		return screen->use_nv4x ? 1 : 0;
-	case PIPE_CAP_MAX_FS_PREDS:
-		return 0; /* we could expose these, but nothing uses them */
-	case PIPE_CAP_MAX_VS_INSTRUCTIONS:
-	case PIPE_CAP_MAX_VS_ALU_INSTRUCTIONS:
-		return screen->use_nv4x ? 512 : 256;
-	case PIPE_CAP_MAX_VS_TEX_INSTRUCTIONS:
-	case PIPE_CAP_MAX_VS_TEX_INDIRECTIONS:
-		return screen->use_nv4x ? 512 : 0;
-	case PIPE_CAP_MAX_VS_CONTROL_FLOW_DEPTH:
-		/* FIXME: is it the dynamic (nv30:24/nv40:24) or the static
-		   value (nv30:1/nv40:4) ? */
-		return screen->use_nv4x ? 4 : 1;
-	case PIPE_CAP_MAX_VS_INPUTS:
-		return 16;
-	case PIPE_CAP_MAX_VS_CONSTS:
-		/* - 6 is for clip planes; Gallium should be fixed to put
-		 * them in the vertex shader itself, so we don't need to reserve these */
-		return (screen->use_nv4x ? 468 : 256) - 6;
-	case PIPE_CAP_MAX_VS_TEMPS:
-		return screen->use_nv4x ? 32 : 13;
-	case PIPE_CAP_MAX_VS_ADDRS:
-		return 2;
-	case PIPE_CAP_MAX_VS_PREDS:
-		return 0; /* we could expose these, but nothing uses them */
-	case PIPE_CAP_GEOMETRY_SHADER4:
-		return 0;
 	case PIPE_CAP_DEPTH_CLAMP:
 		return 0; // TODO: implement depth clamp
 	default:
@@ -128,6 +83,79 @@ nvfx_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
 	}
 }
 
+static int
+nvfx_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader, enum pipe_shader_cap param)
+{
+	struct nvfx_screen *screen = nvfx_screen(pscreen);
+
+	switch(shader) {
+	case PIPE_SHADER_FRAGMENT:
+		switch(param) {
+		case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
+		case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
+		case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
+		case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
+			return 4096;
+		case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
+			/* FIXME: is it the dynamic (nv30:0/nv40:24) or the static
+			 value (nv30:0/nv40:4) ? */
+			return screen->use_nv4x ? 4 : 0;
+		case PIPE_SHADER_CAP_MAX_INPUTS:
+			return screen->use_nv4x ? 12 : 10;
+		case PIPE_SHADER_CAP_MAX_CONSTS:
+			return screen->use_nv4x ? 224 : 32;
+		case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
+		    return 1;
+		case PIPE_SHADER_CAP_MAX_TEMPS:
+			return 32;
+		case PIPE_SHADER_CAP_MAX_ADDRS:
+			return screen->use_nv4x ? 1 : 0;
+		case PIPE_SHADER_CAP_MAX_PREDS:
+			return 0; /* we could expose these, but nothing uses them */
+		case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
+		    return 0;
+		default:
+			break;
+		}
+		break;
+	case PIPE_SHADER_VERTEX:
+		switch(param) {
+		case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
+		case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
+			return screen->use_nv4x ? 512 : 256;
+		case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
+		case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
+			return screen->use_nv4x ? 512 : 0;
+		case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
+			/* FIXME: is it the dynamic (nv30:24/nv40:24) or the static
+			 value (nv30:1/nv40:4) ? */
+			return screen->use_nv4x ? 4 : 1;
+		case PIPE_SHADER_CAP_MAX_INPUTS:
+			return 16;
+		case PIPE_SHADER_CAP_MAX_CONSTS:
+			/* - 6 is for clip planes; Gallium should be fixed to put
+			 * them in the vertex shader itself, so we don't need to reserve these */
+			return (screen->use_nv4x ? 468 : 256) - 6;
+	             case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
+	                    return 1;
+		case PIPE_SHADER_CAP_MAX_TEMPS:
+			return screen->use_nv4x ? 32 : 13;
+		case PIPE_SHADER_CAP_MAX_ADDRS:
+			return 2;
+		case PIPE_SHADER_CAP_MAX_PREDS:
+			return 0; /* we could expose these, but nothing uses them */
+		case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
+                        return 1;
+		default:
+			break;
+		}
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+
 static float
 nvfx_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_cap param)
 {
@@ -400,6 +428,7 @@ nvfx_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
 	pscreen->winsys = ws;
 	pscreen->destroy = nvfx_screen_destroy;
 	pscreen->get_param = nvfx_screen_get_param;
+	pscreen->get_shader_param = nvfx_screen_get_shader_param;
 	pscreen->get_paramf = nvfx_screen_get_paramf;
 	pscreen->is_format_supported = nvfx_screen_is_format_supported;
 	pscreen->context_create = nvfx_create;
diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c
index 1e4edcd..7f41ff0 100644
--- a/src/gallium/drivers/r300/r300_screen.c
+++ b/src/gallium/drivers/r300/r300_screen.c
@@ -120,7 +120,6 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
         /* Unsupported features (boolean caps). */
         case PIPE_CAP_TIMER_QUERY:
         case PIPE_CAP_DUAL_SOURCE_BLEND:
-        case PIPE_CAP_TGSI_CONT_SUPPORTED:
         case PIPE_CAP_INDEP_BLEND_ENABLE:
         case PIPE_CAP_INDEP_BLEND_FUNC:
         case PIPE_CAP_DEPTH_CLAMP: /* XXX implemented, but breaks Regnum Online */
@@ -146,11 +145,6 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
         /* General shader limits and features. */
         case PIPE_CAP_SM3:
             return is_r500 ? 1 : 0;
-        case PIPE_CAP_MAX_CONST_BUFFERS:
-            return 1;
-        case PIPE_CAP_MAX_CONST_BUFFER_SIZE:
-            return 256;
-
         /* Fragment coordinate conventions. */
         case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
         case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
@@ -158,19 +152,39 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
         case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
         case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
             return 0;
+        default:
+            fprintf(stderr, "r300: Implementation error: Bad param %d\n",
+                param);
+            return 0;
+    }
+}
 
-        /* Fragment shader limits. */
-        case PIPE_CAP_MAX_FS_INSTRUCTIONS:
+static int r300_get_shader_param(struct pipe_screen *pscreen, unsigned shader, enum pipe_shader_cap param)
+{
+   struct r300_screen* r300screen = r300_screen(pscreen);
+   boolean is_r400 = r300screen->caps.is_r400;
+   boolean is_r500 = r300screen->caps.is_r500;
+
+   /* XXX extended shader capabilities of r400 unimplemented */
+   is_r400 = FALSE;
+
+   switch (shader)
+    {
+    case PIPE_SHADER_FRAGMENT:
+        switch (param)
+        {
+        case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
             return is_r500 || is_r400 ? 512 : 96;
-        case PIPE_CAP_MAX_FS_ALU_INSTRUCTIONS:
+        case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
             return is_r500 || is_r400 ? 512 : 64;
-        case PIPE_CAP_MAX_FS_TEX_INSTRUCTIONS:
+        case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
             return is_r500 || is_r400 ? 512 : 32;
-        case PIPE_CAP_MAX_FS_TEX_INDIRECTIONS:
+        case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
             return is_r500 ? 511 : 4;
-        case PIPE_CAP_MAX_FS_CONTROL_FLOW_DEPTH:
+        case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
             return is_r500 ? 64 : 0; /* Actually unlimited on r500. */
-        case PIPE_CAP_MAX_FS_INPUTS:
+            /* Fragment shader limits. */
+        case PIPE_SHADER_CAP_MAX_INPUTS:
             /* 2 colors + 8 texcoords are always supported
              * (minus fog and wpos).
              *
@@ -178,42 +192,53 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
              * additional texcoords but there is no two-sided color
              * selection then. However the facing bit can be used instead. */
             return 10;
-        case PIPE_CAP_MAX_FS_CONSTS:
+        case PIPE_SHADER_CAP_MAX_CONSTS:
             return is_r500 ? 256 : 32;
-        case PIPE_CAP_MAX_FS_TEMPS:
+        case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
+            return 1;
+        case PIPE_SHADER_CAP_MAX_TEMPS:
             return is_r500 ? 128 : is_r400 ? 64 : 32;
-        case PIPE_CAP_MAX_FS_ADDRS:
+        case PIPE_SHADER_CAP_MAX_ADDRS:
             return 0;
-        case PIPE_CAP_MAX_FS_PREDS:
+        case PIPE_SHADER_CAP_MAX_PREDS:
             return is_r500 ? 1 : 0;
-
-        /* Vertex shader limits. */
-        case PIPE_CAP_MAX_VS_INSTRUCTIONS:
-        case PIPE_CAP_MAX_VS_ALU_INSTRUCTIONS:
+        case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
+            return 1;
+        }
+        break;
+    case PIPE_SHADER_VERTEX:
+        switch (param)
+        {
+        case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
+        case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
             return is_r500 ? 1024 : 256;
-        case PIPE_CAP_MAX_VS_TEX_INSTRUCTIONS:
-        case PIPE_CAP_MAX_VS_TEX_INDIRECTIONS:
+        case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
+        case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
             return 0;
-        case PIPE_CAP_MAX_VS_CONTROL_FLOW_DEPTH:
+        case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
             return is_r500 ? 4 : 0; /* For loops; not sure about conditionals. */
-        case PIPE_CAP_MAX_VS_INPUTS:
+        case PIPE_SHADER_CAP_MAX_INPUTS:
             return 16;
-        case PIPE_CAP_MAX_VS_CONSTS:
+        case PIPE_SHADER_CAP_MAX_CONSTS:
             return 256;
-        case PIPE_CAP_MAX_VS_TEMPS:
+        case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
+            return 1;
+        case PIPE_SHADER_CAP_MAX_TEMPS:
             return 32;
-        case PIPE_CAP_MAX_VS_ADDRS:
+        case PIPE_SHADER_CAP_MAX_ADDRS:
             return 1; /* XXX guessed */
-        case PIPE_CAP_MAX_VS_PREDS:
+        case PIPE_SHADER_CAP_MAX_PREDS:
             return is_r500 ? 4 : 0; /* XXX guessed. */
-        case PIPE_CAP_GEOMETRY_SHADER4:
-            return 0;
-
+        case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
+            return 1;
         default:
-            fprintf(stderr, "r300: Implementation error: Bad param %d\n",
-                param);
-            return 0;
+            break;
+        }
+        break;
+    default:
+        break;
     }
+    return 0;
 }
 
 static float r300_get_paramf(struct pipe_screen* pscreen, enum pipe_cap param)
@@ -410,6 +435,7 @@ struct pipe_screen* r300_screen_create(struct r300_winsys_screen *rws)
     r300screen->screen.get_name = r300_get_name;
     r300screen->screen.get_vendor = r300_get_vendor;
     r300screen->screen.get_param = r300_get_param;
+    r300screen->screen.get_shader_param = r300_get_shader_param;
     r300screen->screen.get_paramf = r300_get_paramf;
     r300screen->screen.is_format_supported = r300_is_format_supported;
     r300screen->screen.context_create = r300_create_context;
diff --git a/src/gallium/drivers/r600/r600_screen.c b/src/gallium/drivers/r600/r600_screen.c
index a047a49..29b6dc8 100644
--- a/src/gallium/drivers/r600/r600_screen.c
+++ b/src/gallium/drivers/r600/r600_screen.c
@@ -74,10 +74,8 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
 
 	/* Unsupported features (boolean caps). */
 	case PIPE_CAP_TIMER_QUERY:
-	case PIPE_CAP_TGSI_CONT_SUPPORTED:
 	case PIPE_CAP_STREAM_OUTPUT:
 	case PIPE_CAP_INDEP_BLEND_FUNC: /* FIXME allow this */
-	case PIPE_CAP_GEOMETRY_SHADER4:
 		return 0;
 
 	/* Texturing. */
@@ -104,55 +102,62 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
 	case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
 	case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
 		return 0;
-
-	/* Shader limits. */
-	case PIPE_CAP_MAX_VS_INSTRUCTIONS:
-		return 16384;  //max native instructions, not greater than max instructions
-	case PIPE_CAP_MAX_VS_ALU_INSTRUCTIONS:
-	case PIPE_CAP_MAX_VS_TEX_INSTRUCTIONS:
-	case PIPE_CAP_MAX_VS_TEX_INDIRECTIONS:
-		return 16384;
-	case PIPE_CAP_MAX_FS_INSTRUCTIONS:
-		return 16384; //max program native instructions
-	case PIPE_CAP_MAX_FS_ALU_INSTRUCTIONS:
-		return 16384; //max program native ALU instructions
-	case PIPE_CAP_MAX_FS_TEX_INSTRUCTIONS:
-		return 16384; //max program native texture instructions
-	case PIPE_CAP_MAX_FS_TEX_INDIRECTIONS:
-		return 2048; //max program native texture indirections
-	case PIPE_CAP_MAX_VS_CONTROL_FLOW_DEPTH:
-	case PIPE_CAP_MAX_FS_CONTROL_FLOW_DEPTH:
-		return 8; /* FIXME */
-	case PIPE_CAP_MAX_VS_INPUTS:
-		return 16; //max native attributes
-	case PIPE_CAP_MAX_FS_INPUTS:
-		return 10; //max native attributes
-	case PIPE_CAP_MAX_VS_TEMPS:
-		return 256; //max native temporaries
-	case PIPE_CAP_MAX_FS_TEMPS:
-		return 256; //max native temporaries
-	case PIPE_CAP_MAX_VS_ADDRS:
-	case PIPE_CAP_MAX_FS_ADDRS:
-		return 1; //max native address registers/* FIXME Isn't this equal to TEMPS? */
-	case PIPE_CAP_MAX_VS_CONSTS:
-		return 256; //max native parameters
-	case PIPE_CAP_MAX_FS_CONSTS:
-		return 256; //max program native parameters
-	case PIPE_CAP_MAX_CONST_BUFFERS:
-		return 1;
-	case PIPE_CAP_MAX_CONST_BUFFER_SIZE: /* in bytes */
-		return 4096;
-	case PIPE_CAP_MAX_PREDICATE_REGISTERS:
-	case PIPE_CAP_MAX_VS_PREDS:
-	case PIPE_CAP_MAX_FS_PREDS:
-		return 0; /* FIXME */
-
 	default:
 		R600_ERR("r600: unknown param %d\n", param);
 		return 0;
 	}
 }
 
+static int r600_get_shader_param(struct pipe_screen* pscreen, unsigned shader, enum pipe_shader_cap param)
+{
+	switch(shader)
+	{
+	case PIPE_SHADER_FRAGMENT:
+	case PIPE_SHADER_VERTEX:
+		break;
+	case PIPE_SHADER_GEOMETRY:
+		/* TODO: support and enable geometry programs */
+		return 0;
+	case PIPE_SHADER_TESSCTRL:
+	case PIPE_SHADER_TESSEVAL:
+		/* TODO: support tessellation on Evergreen */
+		return 0;
+	default:
+		return 0;
+	}
+
+	/* TODO: all these should be fixed, since r600 surely supports much more! */
+        switch (param) {
+        case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
+        case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
+        case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
+        case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
+                return 16384;
+        case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
+                return 8; /* FIXME */
+        case PIPE_SHADER_CAP_MAX_INPUTS:
+		if(shader == PIPE_SHADER_FRAGMENT)
+			return 10;
+		else
+			return 16;
+        case PIPE_SHADER_CAP_MAX_TEMPS:
+                return 256; //max native temporaries
+        case PIPE_SHADER_CAP_MAX_ADDRS:
+                return 1; //max native address registers/* FIXME Isn't this equal to TEMPS? */
+        case PIPE_SHADER_CAP_MAX_CONSTS:
+                return 256; //max native parameters
+        case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
+                return 1;
+        case PIPE_SHADER_CAP_MAX_PREDS:
+                return 0; /* FIXME */
+        case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
+                /* TODO: support this! */
+                return 0;
+        default:
+                return 0;
+        }
+}
+
 static float r600_get_paramf(struct pipe_screen* pscreen, enum pipe_cap param)
 {
 	switch (param) {
@@ -268,6 +273,7 @@ struct pipe_screen *r600_screen_create(struct radeon *rw)
 	rscreen->screen.get_name = r600_get_name;
 	rscreen->screen.get_vendor = r600_get_vendor;
 	rscreen->screen.get_param = r600_get_param;
+	rscreen->screen.get_shader_param = r600_get_shader_param;
 	rscreen->screen.get_paramf = r600_get_paramf;
 	rscreen->screen.is_format_supported = r600_is_format_supported;
 	rscreen->screen.context_create = r600_create_context;
diff --git a/src/gallium/drivers/rbug/rbug_screen.c b/src/gallium/drivers/rbug/rbug_screen.c
index b9f32ee..42555ab 100644
--- a/src/gallium/drivers/rbug/rbug_screen.c
+++ b/src/gallium/drivers/rbug/rbug_screen.c
@@ -79,6 +79,17 @@ rbug_screen_get_param(struct pipe_screen *_screen,
                             param);
 }
 
+static int
+rbug_screen_get_shader_param(struct pipe_screen *_screen,
+                      unsigned shader, enum pipe_cap param)
+{
+   struct rbug_screen *rb_screen = rbug_screen(_screen);
+   struct pipe_screen *screen = rb_screen->screen;
+
+   return screen->get_shader_param(screen, shader,
+                            param);
+}
+
 static float
 rbug_screen_get_paramf(struct pipe_screen *_screen,
                        enum pipe_cap param)
@@ -317,6 +328,7 @@ rbug_screen_create(struct pipe_screen *screen)
    rb_screen->base.get_name = rbug_screen_get_name;
    rb_screen->base.get_vendor = rbug_screen_get_vendor;
    rb_screen->base.get_param = rbug_screen_get_param;
+   rb_screen->base.get_shader_param = rbug_screen_get_shader_param;
    rb_screen->base.get_paramf = rbug_screen_get_paramf;
    rb_screen->base.is_format_supported = rbug_screen_is_format_supported;
    rb_screen->base.context_create = rbug_screen_context_create;
diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c
index 73ae2de..2053d02 100644
--- a/src/gallium/drivers/softpipe/sp_screen.c
+++ b/src/gallium/drivers/softpipe/sp_screen.c
@@ -31,6 +31,7 @@
 #include "util/u_format_s3tc.h"
 #include "pipe/p_defines.h"
 #include "pipe/p_screen.h"
+#include "draw/draw_context.h"
 
 #include "state_tracker/sw_winsys.h"
 #include "tgsi/tgsi_exec.h"
@@ -98,14 +99,8 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
       return SP_MAX_TEXTURE_3D_LEVELS;
    case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
       return SP_MAX_TEXTURE_2D_LEVELS;
-   case PIPE_CAP_TGSI_CONT_SUPPORTED:
-      return 1;
    case PIPE_CAP_BLEND_EQUATION_SEPARATE:
       return 1;
-   case PIPE_CAP_MAX_CONST_BUFFERS:
-      return PIPE_MAX_CONSTANT_BUFFERS;
-   case PIPE_CAP_MAX_CONST_BUFFER_SIZE:
-      return 4096 * 4 * sizeof(float);
    case PIPE_CAP_INDEP_BLEND_ENABLE:
       return 1;
    case PIPE_CAP_INDEP_BLEND_FUNC:
@@ -117,46 +112,27 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
       return 1;
    case PIPE_CAP_STREAM_OUTPUT:
       return 1;
-
-   case PIPE_CAP_MAX_VS_INSTRUCTIONS:
-   case PIPE_CAP_MAX_FS_INSTRUCTIONS:
-   case PIPE_CAP_MAX_VS_ALU_INSTRUCTIONS:
-   case PIPE_CAP_MAX_FS_ALU_INSTRUCTIONS:
-   case PIPE_CAP_MAX_VS_TEX_INSTRUCTIONS:
-   case PIPE_CAP_MAX_FS_TEX_INSTRUCTIONS:
-   case PIPE_CAP_MAX_VS_TEX_INDIRECTIONS:
-   case PIPE_CAP_MAX_FS_TEX_INDIRECTIONS:
-      /* There is no limit in number of instructions beyond available memory */
-      return 32768;
-   case PIPE_CAP_MAX_VS_CONTROL_FLOW_DEPTH:
-   case PIPE_CAP_MAX_FS_CONTROL_FLOW_DEPTH:
-      return TGSI_EXEC_MAX_NESTING;
-   case PIPE_CAP_MAX_VS_INPUTS:
-   case PIPE_CAP_MAX_FS_INPUTS:
-      return TGSI_EXEC_MAX_INPUT_ATTRIBS;
-   case PIPE_CAP_MAX_FS_CONSTS:
-   case PIPE_CAP_MAX_VS_CONSTS:
-      return TGSI_EXEC_MAX_CONST_BUFFER;
-   case PIPE_CAP_MAX_VS_TEMPS:
-   case PIPE_CAP_MAX_FS_TEMPS:
-      return TGSI_EXEC_NUM_TEMPS;
-   case PIPE_CAP_MAX_VS_ADDRS:
-   case PIPE_CAP_MAX_FS_ADDRS:
-      return TGSI_EXEC_NUM_ADDRS;
-   case PIPE_CAP_MAX_VS_PREDS:
-   case PIPE_CAP_MAX_FS_PREDS:
-      return TGSI_EXEC_NUM_PREDS;
-
    case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
       return 0;
-
-   case PIPE_CAP_GEOMETRY_SHADER4:
-      return 1;
    default:
       return 0;
    }
 }
 
+static int
+softpipe_get_shader_param(struct pipe_screen *screen, unsigned shader, enum pipe_shader_cap param)
+{
+   switch(shader)
+   {
+   case PIPE_SHADER_FRAGMENT:
+      return tgsi_exec_get_shader_param(param);
+   case PIPE_SHADER_VERTEX:
+   case PIPE_SHADER_GEOMETRY:
+      return draw_get_shader_param(shader, param);
+   default:
+      return 0;
+   }
+}
 
 static float
 softpipe_get_paramf(struct pipe_screen *screen, enum pipe_cap param)
@@ -320,6 +296,7 @@ softpipe_create_screen(struct sw_winsys *winsys)
    screen->base.get_name = softpipe_get_name;
    screen->base.get_vendor = softpipe_get_vendor;
    screen->base.get_param = softpipe_get_param;
+   screen->base.get_shader_param = softpipe_get_shader_param;
    screen->base.get_paramf = softpipe_get_paramf;
    screen->base.is_format_supported = softpipe_is_format_supported;
    screen->base.context_create = softpipe_create_context;
diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c
index 077ff9a..b5fae94 100644
--- a/src/gallium/drivers/svga/svga_screen.c
+++ b/src/gallium/drivers/svga/svga_screen.c
@@ -180,57 +180,6 @@ svga_get_paramf(struct pipe_screen *screen, enum pipe_cap param)
    case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
       return 0;
 
-   /*
-    * Fragment shader limits
-    */
-
-   case PIPE_CAP_MAX_FS_INSTRUCTIONS:
-   case PIPE_CAP_MAX_FS_ALU_INSTRUCTIONS:
-   case PIPE_CAP_MAX_FS_TEX_INSTRUCTIONS:
-   case PIPE_CAP_MAX_FS_TEX_INDIRECTIONS:
-      return svgascreen->use_ps30 ? 512 : 96;
-   case PIPE_CAP_MAX_FS_CONTROL_FLOW_DEPTH:
-      return SVGA3D_MAX_NESTING_LEVEL;
-   case PIPE_CAP_MAX_FS_INPUTS:
-      return 10;
-   case PIPE_CAP_MAX_FS_CONSTS:
-      return svgascreen->use_vs30 ? 224 : 16;
-   case PIPE_CAP_MAX_FS_TEMPS:
-      if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_TEMPS, &result))
-         return svgascreen->use_ps30 ? 32 : 12;
-      return result.u;
-   case PIPE_CAP_MAX_FS_ADDRS:
-      return svgascreen->use_ps30 ? 1 : 0;
-   case PIPE_CAP_MAX_FS_PREDS:
-      return svgascreen->use_ps30 ? 1 : 0;
-
-   /*
-    * Vertex shader limits
-    */
-   case PIPE_CAP_MAX_VS_INSTRUCTIONS:
-   case PIPE_CAP_MAX_VS_ALU_INSTRUCTIONS:
-      if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_VERTEX_SHADER_INSTRUCTIONS, &result))
-         return svgascreen->use_vs30 ? 512 : 256;
-      return result.u;
-   case PIPE_CAP_MAX_VS_TEX_INSTRUCTIONS:
-   case PIPE_CAP_MAX_VS_TEX_INDIRECTIONS:
-      /* XXX: until we have vertex texture support */
-      return 0;
-   case PIPE_CAP_MAX_VS_CONTROL_FLOW_DEPTH:
-      return SVGA3D_MAX_NESTING_LEVEL;
-   case PIPE_CAP_MAX_VS_INPUTS:
-      return 16;
-   case PIPE_CAP_MAX_VS_CONSTS:
-      return 256;
-   case PIPE_CAP_MAX_VS_TEMPS:
-      if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEMPS, &result))
-         return svgascreen->use_vs30 ? 32 : 12;
-      return result.u;
-   case PIPE_CAP_MAX_VS_ADDRS:
-      return svgascreen->use_vs30 ? 1 : 0;
-   case PIPE_CAP_MAX_VS_PREDS:
-      return svgascreen->use_vs30 ? 1 : 0;
-
    case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
       return 1;
 
@@ -248,6 +197,81 @@ svga_get_param(struct pipe_screen *screen, enum pipe_cap param)
    return (int) svga_get_paramf( screen, param );
 }
 
+static int svga_get_shader_param(struct pipe_screen *screen, unsigned shader, enum pipe_shader_cap param)
+{
+   struct svga_screen *svgascreen = svga_screen(screen);
+   struct svga_winsys_screen *sws = svgascreen->sws;
+   SVGA3dDevCapResult result;
+
+   switch (shader)
+   {
+   case PIPE_SHADER_FRAGMENT:
+      switch (param)
+      {
+      case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
+      case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
+      case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
+      case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
+         return svgascreen->use_ps30 ? 512 : 96;
+      case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
+         return SVGA3D_MAX_NESTING_LEVEL;
+      case PIPE_SHADER_CAP_MAX_INPUTS:
+         return 10;
+      case PIPE_SHADER_CAP_MAX_CONSTS:
+         return svgascreen->use_ps30 ? 224 : 16;
+      case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
+         return 1;
+      case PIPE_SHADER_CAP_MAX_TEMPS:
+         if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_TEMPS, &result))
+            return svgascreen->use_ps30 ? 32 : 12;
+         return result.u;
+      case PIPE_SHADER_CAP_MAX_ADDRS:
+         return svgascreen->use_ps30 ? 1 : 0;
+      case PIPE_SHADER_CAP_MAX_PREDS:
+         return svgascreen->use_ps30 ? 1 : 0;
+      case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
+         return 1;
+      }
+      break;
+   case PIPE_SHADER_VERTEX:
+      switch (param)
+      {
+      case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
+      case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
+         if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_VERTEX_SHADER_INSTRUCTIONS, &result))
+            return svgascreen->use_vs30 ? 512 : 256;
+         return result.u;
+      case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
+      case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
+         /* XXX: until we have vertex texture support */
+         return 0;
+      case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
+         return SVGA3D_MAX_NESTING_LEVEL;
+      case PIPE_SHADER_CAP_MAX_INPUTS:
+         return 16;
+      case PIPE_SHADER_CAP_MAX_CONSTS:
+         return 256;
+      case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
+         return 1;
+      case PIPE_SHADER_CAP_MAX_TEMPS:
+         if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEMPS, &result))
+            return svgascreen->use_vs30 ? 32 : 12;
+         return result.u;
+      case PIPE_SHADER_CAP_MAX_ADDRS:
+         return svgascreen->use_vs30 ? 1 : 0;
+      case PIPE_SHADER_CAP_MAX_PREDS:
+         return svgascreen->use_vs30 ? 1 : 0;
+      case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
+         return 1;
+      default:
+         break;
+      }
+      break;
+   default:
+      break;
+   }
+   return 0;
+}
 
 static INLINE SVGA3dDevCapIndex
 svga_translate_format_cap(enum pipe_format format)
@@ -449,6 +473,7 @@ svga_screen_create(struct svga_winsys_screen *sws)
    screen->get_name = svga_get_name;
    screen->get_vendor = svga_get_vendor;
    screen->get_param = svga_get_param;
+   screen->get_shader_param = svga_get_shader_param;
    screen->get_paramf = svga_get_paramf;
    screen->is_format_supported = svga_is_format_supported;
    screen->context_create = svga_context_create;
diff --git a/src/gallium/include/pipe/p_compiler.h b/src/gallium/include/pipe/p_compiler.h
index 0a5be43..5020599 100644
--- a/src/gallium/include/pipe/p_compiler.h
+++ b/src/gallium/include/pipe/p_compiler.h
@@ -35,6 +35,7 @@
 #include <string.h>
 #include <stddef.h>
 #include <stdarg.h>
+#include <limits.h>
 
 
 #if defined(_WIN32) && !defined(__WIN32__)
diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h
index 0291bb7..b50784b 100644
--- a/src/gallium/include/pipe/p_defines.h
+++ b/src/gallium/include/pipe/p_defines.h
@@ -451,16 +451,12 @@ enum pipe_cap {
    PIPE_CAP_TEXTURE_MIRROR_CLAMP,
    PIPE_CAP_TEXTURE_MIRROR_REPEAT,
    PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS,
-   PIPE_CAP_TGSI_CONT_SUPPORTED,
    PIPE_CAP_BLEND_EQUATION_SEPARATE,
    PIPE_CAP_SM3,  /*< Shader Model, supported */
    PIPE_CAP_STREAM_OUTPUT,
-   PIPE_CAP_MAX_PREDICATE_REGISTERS,
    /** Maximum texture image units accessible from vertex and fragment shaders
     * combined */
    PIPE_CAP_MAX_COMBINED_SAMPLERS,
-   PIPE_CAP_MAX_CONST_BUFFERS,
-   PIPE_CAP_MAX_CONST_BUFFER_SIZE,  /*< In bytes */
    /** blend enables and write masks per rendertarget */
    PIPE_CAP_INDEP_BLEND_ENABLE,
    /** different blend funcs per rendertarget */
@@ -470,35 +466,25 @@ enum pipe_cap {
    PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT,
    PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER,
    PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER,
-
-   /*
-    * Shader limits.
-    */
-   PIPE_CAP_MAX_FS_INSTRUCTIONS,
-   PIPE_CAP_MAX_FS_ALU_INSTRUCTIONS,
-   PIPE_CAP_MAX_FS_TEX_INSTRUCTIONS,
-   PIPE_CAP_MAX_FS_TEX_INDIRECTIONS,
-   PIPE_CAP_MAX_FS_CONTROL_FLOW_DEPTH,
-   PIPE_CAP_MAX_FS_INPUTS,
-   PIPE_CAP_MAX_FS_CONSTS,
-   PIPE_CAP_MAX_FS_TEMPS,
-   PIPE_CAP_MAX_FS_ADDRS,
-   PIPE_CAP_MAX_FS_PREDS,
-   PIPE_CAP_MAX_VS_INSTRUCTIONS,
-   PIPE_CAP_MAX_VS_ALU_INSTRUCTIONS,
-   PIPE_CAP_MAX_VS_TEX_INSTRUCTIONS,
-   PIPE_CAP_MAX_VS_TEX_INDIRECTIONS,
-   PIPE_CAP_MAX_VS_CONTROL_FLOW_DEPTH,
-   PIPE_CAP_MAX_VS_INPUTS,
-   PIPE_CAP_MAX_VS_CONSTS,
-   PIPE_CAP_MAX_VS_TEMPS,
-   PIPE_CAP_MAX_VS_ADDRS,
-   PIPE_CAP_MAX_VS_PREDS,
-
-   PIPE_CAP_GEOMETRY_SHADER4,
    PIPE_CAP_DEPTH_CLAMP
 };
 
+/* Shader caps not specific to any single stage */
+enum pipe_shader_cap
+{
+   PIPE_SHADER_CAP_MAX_INSTRUCTIONS, /* if 0, it means the stage is unsupported */
+   PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS,
+   PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS,
+   PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS,
+   PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH,
+   PIPE_SHADER_CAP_MAX_INPUTS,
+   PIPE_SHADER_CAP_MAX_CONSTS,
+   PIPE_SHADER_CAP_MAX_CONST_BUFFERS,
+   PIPE_SHADER_CAP_MAX_TEMPS,
+   PIPE_SHADER_CAP_MAX_ADDRS,
+   PIPE_SHADER_CAP_MAX_PREDS,
+   PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED,
+};
 
 /**
  * Referenced query flags.
diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h
index 21f428e..9126312 100644
--- a/src/gallium/include/pipe/p_screen.h
+++ b/src/gallium/include/pipe/p_screen.h
@@ -86,6 +86,12 @@ struct pipe_screen {
     */
    float (*get_paramf)( struct pipe_screen *, enum pipe_cap param );
 
+   /**
+    * Query a per-shader-stage integer-valued capability/parameter/limit
+    * \param param  one of PIPE_CAP_x
+    */
+   int (*get_shader_param)( struct pipe_screen *, unsigned shader, enum pipe_shader_cap param );
+
    struct pipe_context * (*context_create)( struct pipe_screen *,
 					    void *priv );
 
diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c
index 91bd5a9..e505f26 100644
--- a/src/mesa/state_tracker/st_extensions.c
+++ b/src/mesa/state_tracker/st_extensions.c
@@ -135,38 +135,48 @@ void st_init_limits(struct st_context *st)
       = CLAMP(screen->get_param(screen, PIPE_CAP_MAX_RENDER_TARGETS),
               1, MAX_DRAW_BUFFERS);
 
-   for(i = 0; i < MESA_SHADER_TYPES; ++i)
-      st->ctx->ShaderCompilerOptions[i].EmitNoCont = !screen->get_param(screen, PIPE_CAP_TGSI_CONT_SUPPORTED);
-
    /* Quads always follow GL provoking rules. */
    c->QuadsFollowProvokingVertexConvention = GL_FALSE;
 
-   pc = &c->FragmentProgram;
-   pc->MaxNativeInstructions    = screen->get_param(screen, PIPE_CAP_MAX_FS_INSTRUCTIONS);
-   pc->MaxNativeAluInstructions = screen->get_param(screen, PIPE_CAP_MAX_FS_ALU_INSTRUCTIONS);
-   pc->MaxNativeTexInstructions = screen->get_param(screen, PIPE_CAP_MAX_FS_TEX_INSTRUCTIONS);
-   pc->MaxNativeTexIndirections = screen->get_param(screen, PIPE_CAP_MAX_FS_TEX_INDIRECTIONS);
-   pc->MaxNativeAttribs         = screen->get_param(screen, PIPE_CAP_MAX_FS_INPUTS);
-   pc->MaxNativeTemps           = screen->get_param(screen, PIPE_CAP_MAX_FS_TEMPS);
-   pc->MaxNativeAddressRegs     = screen->get_param(screen, PIPE_CAP_MAX_FS_ADDRS);
-   pc->MaxNativeParameters      = screen->get_param(screen, PIPE_CAP_MAX_FS_CONSTS);
-
-   pc = &c->VertexProgram;
-   pc->MaxNativeInstructions    = screen->get_param(screen, PIPE_CAP_MAX_VS_INSTRUCTIONS);
-   pc->MaxNativeAluInstructions = screen->get_param(screen, PIPE_CAP_MAX_VS_ALU_INSTRUCTIONS);
-   pc->MaxNativeTexInstructions = screen->get_param(screen, PIPE_CAP_MAX_VS_TEX_INSTRUCTIONS);
-   pc->MaxNativeTexIndirections = screen->get_param(screen, PIPE_CAP_MAX_VS_TEX_INDIRECTIONS);
-   pc->MaxNativeAttribs         = screen->get_param(screen, PIPE_CAP_MAX_VS_INPUTS);
-   pc->MaxNativeTemps           = screen->get_param(screen, PIPE_CAP_MAX_VS_TEMPS);
-   pc->MaxNativeAddressRegs     = screen->get_param(screen, PIPE_CAP_MAX_VS_ADDRS);
-   pc->MaxNativeParameters      = screen->get_param(screen, PIPE_CAP_MAX_VS_CONSTS);
+   for(i = 0; i < MESA_SHADER_TYPES; ++i) {
+      struct gl_shader_compiler_options *options = &st->ctx->ShaderCompilerOptions[i];
+      switch(i)
+      {
+      case PIPE_SHADER_FRAGMENT:
+         pc = &c->FragmentProgram;
+         break;
+      case PIPE_SHADER_VERTEX:
+         pc = &c->VertexProgram;
+         break;
+      case PIPE_SHADER_GEOMETRY:
+         pc = &c->GeometryProgram;
+         break;
+      case PIPE_SHADER_TESSCTRL:
+         pc = &c->TessControlProgram;
+         break;
+      case PIPE_SHADER_TESSEVAL:
+         pc = &c->TessEvaluationProgram;
+         break;
+      }
+
+      pc->MaxNativeInstructions    = screen->get_shader_param(screen, i, PIPE_SHADER_CAP_MAX_INSTRUCTIONS);
+      pc->MaxNativeAluInstructions = screen->get_shader_param(screen, i, PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS);
+      pc->MaxNativeTexInstructions = screen->get_shader_param(screen, i, PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS);
+      pc->MaxNativeTexIndirections = screen->get_shader_param(screen, i, PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS);
+      pc->MaxNativeAttribs         = screen->get_shader_param(screen, i, PIPE_SHADER_CAP_MAX_INPUTS);
+      pc->MaxNativeTemps           = screen->get_shader_param(screen, i, PIPE_SHADER_CAP_MAX_TEMPS);
+      pc->MaxNativeAddressRegs     = screen->get_shader_param(screen, i, PIPE_SHADER_CAP_MAX_ADDRS);
+      pc->MaxNativeParameters      = screen->get_shader_param(screen, i, PIPE_SHADER_CAP_MAX_CONSTS);
+
+      options->EmitNoCont = !screen->get_shader_param(screen, i, PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED);
+   }
 
    /* PIPE_CAP_MAX_FS_INPUTS specifies the number of COLORn + GENERICn inputs
     * and is set in MaxNativeAttribs. It's always 2 colors + N generic
     * attributes. The GLSL compiler never uses COLORn for varyings, so we
     * subtract the 2 colors to get the maximum number of varyings (generic
     * attributes) supported by a driver. */
-   c->MaxVarying = screen->get_param(screen, PIPE_CAP_MAX_FS_INPUTS) - 2;
+   c->MaxVarying = screen->get_shader_param(screen, PIPE_SHADER_FRAGMENT, PIPE_SHADER_CAP_MAX_INPUTS) - 2;
    c->MaxVarying = MIN2(c->MaxVarying, MAX_VARYING);
 }
 
@@ -401,10 +411,15 @@ void st_init_extensions(struct st_context *st)
    }
 #endif
 
-   if (screen->get_param(screen, PIPE_CAP_GEOMETRY_SHADER4)) {
+   if (screen->get_shader_param(screen, PIPE_SHADER_GEOMETRY, PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0) {
       ctx->Extensions.ARB_geometry_shader4 = GL_TRUE;
    }
 
+   if ((screen->get_shader_param(screen, PIPE_SHADER_TESSCTRL, PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0)
+      && (screen->get_shader_param(screen, PIPE_SHADER_TESSEVAL, PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0)) {
+      ctx->Extensions.ARB_tessellation_shader = GL_TRUE;
+   }
+
    if (screen->get_param(screen, PIPE_CAP_DEPTH_CLAMP)) {
       ctx->Extensions.ARB_depth_clamp = GL_TRUE;
    }
-- 
1.7.0.4



More information about the mesa-dev mailing list