gallium: introduce get_shader_param (ALL DRIVERS CHANGED) (v3)
authorLuca Barbieri <luca@luca-barbieri.com>
Sun, 5 Sep 2010 18:50:50 +0000 (20:50 +0200)
committerLuca Barbieri <luca@luca-barbieri.com>
Tue, 14 Sep 2010 04:07:41 +0000 (06:07 +0200)
Changes in v3:
- Also change trace, which I forgot about

Changes in v2:
- No longer adds tessellation shaders

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

25 files changed:
src/gallium/auxiliary/draw/draw_context.h
src/gallium/auxiliary/tgsi/tgsi_exec.h
src/gallium/auxiliary/util/u_caps.c
src/gallium/auxiliary/util/u_caps.h
src/gallium/auxiliary/util/u_inlines.h
src/gallium/drivers/cell/ppu/cell_screen.c
src/gallium/drivers/failover/fo_context.c
src/gallium/drivers/galahad/glhd_context.c
src/gallium/drivers/galahad/glhd_screen.c
src/gallium/drivers/i915/i915_screen.c
src/gallium/drivers/i965/brw_screen.c
src/gallium/drivers/identity/id_screen.c
src/gallium/drivers/llvmpipe/lp_screen.c
src/gallium/drivers/nv50/nv50_screen.c
src/gallium/drivers/nvfx/nvfx_screen.c
src/gallium/drivers/r300/r300_screen.c
src/gallium/drivers/r600/r600_screen.c
src/gallium/drivers/rbug/rbug_screen.c
src/gallium/drivers/softpipe/sp_screen.c
src/gallium/drivers/svga/svga_screen.c
src/gallium/drivers/trace/tr_screen.c
src/gallium/include/pipe/p_compiler.h
src/gallium/include/pipe/p_defines.h
src/gallium/include/pipe/p_screen.h
src/mesa/state_tracker/st_extensions.c

index 4c780e4dcb4dc646e52966496ceefb87b8627c75..4f0d30123a4bc018a780e699c2865df72ea2f5de 100644 (file)
@@ -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 */
index 6dee362d5899bf8c6a8ac51d213bc2b88e5ec31a..9d62c1d7e7eb891d041c012d5cb3bf8853760593 100644 (file)
@@ -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
index 94d5bd30278f0697624f27cc2bd067b6c6b1f004..f6a87869c7665ff07713b589d8c704e7ace2395d 100644 (file)
@@ -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
 };
index b1074f9eb2134de7642b2e403349c22b052d4df9..7bd2380041426f3c35372b289a3c3710d14fe920 100644 (file)
@@ -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
 
index 78473bf35ac0d690182c984d3160a55e43f9dfae..6ed39561fbe941aa56f238b4932c8fac262e4cf6 100644 (file)
@@ -399,7 +399,6 @@ static INLINE boolean util_get_offset(
    }
 }
 
-
 #ifdef __cplusplus
 }
 #endif
index 0f12e0667eb93e28512f048c63674de5b67b08c3..8d2b4b964382c554d0750edcb4ce80007b211b5e 100644 (file)
@@ -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;
index 761a0fce721617f39971b433e962073dcdf483e6..ec3609291e9a51e423a79905e1c1a9ba8e776481 100644 (file)
@@ -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
 
index 5b56a4d0edb3af7e460149d9ef7a1ff78ef30b33..ff6d2aa00ab694533caadc11e4891a5defac5369 100644 (file)
@@ -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 */
index 75e4c2d82e91ddd7eae42ca9ffdbf73b28ee87af..288941b10667246f5fd48bd0ffc9236f58305dad 100644 (file)
@@ -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;
index 77345d5f7117fe3d369984245188bdd71aab3767..34bd81f9bd641d7d783207823475d573439135ed 100644 (file)
@@ -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;
 
index bdfead73cc87b7e39f722ea20d34886e82b7720e..2359980619784716298820155535d1f5ca5f52d2 100644 (file)
@@ -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;
index f71585e06f81c7f0a399ec605b2e8c722b6e37ba..c46d7457fcda7de8cb5273e55bf21aa5fb2ad20e 100644 (file)
@@ -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;
index 363940d3a7398b313ff61ac8683f48738acb264b..364a299871a883bb4faeb43f0d70aef4abbd48c5 100644 (file)
@@ -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"
@@ -132,8 +133,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:
@@ -146,47 +145,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)
@@ -402,6 +383,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;
 
index ca4b01b12b3fc54b8370b6d983af65a0b718ba2a..f37dd079acb0e3cb9336dbad6aa2ad81120236dc 100644 (file)
@@ -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;
index 0290370d9896dd82ffb627a7993622439a186209..3f177b7ed0723c51ca0be99865bbcdcd1496939b 100644 (file)
@@ -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;
index 1e4edcdbc31425a55e4b828c3e418165829e753b..7f41ff0e2ec9f58ce2c7a1093d3cefa96abc9742 100644 (file)
@@ -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;
index bb215a33670e08d351740ae7c649c83b82ed0034..19d1005e77183d9371d55482588acd607ae25602 100644 (file)
@@ -76,10 +76,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. */
@@ -106,55 +104,59 @@ 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;
+       default:
+               /* TODO: support tessellation on Evergreen */
+               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) {
@@ -281,6 +283,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;
index b9f32ee6a9b83a85ce11d5ee30bbb12887fdd421..42555ab3310ee2a68a71f0ec59eefdf48061741e 100644 (file)
@@ -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;
index 73ae2dea561e588ea24461be234ac611f20defa9..2053d02f6289fcb4d726e975c71abe9342b658c2 100644 (file)
@@ -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;
index 077ff9a2cf6bfe58a58d1748eafe9a64c613c270..b5fae94f783194a66f3bedd53a6be9d805faee68 100644 (file)
@@ -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;
index 32e519a68a094e0263ef50aa145f74d4605ac94a..935831071e62dd34a07e93874cc6b95b98ccb91d 100644 (file)
@@ -106,6 +106,30 @@ trace_screen_get_param(struct pipe_screen *_screen,
 }
 
 
+static int
+trace_screen_get_shader_param(struct pipe_screen *_screen, unsigned shader,
+                       enum pipe_shader_cap param)
+{
+   struct trace_screen *tr_scr = trace_screen(_screen);
+   struct pipe_screen *screen = tr_scr->screen;
+   int result;
+
+   trace_dump_call_begin("pipe_screen", "get_shader_param");
+
+   trace_dump_arg(ptr, screen);
+   trace_dump_arg(int, shader);
+   trace_dump_arg(int, param);
+
+   result = screen->get_shader_param(screen, shader, param);
+
+   trace_dump_ret(int, result);
+
+   trace_dump_call_end();
+
+   return result;
+}
+
+
 static float
 trace_screen_get_paramf(struct pipe_screen *_screen,
                         enum pipe_cap param)
@@ -547,6 +571,7 @@ trace_screen_create(struct pipe_screen *screen)
    tr_scr->base.get_name = trace_screen_get_name;
    tr_scr->base.get_vendor = trace_screen_get_vendor;
    tr_scr->base.get_param = trace_screen_get_param;
+   tr_scr->base.get_shader_param = trace_screen_get_shader_param;
    tr_scr->base.get_paramf = trace_screen_get_paramf;
    tr_scr->base.is_format_supported = trace_screen_is_format_supported;
    assert(screen->context_create);
index 0a5be43f6bf0e6472d76aa50f49de6b6914359bd..50205995911ec691f243ea9697c5ab0915f7bb91 100644 (file)
@@ -35,6 +35,7 @@
 #include <string.h>
 #include <stddef.h>
 #include <stdarg.h>
+#include <limits.h>
 
 
 #if defined(_WIN32) && !defined(__WIN32__)
index 627b5ae53807ebcf470d2ad997e91a08fcdaebd5..8b4663742fa5bd4fcfee53b4143c197095dd6907 100644 (file)
@@ -449,16 +449,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 */
@@ -468,35 +464,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.
index 21f428ed4af0862b1e1e0bd050188de68d5fc326..912631242f51ba52734ee5e06b8d646838374b76 100644 (file)
@@ -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 );
 
index 91bd5a92c92856d1bb78efa26153282b9aa9aea5..d637e6f43a0d39f4aee2faa0030803219131600e 100644 (file)
@@ -135,38 +135,42 @@ 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;
+      }
+
+      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,7 +405,7 @@ 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;
    }