diff options
25 files changed, 612 insertions, 345 deletions
diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index 4c780e4dcb4..4f0d30123a4 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 6dee362d589..9d62c1d7e7e 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 94d5bd30278..f6a87869c76 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 b1074f9eb21..7bd23800414 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 78473bf35ac..6ed39561fbe 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 0f12e0667eb..8d2b4b96438 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 761a0fce721..ec3609291e9 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 5b56a4d0edb..ff6d2aa00ab 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 75e4c2d82e9..288941b1066 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 77345d5f711..34bd81f9bd6 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 bdfead73cc8..23599806197 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 f71585e06f8..c46d7457fcd 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 363940d3a73..364a299871a 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" @@ -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; diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index ca4b01b12b3..f37dd079acb 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 0290370d989..3f177b7ed07 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 1e4edcdbc31..7f41ff0e2ec 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 bb215a33670..19d1005e771 100644 --- a/src/gallium/drivers/r600/r600_screen.c +++ b/src/gallium/drivers/r600/r600_screen.c @@ -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; diff --git a/src/gallium/drivers/rbug/rbug_screen.c b/src/gallium/drivers/rbug/rbug_screen.c index b9f32ee6a9b..42555ab3310 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 73ae2dea561..2053d02f628 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 077ff9a2cf6..b5fae94f783 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/drivers/trace/tr_screen.c b/src/gallium/drivers/trace/tr_screen.c index 32e519a68a0..935831071e6 100644 --- a/src/gallium/drivers/trace/tr_screen.c +++ b/src/gallium/drivers/trace/tr_screen.c @@ -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); diff --git a/src/gallium/include/pipe/p_compiler.h b/src/gallium/include/pipe/p_compiler.h index 0a5be43f6bf..50205995911 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 627b5ae5380..8b4663742fa 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -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. diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h index 21f428ed4af..912631242f5 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 91bd5a92c92..d637e6f43a0 100644 --- a/src/mesa/state_tracker/st_extensions.c +++ b/src/mesa/state_tracker/st_extensions.c @@ -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; } |