mesa/formats: add more MESA_FORMAT_LAYOUTs
[mesa.git] / src / mesa / program / program_parse_extra.c
index ae98b782b70523cb237aea3b05ec85d62759f3bf..71f86d13acea82815ee824fecdb9224cdfbe25b1 100644 (file)
@@ -40,7 +40,7 @@ _mesa_parse_instruction_suffix(const struct asm_parser_state *state,
 {
    inst->CondUpdate = 0;
    inst->CondDst = 0;
-   inst->SaturateMode = SATURATE_OFF;
+   inst->Saturate = GL_FALSE;
    inst->Precision = FLOAT32;
 
 
@@ -82,7 +82,7 @@ _mesa_parse_instruction_suffix(const struct asm_parser_state *state,
     */
    if (state->mode == ARB_fragment) {
       if (strcmp(suffix, "_SAT") == 0) {
-        inst->SaturateMode = SATURATE_ZERO_ONE;
+        inst->Saturate = GL_TRUE;
         suffix += 4;
       }
    }
@@ -163,6 +163,8 @@ _mesa_ARBvp_parse_option(struct asm_parser_state *state, const char *option)
 int
 _mesa_ARBfp_parse_option(struct asm_parser_state *state, const char *option)
 {
+   unsigned fog_option;
+
    /* All of the options currently supported start with "ARB_".  The code is
     * currently structured with nested if-statements because eventually options
     * that start with "NV_" will be supported.  This structure will result in
@@ -177,32 +179,60 @@ _mesa_ARBfp_parse_option(struct asm_parser_state *state, const char *option)
       if (strncmp(option, "fog_", 4) == 0) {
         option += 4;
 
-        if (state->option.Fog == OPTION_NONE) {
-           if (strcmp(option, "exp") == 0) {
-              state->option.Fog = OPTION_FOG_EXP;
-              return 1;
-           } else if (strcmp(option, "exp2") == 0) {
-              state->option.Fog = OPTION_FOG_EXP2;
-              return 1;
-           } else if (strcmp(option, "linear") == 0) {
-              state->option.Fog = OPTION_FOG_LINEAR;
-              return 1;
-           }
-        }
+         if (strcmp(option, "exp") == 0) {
+            fog_option = OPTION_FOG_EXP;
+         } else if (strcmp(option, "exp2") == 0) {
+            fog_option = OPTION_FOG_EXP2;
+         } else if (strcmp(option, "linear") == 0) {
+            fog_option = OPTION_FOG_LINEAR;
+         } else {
+            /* invalid option */
+            return 0;
+         }
 
-        return 0;
+         if (state->option.Fog == OPTION_NONE) {
+            state->option.Fog = fog_option;
+            return 1;
+         }
+
+         /* The ARB_fragment_program specification instructs us to handle
+          * redundant options in two seemingly contradictory ways:
+          *
+          * Section 3.11.4.5.1 says:
+          * "Only one fog application option may be specified by any given
+          *  fragment program.  A fragment program that specifies more than one
+          *  of the program options "ARB_fog_exp", "ARB_fog_exp2", and
+          *  "ARB_fog_linear", will fail to load."
+          *
+          * Issue 27 says:
+          * "The three mandatory options are ARB_fog_exp, ARB_fog_exp2, and
+          *  ARB_fog_linear.  As these options are mutually exclusive by
+          *  nature, specifying more than one is not useful.  If more than one
+          *  is specified, the last one encountered in the <optionSequence>
+          *  will be the one to actually modify the execution environment."
+          *
+          * We choose to allow programs to specify the same OPTION redundantly,
+          * but fail to load programs that specify contradictory options.
+          */
+         return state->option.Fog == fog_option ? 1 : 0;
       } else if (strncmp(option, "precision_hint_", 15) == 0) {
         option += 15;
 
-        if (state->option.PrecisionHint == OPTION_NONE) {
-           if (strcmp(option, "nicest") == 0) {
-              state->option.PrecisionHint = OPTION_NICEST;
-              return 1;
-           } else if (strcmp(option, "fastest") == 0) {
-              state->option.PrecisionHint = OPTION_FASTEST;
-              return 1;
-           }
-        }
+         /* The ARB_fragment_program spec, 3.11.4.5.2 says:
+          *
+          * "Only one precision control option may be specified by any given
+          * fragment program.  A fragment program that specifies both the
+          * "ARB_precision_hint_fastest" and "ARB_precision_hint_nicest"
+          * program options will fail to load.
+          */
+
+         if (strcmp(option, "nicest") == 0 && state->option.PrecisionHint != OPTION_FASTEST) {
+            state->option.PrecisionHint = OPTION_NICEST;
+            return 1;
+         } else if (strcmp(option, "fastest") == 0 && state->option.PrecisionHint != OPTION_NICEST) {
+            state->option.PrecisionHint = OPTION_FASTEST;
+            return 1;
+         }
 
         return 0;
       } else if (strcmp(option, "draw_buffers") == 0) {
@@ -229,6 +259,16 @@ _mesa_ARBfp_parse_option(struct asm_parser_state *state, const char *option)
             }
          }
       }
+   } else if (strncmp(option, "ATI_", 4) == 0) {
+      option += 4;
+
+      if (strcmp(option, "draw_buffers") == 0) {
+        /* Don't need to check extension availability because all Mesa-based
+         * drivers support GL_ATI_draw_buffers.
+         */
+        state->option.DrawBuffers = 1;
+        return 1;
+      }
    } else if (strncmp(option, "NV_fragment_program", 19) == 0) {
       option += 19;
 
@@ -240,15 +280,6 @@ _mesa_ARBfp_parse_option(struct asm_parser_state *state, const char *option)
            return 1;
         }
       }
-   } else if (strncmp(option, "MESA_", 5) == 0) {
-      option += 5;
-
-      if (strcmp(option, "texture_array") == 0) {
-        if (state->ctx->Extensions.MESA_texture_array) {
-           state->option.TexArray = 1;
-           return 1;
-        }
-      }
    }
 
    return 0;