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

José Fonseca jfonseca at vmware.com
Mon Sep 6 07:27:38 PDT 2010


FWIW, I think this is a worthwhile interface cleanup. Your commit
comment says it all. 

I did think of this when introducing the current shader caps enums, but
informal feedback I got was that it was better to stick with the current
get_param system. Now that the number of shader types is growing perhaps
this becomes more appealing to everyone.

Jose

On Sun, 2010-09-05 at 18:30 -0700, Luca Barbieri wrote:
> 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
> 
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev




More information about the mesa-dev mailing list