Browse Source

Merge branch 'asm-shader-rework-1'

tags/mesa_7_6_rc1
Ian Romanick 16 years ago
parent
commit
4cfb1b880b

+ 1
- 0
src/mesa/shader/.gitignore View File

program_parse.output

+ 7
- 0
src/mesa/shader/Makefile View File

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 $<

+ 67
- 3908
src/mesa/shader/arbprogparse.c
File diff suppressed because it is too large
View File


+ 0
- 2824
src/mesa/shader/arbprogram.syn
File diff suppressed because it is too large
View File


+ 0
- 1350
src/mesa/shader/arbprogram_syn.h
File diff suppressed because it is too large
View File


+ 162
- 0
src/mesa/shader/hash_table.c View File

/*
* 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;
}

+ 117
- 0
src/mesa/shader/hash_table.h View File

/*
* 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 */

+ 3583
- 0
src/mesa/shader/lex.yy.c
File diff suppressed because it is too large
View File


+ 28
- 0
src/mesa/shader/prog_parameter.c View File

} }




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
*/ */

+ 3
- 0
src/mesa/shader/prog_parameter.h View File

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);



+ 213
- 0
src/mesa/shader/prog_parameter_layout.c View File

/*
* 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;
}

+ 41
- 0
src/mesa/shader/prog_parameter_layout.h View File

/*
* 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 */

+ 1
- 1
src/mesa/shader/prog_print.c View File

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);
} }





+ 488
- 0
src/mesa/shader/program_lexer.l View File

%{
/*
* 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);
}

+ 5250
- 0
src/mesa/shader/program_parse.tab.c
File diff suppressed because it is too large
View File


+ 207
- 0
src/mesa/shader/program_parse.tab.h View File


/* 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




+ 2380
- 0
src/mesa/shader/program_parse.y
File diff suppressed because it is too large
View File


+ 117
- 0
src/mesa/shader/program_parse_extra.c View File

/*
* 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;
}

+ 266
- 0
src/mesa/shader/program_parser.h View File

/*
* 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);

/*@}*/

+ 348
- 0
src/mesa/shader/symbol_table.c View File

/*
* 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);
}

+ 55
- 0
src/mesa/shader/symbol_table.h View File

/*
* 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 */

+ 7
- 1
src/mesa/sources.mak View File

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 \

Loading…
Cancel
Save