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->CondUpdate = 0;
     42    inst->CondDst = 0;
     43    inst->SaturateMode = SATURATE_OFF;
     44    inst->Precision = FLOAT32;
     45 
     46 
     47    /* The first possible suffix element is the precision specifier from
     48     * NV_fragment_program_option.
     49     */
     50    if (state->option.NV_fragment) {
     51       switch (suffix[0]) {
     52       case 'H':
     53 	 inst->Precision = FLOAT16;
     54 	 suffix++;
     55 	 break;
     56       case 'R':
     57 	 inst->Precision = FLOAT32;
     58 	 suffix++;
     59 	 break;
     60       case 'X':
     61 	 inst->Precision = FIXED12;
     62 	 suffix++;
     63 	 break;
     64       default:
     65 	 break;
     66       }
     67    }
     68 
     69    /* The next possible suffix element is the condition code modifier selection
     70     * from NV_fragment_program_option.
     71     */
     72    if (state->option.NV_fragment) {
     73       if (suffix[0] == 'C') {
     74 	 inst->CondUpdate = 1;
     75 	 suffix++;
     76       }
     77    }
     78 
     79 
     80    /* The final possible suffix element is the saturation selector from
     81     * ARB_fragment_program.
     82     */
     83    if (state->mode == ARB_fragment) {
     84       if (strcmp(suffix, "_SAT") == 0) {
     85 	 inst->SaturateMode = SATURATE_ZERO_ONE;
     86 	 suffix += 4;
     87       }
     88    }
     89 
     90 
     91    /* It is an error for all of the suffix string not to be consumed.
     92     */
     93    return suffix[0] == '\0';
     94 }
     95 
     96 
     97 int
     98 _mesa_parse_cc(const char *s)
     99 {
    100    int cond = 0;
    101 
    102    switch (s[0]) {
    103    case 'E':
    104       if (s[1] == 'Q') {
    105 	 cond = COND_EQ;
    106       }
    107       break;
    108 
    109    case 'F':
    110       if (s[1] == 'L') {
    111 	 cond = COND_FL;
    112       }
    113       break;
    114 
    115    case 'G':
    116       if (s[1] == 'E') {
    117 	 cond = COND_GE;
    118       } else if (s[1] == 'T') {
    119 	 cond = COND_GT;
    120       }
    121       break;
    122 
    123    case 'L':
    124       if (s[1] == 'E') {
    125 	 cond = COND_LE;
    126       } else if (s[1] == 'T') {
    127 	 cond = COND_LT;
    128       }
    129       break;
    130 
    131    case 'N':
    132       if (s[1] == 'E') {
    133 	 cond = COND_NE;
    134       }
    135       break;
    136 
    137    case 'T':
    138       if (s[1] == 'R') {
    139 	 cond = COND_TR;
    140       }
    141       break;
    142 
    143    default:
    144       break;
    145    }
    146 
    147    return ((cond == 0) || (s[2] != '\0')) ? 0 : cond;
    148 }
    149 
    150 
    151 int
    152 _mesa_ARBvp_parse_option(struct asm_parser_state *state, const char *option)
    153 {
    154    if (strcmp(option, "ARB_position_invariant") == 0) {
    155       state->option.PositionInvariant = 1;
    156       return 1;
    157    }
    158 
    159    return 0;
    160 }
    161 
    162 
    163 int
    164 _mesa_ARBfp_parse_option(struct asm_parser_state *state, const char *option)
    165 {
    166    /* All of the options currently supported start with "ARB_".  The code is
    167     * currently structured with nested if-statements because eventually options
    168     * that start with "NV_" will be supported.  This structure will result in
    169     * less churn when those options are added.
    170     */
    171    if (strncmp(option, "ARB_", 4) == 0) {
    172       /* Advance the pointer past the "ARB_" prefix.
    173        */
    174       option += 4;
    175 
    176 
    177       if (strncmp(option, "fog_", 4) == 0) {
    178 	 option += 4;
    179 
    180 	 if (state->option.Fog == OPTION_NONE) {
    181 	    if (strcmp(option, "exp") == 0) {
    182 	       state->option.Fog = OPTION_FOG_EXP;
    183 	       return 1;
    184 	    } else if (strcmp(option, "exp2") == 0) {
    185 	       state->option.Fog = OPTION_FOG_EXP2;
    186 	       return 1;
    187 	    } else if (strcmp(option, "linear") == 0) {
    188 	       state->option.Fog = OPTION_FOG_LINEAR;
    189 	       return 1;
    190 	    }
    191 	 }
    192 
    193 	 return 0;
    194       } else if (strncmp(option, "precision_hint_", 15) == 0) {
    195 	 option += 15;
    196 
    197 	 if (state->option.PrecisionHint == OPTION_NONE) {
    198 	    if (strcmp(option, "nicest") == 0) {
    199 	       state->option.PrecisionHint = OPTION_NICEST;
    200 	       return 1;
    201 	    } else if (strcmp(option, "fastest") == 0) {
    202 	       state->option.PrecisionHint = OPTION_FASTEST;
    203 	       return 1;
    204 	    }
    205 	 }
    206 
    207 	 return 0;
    208       } else if (strcmp(option, "draw_buffers") == 0) {
    209 	 /* Don't need to check extension availability because all Mesa-based
    210 	  * drivers support GL_ARB_draw_buffers.
    211 	  */
    212 	 state->option.DrawBuffers = 1;
    213 	 return 1;
    214       } else if (strcmp(option, "fragment_program_shadow") == 0) {
    215 	 if (state->ctx->Extensions.ARB_fragment_program_shadow) {
    216 	    state->option.Shadow = 1;
    217 	    return 1;
    218 	 }
    219       } else if (strncmp(option, "fragment_coord_", 15) == 0) {
    220          option += 15;
    221          if (state->ctx->Extensions.ARB_fragment_coord_conventions) {
    222             if (strcmp(option, "origin_upper_left") == 0) {
    223                state->option.OriginUpperLeft = 1;
    224                return 1;
    225             }
    226             else if (strcmp(option, "pixel_center_integer") == 0) {
    227                state->option.PixelCenterInteger = 1;
    228                return 1;
    229             }
    230          }
    231       }
    232    } else if (strncmp(option, "ATI_", 4) == 0) {
    233       option += 4;
    234 
    235       if (strcmp(option, "draw_buffers") == 0) {
    236 	 /* Don't need to check extension availability because all Mesa-based
    237 	  * drivers support GL_ATI_draw_buffers.
    238 	  */
    239 	 state->option.DrawBuffers = 1;
    240 	 return 1;
    241       }
    242    } else if (strncmp(option, "NV_fragment_program", 19) == 0) {
    243       option += 19;
    244 
    245       /* Other NV_fragment_program strings may be supported later.
    246        */
    247       if (option[0] == '\0') {
    248 	 if (state->ctx->Extensions.NV_fragment_program_option) {
    249 	    state->option.NV_fragment = 1;
    250 	    return 1;
    251 	 }
    252       }
    253    } else if (strncmp(option, "MESA_", 5) == 0) {
    254       option += 5;
    255 
    256       if (strcmp(option, "texture_array") == 0) {
    257 	 if (state->ctx->Extensions.MESA_texture_array) {
    258 	    state->option.TexArray = 1;
    259 	    return 1;
    260 	 }
    261       }
    262    }
    263 
    264    return 0;
    265 }
    266