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