13464ebd5Sriastradh/* 23464ebd5Sriastradh * Copyright © 2009 Intel Corporation 33464ebd5Sriastradh * 43464ebd5Sriastradh * Permission is hereby granted, free of charge, to any person obtaining a 53464ebd5Sriastradh * copy of this software and associated documentation files (the "Software"), 63464ebd5Sriastradh * to deal in the Software without restriction, including without limitation 73464ebd5Sriastradh * the rights to use, copy, modify, merge, publish, distribute, sublicense, 83464ebd5Sriastradh * and/or sell copies of the Software, and to permit persons to whom the 93464ebd5Sriastradh * Software is furnished to do so, subject to the following conditions: 103464ebd5Sriastradh * 113464ebd5Sriastradh * The above copyright notice and this permission notice (including the next 123464ebd5Sriastradh * paragraph) shall be included in all copies or substantial portions of the 133464ebd5Sriastradh * Software. 143464ebd5Sriastradh * 153464ebd5Sriastradh * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 163464ebd5Sriastradh * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 173464ebd5Sriastradh * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 183464ebd5Sriastradh * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 193464ebd5Sriastradh * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 203464ebd5Sriastradh * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 213464ebd5Sriastradh * DEALINGS IN THE SOFTWARE. 223464ebd5Sriastradh */ 233464ebd5Sriastradh 243464ebd5Sriastradh#include <string.h> 253464ebd5Sriastradh#include "main/mtypes.h" 263464ebd5Sriastradh#include "prog_instruction.h" 273464ebd5Sriastradh#include "program_parser.h" 283464ebd5Sriastradh 293464ebd5Sriastradh 303464ebd5Sriastradh/** 313464ebd5Sriastradh * Extra assembly-level parser routines 323464ebd5Sriastradh * 333464ebd5Sriastradh * \author Ian Romanick <ian.d.romanick@intel.com> 343464ebd5Sriastradh */ 353464ebd5Sriastradh 363464ebd5Sriastradhint 373464ebd5Sriastradh_mesa_parse_instruction_suffix(const struct asm_parser_state *state, 383464ebd5Sriastradh const char *suffix, 393464ebd5Sriastradh struct prog_instruction *inst) 403464ebd5Sriastradh{ 4101e04c3fSmrg inst->Saturate = GL_FALSE; 423464ebd5Sriastradh 4301e04c3fSmrg /* The only possible suffix element is the saturation selector from 443464ebd5Sriastradh * ARB_fragment_program. 453464ebd5Sriastradh */ 463464ebd5Sriastradh if (state->mode == ARB_fragment) { 473464ebd5Sriastradh if (strcmp(suffix, "_SAT") == 0) { 4801e04c3fSmrg inst->Saturate = GL_TRUE; 493464ebd5Sriastradh suffix += 4; 503464ebd5Sriastradh } 513464ebd5Sriastradh } 523464ebd5Sriastradh 533464ebd5Sriastradh /* It is an error for all of the suffix string not to be consumed. 543464ebd5Sriastradh */ 553464ebd5Sriastradh return suffix[0] == '\0'; 563464ebd5Sriastradh} 573464ebd5Sriastradh 583464ebd5Sriastradh 593464ebd5Sriastradhint 603464ebd5Sriastradh_mesa_ARBvp_parse_option(struct asm_parser_state *state, const char *option) 613464ebd5Sriastradh{ 623464ebd5Sriastradh if (strcmp(option, "ARB_position_invariant") == 0) { 633464ebd5Sriastradh state->option.PositionInvariant = 1; 643464ebd5Sriastradh return 1; 653464ebd5Sriastradh } 663464ebd5Sriastradh 673464ebd5Sriastradh return 0; 683464ebd5Sriastradh} 693464ebd5Sriastradh 703464ebd5Sriastradh 713464ebd5Sriastradhint 723464ebd5Sriastradh_mesa_ARBfp_parse_option(struct asm_parser_state *state, const char *option) 733464ebd5Sriastradh{ 7401e04c3fSmrg unsigned fog_option; 7501e04c3fSmrg 763464ebd5Sriastradh /* All of the options currently supported start with "ARB_". The code is 773464ebd5Sriastradh * currently structured with nested if-statements because eventually options 783464ebd5Sriastradh * that start with "NV_" will be supported. This structure will result in 793464ebd5Sriastradh * less churn when those options are added. 803464ebd5Sriastradh */ 813464ebd5Sriastradh if (strncmp(option, "ARB_", 4) == 0) { 823464ebd5Sriastradh /* Advance the pointer past the "ARB_" prefix. 833464ebd5Sriastradh */ 843464ebd5Sriastradh option += 4; 853464ebd5Sriastradh 863464ebd5Sriastradh if (strncmp(option, "fog_", 4) == 0) { 873464ebd5Sriastradh option += 4; 883464ebd5Sriastradh 8901e04c3fSmrg if (strcmp(option, "exp") == 0) { 9001e04c3fSmrg fog_option = OPTION_FOG_EXP; 9101e04c3fSmrg } else if (strcmp(option, "exp2") == 0) { 9201e04c3fSmrg fog_option = OPTION_FOG_EXP2; 9301e04c3fSmrg } else if (strcmp(option, "linear") == 0) { 9401e04c3fSmrg fog_option = OPTION_FOG_LINEAR; 9501e04c3fSmrg } else { 9601e04c3fSmrg /* invalid option */ 9701e04c3fSmrg return 0; 9801e04c3fSmrg } 993464ebd5Sriastradh 10001e04c3fSmrg if (state->option.Fog == OPTION_NONE) { 10101e04c3fSmrg state->option.Fog = fog_option; 10201e04c3fSmrg return 1; 10301e04c3fSmrg } 10401e04c3fSmrg 10501e04c3fSmrg /* The ARB_fragment_program specification instructs us to handle 10601e04c3fSmrg * redundant options in two seemingly contradictory ways: 10701e04c3fSmrg * 10801e04c3fSmrg * Section 3.11.4.5.1 says: 10901e04c3fSmrg * "Only one fog application option may be specified by any given 11001e04c3fSmrg * fragment program. A fragment program that specifies more than one 11101e04c3fSmrg * of the program options "ARB_fog_exp", "ARB_fog_exp2", and 11201e04c3fSmrg * "ARB_fog_linear", will fail to load." 11301e04c3fSmrg * 11401e04c3fSmrg * Issue 27 says: 11501e04c3fSmrg * "The three mandatory options are ARB_fog_exp, ARB_fog_exp2, and 11601e04c3fSmrg * ARB_fog_linear. As these options are mutually exclusive by 11701e04c3fSmrg * nature, specifying more than one is not useful. If more than one 11801e04c3fSmrg * is specified, the last one encountered in the <optionSequence> 11901e04c3fSmrg * will be the one to actually modify the execution environment." 12001e04c3fSmrg * 12101e04c3fSmrg * We choose to allow programs to specify the same OPTION redundantly, 12201e04c3fSmrg * but fail to load programs that specify contradictory options. 12301e04c3fSmrg */ 12401e04c3fSmrg return state->option.Fog == fog_option ? 1 : 0; 1253464ebd5Sriastradh } else if (strncmp(option, "precision_hint_", 15) == 0) { 1263464ebd5Sriastradh option += 15; 1273464ebd5Sriastradh 128af69d88dSmrg /* The ARB_fragment_program spec, 3.11.4.5.2 says: 129af69d88dSmrg * 130af69d88dSmrg * "Only one precision control option may be specified by any given 131af69d88dSmrg * fragment program. A fragment program that specifies both the 132af69d88dSmrg * "ARB_precision_hint_fastest" and "ARB_precision_hint_nicest" 133af69d88dSmrg * program options will fail to load. 134af69d88dSmrg */ 135af69d88dSmrg 13601e04c3fSmrg if (strcmp(option, "nicest") == 0 && 13701e04c3fSmrg state->option.PrecisionHint != OPTION_FASTEST) { 138af69d88dSmrg state->option.PrecisionHint = OPTION_NICEST; 139af69d88dSmrg return 1; 14001e04c3fSmrg } else if (strcmp(option, "fastest") == 0 && 14101e04c3fSmrg state->option.PrecisionHint != OPTION_NICEST) { 142af69d88dSmrg state->option.PrecisionHint = OPTION_FASTEST; 143af69d88dSmrg return 1; 144af69d88dSmrg } 1453464ebd5Sriastradh 1463464ebd5Sriastradh return 0; 1473464ebd5Sriastradh } else if (strcmp(option, "draw_buffers") == 0) { 1483464ebd5Sriastradh /* Don't need to check extension availability because all Mesa-based 1493464ebd5Sriastradh * drivers support GL_ARB_draw_buffers. 1503464ebd5Sriastradh */ 1513464ebd5Sriastradh state->option.DrawBuffers = 1; 1523464ebd5Sriastradh return 1; 1533464ebd5Sriastradh } else if (strcmp(option, "fragment_program_shadow") == 0) { 1543464ebd5Sriastradh if (state->ctx->Extensions.ARB_fragment_program_shadow) { 1553464ebd5Sriastradh state->option.Shadow = 1; 1563464ebd5Sriastradh return 1; 1573464ebd5Sriastradh } 1583464ebd5Sriastradh } else if (strncmp(option, "fragment_coord_", 15) == 0) { 1593464ebd5Sriastradh option += 15; 1603464ebd5Sriastradh if (state->ctx->Extensions.ARB_fragment_coord_conventions) { 1613464ebd5Sriastradh if (strcmp(option, "origin_upper_left") == 0) { 1623464ebd5Sriastradh state->option.OriginUpperLeft = 1; 1633464ebd5Sriastradh return 1; 1643464ebd5Sriastradh } 1653464ebd5Sriastradh else if (strcmp(option, "pixel_center_integer") == 0) { 1663464ebd5Sriastradh state->option.PixelCenterInteger = 1; 1673464ebd5Sriastradh return 1; 1683464ebd5Sriastradh } 1693464ebd5Sriastradh } 1703464ebd5Sriastradh } 1713464ebd5Sriastradh } else if (strncmp(option, "ATI_", 4) == 0) { 1723464ebd5Sriastradh option += 4; 1733464ebd5Sriastradh 1743464ebd5Sriastradh if (strcmp(option, "draw_buffers") == 0) { 1753464ebd5Sriastradh /* Don't need to check extension availability because all Mesa-based 1763464ebd5Sriastradh * drivers support GL_ATI_draw_buffers. 1773464ebd5Sriastradh */ 1783464ebd5Sriastradh state->option.DrawBuffers = 1; 1793464ebd5Sriastradh return 1; 1803464ebd5Sriastradh } 1813464ebd5Sriastradh } 1823464ebd5Sriastradh 1833464ebd5Sriastradh return 0; 1843464ebd5Sriastradh} 185