ARB_fp: accept duplicate precision options
authorChris Forbes <chrisf@ijw.co.nz>
Thu, 16 May 2013 09:21:05 +0000 (21:21 +1200)
committerChris Forbes <chrisf@ijw.co.nz>
Thu, 23 May 2013 19:50:51 +0000 (07:50 +1200)
Relaxes the validation of

   OPTION ARB_precision_hint_{nicest,fastest};

to allow duplicate options. The spec says that both /nicest/ and
/fastest/ cannot be specified together, but could be interpreted
either way for respecification of the same option.

Other drivers (NVIDIA etc) accept this, and at least one Unity3D game
expects it to succeed (Kerbal Space Program).

V2: Add spec quote.

Signed-off-by: Chris Forbes <chrisf@ijw.co.nz>
Reviewed-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
src/mesa/program/program_parse_extra.c

index 4d928483e1602f7a430b4e798dfb0f8e142a3c37..e8e1912eb855ae7365dbbb932c166a7aa2676b3b 100644 (file)
@@ -194,15 +194,21 @@ _mesa_ARBfp_parse_option(struct asm_parser_state *state, const char *option)
       } 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) {