Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  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.  
  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.          /* 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.    } else if (strncmp(option, "MESA_", 5) == 0) {
  260.       option += 5;
  261.  
  262.       if (strcmp(option, "texture_array") == 0) {
  263.          if (state->ctx->Extensions.MESA_texture_array) {
  264.             state->option.TexArray = 1;
  265.             return 1;
  266.          }
  267.       }
  268.    }
  269.  
  270.    return 0;
  271. }
  272.