program_parse_extra.c revision 848b8605
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@intel.com> 34 */ 35 36int 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 97int 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 151int 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 163int 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 /* The ARB_fragment_program spec, 3.11.4.5.2 says: 198 * 199 * "Only one precision control option may be specified by any given 200 * fragment program. A fragment program that specifies both the 201 * "ARB_precision_hint_fastest" and "ARB_precision_hint_nicest" 202 * program options will fail to load. 203 */ 204 205 if (strcmp(option, "nicest") == 0 && state->option.PrecisionHint != OPTION_FASTEST) { 206 state->option.PrecisionHint = OPTION_NICEST; 207 return 1; 208 } else if (strcmp(option, "fastest") == 0 && state->option.PrecisionHint != OPTION_NICEST) { 209 state->option.PrecisionHint = OPTION_FASTEST; 210 return 1; 211 } 212 213 return 0; 214 } else if (strcmp(option, "draw_buffers") == 0) { 215 /* Don't need to check extension availability because all Mesa-based 216 * drivers support GL_ARB_draw_buffers. 217 */ 218 state->option.DrawBuffers = 1; 219 return 1; 220 } else if (strcmp(option, "fragment_program_shadow") == 0) { 221 if (state->ctx->Extensions.ARB_fragment_program_shadow) { 222 state->option.Shadow = 1; 223 return 1; 224 } 225 } else if (strncmp(option, "fragment_coord_", 15) == 0) { 226 option += 15; 227 if (state->ctx->Extensions.ARB_fragment_coord_conventions) { 228 if (strcmp(option, "origin_upper_left") == 0) { 229 state->option.OriginUpperLeft = 1; 230 return 1; 231 } 232 else if (strcmp(option, "pixel_center_integer") == 0) { 233 state->option.PixelCenterInteger = 1; 234 return 1; 235 } 236 } 237 } 238 } else if (strncmp(option, "ATI_", 4) == 0) { 239 option += 4; 240 241 if (strcmp(option, "draw_buffers") == 0) { 242 /* Don't need to check extension availability because all Mesa-based 243 * drivers support GL_ATI_draw_buffers. 244 */ 245 state->option.DrawBuffers = 1; 246 return 1; 247 } 248 } else if (strncmp(option, "NV_fragment_program", 19) == 0) { 249 option += 19; 250 251 /* Other NV_fragment_program strings may be supported later. 252 */ 253 if (option[0] == '\0') { 254 if (state->ctx->Extensions.NV_fragment_program_option) { 255 state->option.NV_fragment = 1; 256 return 1; 257 } 258 } 259 } 260 261 return 0; 262} 263