Merge branch 'gallium-msaa'
[mesa.git] / src / gallium / drivers / r300 / r300_screen.c
index b7f1c617f0390d63f732c2d725331295a1aa96b6..ef0255066b798061a30f74924c5c2557e5ba3d1a 100644 (file)
@@ -76,20 +76,19 @@ static const char* r300_get_name(struct pipe_screen* pscreen)
     return chip_families[r300screen->caps.family];
 }
 
-static int r300_get_param(struct pipe_screen* pscreen, int param)
+static int r300_get_param(struct pipe_screen* pscreen, enum pipe_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 (param) {
-        case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
-        case PIPE_CAP_MAX_COMBINED_SAMPLERS:
-            return r300screen->caps.num_tex_units;
+        /* Supported features (boolean caps). */
         case PIPE_CAP_NPOT_TEXTURES:
-            /* XXX enable now to get GL2.1 API,
-             * figure out later how to emulate this */
-            return 1;
         case PIPE_CAP_TWO_SIDED_STENCIL:
-            return 1;
         case PIPE_CAP_GLSL:
             /* I'll be frank. This is a lie.
              *
@@ -106,59 +105,103 @@ static int r300_get_param(struct pipe_screen* pscreen, int param)
              *
              * ~ C.
              */
-            return 1;
-        case PIPE_CAP_DUAL_SOURCE_BLEND:
-            return 0;
         case PIPE_CAP_ANISOTROPIC_FILTER:
-            return 1;
         case PIPE_CAP_POINT_SPRITE:
-            return 1;
-        case PIPE_CAP_MAX_RENDER_TARGETS:
-            return 4;
         case PIPE_CAP_OCCLUSION_QUERY:
-            return 1;
         case PIPE_CAP_TEXTURE_SHADOW_MAP:
-            return 1;
-        case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
-        case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
-        case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
-            if (r300screen->caps.is_r500) {
-                /* 13 == 4096 */
-                return 13;
-            } else {
-                /* 12 == 2048 */
-                return 12;
-            }
         case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
-            return 1;
         case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
+        case PIPE_CAP_BLEND_EQUATION_SEPARATE:
             return 1;
-        case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
-            return 0;
+
+        /* 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:
             return 0;
-        case PIPE_CAP_BLEND_EQUATION_SEPARATE:
-            return 1;
+
+        /* Texturing. */
+        case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
+        case PIPE_CAP_MAX_COMBINED_SAMPLERS:
+            return r300screen->caps.num_tex_units;
+        case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
+            return 0;
+        case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
+        case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
+        case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
+            /* 13 == 4096, 12 == 2048 */
+            return is_r500 ? 13 : 12;
+
+        /* Render targets. */
+        case PIPE_CAP_MAX_RENDER_TARGETS:
+            return 4;
+
+        /* General shader limits and features. */
         case PIPE_CAP_SM3:
-            if (r300screen->caps.is_r500) {
-                return 1;
-            } else {
-                return 0;
-            }
+            return is_r500 ? 1 : 0;
         case PIPE_CAP_MAX_CONST_BUFFERS:
             return 1;
         case PIPE_CAP_MAX_CONST_BUFFER_SIZE:
             return 256;
-        case PIPE_CAP_INDEP_BLEND_ENABLE:
-            return 0;
-        case PIPE_CAP_INDEP_BLEND_FUNC:
-            return 0;
+
+        /* Fragment coordinate conventions. */
         case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
         case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
            return 1;
         case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
         case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
             return 0;
+
+        /* Fragment shader limits. */
+        case PIPE_CAP_MAX_FS_INSTRUCTIONS:
+            return is_r500 || is_r400 ? 512 : 96;
+        case PIPE_CAP_MAX_FS_ALU_INSTRUCTIONS:
+            return is_r500 || is_r400 ? 512 : 64;
+        case PIPE_CAP_MAX_FS_TEX_INSTRUCTIONS:
+            return is_r500 || is_r400 ? 512 : 32;
+        case PIPE_CAP_MAX_FS_TEX_INDIRECTIONS:
+            return is_r500 ? 511 : 4;
+        case PIPE_CAP_MAX_FS_CONTROL_FLOW_DEPTH:
+            return is_r500 ? 64 : 0; /* Actually unlimited on r500. */
+        case PIPE_CAP_MAX_FS_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_CAP_MAX_FS_CONSTS:
+            return is_r500 ? 256 : 32;
+        case PIPE_CAP_MAX_FS_TEMPS:
+            return is_r500 ? 128 : is_r400 ? 64 : 32;
+        case PIPE_CAP_MAX_FS_ADDRS:
+            return 0;
+        case PIPE_CAP_MAX_FS_PREDS:
+            return is_r500 ? 1 : 0;
+
+        /* Vertex shader limits. */
+        case PIPE_CAP_MAX_VS_INSTRUCTIONS:
+        case PIPE_CAP_MAX_VS_ALU_INSTRUCTIONS:
+            return is_r500 ? 1024 : 256;
+        case PIPE_CAP_MAX_VS_TEX_INSTRUCTIONS:
+        case PIPE_CAP_MAX_VS_TEX_INDIRECTIONS:
+            return 0;
+        case PIPE_CAP_MAX_VS_CONTROL_FLOW_DEPTH:
+            return is_r500 ? 4 : 0; /* For loops; not sure about conditionals. */
+        case PIPE_CAP_MAX_VS_INPUTS:
+            return 16;
+        case PIPE_CAP_MAX_VS_CONSTS:
+            return 256;
+        case PIPE_CAP_MAX_VS_TEMPS:
+            return 32;
+        case PIPE_CAP_MAX_VS_ADDRS:
+            return 1; /* XXX guessed */
+        case PIPE_CAP_MAX_VS_PREDS:
+            return is_r500 ? 4 : 0; /* XXX guessed. */
+
         default:
             fprintf(stderr, "r300: Implementation error: Bad param %d\n",
                 param);
@@ -166,7 +209,7 @@ static int r300_get_param(struct pipe_screen* pscreen, int param)
     }
 }
 
-static float r300_get_paramf(struct pipe_screen* pscreen, int param)
+static float r300_get_paramf(struct pipe_screen* pscreen, enum pipe_cap param)
 {
     struct r300_screen* r300screen = r300_screen(pscreen);