1848b8605Smrg/*
2848b8605Smrg * Copyright © 2009 Intel Corporation
3848b8605Smrg *
4848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a
5848b8605Smrg * copy of this software and associated documentation files (the "Software"),
6848b8605Smrg * to deal in the Software without restriction, including without limitation
7848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the
9848b8605Smrg * Software is furnished to do so, subject to the following conditions:
10848b8605Smrg *
11848b8605Smrg * The above copyright notice and this permission notice (including the next
12848b8605Smrg * paragraph) shall be included in all copies or substantial portions of the
13848b8605Smrg * Software.
14848b8605Smrg *
15848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16848b8605Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19848b8605Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20848b8605Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21848b8605Smrg * DEALINGS IN THE SOFTWARE.
22848b8605Smrg */
23848b8605Smrg
24848b8605Smrg#include <string.h>
25848b8605Smrg#include "main/mtypes.h"
26848b8605Smrg#include "prog_instruction.h"
27848b8605Smrg#include "program_parser.h"
28848b8605Smrg
29848b8605Smrg
30848b8605Smrg/**
31848b8605Smrg * Extra assembly-level parser routines
32848b8605Smrg *
33848b8605Smrg * \author Ian Romanick <ian.d.romanick@intel.com>
34848b8605Smrg */
35848b8605Smrg
36848b8605Smrgint
37848b8605Smrg_mesa_parse_instruction_suffix(const struct asm_parser_state *state,
38848b8605Smrg			       const char *suffix,
39848b8605Smrg			       struct prog_instruction *inst)
40848b8605Smrg{
41b8e80941Smrg   inst->Saturate = GL_FALSE;
42848b8605Smrg
43b8e80941Smrg   /* The only possible suffix element is the saturation selector from
44848b8605Smrg    * ARB_fragment_program.
45848b8605Smrg    */
46848b8605Smrg   if (state->mode == ARB_fragment) {
47848b8605Smrg      if (strcmp(suffix, "_SAT") == 0) {
48b8e80941Smrg	 inst->Saturate = GL_TRUE;
49848b8605Smrg	 suffix += 4;
50848b8605Smrg      }
51848b8605Smrg   }
52848b8605Smrg
53848b8605Smrg   /* It is an error for all of the suffix string not to be consumed.
54848b8605Smrg    */
55848b8605Smrg   return suffix[0] == '\0';
56848b8605Smrg}
57848b8605Smrg
58848b8605Smrg
59848b8605Smrgint
60848b8605Smrg_mesa_ARBvp_parse_option(struct asm_parser_state *state, const char *option)
61848b8605Smrg{
62848b8605Smrg   if (strcmp(option, "ARB_position_invariant") == 0) {
63848b8605Smrg      state->option.PositionInvariant = 1;
64848b8605Smrg      return 1;
65848b8605Smrg   }
66848b8605Smrg
67848b8605Smrg   return 0;
68848b8605Smrg}
69848b8605Smrg
70848b8605Smrg
71848b8605Smrgint
72848b8605Smrg_mesa_ARBfp_parse_option(struct asm_parser_state *state, const char *option)
73848b8605Smrg{
74b8e80941Smrg   unsigned fog_option;
75b8e80941Smrg
76848b8605Smrg   /* All of the options currently supported start with "ARB_".  The code is
77848b8605Smrg    * currently structured with nested if-statements because eventually options
78848b8605Smrg    * that start with "NV_" will be supported.  This structure will result in
79848b8605Smrg    * less churn when those options are added.
80848b8605Smrg    */
81848b8605Smrg   if (strncmp(option, "ARB_", 4) == 0) {
82848b8605Smrg      /* Advance the pointer past the "ARB_" prefix.
83848b8605Smrg       */
84848b8605Smrg      option += 4;
85848b8605Smrg
86848b8605Smrg      if (strncmp(option, "fog_", 4) == 0) {
87848b8605Smrg	 option += 4;
88848b8605Smrg
89b8e80941Smrg         if (strcmp(option, "exp") == 0) {
90b8e80941Smrg            fog_option = OPTION_FOG_EXP;
91b8e80941Smrg         } else if (strcmp(option, "exp2") == 0) {
92b8e80941Smrg            fog_option = OPTION_FOG_EXP2;
93b8e80941Smrg         } else if (strcmp(option, "linear") == 0) {
94b8e80941Smrg            fog_option = OPTION_FOG_LINEAR;
95b8e80941Smrg         } else {
96b8e80941Smrg            /* invalid option */
97b8e80941Smrg            return 0;
98b8e80941Smrg         }
99848b8605Smrg
100b8e80941Smrg         if (state->option.Fog == OPTION_NONE) {
101b8e80941Smrg            state->option.Fog = fog_option;
102b8e80941Smrg            return 1;
103b8e80941Smrg         }
104b8e80941Smrg
105b8e80941Smrg         /* The ARB_fragment_program specification instructs us to handle
106b8e80941Smrg          * redundant options in two seemingly contradictory ways:
107b8e80941Smrg          *
108b8e80941Smrg          * Section 3.11.4.5.1 says:
109b8e80941Smrg          * "Only one fog application option may be specified by any given
110b8e80941Smrg          *  fragment program.  A fragment program that specifies more than one
111b8e80941Smrg          *  of the program options "ARB_fog_exp", "ARB_fog_exp2", and
112b8e80941Smrg          *  "ARB_fog_linear", will fail to load."
113b8e80941Smrg          *
114b8e80941Smrg          * Issue 27 says:
115b8e80941Smrg          * "The three mandatory options are ARB_fog_exp, ARB_fog_exp2, and
116b8e80941Smrg          *  ARB_fog_linear.  As these options are mutually exclusive by
117b8e80941Smrg          *  nature, specifying more than one is not useful.  If more than one
118b8e80941Smrg          *  is specified, the last one encountered in the <optionSequence>
119b8e80941Smrg          *  will be the one to actually modify the execution environment."
120b8e80941Smrg          *
121b8e80941Smrg          * We choose to allow programs to specify the same OPTION redundantly,
122b8e80941Smrg          * but fail to load programs that specify contradictory options.
123b8e80941Smrg          */
124b8e80941Smrg         return state->option.Fog == fog_option ? 1 : 0;
125848b8605Smrg      } else if (strncmp(option, "precision_hint_", 15) == 0) {
126848b8605Smrg	 option += 15;
127848b8605Smrg
128848b8605Smrg         /* The ARB_fragment_program spec, 3.11.4.5.2 says:
129848b8605Smrg          *
130848b8605Smrg          * "Only one precision control option may be specified by any given
131848b8605Smrg          * fragment program.  A fragment program that specifies both the
132848b8605Smrg          * "ARB_precision_hint_fastest" and "ARB_precision_hint_nicest"
133848b8605Smrg          * program options will fail to load.
134848b8605Smrg          */
135848b8605Smrg
136b8e80941Smrg         if (strcmp(option, "nicest") == 0 &&
137b8e80941Smrg             state->option.PrecisionHint != OPTION_FASTEST) {
138848b8605Smrg            state->option.PrecisionHint = OPTION_NICEST;
139848b8605Smrg            return 1;
140b8e80941Smrg         } else if (strcmp(option, "fastest") == 0 &&
141b8e80941Smrg                    state->option.PrecisionHint != OPTION_NICEST) {
142848b8605Smrg            state->option.PrecisionHint = OPTION_FASTEST;
143848b8605Smrg            return 1;
144848b8605Smrg         }
145848b8605Smrg
146848b8605Smrg	 return 0;
147848b8605Smrg      } else if (strcmp(option, "draw_buffers") == 0) {
148848b8605Smrg	 /* Don't need to check extension availability because all Mesa-based
149848b8605Smrg	  * drivers support GL_ARB_draw_buffers.
150848b8605Smrg	  */
151848b8605Smrg	 state->option.DrawBuffers = 1;
152848b8605Smrg	 return 1;
153848b8605Smrg      } else if (strcmp(option, "fragment_program_shadow") == 0) {
154848b8605Smrg	 if (state->ctx->Extensions.ARB_fragment_program_shadow) {
155848b8605Smrg	    state->option.Shadow = 1;
156848b8605Smrg	    return 1;
157848b8605Smrg	 }
158848b8605Smrg      } else if (strncmp(option, "fragment_coord_", 15) == 0) {
159848b8605Smrg         option += 15;
160848b8605Smrg         if (state->ctx->Extensions.ARB_fragment_coord_conventions) {
161848b8605Smrg            if (strcmp(option, "origin_upper_left") == 0) {
162848b8605Smrg               state->option.OriginUpperLeft = 1;
163848b8605Smrg               return 1;
164848b8605Smrg            }
165848b8605Smrg            else if (strcmp(option, "pixel_center_integer") == 0) {
166848b8605Smrg               state->option.PixelCenterInteger = 1;
167848b8605Smrg               return 1;
168848b8605Smrg            }
169848b8605Smrg         }
170848b8605Smrg      }
171848b8605Smrg   } else if (strncmp(option, "ATI_", 4) == 0) {
172848b8605Smrg      option += 4;
173848b8605Smrg
174848b8605Smrg      if (strcmp(option, "draw_buffers") == 0) {
175848b8605Smrg	 /* Don't need to check extension availability because all Mesa-based
176848b8605Smrg	  * drivers support GL_ATI_draw_buffers.
177848b8605Smrg	  */
178848b8605Smrg	 state->option.DrawBuffers = 1;
179848b8605Smrg	 return 1;
180848b8605Smrg      }
181848b8605Smrg   }
182848b8605Smrg
183848b8605Smrg   return 0;
184848b8605Smrg}
185