program_parse.output |
all: program_parse.tab.c lex.yy.c | |||||
program_parse.tab.c program_parse.tab.h: program_parse.y | |||||
bison -v -d $< | |||||
lex.yy.c: program_lexer.l | |||||
flex --never-interactive $< |
/* | |||||
* Copyright © 2008 Intel Corporation | |||||
* | |||||
* Permission is hereby granted, free of charge, to any person obtaining a | |||||
* copy of this software and associated documentation files (the "Software"), | |||||
* to deal in the Software without restriction, including without limitation | |||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||||
* and/or sell copies of the Software, and to permit persons to whom the | |||||
* Software is furnished to do so, subject to the following conditions: | |||||
* | |||||
* The above copyright notice and this permission notice (including the next | |||||
* paragraph) shall be included in all copies or substantial portions of the | |||||
* Software. | |||||
* | |||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||||
* DEALINGS IN THE SOFTWARE. | |||||
*/ | |||||
/** | |||||
* \file hash_table.c | |||||
* \brief Implementation of a generic, opaque hash table data type. | |||||
* | |||||
* \author Ian Romanick <ian.d.romanick@intel.com> | |||||
*/ | |||||
#include <stdlib.h> | |||||
#include <string.h> | |||||
#include <assert.h> | |||||
#include "main/simple_list.h" | |||||
#include "hash_table.h" | |||||
struct node { | |||||
struct node *next; | |||||
struct node *prev; | |||||
}; | |||||
struct hash_table { | |||||
hash_func_t hash; | |||||
hash_compare_func_t compare; | |||||
unsigned num_buckets; | |||||
struct node buckets[1]; | |||||
}; | |||||
struct hash_node { | |||||
struct node link; | |||||
const void *key; | |||||
void *data; | |||||
}; | |||||
struct hash_table * | |||||
hash_table_ctor(unsigned num_buckets, hash_func_t hash, | |||||
hash_compare_func_t compare) | |||||
{ | |||||
struct hash_table *ht; | |||||
unsigned i; | |||||
if (num_buckets < 16) { | |||||
num_buckets = 16; | |||||
} | |||||
ht = _mesa_malloc(sizeof(*ht) + ((num_buckets - 1) | |||||
* sizeof(ht->buckets[0]))); | |||||
if (ht != NULL) { | |||||
ht->hash = hash; | |||||
ht->compare = compare; | |||||
ht->num_buckets = num_buckets; | |||||
for (i = 0; i < num_buckets; i++) { | |||||
make_empty_list(& ht->buckets[i]); | |||||
} | |||||
} | |||||
return ht; | |||||
} | |||||
void | |||||
hash_table_dtor(struct hash_table *ht) | |||||
{ | |||||
hash_table_clear(ht); | |||||
_mesa_free(ht); | |||||
} | |||||
void | |||||
hash_table_clear(struct hash_table *ht) | |||||
{ | |||||
struct node *node; | |||||
struct node *temp; | |||||
unsigned i; | |||||
for (i = 0; i < ht->num_buckets; i++) { | |||||
foreach_s(node, temp, & ht->buckets[i]) { | |||||
remove_from_list(node); | |||||
_mesa_free(node); | |||||
} | |||||
assert(is_empty_list(& ht->buckets[i])); | |||||
} | |||||
} | |||||
void * | |||||
hash_table_find(struct hash_table *ht, const void *key) | |||||
{ | |||||
const unsigned hash_value = (*ht->hash)(key); | |||||
const unsigned bucket = hash_value % ht->num_buckets; | |||||
struct node *node; | |||||
foreach(node, & ht->buckets[bucket]) { | |||||
struct hash_node *hn = (struct hash_node *) node; | |||||
if ((*ht->compare)(hn->key, key) == 0) { | |||||
return hn->data; | |||||
} | |||||
} | |||||
return NULL; | |||||
} | |||||
void | |||||
hash_table_insert(struct hash_table *ht, void *data, const void *key) | |||||
{ | |||||
const unsigned hash_value = (*ht->hash)(key); | |||||
const unsigned bucket = hash_value % ht->num_buckets; | |||||
struct hash_node *node; | |||||
node = _mesa_calloc(sizeof(*node)); | |||||
node->data = data; | |||||
node->key = key; | |||||
insert_at_head(& ht->buckets[bucket], & node->link); | |||||
} | |||||
unsigned | |||||
hash_table_string_hash(const void *key) | |||||
{ | |||||
const char *str = (const char *) key; | |||||
unsigned hash = 5381; | |||||
while (*str != '\0') { | |||||
hash = (hash * 33) + *str; | |||||
str++; | |||||
} | |||||
return hash; | |||||
} |
/* | |||||
* Copyright © 2008 Intel Corporation | |||||
* | |||||
* Permission is hereby granted, free of charge, to any person obtaining a | |||||
* copy of this software and associated documentation files (the "Software"), | |||||
* to deal in the Software without restriction, including without limitation | |||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||||
* and/or sell copies of the Software, and to permit persons to whom the | |||||
* Software is furnished to do so, subject to the following conditions: | |||||
* | |||||
* The above copyright notice and this permission notice (including the next | |||||
* paragraph) shall be included in all copies or substantial portions of the | |||||
* Software. | |||||
* | |||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||||
* DEALINGS IN THE SOFTWARE. | |||||
*/ | |||||
/** | |||||
* \file hash_table.h | |||||
* \brief Implementation of a generic, opaque hash table data type. | |||||
* | |||||
* \author Ian Romanick <ian.d.romanick@intel.com> | |||||
*/ | |||||
#ifndef HASH_TABLE_H | |||||
#define HASH_TABLE_H | |||||
#include <string.h> | |||||
struct hash_table; | |||||
typedef unsigned (*hash_func_t)(const void *key); | |||||
typedef int (*hash_compare_func_t)(const void *key1, const void *key2); | |||||
/** | |||||
* Hash table constructor | |||||
* | |||||
* Creates a hash table with the specified number of buckets. The supplied | |||||
* \c hash and \c compare routines are used when adding elements to the table | |||||
* and when searching for elements in the table. | |||||
* | |||||
* \param num_buckets Number of buckets (bins) in the hash table. | |||||
* \param hash Function used to compute hash value of input keys. | |||||
* \param compare Function used to compare keys. | |||||
*/ | |||||
extern struct hash_table *hash_table_ctor(unsigned num_buckets, | |||||
hash_func_t hash, hash_compare_func_t compare); | |||||
/** | |||||
* Release all memory associated with a hash table | |||||
* | |||||
* \warning | |||||
* This function cannot release memory occupied either by keys or data. | |||||
*/ | |||||
extern void hash_table_dtor(struct hash_table *ht); | |||||
/** | |||||
* Flush all entries from a hash table | |||||
* | |||||
* \param ht Table to be cleared of its entries. | |||||
*/ | |||||
extern void hash_table_clear(struct hash_table *ht); | |||||
/** | |||||
* Search a hash table for a specific element | |||||
* | |||||
* \param ht Table to be searched | |||||
* \param key Key of the desired element | |||||
* | |||||
* \return | |||||
* The \c data value supplied to \c hash_table_insert when the element with | |||||
* the matching key was added. If no matching key exists in the table, | |||||
* \c NULL is returned. | |||||
*/ | |||||
extern void *hash_table_find(struct hash_table *ht, const void *key); | |||||
/** | |||||
* Add an element to a hash table | |||||
*/ | |||||
extern void hash_table_insert(struct hash_table *ht, void *data, | |||||
const void *key); | |||||
/** | |||||
* Compute hash value of a string | |||||
* | |||||
* Computes the hash value of a string using the DJB2 algorithm developed by | |||||
* Professor Daniel J. Bernstein. It was published on comp.lang.c once upon | |||||
* a time. I was unable to find the original posting in the archives. | |||||
* | |||||
* \param key Pointer to a NUL terminated string to be hashed. | |||||
* | |||||
* \sa hash_table_string_compare | |||||
*/ | |||||
extern unsigned hash_table_string_hash(const void *key); | |||||
/** | |||||
* Compare two strings used as keys | |||||
* | |||||
* This is just a macro wrapper around \c strcmp. | |||||
* | |||||
* \sa hash_table_string_hash | |||||
*/ | |||||
#define hash_table_string_compare ((hash_compare_func_t) strcmp) | |||||
#endif /* HASH_TABLE_H */ |
} | } | ||||
struct gl_program_parameter_list * | |||||
_mesa_new_parameter_list_sized(unsigned size) | |||||
{ | |||||
struct gl_program_parameter_list *p = _mesa_new_parameter_list(); | |||||
if ((p != NULL) && (size != 0)) { | |||||
p->Size = size; | |||||
/* alloc arrays */ | |||||
p->Parameters = (struct gl_program_parameter *) | |||||
_mesa_calloc(size * sizeof(struct gl_program_parameter)); | |||||
p->ParameterValues = (GLfloat (*)[4]) | |||||
_mesa_align_malloc(size * 4 *sizeof(GLfloat), 16); | |||||
if ((p->Parameters == NULL) || (p->ParameterValues == NULL)) { | |||||
_mesa_free(p->Parameters); | |||||
_mesa_align_free(p->ParameterValues); | |||||
_mesa_free(p); | |||||
p = NULL; | |||||
} | |||||
} | |||||
return p; | |||||
} | |||||
/** | /** | ||||
* Free a parameter list and all its parameters | * Free a parameter list and all its parameters | ||||
*/ | */ |
extern struct gl_program_parameter_list * | extern struct gl_program_parameter_list * | ||||
_mesa_new_parameter_list(void); | _mesa_new_parameter_list(void); | ||||
extern struct gl_program_parameter_list * | |||||
_mesa_new_parameter_list_sized(unsigned size); | |||||
extern void | extern void | ||||
_mesa_free_parameter_list(struct gl_program_parameter_list *paramList); | _mesa_free_parameter_list(struct gl_program_parameter_list *paramList); | ||||
/* | |||||
* Copyright © 2009 Intel Corporation | |||||
* | |||||
* Permission is hereby granted, free of charge, to any person obtaining a | |||||
* copy of this software and associated documentation files (the "Software"), | |||||
* to deal in the Software without restriction, including without limitation | |||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||||
* and/or sell copies of the Software, and to permit persons to whom the | |||||
* Software is furnished to do so, subject to the following conditions: | |||||
* | |||||
* The above copyright notice and this permission notice (including the next | |||||
* paragraph) shall be included in all copies or substantial portions of the | |||||
* Software. | |||||
* | |||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||||
* DEALINGS IN THE SOFTWARE. | |||||
*/ | |||||
/** | |||||
* \file prog_parameter_layout.c | |||||
* \brief Helper functions to layout storage for program parameters | |||||
* | |||||
* \author Ian Romanick <ian.d.romanick@intel.com> | |||||
*/ | |||||
#include "main/mtypes.h" | |||||
#include "prog_parameter.h" | |||||
#include "prog_parameter_layout.h" | |||||
#include "prog_instruction.h" | |||||
#include "program_parser.h" | |||||
unsigned | |||||
_mesa_combine_swizzles(unsigned base, unsigned applied) | |||||
{ | |||||
unsigned swiz = 0; | |||||
unsigned i; | |||||
for (i = 0; i < 4; i++) { | |||||
const unsigned s = GET_SWZ(applied, i); | |||||
swiz |= ((s <= SWIZZLE_W) ? GET_SWZ(base, s) : s) << (i * 3); | |||||
} | |||||
return swiz; | |||||
} | |||||
/** | |||||
* Copy indirect access array from one parameter list to another | |||||
* | |||||
* \param src Parameter array copied from | |||||
* \param dst Parameter array copied to | |||||
* \param first Index of first element in \c src to copy | |||||
* \param count Number of elements to copy | |||||
* | |||||
* \return | |||||
* The location in \c dst of the first element copied from \c src on | |||||
* success. -1 on failure. | |||||
* | |||||
* \warning | |||||
* This function assumes that there is already enough space available in | |||||
* \c dst to hold all of the elements that will be copied over. | |||||
*/ | |||||
static int | |||||
copy_indirect_accessed_array(struct gl_program_parameter_list *src, | |||||
struct gl_program_parameter_list *dst, | |||||
unsigned first, unsigned count) | |||||
{ | |||||
const int base = dst->NumParameters; | |||||
unsigned i; | |||||
unsigned j; | |||||
for (i = first; i < (first + count); i++) { | |||||
struct gl_program_parameter *curr = & src->Parameters[i]; | |||||
if (curr->Type == PROGRAM_CONSTANT) { | |||||
j = dst->NumParameters; | |||||
} else { | |||||
for (j = 0; j < dst->NumParameters; j++) { | |||||
if (memcmp(dst->Parameters[j].StateIndexes, curr->StateIndexes, | |||||
sizeof(curr->StateIndexes)) == 0) { | |||||
return -1; | |||||
} | |||||
} | |||||
} | |||||
assert(j == dst->NumParameters); | |||||
memcpy(& dst->Parameters[j], curr, | |||||
sizeof(dst->Parameters[j])); | |||||
memcpy(dst->ParameterValues[j], src->ParameterValues[i], | |||||
sizeof(GLfloat) * 4); | |||||
curr->Name = NULL; | |||||
dst->NumParameters++; | |||||
} | |||||
return base; | |||||
} | |||||
int | |||||
_mesa_layout_parameters(struct asm_parser_state *state) | |||||
{ | |||||
struct gl_program_parameter_list *layout; | |||||
struct asm_instruction *inst; | |||||
unsigned i; | |||||
layout = | |||||
_mesa_new_parameter_list_sized(state->prog->Parameters->NumParameters); | |||||
/* PASS 1: Move any parameters that are accessed indirectly from the | |||||
* original parameter list to the new parameter list. | |||||
*/ | |||||
for (inst = state->inst_head; inst != NULL; inst = inst->next) { | |||||
for (i = 0; i < 3; i++) { | |||||
if (inst->SrcReg[i].Base.RelAddr) { | |||||
/* Only attempt to add the to the new parameter list once. | |||||
*/ | |||||
if (!inst->SrcReg[i].Symbol->pass1_done) { | |||||
const int new_begin = | |||||
copy_indirect_accessed_array(state->prog->Parameters, layout, | |||||
inst->SrcReg[i].Symbol->param_binding_begin, | |||||
inst->SrcReg[i].Symbol->param_binding_length); | |||||
if (new_begin < 0) { | |||||
return 0; | |||||
} | |||||
inst->SrcReg[i].Symbol->param_binding_begin = new_begin; | |||||
inst->SrcReg[i].Symbol->pass1_done = 1; | |||||
} | |||||
/* Previously the Index was just the offset from the parameter | |||||
* array. Now that the base of the parameter array is known, the | |||||
* index can be updated to its actual value. | |||||
*/ | |||||
inst->Base.SrcReg[i] = inst->SrcReg[i].Base; | |||||
inst->Base.SrcReg[i].Index += | |||||
inst->SrcReg[i].Symbol->param_binding_begin; | |||||
} | |||||
} | |||||
} | |||||
/* PASS 2: Move any parameters that are not accessed indirectly from the | |||||
* original parameter list to the new parameter list. | |||||
*/ | |||||
for (inst = state->inst_head; inst != NULL; inst = inst->next) { | |||||
for (i = 0; i < 3; i++) { | |||||
const struct gl_program_parameter *p; | |||||
const int idx = inst->SrcReg[i].Base.Index; | |||||
unsigned swizzle = SWIZZLE_NOOP; | |||||
/* All relative addressed operands were processed on the first | |||||
* pass. Just skip them here. | |||||
*/ | |||||
if (inst->SrcReg[i].Base.RelAddr) { | |||||
continue; | |||||
} | |||||
if ((inst->SrcReg[i].Base.File <= PROGRAM_VARYING ) | |||||
|| (inst->SrcReg[i].Base.File >= PROGRAM_WRITE_ONLY)) { | |||||
continue; | |||||
} | |||||
inst->Base.SrcReg[i] = inst->SrcReg[i].Base; | |||||
p = & state->prog->Parameters->Parameters[idx]; | |||||
switch (p->Type) { | |||||
case PROGRAM_CONSTANT: { | |||||
const float *const v = | |||||
state->prog->Parameters->ParameterValues[idx]; | |||||
inst->Base.SrcReg[i].Index = | |||||
_mesa_add_unnamed_constant(layout, v, p->Size, & swizzle); | |||||
inst->Base.SrcReg[i].Swizzle = | |||||
_mesa_combine_swizzles(swizzle, inst->Base.SrcReg[i].Swizzle); | |||||
break; | |||||
} | |||||
case PROGRAM_STATE_VAR: | |||||
inst->Base.SrcReg[i].Index = | |||||
_mesa_add_state_reference(layout, p->StateIndexes); | |||||
break; | |||||
default: | |||||
break; | |||||
} | |||||
inst->SrcReg[i].Base.File = p->Type; | |||||
inst->Base.SrcReg[i].File = p->Type; | |||||
} | |||||
} | |||||
_mesa_free_parameter_list(state->prog->Parameters); | |||||
state->prog->Parameters = layout; | |||||
return 1; | |||||
} |
/* | |||||
* Copyright © 2009 Intel Corporation | |||||
* | |||||
* Permission is hereby granted, free of charge, to any person obtaining a | |||||
* copy of this software and associated documentation files (the "Software"), | |||||
* to deal in the Software without restriction, including without limitation | |||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||||
* and/or sell copies of the Software, and to permit persons to whom the | |||||
* Software is furnished to do so, subject to the following conditions: | |||||
* | |||||
* The above copyright notice and this permission notice (including the next | |||||
* paragraph) shall be included in all copies or substantial portions of the | |||||
* Software. | |||||
* | |||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||||
* DEALINGS IN THE SOFTWARE. | |||||
*/ | |||||
/** | |||||
* \file prog_parameter_layout.h | |||||
* \brief Helper functions to layout storage for program parameters | |||||
* | |||||
* \author Ian Romanick <ian.d.romanick@intel.com> | |||||
*/ | |||||
#pragma once | |||||
#ifndef PROG_PARAMETER_LAYOUT_H | |||||
#define PROG_PARAMETER_LAYOUT_H | |||||
extern unsigned _mesa_combine_swizzles(unsigned base, unsigned applied); | |||||
struct asm_parser_state; | |||||
extern int _mesa_layout_parameters(struct asm_parser_state *state); | |||||
#endif /* PROG_PARAMETER_LAYOUT_H */ |
void | void | ||||
_mesa_print_program(const struct gl_program *prog) | _mesa_print_program(const struct gl_program *prog) | ||||
{ | { | ||||
_mesa_fprint_program_opt(stdout, prog, PROG_PRINT_DEBUG, GL_TRUE); | |||||
_mesa_fprint_program_opt(stderr, prog, PROG_PRINT_DEBUG, GL_TRUE); | |||||
} | } | ||||
%{ | |||||
/* | |||||
* Copyright © 2009 Intel Corporation | |||||
* | |||||
* Permission is hereby granted, free of charge, to any person obtaining a | |||||
* copy of this software and associated documentation files (the "Software"), | |||||
* to deal in the Software without restriction, including without limitation | |||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||||
* and/or sell copies of the Software, and to permit persons to whom the | |||||
* Software is furnished to do so, subject to the following conditions: | |||||
* | |||||
* The above copyright notice and this permission notice (including the next | |||||
* paragraph) shall be included in all copies or substantial portions of the | |||||
* Software. | |||||
* | |||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||||
* DEALINGS IN THE SOFTWARE. | |||||
*/ | |||||
#include "main/glheader.h" | |||||
#include "prog_instruction.h" | |||||
#include "program_parser.h" | |||||
#include "program_parse.tab.h" | |||||
#define require_ARB_vp (yyextra->mode == ARB_vertex) | |||||
#define require_ARB_fp (yyextra->mode == ARB_fragment) | |||||
#define require_shadow (yyextra->option.Shadow) | |||||
#define require_rect (yyextra->option.TexRect) | |||||
#define require_texarray (yyextra->option.TexArray) | |||||
#define return_token_or_IDENTIFIER(condition, token) \ | |||||
do { \ | |||||
if (condition) { \ | |||||
return token; \ | |||||
} else { \ | |||||
yylval->string = strdup(yytext); \ | |||||
return IDENTIFIER; \ | |||||
} \ | |||||
} while (0) | |||||
#define return_token_or_DOT(condition, token) \ | |||||
do { \ | |||||
if (condition) { \ | |||||
return token; \ | |||||
} else { \ | |||||
yyless(1); \ | |||||
return DOT; \ | |||||
} \ | |||||
} while (0) | |||||
#define return_opcode(condition, token, opcode, sat) \ | |||||
do { \ | |||||
if (condition) { \ | |||||
yylval->temp_inst.Opcode = OPCODE_ ## opcode; \ | |||||
yylval->temp_inst.SaturateMode = SATURATE_ ## sat; \ | |||||
return token; \ | |||||
} else { \ | |||||
yylval->string = strdup(yytext); \ | |||||
return IDENTIFIER; \ | |||||
} \ | |||||
} while (0) | |||||
#define SWIZZLE_INVAL MAKE_SWIZZLE4(SWIZZLE_NIL, SWIZZLE_NIL, \ | |||||
SWIZZLE_NIL, SWIZZLE_NIL) | |||||
static unsigned | |||||
mask_from_char(char c) | |||||
{ | |||||
switch (c) { | |||||
case 'x': | |||||
case 'r': | |||||
return WRITEMASK_X; | |||||
case 'y': | |||||
case 'g': | |||||
return WRITEMASK_Y; | |||||
case 'z': | |||||
case 'b': | |||||
return WRITEMASK_Z; | |||||
case 'w': | |||||
case 'a': | |||||
return WRITEMASK_W; | |||||
} | |||||
return 0; | |||||
} | |||||
static unsigned | |||||
swiz_from_char(char c) | |||||
{ | |||||
switch (c) { | |||||
case 'x': | |||||
case 'r': | |||||
return SWIZZLE_X; | |||||
case 'y': | |||||
case 'g': | |||||
return SWIZZLE_Y; | |||||
case 'z': | |||||
case 'b': | |||||
return SWIZZLE_Z; | |||||
case 'w': | |||||
case 'a': | |||||
return SWIZZLE_W; | |||||
} | |||||
return 0; | |||||
} | |||||
#define YY_USER_ACTION \ | |||||
do { \ | |||||
yylloc->first_column = yylloc->last_column; \ | |||||
yylloc->last_column += yyleng; \ | |||||
if ((yylloc->first_line == 1) \ | |||||
&& (yylloc->first_column == 1)) { \ | |||||
yylloc->position = 1; \ | |||||
} else { \ | |||||
yylloc->position += yylloc->last_column - yylloc->first_column; \ | |||||
} \ | |||||
} while(0); | |||||
#define YY_EXTRA_TYPE struct asm_parser_state * | |||||
%} | |||||
num [0-9]+ | |||||
exp [Ee][-+]?[0-9]+ | |||||
frac "."[0-9]+ | |||||
dot "."[ \t]* | |||||
%option bison-bridge bison-locations reentrant noyywrap | |||||
%% | |||||
"!!ARBvp1.0" { return ARBvp_10; } | |||||
"!!ARBfp1.0" { return ARBfp_10; } | |||||
ADDRESS { | |||||
yylval->integer = at_address; | |||||
return_token_or_IDENTIFIER(require_ARB_vp, ADDRESS); | |||||
} | |||||
ALIAS { return ALIAS; } | |||||
ATTRIB { return ATTRIB; } | |||||
END { return END; } | |||||
OPTION { return OPTION; } | |||||
OUTPUT { return OUTPUT; } | |||||
PARAM { return PARAM; } | |||||
TEMP { yylval->integer = at_temp; return TEMP; } | |||||
ABS { return_opcode( 1, VECTOR_OP, ABS, OFF); } | |||||
ABS_SAT { return_opcode(require_ARB_fp, VECTOR_OP, ABS, ZERO_ONE); } | |||||
ADD { return_opcode( 1, BIN_OP, ADD, OFF); } | |||||
ADD_SAT { return_opcode(require_ARB_fp, BIN_OP, ADD, ZERO_ONE); } | |||||
ARL { return_opcode(require_ARB_vp, ARL, ARL, OFF); } | |||||
CMP { return_opcode(require_ARB_fp, TRI_OP, CMP, OFF); } | |||||
CMP_SAT { return_opcode(require_ARB_fp, TRI_OP, CMP, ZERO_ONE); } | |||||
COS { return_opcode(require_ARB_fp, SCALAR_OP, COS, OFF); } | |||||
COS_SAT { return_opcode(require_ARB_fp, SCALAR_OP, COS, ZERO_ONE); } | |||||
DP3 { return_opcode( 1, BIN_OP, DP3, OFF); } | |||||
DP3_SAT { return_opcode(require_ARB_fp, BIN_OP, DP3, ZERO_ONE); } | |||||
DP4 { return_opcode( 1, BIN_OP, DP4, OFF); } | |||||
DP4_SAT { return_opcode(require_ARB_fp, BIN_OP, DP4, ZERO_ONE); } | |||||
DPH { return_opcode( 1, BIN_OP, DPH, OFF); } | |||||
DPH_SAT { return_opcode(require_ARB_fp, BIN_OP, DPH, ZERO_ONE); } | |||||
DST { return_opcode( 1, BIN_OP, DST, OFF); } | |||||
DST_SAT { return_opcode(require_ARB_fp, BIN_OP, DST, ZERO_ONE); } | |||||
EX2 { return_opcode( 1, SCALAR_OP, EX2, OFF); } | |||||
EX2_SAT { return_opcode(require_ARB_fp, SCALAR_OP, EX2, ZERO_ONE); } | |||||
EXP { return_opcode(require_ARB_vp, SCALAR_OP, EXP, OFF); } | |||||
FLR { return_opcode( 1, VECTOR_OP, FLR, OFF); } | |||||
FLR_SAT { return_opcode(require_ARB_fp, VECTOR_OP, FLR, ZERO_ONE); } | |||||
FRC { return_opcode( 1, VECTOR_OP, FRC, OFF); } | |||||
FRC_SAT { return_opcode(require_ARB_fp, VECTOR_OP, FRC, ZERO_ONE); } | |||||
KIL { return_opcode(require_ARB_fp, KIL, KIL, OFF); } | |||||
LIT { return_opcode( 1, VECTOR_OP, LIT, OFF); } | |||||
LIT_SAT { return_opcode(require_ARB_fp, VECTOR_OP, LIT, ZERO_ONE); } | |||||
LG2 { return_opcode( 1, SCALAR_OP, LG2, OFF); } | |||||
LG2_SAT { return_opcode(require_ARB_fp, SCALAR_OP, LG2, ZERO_ONE); } | |||||
LOG { return_opcode(require_ARB_vp, SCALAR_OP, LOG, OFF); } | |||||
LRP { return_opcode(require_ARB_fp, TRI_OP, LRP, OFF); } | |||||
LRP_SAT { return_opcode(require_ARB_fp, TRI_OP, LRP, ZERO_ONE); } | |||||
MAD { return_opcode( 1, TRI_OP, MAD, OFF); } | |||||
MAD_SAT { return_opcode(require_ARB_fp, TRI_OP, MAD, ZERO_ONE); } | |||||
MAX { return_opcode( 1, BIN_OP, MAX, OFF); } | |||||
MAX_SAT { return_opcode(require_ARB_fp, BIN_OP, MAX, ZERO_ONE); } | |||||
MIN { return_opcode( 1, BIN_OP, MIN, OFF); } | |||||
MIN_SAT { return_opcode(require_ARB_fp, BIN_OP, MIN, ZERO_ONE); } | |||||
MOV { return_opcode( 1, VECTOR_OP, MOV, OFF); } | |||||
MOV_SAT { return_opcode(require_ARB_fp, VECTOR_OP, MOV, ZERO_ONE); } | |||||
MUL { return_opcode( 1, BIN_OP, MUL, OFF); } | |||||
MUL_SAT { return_opcode(require_ARB_fp, BIN_OP, MUL, ZERO_ONE); } | |||||
POW { return_opcode( 1, BINSC_OP, POW, OFF); } | |||||
POW_SAT { return_opcode(require_ARB_fp, BINSC_OP, POW, ZERO_ONE); } | |||||
RCP { return_opcode( 1, SCALAR_OP, RCP, OFF); } | |||||
RCP_SAT { return_opcode(require_ARB_fp, SCALAR_OP, RCP, ZERO_ONE); } | |||||
RSQ { return_opcode( 1, SCALAR_OP, RSQ, OFF); } | |||||
RSQ_SAT { return_opcode(require_ARB_fp, SCALAR_OP, RSQ, ZERO_ONE); } | |||||
SCS { return_opcode(require_ARB_fp, SCALAR_OP, SCS, OFF); } | |||||
SCS_SAT { return_opcode(require_ARB_fp, SCALAR_OP, SCS, ZERO_ONE); } | |||||
SGE { return_opcode( 1, BIN_OP, SGE, OFF); } | |||||
SGE_SAT { return_opcode(require_ARB_fp, BIN_OP, SGE, ZERO_ONE); } | |||||
SIN { return_opcode(require_ARB_fp, SCALAR_OP, SIN, OFF); } | |||||
SIN_SAT { return_opcode(require_ARB_fp, SCALAR_OP, SIN, ZERO_ONE); } | |||||
SLT { return_opcode( 1, BIN_OP, SLT, OFF); } | |||||
SLT_SAT { return_opcode(require_ARB_fp, BIN_OP, SLT, ZERO_ONE); } | |||||
SUB { return_opcode( 1, BIN_OP, SUB, OFF); } | |||||
SUB_SAT { return_opcode(require_ARB_fp, BIN_OP, SUB, ZERO_ONE); } | |||||
SWZ { return_opcode( 1, SWZ, SWZ, OFF); } | |||||
SWZ_SAT { return_opcode(require_ARB_fp, SWZ, SWZ, ZERO_ONE); } | |||||
TEX { return_opcode(require_ARB_fp, SAMPLE_OP, TEX, OFF); } | |||||
TEX_SAT { return_opcode(require_ARB_fp, SAMPLE_OP, TEX, ZERO_ONE); } | |||||
TXB { return_opcode(require_ARB_fp, SAMPLE_OP, TXB, OFF); } | |||||
TXB_SAT { return_opcode(require_ARB_fp, SAMPLE_OP, TXB, ZERO_ONE); } | |||||
TXP { return_opcode(require_ARB_fp, SAMPLE_OP, TXP, OFF); } | |||||
TXP_SAT { return_opcode(require_ARB_fp, SAMPLE_OP, TXP, ZERO_ONE); } | |||||
XPD { return_opcode( 1, BIN_OP, XPD, OFF); } | |||||
XPD_SAT { return_opcode(require_ARB_fp, BIN_OP, XPD, ZERO_ONE); } | |||||
vertex { return_token_or_IDENTIFIER(require_ARB_vp, VERTEX); } | |||||
fragment { return_token_or_IDENTIFIER(require_ARB_fp, FRAGMENT); } | |||||
program { return PROGRAM; } | |||||
state { return STATE; } | |||||
result { return RESULT; } | |||||
{dot}ambient { return AMBIENT; } | |||||
{dot}attenuation { return ATTENUATION; } | |||||
{dot}back { return BACK; } | |||||
{dot}clip { return_token_or_DOT(require_ARB_vp, CLIP); } | |||||
{dot}color { return COLOR; } | |||||
{dot}depth { return_token_or_DOT(require_ARB_fp, DEPTH); } | |||||
{dot}diffuse { return DIFFUSE; } | |||||
{dot}direction { return DIRECTION; } | |||||
{dot}emission { return EMISSION; } | |||||
{dot}env { return ENV; } | |||||
{dot}eye { return EYE; } | |||||
{dot}fogcoord { return FOGCOORD; } | |||||
{dot}fog { return FOG; } | |||||
{dot}front { return FRONT; } | |||||
{dot}half { return HALF; } | |||||
{dot}inverse { return INVERSE; } | |||||
{dot}invtrans { return INVTRANS; } | |||||
{dot}light { return LIGHT; } | |||||
{dot}lightmodel { return LIGHTMODEL; } | |||||
{dot}lightprod { return LIGHTPROD; } | |||||
{dot}local { return LOCAL; } | |||||
{dot}material { return MATERIAL; } | |||||
{dot}program { return MAT_PROGRAM; } | |||||
{dot}matrix { return MATRIX; } | |||||
{dot}matrixindex { return_token_or_DOT(require_ARB_vp, MATRIXINDEX); } | |||||
{dot}modelview { return MODELVIEW; } | |||||
{dot}mvp { return MVP; } | |||||
{dot}normal { return_token_or_DOT(require_ARB_vp, NORMAL); } | |||||
{dot}object { return OBJECT; } | |||||
{dot}palette { return PALETTE; } | |||||
{dot}params { return PARAMS; } | |||||
{dot}plane { return PLANE; } | |||||
{dot}point { return_token_or_DOT(require_ARB_vp, POINT); } | |||||
{dot}pointsize { return_token_or_DOT(require_ARB_vp, POINTSIZE); } | |||||
{dot}position { return POSITION; } | |||||
{dot}primary { return PRIMARY; } | |||||
{dot}projection { return PROJECTION; } | |||||
{dot}range { return_token_or_DOT(require_ARB_fp, RANGE); } | |||||
{dot}row { return ROW; } | |||||
{dot}scenecolor { return SCENECOLOR; } | |||||
{dot}secondary { return SECONDARY; } | |||||
{dot}shininess { return SHININESS; } | |||||
{dot}size { return_token_or_DOT(require_ARB_vp, SIZE); } | |||||
{dot}specular { return SPECULAR; } | |||||
{dot}spot { return SPOT; } | |||||
{dot}texcoord { return TEXCOORD; } | |||||
{dot}texenv { return_token_or_DOT(require_ARB_fp, TEXENV); } | |||||
{dot}texgen { return_token_or_DOT(require_ARB_vp, TEXGEN); } | |||||
{dot}q { return_token_or_DOT(require_ARB_vp, TEXGEN_Q); } | |||||
{dot}s { return_token_or_DOT(require_ARB_vp, TEXGEN_S); } | |||||
{dot}t { return_token_or_DOT(require_ARB_vp, TEXGEN_T); } | |||||
{dot}texture { return TEXTURE; } | |||||
{dot}transpose { return TRANSPOSE; } | |||||
{dot}attrib { return_token_or_DOT(require_ARB_vp, VTXATTRIB); } | |||||
{dot}weight { return_token_or_DOT(require_ARB_vp, WEIGHT); } | |||||
texture { return_token_or_IDENTIFIER(require_ARB_fp, TEXTURE_UNIT); } | |||||
1D { return_token_or_IDENTIFIER(require_ARB_fp, TEX_1D); } | |||||
2D { return_token_or_IDENTIFIER(require_ARB_fp, TEX_2D); } | |||||
3D { return_token_or_IDENTIFIER(require_ARB_fp, TEX_3D); } | |||||
CUBE { return_token_or_IDENTIFIER(require_ARB_fp, TEX_CUBE); } | |||||
RECT { return_token_or_IDENTIFIER(require_ARB_fp && require_rect, TEX_RECT); } | |||||
SHADOW1D { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow, TEX_SHADOW1D); } | |||||
SHADOW2D { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow, TEX_SHADOW2D); } | |||||
SHADOWRECT { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_rect, TEX_SHADOWRECT); } | |||||
ARRAY1D { return_token_or_IDENTIFIER(require_ARB_fp && require_texarray, TEX_ARRAY1D); } | |||||
ARRAY2D { return_token_or_IDENTIFIER(require_ARB_fp && require_texarray, TEX_ARRAY2D); } | |||||
ARRAYSHADOW1D { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_texarray, TEX_ARRAYSHADOW1D); } | |||||
ARRAYSHADOW2D { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_texarray, TEX_ARRAYSHADOW2D); } | |||||
[_a-zA-Z$][_a-zA-Z0-9$]* { | |||||
yylval->string = strdup(yytext); | |||||
return IDENTIFIER; | |||||
} | |||||
".." { return DOT_DOT; } | |||||
{num} { | |||||
yylval->integer = strtol(yytext, NULL, 10); | |||||
return INTEGER; | |||||
} | |||||
{num}?{frac}{exp}? { | |||||
yylval->real = strtod(yytext, NULL); | |||||
return REAL; | |||||
} | |||||
{num}"."/[^.] { | |||||
yylval->real = strtod(yytext, NULL); | |||||
return REAL; | |||||
} | |||||
{num}{exp} { | |||||
yylval->real = strtod(yytext, NULL); | |||||
return REAL; | |||||
} | |||||
{num}"."{exp} { | |||||
yylval->real = strtod(yytext, NULL); | |||||
return REAL; | |||||
} | |||||
".xyzw" { | |||||
yylval->swiz_mask.swizzle = SWIZZLE_NOOP; | |||||
yylval->swiz_mask.mask = WRITEMASK_XYZW; | |||||
return MASK4; | |||||
} | |||||
".xy"[zw] { | |||||
yylval->swiz_mask.swizzle = SWIZZLE_INVAL; | |||||
yylval->swiz_mask.mask = WRITEMASK_XY | |||||
| mask_from_char(yytext[3]); | |||||
return MASK3; | |||||
} | |||||
".xzw" { | |||||
yylval->swiz_mask.swizzle = SWIZZLE_INVAL; | |||||
yylval->swiz_mask.mask = WRITEMASK_XZW; | |||||
return MASK3; | |||||
} | |||||
".yzw" { | |||||
yylval->swiz_mask.swizzle = SWIZZLE_INVAL; | |||||
yylval->swiz_mask.mask = WRITEMASK_YZW; | |||||
return MASK3; | |||||
} | |||||
".x"[yzw] { | |||||
yylval->swiz_mask.swizzle = SWIZZLE_INVAL; | |||||
yylval->swiz_mask.mask = WRITEMASK_X | |||||
| mask_from_char(yytext[2]); | |||||
return MASK2; | |||||
} | |||||
".y"[zw] { | |||||
yylval->swiz_mask.swizzle = SWIZZLE_INVAL; | |||||
yylval->swiz_mask.mask = WRITEMASK_Y | |||||
| mask_from_char(yytext[2]); | |||||
return MASK2; | |||||
} | |||||
".zw" { | |||||
yylval->swiz_mask.swizzle = SWIZZLE_INVAL; | |||||
yylval->swiz_mask.mask = WRITEMASK_ZW; | |||||
return MASK2; | |||||
} | |||||
"."[xyzw] { | |||||
const unsigned s = swiz_from_char(yytext[1]); | |||||
yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(s, s, s, s); | |||||
yylval->swiz_mask.mask = mask_from_char(yytext[1]); | |||||
return MASK1; | |||||
} | |||||
"."[xyzw]{4} { | |||||
yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(swiz_from_char(yytext[1]), | |||||
swiz_from_char(yytext[2]), | |||||
swiz_from_char(yytext[3]), | |||||
swiz_from_char(yytext[4])); | |||||
yylval->swiz_mask.mask = 0; | |||||
return SWIZZLE; | |||||
} | |||||
".rgba" { | |||||
yylval->swiz_mask.swizzle = SWIZZLE_NOOP; | |||||
yylval->swiz_mask.mask = WRITEMASK_XYZW; | |||||
return_token_or_DOT(require_ARB_fp, MASK4); | |||||
} | |||||
".rg"[ba] { | |||||
yylval->swiz_mask.swizzle = SWIZZLE_INVAL; | |||||
yylval->swiz_mask.mask = WRITEMASK_XY | |||||
| mask_from_char(yytext[3]); | |||||
return_token_or_DOT(require_ARB_fp, MASK3); | |||||
} | |||||
".rba" { | |||||
yylval->swiz_mask.swizzle = SWIZZLE_INVAL; | |||||
yylval->swiz_mask.mask = WRITEMASK_XZW; | |||||
return_token_or_DOT(require_ARB_fp, MASK3); | |||||
} | |||||
".gba" { | |||||
yylval->swiz_mask.swizzle = SWIZZLE_INVAL; | |||||
yylval->swiz_mask.mask = WRITEMASK_YZW; | |||||
return_token_or_DOT(require_ARB_fp, MASK3); | |||||
} | |||||
".r"[gba] { | |||||
yylval->swiz_mask.swizzle = SWIZZLE_INVAL; | |||||
yylval->swiz_mask.mask = WRITEMASK_X | |||||
| mask_from_char(yytext[2]); | |||||
return_token_or_DOT(require_ARB_fp, MASK2); | |||||
} | |||||
".g"[ba] { | |||||
yylval->swiz_mask.swizzle = SWIZZLE_INVAL; | |||||
yylval->swiz_mask.mask = WRITEMASK_Y | |||||
| mask_from_char(yytext[2]); | |||||
return_token_or_DOT(require_ARB_fp, MASK2); | |||||
} | |||||
".ba" { | |||||
yylval->swiz_mask.swizzle = SWIZZLE_INVAL; | |||||
yylval->swiz_mask.mask = WRITEMASK_ZW; | |||||
return_token_or_DOT(require_ARB_fp, MASK2); | |||||
} | |||||
"."[gba] { | |||||
const unsigned s = swiz_from_char(yytext[1]); | |||||
yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(s, s, s, s); | |||||
yylval->swiz_mask.mask = mask_from_char(yytext[1]); | |||||
return_token_or_DOT(require_ARB_fp, MASK1); | |||||
} | |||||
".r" { | |||||
if (require_ARB_vp) { | |||||
return TEXGEN_R; | |||||
} else { | |||||
yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, | |||||
SWIZZLE_X, SWIZZLE_X); | |||||
yylval->swiz_mask.mask = WRITEMASK_X; | |||||
return MASK1; | |||||
} | |||||
} | |||||
"."[rgba]{4} { | |||||
yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(swiz_from_char(yytext[1]), | |||||
swiz_from_char(yytext[2]), | |||||
swiz_from_char(yytext[3]), | |||||
swiz_from_char(yytext[4])); | |||||
yylval->swiz_mask.mask = 0; | |||||
return_token_or_DOT(require_ARB_fp, SWIZZLE); | |||||
} | |||||
"." { return DOT; } | |||||
\n { | |||||
yylloc->first_line++; | |||||
yylloc->first_column = 1; | |||||
yylloc->last_line++; | |||||
yylloc->last_column = 1; | |||||
yylloc->position++; | |||||
} | |||||
[ \t]+ /* eat whitespace */ ; | |||||
#.*$ /* eat comments */ ; | |||||
. { return yytext[0]; } | |||||
%% | |||||
void | |||||
_mesa_program_lexer_ctor(void **scanner, struct asm_parser_state *state, | |||||
const char *string, size_t len) | |||||
{ | |||||
yylex_init_extra(state, scanner); | |||||
yy_scan_bytes(string, len, *scanner); | |||||
} | |||||
void | |||||
_mesa_program_lexer_dtor(void *scanner) | |||||
{ | |||||
yylex_destroy(scanner); | |||||
} |
/* A Bison parser, made by GNU Bison 2.4.1. */ | |||||
/* Skeleton interface for Bison's Yacc-like parsers in C | |||||
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 | |||||
Free Software Foundation, Inc. | |||||
This program is free software: you can redistribute it and/or modify | |||||
it under the terms of the GNU General Public License as published by | |||||
the Free Software Foundation, either version 3 of the License, or | |||||
(at your option) any later version. | |||||
This program is distributed in the hope that it will be useful, | |||||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
GNU General Public License for more details. | |||||
You should have received a copy of the GNU General Public License | |||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |||||
/* As a special exception, you may create a larger work that contains | |||||
part or all of the Bison parser skeleton and distribute that work | |||||
under terms of your choice, so long as that work isn't itself a | |||||
parser generator using the skeleton or a modified version thereof | |||||
as a parser skeleton. Alternatively, if you modify or redistribute | |||||
the parser skeleton itself, you may (at your option) remove this | |||||
special exception, which will cause the skeleton and the resulting | |||||
Bison output files to be licensed under the GNU General Public | |||||
License without this special exception. | |||||
This special exception was added by the Free Software Foundation in | |||||
version 2.2 of Bison. */ | |||||
/* Tokens. */ | |||||
#ifndef YYTOKENTYPE | |||||
# define YYTOKENTYPE | |||||
/* Put the tokens into the symbol table, so that GDB and other debuggers | |||||
know about them. */ | |||||
enum yytokentype { | |||||
ARBvp_10 = 258, | |||||
ARBfp_10 = 259, | |||||
ADDRESS = 260, | |||||
ALIAS = 261, | |||||
ATTRIB = 262, | |||||
OPTION = 263, | |||||
OUTPUT = 264, | |||||
PARAM = 265, | |||||
TEMP = 266, | |||||
END = 267, | |||||
BIN_OP = 268, | |||||
BINSC_OP = 269, | |||||
SAMPLE_OP = 270, | |||||
SCALAR_OP = 271, | |||||
TRI_OP = 272, | |||||
VECTOR_OP = 273, | |||||
ARL = 274, | |||||
KIL = 275, | |||||
SWZ = 276, | |||||
INTEGER = 277, | |||||
REAL = 278, | |||||
AMBIENT = 279, | |||||
ATTENUATION = 280, | |||||
BACK = 281, | |||||
CLIP = 282, | |||||
COLOR = 283, | |||||
DEPTH = 284, | |||||
DIFFUSE = 285, | |||||
DIRECTION = 286, | |||||
EMISSION = 287, | |||||
ENV = 288, | |||||
EYE = 289, | |||||
FOG = 290, | |||||
FOGCOORD = 291, | |||||
FRAGMENT = 292, | |||||
FRONT = 293, | |||||
HALF = 294, | |||||
INVERSE = 295, | |||||
INVTRANS = 296, | |||||
LIGHT = 297, | |||||
LIGHTMODEL = 298, | |||||
LIGHTPROD = 299, | |||||
LOCAL = 300, | |||||
MATERIAL = 301, | |||||
MAT_PROGRAM = 302, | |||||
MATRIX = 303, | |||||
MATRIXINDEX = 304, | |||||
MODELVIEW = 305, | |||||
MVP = 306, | |||||
NORMAL = 307, | |||||
OBJECT = 308, | |||||
PALETTE = 309, | |||||
PARAMS = 310, | |||||
PLANE = 311, | |||||
POINT = 312, | |||||
POINTSIZE = 313, | |||||
POSITION = 314, | |||||
PRIMARY = 315, | |||||
PROGRAM = 316, | |||||
PROJECTION = 317, | |||||
RANGE = 318, | |||||
RESULT = 319, | |||||
ROW = 320, | |||||
SCENECOLOR = 321, | |||||
SECONDARY = 322, | |||||
SHININESS = 323, | |||||
SIZE = 324, | |||||
SPECULAR = 325, | |||||
SPOT = 326, | |||||
STATE = 327, | |||||
TEXCOORD = 328, | |||||
TEXENV = 329, | |||||
TEXGEN = 330, | |||||
TEXGEN_Q = 331, | |||||
TEXGEN_R = 332, | |||||
TEXGEN_S = 333, | |||||
TEXGEN_T = 334, | |||||
TEXTURE = 335, | |||||
TRANSPOSE = 336, | |||||
TEXTURE_UNIT = 337, | |||||
TEX_1D = 338, | |||||
TEX_2D = 339, | |||||
TEX_3D = 340, | |||||
TEX_CUBE = 341, | |||||
TEX_RECT = 342, | |||||
TEX_SHADOW1D = 343, | |||||
TEX_SHADOW2D = 344, | |||||
TEX_SHADOWRECT = 345, | |||||
TEX_ARRAY1D = 346, | |||||
TEX_ARRAY2D = 347, | |||||
TEX_ARRAYSHADOW1D = 348, | |||||
TEX_ARRAYSHADOW2D = 349, | |||||
VERTEX = 350, | |||||
VTXATTRIB = 351, | |||||
WEIGHT = 352, | |||||
IDENTIFIER = 353, | |||||
MASK4 = 354, | |||||
MASK3 = 355, | |||||
MASK2 = 356, | |||||
MASK1 = 357, | |||||
SWIZZLE = 358, | |||||
DOT_DOT = 359, | |||||
DOT = 360 | |||||
}; | |||||
#endif | |||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED | |||||
typedef union YYSTYPE | |||||
{ | |||||
/* Line 1676 of yacc.c */ | |||||
#line 107 "program_parse.y" | |||||
struct asm_instruction *inst; | |||||
struct asm_symbol *sym; | |||||
struct asm_symbol temp_sym; | |||||
struct asm_swizzle_mask swiz_mask; | |||||
struct asm_src_register src_reg; | |||||
struct prog_dst_register dst_reg; | |||||
struct prog_instruction temp_inst; | |||||
char *string; | |||||
unsigned result; | |||||
unsigned attrib; | |||||
int integer; | |||||
float real; | |||||
unsigned state[5]; | |||||
int negate; | |||||
struct asm_vector vector; | |||||
gl_inst_opcode opcode; | |||||
struct { | |||||
unsigned swz; | |||||
unsigned rgba_valid:1; | |||||
unsigned xyzw_valid:1; | |||||
unsigned negate:1; | |||||
} ext_swizzle; | |||||
/* Line 1676 of yacc.c */ | |||||
#line 185 "program_parse.tab.h" | |||||
} YYSTYPE; | |||||
# define YYSTYPE_IS_TRIVIAL 1 | |||||
# define yystype YYSTYPE /* obsolescent; will be withdrawn */ | |||||
# define YYSTYPE_IS_DECLARED 1 | |||||
#endif | |||||
#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED | |||||
typedef struct YYLTYPE | |||||
{ | |||||
int first_line; | |||||
int first_column; | |||||
int last_line; | |||||
int last_column; | |||||
} YYLTYPE; | |||||
# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ | |||||
# define YYLTYPE_IS_DECLARED 1 | |||||
# define YYLTYPE_IS_TRIVIAL 1 | |||||
#endif | |||||
/* | |||||
* Copyright © 2009 Intel Corporation | |||||
* | |||||
* Permission is hereby granted, free of charge, to any person obtaining a | |||||
* copy of this software and associated documentation files (the "Software"), | |||||
* to deal in the Software without restriction, including without limitation | |||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||||
* and/or sell copies of the Software, and to permit persons to whom the | |||||
* Software is furnished to do so, subject to the following conditions: | |||||
* | |||||
* The above copyright notice and this permission notice (including the next | |||||
* paragraph) shall be included in all copies or substantial portions of the | |||||
* Software. | |||||
* | |||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||||
* DEALINGS IN THE SOFTWARE. | |||||
*/ | |||||
#include <string.h> | |||||
#include "main/mtypes.h" | |||||
#include "prog_instruction.h" | |||||
#include "program_parser.h" | |||||
/** | |||||
* Extra assembly-level parser routines | |||||
* | |||||
* \author Ian Romanick <ian.d.romanick@intel.com> | |||||
*/ | |||||
int | |||||
_mesa_ARBvp_parse_option(struct asm_parser_state *state, const char *option) | |||||
{ | |||||
if (strcmp(option, "ARB_position_invariant") == 0) { | |||||
state->option.PositionInvariant = 1; | |||||
return 1; | |||||
} | |||||
return 0; | |||||
} | |||||
int | |||||
_mesa_ARBfp_parse_option(struct asm_parser_state *state, const char *option) | |||||
{ | |||||
/* All of the options currently supported start with "ARB_". The code is | |||||
* currently structured with nested if-statements because eventually options | |||||
* that start with "NV_" will be supported. This structure will result in | |||||
* less churn when those options are added. | |||||
*/ | |||||
if (strncmp(option, "ARB_", 4) == 0) { | |||||
/* Advance the pointer past the "ARB_" prefix. | |||||
*/ | |||||
option += 4; | |||||
if (strncmp(option, "fog_", 4) == 0) { | |||||
option += 4; | |||||
if (state->option.Fog == OPTION_NONE) { | |||||
if (strcmp(option, "exp") == 0) { | |||||
state->option.Fog = OPTION_FOG_EXP; | |||||
return 1; | |||||
} else if (strcmp(option, "exp2") == 0) { | |||||
state->option.Fog = OPTION_FOG_EXP2; | |||||
return 1; | |||||
} else if (strcmp(option, "linear") == 0) { | |||||
state->option.Fog = OPTION_FOG_LINEAR; | |||||
return 1; | |||||
} | |||||
} | |||||
return 0; | |||||
} else if (strncmp(option, "precision_hint_", 15) == 0) { | |||||
option += 15; | |||||
if (state->option.PrecisionHint == OPTION_NONE) { | |||||
if (strcmp(option, "nicest") == 0) { | |||||
state->option.PrecisionHint = OPTION_NICEST; | |||||
return 1; | |||||
} else if (strcmp(option, "fastest") == 0) { | |||||
state->option.PrecisionHint = OPTION_FASTEST; | |||||
return 1; | |||||
} | |||||
} | |||||
return 0; | |||||
} else if (strcmp(option, "draw_buffers") == 0) { | |||||
/* Don't need to check extension availability because all Mesa-based | |||||
* drivers support GL_ARB_draw_buffers. | |||||
*/ | |||||
state->option.DrawBuffers = 1; | |||||
return 1; | |||||
} else if (strcmp(option, "fragment_program_shadow") == 0) { | |||||
if (state->ctx->Extensions.ARB_fragment_program_shadow) { | |||||
state->option.Shadow = 1; | |||||
return 1; | |||||
} | |||||
} | |||||
} else if (strncmp(option, "MESA_", 5) == 0) { | |||||
option += 5; | |||||
if (strcmp(option, "texture_array") == 0) { | |||||
if (state->ctx->Extensions.MESA_texture_array) { | |||||
state->option.TexArray = 1; | |||||
return 1; | |||||
} | |||||
} | |||||
} | |||||
return 0; | |||||
} |
/* | |||||
* Copyright © 2009 Intel Corporation | |||||
* | |||||
* Permission is hereby granted, free of charge, to any person obtaining a | |||||
* copy of this software and associated documentation files (the "Software"), | |||||
* to deal in the Software without restriction, including without limitation | |||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||||
* and/or sell copies of the Software, and to permit persons to whom the | |||||
* Software is furnished to do so, subject to the following conditions: | |||||
* | |||||
* The above copyright notice and this permission notice (including the next | |||||
* paragraph) shall be included in all copies or substantial portions of the | |||||
* Software. | |||||
* | |||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||||
* DEALINGS IN THE SOFTWARE. | |||||
*/ | |||||
#pragma once | |||||
#include "main/config.h" | |||||
#ifndef MTYPES_H | |||||
struct __GLcontextRec; | |||||
typedef struct __GLcontextRec GLcontext; | |||||
#endif | |||||
enum asm_type { | |||||
at_none, | |||||
at_address, | |||||
at_attrib, | |||||
at_param, | |||||
at_temp, | |||||
at_output, | |||||
}; | |||||
struct asm_symbol { | |||||
struct asm_symbol *next; /**< List linkage for freeing. */ | |||||
const char *name; | |||||
enum asm_type type; | |||||
unsigned attrib_binding; | |||||
unsigned output_binding; /**< Output / result register number. */ | |||||
/** | |||||
* One of PROGRAM_STATE_VAR, PROGRAM_LOCAL_PARAM, or PROGRAM_ENV_PARAM. | |||||
*/ | |||||
unsigned param_binding_type; | |||||
/** | |||||
* Offset into the program_parameter_list where the tokens representing our | |||||
* bound state (or constants) start. | |||||
*/ | |||||
unsigned param_binding_begin; | |||||
/* This is how many entries in the the program_parameter_list we take up | |||||
* with our state tokens or constants. Note that this is _not_ the same as | |||||
* the number of param registers we eventually use. | |||||
*/ | |||||
unsigned param_binding_length; | |||||
/** | |||||
* Index of the temp register assigned to this variable. | |||||
*/ | |||||
unsigned temp_binding; | |||||
/** | |||||
* Flag whether or not a PARAM is an array | |||||
*/ | |||||
unsigned param_is_array:1; | |||||
/** | |||||
* Flag whether or not a PARAM array is accessed indirectly | |||||
*/ | |||||
unsigned param_accessed_indirectly:1; | |||||
/** | |||||
* \brief Is first pass of parameter layout done with this variable? | |||||
* | |||||
* The parameter layout routine operates in two passes. This flag tracks | |||||
* whether or not the first pass has handled this variable. | |||||
* | |||||
* \sa _mesa_layout_parameters | |||||
*/ | |||||
unsigned pass1_done:1; | |||||
}; | |||||
struct asm_vector { | |||||
unsigned count; | |||||
float data[4]; | |||||
}; | |||||
struct asm_swizzle_mask { | |||||
unsigned swizzle:12; | |||||
unsigned mask:4; | |||||
}; | |||||
struct asm_src_register { | |||||
struct prog_src_register Base; | |||||
/** | |||||
* Symbol associated with indirect access to parameter arrays. | |||||
* | |||||
* If \c Base::RelAddr is 1, this will point to the symbol for the parameter | |||||
* that is being dereferenced. Further, \c Base::Index will be the offset | |||||
* from the address register being used. | |||||
*/ | |||||
struct asm_symbol *Symbol; | |||||
}; | |||||
struct asm_instruction { | |||||
struct prog_instruction Base; | |||||
struct asm_instruction *next; | |||||
struct asm_src_register SrcReg[3]; | |||||
}; | |||||
struct asm_parser_state { | |||||
GLcontext *ctx; | |||||
struct gl_program *prog; | |||||
/** | |||||
* Per-program target limits | |||||
*/ | |||||
struct gl_program_constants *limits; | |||||
struct _mesa_symbol_table *st; | |||||
/** | |||||
* Linked list of symbols | |||||
* | |||||
* This list is \b only used when cleaning up compiler state and freeing | |||||
* memory. | |||||
*/ | |||||
struct asm_symbol *sym; | |||||
/** | |||||
* State for the lexer. | |||||
*/ | |||||
void *scanner; | |||||
/** | |||||
* Linked list of instructions generated during parsing. | |||||
*/ | |||||
/*@{*/ | |||||
struct asm_instruction *inst_head; | |||||
struct asm_instruction *inst_tail; | |||||
/*@}*/ | |||||
/** | |||||
* Selected limits copied from gl_constants | |||||
* | |||||
* These are limits from the GL context, but various bits in the program | |||||
* must be validated against these values. | |||||
*/ | |||||
/*@{*/ | |||||
unsigned MaxTextureCoordUnits; | |||||
unsigned MaxTextureImageUnits; | |||||
unsigned MaxTextureUnits; | |||||
unsigned MaxClipPlanes; | |||||
unsigned MaxLights; | |||||
unsigned MaxProgramMatrices; | |||||
/*@}*/ | |||||
/** | |||||
* Value to use in state vector accessors for environment and local | |||||
* parameters | |||||
*/ | |||||
unsigned state_param_enum; | |||||
/** | |||||
* Input attributes bound to specific names | |||||
* | |||||
* This is only needed so that errors can be properly produced when | |||||
* multiple ATTRIB statements bind illegal combinations of vertex | |||||
* attributes. | |||||
*/ | |||||
unsigned InputsBound; | |||||
enum { | |||||
invalid_mode = 0, | |||||
ARB_vertex, | |||||
ARB_fragment | |||||
} mode; | |||||
struct { | |||||
unsigned PositionInvariant:1; | |||||
unsigned Fog:2; | |||||
unsigned PrecisionHint:2; | |||||
unsigned DrawBuffers:1; | |||||
unsigned Shadow:1; | |||||
unsigned TexRect:1; | |||||
unsigned TexArray:1; | |||||
} option; | |||||
struct { | |||||
unsigned UsesKill:1; | |||||
} fragment; | |||||
}; | |||||
#define OPTION_NONE 0 | |||||
#define OPTION_FOG_EXP 1 | |||||
#define OPTION_FOG_EXP2 2 | |||||
#define OPTION_FOG_LINEAR 3 | |||||
#define OPTION_NICEST 1 | |||||
#define OPTION_FASTEST 2 | |||||
typedef struct YYLTYPE { | |||||
int first_line; | |||||
int first_column; | |||||
int last_line; | |||||
int last_column; | |||||
int position; | |||||
} YYLTYPE; | |||||
#define YYLTYPE_IS_DECLARED 1 | |||||
#define YYLTYPE_IS_TRIVIAL 1 | |||||
extern GLboolean _mesa_parse_arb_program(GLcontext *ctx, GLenum target, | |||||
const GLubyte *str, GLsizei len, struct asm_parser_state *state); | |||||
/* From program_lexer.l. */ | |||||
extern void _mesa_program_lexer_dtor(void *scanner); | |||||
extern void _mesa_program_lexer_ctor(void **scanner, | |||||
struct asm_parser_state *state, const char *string, size_t len); | |||||
/** | |||||
*\name From program_parse_extra.c | |||||
*/ | |||||
/*@{*/ | |||||
/** | |||||
* Parses and processes an option string to an ARB vertex program | |||||
* | |||||
* \return | |||||
* Non-zero on success, zero on failure. | |||||
*/ | |||||
extern int _mesa_ARBvp_parse_option(struct asm_parser_state *state, | |||||
const char *option); | |||||
/** | |||||
* Parses and processes an option string to an ARB fragment program | |||||
* | |||||
* \return | |||||
* Non-zero on success, zero on failure. | |||||
*/ | |||||
extern int _mesa_ARBfp_parse_option(struct asm_parser_state *state, | |||||
const char *option); | |||||
/*@}*/ |
/* | |||||
* Copyright © 2008 Intel Corporation | |||||
* | |||||
* Permission is hereby granted, free of charge, to any person obtaining a | |||||
* copy of this software and associated documentation files (the "Software"), | |||||
* to deal in the Software without restriction, including without limitation | |||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||||
* and/or sell copies of the Software, and to permit persons to whom the | |||||
* Software is furnished to do so, subject to the following conditions: | |||||
* | |||||
* The above copyright notice and this permission notice (including the next | |||||
* paragraph) shall be included in all copies or substantial portions of the | |||||
* Software. | |||||
* | |||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||||
* DEALINGS IN THE SOFTWARE. | |||||
*/ | |||||
#include <stdlib.h> | |||||
#include <stdio.h> | |||||
#include <string.h> | |||||
#include <errno.h> | |||||
#include <assert.h> | |||||
#include "symbol_table.h" | |||||
#include "hash_table.h" | |||||
struct symbol { | |||||
/** | |||||
* Link to the next symbol in the table with the same name | |||||
* | |||||
* The linked list of symbols with the same name is ordered by scope | |||||
* from inner-most to outer-most. | |||||
*/ | |||||
struct symbol *next_with_same_name; | |||||
/** | |||||
* Link to the next symbol in the table with the same scope | |||||
* | |||||
* The linked list of symbols with the same scope is unordered. Symbols | |||||
* in this list my have unique names. | |||||
*/ | |||||
struct symbol *next_with_same_scope; | |||||
/** | |||||
* Header information for the list of symbols with the same name. | |||||
*/ | |||||
struct symbol_header *hdr; | |||||
/** | |||||
* Name space of the symbol | |||||
* | |||||
* Name space are arbitrary user assigned integers. No two symbols can | |||||
* exist in the same name space at the same scope level. | |||||
*/ | |||||
int name_space; | |||||
/** | |||||
* Arbitrary user supplied data. | |||||
*/ | |||||
void *data; | |||||
}; | |||||
/** | |||||
*/ | |||||
struct symbol_header { | |||||
/** Symbol name. */ | |||||
const char *name; | |||||
/** Linked list of symbols with the same name. */ | |||||
struct symbol *symbols; | |||||
}; | |||||
/** | |||||
* Element of the scope stack. | |||||
*/ | |||||
struct scope_level { | |||||
/** Link to next (inner) scope level. */ | |||||
struct scope_level *next; | |||||
/** Linked list of symbols with the same scope. */ | |||||
struct symbol *symbols; | |||||
}; | |||||
/** | |||||
* | |||||
*/ | |||||
struct _mesa_symbol_table { | |||||
/** Hash table containing all symbols in the symbol table. */ | |||||
struct hash_table *ht; | |||||
/** Top of scope stack. */ | |||||
struct scope_level *current_scope; | |||||
}; | |||||
struct _mesa_symbol_table_iterator { | |||||
/** | |||||
* Name space of symbols returned by this iterator. | |||||
*/ | |||||
int name_space; | |||||
/** | |||||
* Currently iterated symbol | |||||
* | |||||
* The next call to \c _mesa_symbol_table_iterator_get will return this | |||||
* value. It will also update this value to the value that should be | |||||
* returned by the next call. | |||||
*/ | |||||
struct symbol *curr; | |||||
}; | |||||
static void | |||||
check_symbol_table(struct _mesa_symbol_table *table) | |||||
{ | |||||
#if 1 | |||||
struct scope_level *scope; | |||||
for (scope = table->current_scope; scope != NULL; scope = scope->next) { | |||||
struct symbol *sym; | |||||
for (sym = scope->symbols | |||||
; sym != NULL | |||||
; sym = sym->next_with_same_name) { | |||||
const struct symbol_header *const hdr = sym->hdr; | |||||
struct symbol *sym2; | |||||
for (sym2 = hdr->symbols | |||||
; sym2 != NULL | |||||
; sym2 = sym2->next_with_same_name) { | |||||
assert(sym2->hdr == hdr); | |||||
} | |||||
} | |||||
} | |||||
#endif | |||||
} | |||||
void | |||||
_mesa_symbol_table_pop_scope(struct _mesa_symbol_table *table) | |||||
{ | |||||
struct scope_level *const scope = table->current_scope; | |||||
struct symbol *sym = scope->symbols; | |||||
table->current_scope = scope->next; | |||||
free(scope); | |||||
while (sym != NULL) { | |||||
struct symbol *const next = sym->next_with_same_scope; | |||||
struct symbol_header *const hdr = sym->hdr; | |||||
assert(hdr->symbols == sym); | |||||
hdr->symbols = sym->next_with_same_name; | |||||
free(sym); | |||||
sym = next; | |||||
} | |||||
check_symbol_table(table); | |||||
} | |||||
void | |||||
_mesa_symbol_table_push_scope(struct _mesa_symbol_table *table) | |||||
{ | |||||
struct scope_level *const scope = calloc(1, sizeof(*scope)); | |||||
scope->next = table->current_scope; | |||||
table->current_scope = scope; | |||||
} | |||||
static struct symbol_header * | |||||
find_symbol(struct _mesa_symbol_table *table, const char *name) | |||||
{ | |||||
return (struct symbol_header *) hash_table_find(table->ht, name); | |||||
} | |||||
struct _mesa_symbol_table_iterator * | |||||
_mesa_symbol_table_iterator_ctor(struct _mesa_symbol_table *table, | |||||
int name_space, const char *name) | |||||
{ | |||||
struct _mesa_symbol_table_iterator *iter = calloc(1, sizeof(*iter)); | |||||
struct symbol_header *const hdr = find_symbol(table, name); | |||||
iter->name_space = name_space; | |||||
if (hdr != NULL) { | |||||
struct symbol *sym; | |||||
for (sym = hdr->symbols; sym != NULL; sym = sym->next_with_same_name) { | |||||
assert(sym->hdr == hdr); | |||||
if ((name_space == -1) || (sym->name_space == name_space)) { | |||||
iter->curr = sym; | |||||
break; | |||||
} | |||||
} | |||||
} | |||||
return iter; | |||||
} | |||||
void | |||||
_mesa_symbol_table_iterator_dtor(struct _mesa_symbol_table_iterator *iter) | |||||
{ | |||||
free(iter); | |||||
} | |||||
void * | |||||
_mesa_symbol_table_iterator_get(struct _mesa_symbol_table_iterator *iter) | |||||
{ | |||||
return (iter->curr == NULL) ? NULL : iter->curr->data; | |||||
} | |||||
int | |||||
_mesa_symbol_table_iterator_next(struct _mesa_symbol_table_iterator *iter) | |||||
{ | |||||
struct symbol_header *hdr; | |||||
if (iter->curr == NULL) { | |||||
return 0; | |||||
} | |||||
hdr = iter->curr->hdr; | |||||
iter->curr = iter->curr->next_with_same_name; | |||||
while (iter->curr != NULL) { | |||||
assert(iter->curr->hdr == hdr); | |||||
if ((iter->name_space == -1) | |||||
|| (iter->curr->name_space == iter->name_space)) { | |||||
return 1; | |||||
} | |||||
iter->curr = iter->curr->next_with_same_name; | |||||
} | |||||
return 0; | |||||
} | |||||
void * | |||||
_mesa_symbol_table_find_symbol(struct _mesa_symbol_table *table, | |||||
int name_space, const char *name) | |||||
{ | |||||
struct symbol_header *const hdr = find_symbol(table, name); | |||||
if (hdr != NULL) { | |||||
struct symbol *sym; | |||||
for (sym = hdr->symbols; sym != NULL; sym = sym->next_with_same_name) { | |||||
assert(sym->hdr == hdr); | |||||
if ((name_space == -1) || (sym->name_space == name_space)) { | |||||
return sym->data; | |||||
} | |||||
} | |||||
} | |||||
return NULL; | |||||
} | |||||
int | |||||
_mesa_symbol_table_add_symbol(struct _mesa_symbol_table *table, | |||||
int name_space, const char *name, | |||||
void *declaration) | |||||
{ | |||||
check_symbol_table(table); | |||||
struct symbol_header *hdr = find_symbol(table, name); | |||||
struct symbol *sym; | |||||
check_symbol_table(table); | |||||
if (hdr == NULL) { | |||||
hdr = calloc(1, sizeof(*hdr)); | |||||
hdr->name = name; | |||||
hash_table_insert(table->ht, hdr, name); | |||||
} | |||||
check_symbol_table(table); | |||||
sym = calloc(1, sizeof(*sym)); | |||||
sym->next_with_same_name = hdr->symbols; | |||||
sym->next_with_same_scope = table->current_scope->symbols; | |||||
sym->hdr = hdr; | |||||
sym->name_space = name_space; | |||||
sym->data = declaration; | |||||
assert(sym->hdr == hdr); | |||||
hdr->symbols = sym; | |||||
table->current_scope->symbols = sym; | |||||
check_symbol_table(table); | |||||
return 0; | |||||
} | |||||
struct _mesa_symbol_table * | |||||
_mesa_symbol_table_ctor(void) | |||||
{ | |||||
struct _mesa_symbol_table *table = calloc(1, sizeof(*table)); | |||||
if (table != NULL) { | |||||
table->ht = hash_table_ctor(32, hash_table_string_hash, | |||||
hash_table_string_compare); | |||||
_mesa_symbol_table_push_scope(table); | |||||
} | |||||
return table; | |||||
} | |||||
void | |||||
_mesa_symbol_table_dtor(struct _mesa_symbol_table *table) | |||||
{ | |||||
while (table->current_scope != NULL) { | |||||
_mesa_symbol_table_pop_scope(table); | |||||
} | |||||
hash_table_dtor(table->ht); | |||||
free(table); | |||||
} |
/* | |||||
* Copyright © 2008 Intel Corporation | |||||
* | |||||
* Permission is hereby granted, free of charge, to any person obtaining a | |||||
* copy of this software and associated documentation files (the "Software"), | |||||
* to deal in the Software without restriction, including without limitation | |||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||||
* and/or sell copies of the Software, and to permit persons to whom the | |||||
* Software is furnished to do so, subject to the following conditions: | |||||
* | |||||
* The above copyright notice and this permission notice (including the next | |||||
* paragraph) shall be included in all copies or substantial portions of the | |||||
* Software. | |||||
* | |||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||||
* DEALINGS IN THE SOFTWARE. | |||||
*/ | |||||
#ifndef MESA_SYMBOL_TABLE_H | |||||
#define MESA_SYMBOL_TABLE_H | |||||
struct _mesa_symbol_table; | |||||
struct _mesa_symbol_table_iterator; | |||||
extern void _mesa_symbol_table_push_scope(struct _mesa_symbol_table *table); | |||||
extern void _mesa_symbol_table_pop_scope(struct _mesa_symbol_table *table); | |||||
extern int _mesa_symbol_table_add_symbol(struct _mesa_symbol_table *symtab, | |||||
int name_space, const char *name, void *declaration); | |||||
extern void *_mesa_symbol_table_find_symbol( | |||||
struct _mesa_symbol_table *symtab, int name_space, const char *name); | |||||
extern struct _mesa_symbol_table *_mesa_symbol_table_ctor(void); | |||||
extern void _mesa_symbol_table_dtor(struct _mesa_symbol_table *); | |||||
extern struct _mesa_symbol_table_iterator *_mesa_symbol_table_iterator_ctor( | |||||
struct _mesa_symbol_table *table, int name_space, const char *name); | |||||
extern void _mesa_symbol_table_iterator_dtor( | |||||
struct _mesa_symbol_table_iterator *); | |||||
extern void *_mesa_symbol_table_iterator_get( | |||||
struct _mesa_symbol_table_iterator *iter); | |||||
extern int _mesa_symbol_table_iterator_next( | |||||
struct _mesa_symbol_table_iterator *iter); | |||||
#endif /* MESA_SYMBOL_TABLE_H */ |
shader/arbprogram.c \ | shader/arbprogram.c \ | ||||
shader/atifragshader.c \ | shader/atifragshader.c \ | ||||
shader/grammar/grammar_mesa.c \ | shader/grammar/grammar_mesa.c \ | ||||
shader/hash_table.c \ | |||||
shader/lex.yy.c \ | |||||
shader/nvfragparse.c \ | shader/nvfragparse.c \ | ||||
shader/nvprogram.c \ | shader/nvprogram.c \ | ||||
shader/nvvertparse.c \ | shader/nvvertparse.c \ | ||||
shader/program.c \ | shader/program.c \ | ||||
shader/program_parse.tab.c \ | |||||
shader/program_parse_extra.c \ | |||||
shader/prog_cache.c \ | shader/prog_cache.c \ | ||||
shader/prog_execute.c \ | shader/prog_execute.c \ | ||||
shader/prog_instruction.c \ | shader/prog_instruction.c \ | ||||
shader/prog_noise.c \ | shader/prog_noise.c \ | ||||
shader/prog_optimize.c \ | shader/prog_optimize.c \ | ||||
shader/prog_parameter.c \ | shader/prog_parameter.c \ | ||||
shader/prog_parameter_layout.c \ | |||||
shader/prog_print.c \ | shader/prog_print.c \ | ||||
shader/prog_statevars.c \ | shader/prog_statevars.c \ | ||||
shader/prog_uniform.c \ | shader/prog_uniform.c \ | ||||
shader/programopt.c \ | shader/programopt.c \ | ||||
shader/shader_api.c \ | |||||
shader/symbol_table.c \ | |||||
shader/shader_api.c | |||||
SLANG_SOURCES = \ | SLANG_SOURCES = \ | ||||
shader/slang/slang_builtin.c \ | shader/slang/slang_builtin.c \ |