[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