+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;
+
+ switch (shader)
+ {
+ case PIPE_SHADER_FRAGMENT:
+ switch (param)
+ {
+ case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
+ return is_r500 || is_r400 ? 512 : 96;
+ case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
+ return is_r500 || is_r400 ? 512 : 64;
+ case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
+ return is_r500 || is_r400 ? 512 : 32;
+ case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
+ return is_r500 ? 511 : 4;
+ case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
+ return is_r500 ? 64 : 0; /* Actually unlimited on r500. */
+ /* Fragment shader limits. */
+ case PIPE_SHADER_CAP_MAX_INPUTS:
+ /* 2 colors + 8 texcoords are always supported
+ * (minus fog and wpos).
+ *
+ * R500 has the ability to turn 3rd and 4th color into
+ * additional texcoords but there is no two-sided color
+ * selection then. However the facing bit can be used instead. */
+ return 10;
+ case PIPE_SHADER_CAP_MAX_CONSTS:
+ return is_r500 ? 256 : 32;
+ 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_SHADER_CAP_MAX_ADDRS:
+ return 0;
+ case PIPE_SHADER_CAP_MAX_PREDS:
+ return is_r500 ? 1 : 0;
+ case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
+ return 0;
+ case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
+ case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
+ case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
+ case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
+ return 0;
+ case PIPE_SHADER_CAP_SUBROUTINES:
+ return 0;
+ }
+ break;
+ case PIPE_SHADER_VERTEX:
+ if (!r300screen->caps.has_tcl) {
+ return draw_get_shader_param(shader, param);
+ }
+
+ switch (param)
+ {
+ case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
+ case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
+ return is_r500 ? 1024 : 256;
+ case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
+ case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
+ return 0;
+ case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
+ return is_r500 ? 4 : 0; /* For loops; not sure about conditionals. */
+ 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:
+ return 32;
+ case PIPE_SHADER_CAP_MAX_ADDRS:
+ return 1; /* XXX guessed */
+ case PIPE_SHADER_CAP_MAX_PREDS:
+ return is_r500 ? 4 : 0; /* XXX guessed. */
+ case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
+ return 0;
+ case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
+ case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
+ case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
+ return 0;
+ case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
+ return 1;
+ case PIPE_SHADER_CAP_SUBROUTINES:
+ return 0;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+static float r300_get_paramf(struct pipe_screen* pscreen, enum pipe_cap param)