Home | History | Annotate | Download | only in program
      1 /*
      2  * Copyright  2009 Intel Corporation
      3  *
      4  * Permission is hereby granted, free of charge, to any person obtaining a
      5  * copy of this software and associated documentation files (the "Software"),
      6  * to deal in the Software without restriction, including without limitation
      7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8  * and/or sell copies of the Software, and to permit persons to whom the
      9  * Software is furnished to do so, subject to the following conditions:
     10  *
     11  * The above copyright notice and this permission notice (including the next
     12  * paragraph) shall be included in all copies or substantial portions of the
     13  * Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     21  * DEALINGS IN THE SOFTWARE.
     22  */
     23 
     24 #include <string.h>
     25 #include "main/mtypes.h"
     26 #include "prog_instruction.h"
     27 #include "program_parser.h"
     28 
     29 
     30 /**
     31  * Extra assembly-level parser routines
     32  *
     33  * \author Ian Romanick <ian.d.romanick (at) intel.com>
     34  */
     35 
     36 int
     37 _mesa_parse_instruction_suffix(const struct asm_parser_state *state,
     38 			       const char *suffix,
     39 			       struct prog_instruction *inst)
     40 {
     41    inst->Saturate = GL_FALSE;
     42 
     43    /* The only possible suffix element is the saturation selector from
     44     * ARB_fragment_program.
     45     */
     46    if (state->mode == ARB_fragment) {
     47       if (strcmp(suffix, "_SAT") == 0) {
     48 	 inst->Saturate = GL_TRUE;
     49 	 suffix += 4;
     50       }
     51    }
     52 
     53    /* It is an error for all of the suffix string not to be consumed.
     54     */
     55    return suffix[0] == '\0';
     56 }
     57 
     58 
     59 int
     60 _mesa_ARBvp_parse_option(struct asm_parser_state *state, const char *option)
     61 {
     62    if (strcmp(option, "ARB_position_invariant") == 0) {
     63       state->option.PositionInvariant = 1;
     64       return 1;
     65    }
     66 
     67    return 0;
     68 }
     69 
     70 
     71 int
     72 _mesa_ARBfp_parse_option(struct asm_parser_state *state, const char *option)
     73 {
     74    unsigned fog_option;
     75 
     76    /* All of the options currently supported start with "ARB_".  The code is
     77     * currently structured with nested if-statements because eventually options
     78     * that start with "NV_" will be supported.  This structure will result in
     79     * less churn when those options are added.
     80     */
     81    if (strncmp(option, "ARB_", 4) == 0) {
     82       /* Advance the pointer past the "ARB_" prefix.
     83        */
     84       option += 4;
     85 
     86       if (strncmp(option, "fog_", 4) == 0) {
     87 	 option += 4;
     88 
     89          if (strcmp(option, "exp") == 0) {
     90             fog_option = OPTION_FOG_EXP;
     91          } else if (strcmp(option, "exp2") == 0) {
     92             fog_option = OPTION_FOG_EXP2;
     93          } else if (strcmp(option, "linear") == 0) {
     94             fog_option = OPTION_FOG_LINEAR;
     95          } else {
     96             /* invalid option */
     97             return 0;
     98          }
     99 
    100          if (state->option.Fog == OPTION_NONE) {
    101             state->option.Fog = fog_option;
    102             return 1;
    103          }
    104 
    105          /* The ARB_fragment_program specification instructs us to handle
    106           * redundant options in two seemingly contradictory ways:
    107           *
    108           * Section 3.11.4.5.1 says:
    109           * "Only one fog application option may be specified by any given
    110           *  fragment program.  A fragment program that specifies more than one
    111           *  of the program options "ARB_fog_exp", "ARB_fog_exp2", and
    112           *  "ARB_fog_linear", will fail to load."
    113           *
    114           * Issue 27 says:
    115           * "The three mandatory options are ARB_fog_exp, ARB_fog_exp2, and
    116           *  ARB_fog_linear.  As these options are mutually exclusive by
    117           *  nature, specifying more than one is not useful.  If more than one
    118           *  is specified, the last one encountered in the <optionSequence>
    119           *  will be the one to actually modify the execution environment."
    120           *
    121           * We choose to allow programs to specify the same OPTION redundantly,
    122           * but fail to load programs that specify contradictory options.
    123           */
    124          return state->option.Fog == fog_option ? 1 : 0;
    125       } else if (strncmp(option, "precision_hint_", 15) == 0) {
    126 	 option += 15;
    127 
    128          /* The ARB_fragment_program spec, 3.11.4.5.2 says:
    129           *
    130           * "Only one precision control option may be specified by any given
    131           * fragment program.  A fragment program that specifies both the
    132           * "ARB_precision_hint_fastest" and "ARB_precision_hint_nicest"
    133           * program options will fail to load.
    134           */
    135 
    136          if (strcmp(option, "nicest") == 0 &&
    137              state->option.PrecisionHint != OPTION_FASTEST) {
    138             state->option.PrecisionHint = OPTION_NICEST;
    139             return 1;
    140          } else if (strcmp(option, "fastest") == 0 &&
    141                     state->option.PrecisionHint != OPTION_NICEST) {
    142             state->option.PrecisionHint = OPTION_FASTEST;
    143             return 1;
    144          }
    145 
    146 	 return 0;
    147       } else if (strcmp(option, "draw_buffers") == 0) {
    148 	 /* Don't need to check extension availability because all Mesa-based
    149 	  * drivers support GL_ARB_draw_buffers.
    150 	  */
    151 	 state->option.DrawBuffers = 1;
    152 	 return 1;
    153       } else if (strcmp(option, "fragment_program_shadow") == 0) {
    154 	 if (state->ctx->Extensions.ARB_fragment_program_shadow) {
    155 	    state->option.Shadow = 1;
    156 	    return 1;
    157 	 }
    158       } else if (strncmp(option, "fragment_coord_", 15) == 0) {
    159          option += 15;
    160          if (state->ctx->Extensions.ARB_fragment_coord_conventions) {
    161             if (strcmp(option, "origin_upper_left") == 0) {
    162                state->option.OriginUpperLeft = 1;
    163                return 1;
    164             }
    165             else if (strcmp(option, "pixel_center_integer") == 0) {
    166                state->option.PixelCenterInteger = 1;
    167                return 1;
    168             }
    169          }
    170       }
    171    } else if (strncmp(option, "ATI_", 4) == 0) {
    172       option += 4;
    173 
    174       if (strcmp(option, "draw_buffers") == 0) {
    175 	 /* Don't need to check extension availability because all Mesa-based
    176 	  * drivers support GL_ATI_draw_buffers.
    177 	  */
    178 	 state->option.DrawBuffers = 1;
    179 	 return 1;
    180       }
    181    }
    182 
    183    return 0;
    184 }
    185