Merge branch 'asm-shader-rework-2'

Conflicts:
	src/mesa/shader/program_parse.tab.c
This commit is contained in:
Ian Romanick
2009-09-25 16:57:38 -07:00
10 changed files with 3099 additions and 2198 deletions

View File

@@ -116,6 +116,7 @@ const struct dri_extension card_extensions[] =
{ "GL_NV_depth_clamp", NULL },
{ "GL_NV_vertex_program", GL_NV_vertex_program_functions },
{ "GL_NV_fragment_program", GL_NV_fragment_program_functions },
{ "GL_NV_fragment_program_option", NULL },
{ NULL, NULL }
};

View File

@@ -167,6 +167,7 @@ static const struct {
{ OFF, "GL_NV_blend_square", F(NV_blend_square) },
{ OFF, "GL_NV_depth_clamp", F(ARB_depth_clamp) },
{ OFF, "GL_NV_fragment_program", F(NV_fragment_program) },
{ OFF, "GL_NV_fragment_program_option", F(NV_fragment_program_option) },
{ ON, "GL_NV_light_max_exponent", F(NV_light_max_exponent) },
{ OFF, "GL_NV_point_sprite", F(NV_point_sprite) },
{ OFF, "GL_NV_texture_env_combine4", F(NV_texture_env_combine4) },
@@ -314,6 +315,9 @@ _mesa_enable_sw_extensions(GLcontext *ctx)
#endif
#if FEATURE_NV_fragment_program
ctx->Extensions.NV_fragment_program = GL_TRUE;
#endif
#if FEATURE_NV_fragment_program && FEATURE_ARB_fragment_program
ctx->Extensions.NV_fragment_program_option = GL_TRUE;
#endif
ctx->Extensions.SGI_color_matrix = GL_TRUE;
ctx->Extensions.SGI_color_table = GL_TRUE;

View File

@@ -2583,6 +2583,7 @@ struct gl_extensions
GLboolean MESA_texture_signed_rgba;
GLboolean NV_blend_square;
GLboolean NV_fragment_program;
GLboolean NV_fragment_program_option;
GLboolean NV_light_max_exponent;
GLboolean NV_point_sprite;
GLboolean NV_texgen_reflection;

File diff suppressed because it is too large Load Diff

View File

@@ -25,11 +25,13 @@
#include "prog_instruction.h"
#include "prog_statevars.h"
#include "symbol_table.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_NV_fp (yyextra->option.NV_fragment)
#define require_shadow (yyextra->option.Shadow)
#define require_rect (yyextra->option.TexRect)
#define require_texarray (yyextra->option.TexArray)
@@ -43,8 +45,7 @@
if (condition) { \
return token; \
} else { \
yylval->string = strdup(yytext); \
return IDENTIFIER; \
return handle_ident(yyextra, yytext, yylval); \
} \
} while (0)
@@ -59,15 +60,16 @@
} while (0)
#define return_opcode(condition, token, opcode, sat) \
#define return_opcode(condition, token, opcode, len) \
do { \
if (condition) { \
if (condition && \
_mesa_parse_instruction_suffix(yyextra, \
yytext + len, \
& yylval->temp_inst)) { \
yylval->temp_inst.Opcode = OPCODE_ ## opcode; \
yylval->temp_inst.SaturateMode = SATURATE_ ## sat; \
return token; \
} else { \
yylval->string = strdup(yytext); \
return IDENTIFIER; \
return handle_ident(yyextra, yytext, yylval); \
} \
} while (0)
@@ -116,6 +118,15 @@ swiz_from_char(char c)
return 0;
}
static int
handle_ident(struct asm_parser_state *state, const char *text, YYSTYPE *lval)
{
lval->string = strdup(text);
return (_mesa_symbol_table_find_symbol(state->st, 0, text) == NULL)
? IDENTIFIER : USED_IDENTIFIER;
}
#define YY_USER_ACTION \
do { \
yylloc->first_column = yylloc->last_column; \
@@ -136,6 +147,11 @@ exp [Ee][-+]?[0-9]+
frac "."[0-9]+
dot "."[ \t]*
sz [HRX]?
szf [HR]?
cc C?
sat (_SAT)?
%option bison-bridge bison-locations reentrant noyywrap
%%
@@ -153,86 +169,74 @@ 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); }
ABS{sz}{cc}{sat} { return_opcode( 1, VECTOR_OP, ABS, 3); }
ADD{sz}{cc}{sat} { return_opcode( 1, BIN_OP, ADD, 3); }
ARL { return_opcode(require_ARB_vp, ARL, ARL, 3); }
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); }
CMP{sat} { return_opcode(require_ARB_fp, TRI_OP, CMP, 3); }
COS{szf}{cc}{sat} { return_opcode(require_ARB_fp, SCALAR_OP, COS, 3); }
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); }
DDX{szf}{cc}{sat} { return_opcode(require_NV_fp, VECTOR_OP, DDX, 3); }
DDY{szf}{cc}{sat} { return_opcode(require_NV_fp, VECTOR_OP, DDY, 3); }
DP3{sz}{cc}{sat} { return_opcode( 1, BIN_OP, DP3, 3); }
DP4{sz}{cc}{sat} { return_opcode( 1, BIN_OP, DP4, 3); }
DPH{sz}{cc}{sat} { return_opcode( 1, BIN_OP, DPH, 3); }
DST{szf}{cc}{sat} { return_opcode( 1, BIN_OP, DST, 3); }
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); }
EX2{szf}{cc}{sat} { return_opcode( 1, SCALAR_OP, EX2, 3); }
EXP { return_opcode(require_ARB_vp, SCALAR_OP, EXP, 3); }
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); }
FLR{sz}{cc}{sat} { return_opcode( 1, VECTOR_OP, FLR, 3); }
FRC{sz}{cc}{sat} { return_opcode( 1, VECTOR_OP, FRC, 3); }
KIL { return_opcode(require_ARB_fp, KIL, KIL, OFF); }
KIL { return_opcode(require_ARB_fp, KIL, KIL, 3); }
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); }
LIT{szf}{cc}{sat} { return_opcode( 1, VECTOR_OP, LIT, 3); }
LG2{szf}{cc}{sat} { return_opcode( 1, SCALAR_OP, LG2, 3); }
LOG { return_opcode(require_ARB_vp, SCALAR_OP, LOG, 3); }
LRP{sz}{cc}{sat} { return_opcode(require_ARB_fp, TRI_OP, LRP, 3); }
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); }
MAD{sz}{cc}{sat} { return_opcode( 1, TRI_OP, MAD, 3); }
MAX{sz}{cc}{sat} { return_opcode( 1, BIN_OP, MAX, 3); }
MIN{sz}{cc}{sat} { return_opcode( 1, BIN_OP, MIN, 3); }
MOV{sz}{cc}{sat} { return_opcode( 1, VECTOR_OP, MOV, 3); }
MUL{sz}{cc}{sat} { return_opcode( 1, BIN_OP, MUL, 3); }
POW { return_opcode( 1, BINSC_OP, POW, OFF); }
POW_SAT { return_opcode(require_ARB_fp, BINSC_OP, POW, ZERO_ONE); }
PK2H { return_opcode(require_NV_fp, VECTOR_OP, PK2H, 4); }
PK2US { return_opcode(require_NV_fp, VECTOR_OP, PK2US, 5); }
PK4B { return_opcode(require_NV_fp, VECTOR_OP, PK4B, 4); }
PK4UB { return_opcode(require_NV_fp, VECTOR_OP, PK4UB, 5); }
POW{szf}{cc}{sat} { return_opcode( 1, BINSC_OP, POW, 3); }
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); }
RCP{szf}{cc}{sat} { return_opcode( 1, SCALAR_OP, RCP, 3); }
RFL{szf}{cc}{sat} { return_opcode(require_NV_fp, BIN_OP, RFL, 3); }
RSQ{szf}{cc}{sat} { return_opcode( 1, SCALAR_OP, RSQ, 3); }
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); }
SCS{sat} { return_opcode(require_ARB_fp, SCALAR_OP, SCS, 3); }
SEQ{sz}{cc}{sat} { return_opcode(require_NV_fp, BIN_OP, SEQ, 3); }
SFL{sz}{cc}{sat} { return_opcode(require_NV_fp, BIN_OP, SFL, 3); }
SGE{sz}{cc}{sat} { return_opcode( 1, BIN_OP, SGE, 3); }
SGT{sz}{cc}{sat} { return_opcode(require_NV_fp, BIN_OP, SGT, 3); }
SIN{szf}{cc}{sat} { return_opcode(require_ARB_fp, SCALAR_OP, SIN, 3); }
SLE{sz}{cc}{sat} { return_opcode(require_NV_fp, BIN_OP, SLE, 3); }
SLT{sz}{cc}{sat} { return_opcode( 1, BIN_OP, SLT, 3); }
SNE{sz}{cc}{sat} { return_opcode(require_NV_fp, BIN_OP, SNE, 3); }
STR{sz}{cc}{sat} { return_opcode(require_NV_fp, BIN_OP, STR, 3); }
SUB{sz}{cc}{sat} { return_opcode( 1, BIN_OP, SUB, 3); }
SWZ{sat} { return_opcode( 1, SWZ, SWZ, 3); }
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); }
TEX{cc}{sat} { return_opcode(require_ARB_fp, SAMPLE_OP, TEX, 3); }
TXB{cc}{sat} { return_opcode(require_ARB_fp, SAMPLE_OP, TXB, 3); }
TXD{cc}{sat} { return_opcode(require_NV_fp, TXD_OP, TXD, 3); }
TXP{cc}{sat} { return_opcode(require_ARB_fp, SAMPLE_OP, TXP, 3); }
XPD { return_opcode( 1, BIN_OP, XPD, OFF); }
XPD_SAT { return_opcode(require_ARB_fp, BIN_OP, XPD, ZERO_ONE); }
UP2H{cc}{sat} { return_opcode(require_NV_fp, SCALAR_OP, UP2H, 4); }
UP2US{cc}{sat} { return_opcode(require_NV_fp, SCALAR_OP, UP2US, 5); }
UP4B{cc}{sat} { return_opcode(require_NV_fp, SCALAR_OP, UP4B, 4); }
UP4UB{cc}{sat} { return_opcode(require_NV_fp, SCALAR_OP, UP4UB, 5); }
X2D{szf}{cc}{sat} { return_opcode(require_NV_fp, TRI_OP, X2D, 3); }
XPD{sat} { return_opcode( 1, BIN_OP, XPD, 3); }
vertex { return_token_or_IDENTIFIER(require_ARB_vp, VERTEX); }
fragment { return_token_or_IDENTIFIER(require_ARB_fp, FRAGMENT); }
@@ -310,10 +314,7 @@ ARRAY2D { return_token_or_IDENTIFIER(require_ARB_fp && require
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;
}
[_a-zA-Z$][_a-zA-Z0-9$]* { return handle_ident(yyextra, yytext, yylval); }
".." { return DOT_DOT; }

File diff suppressed because it is too large Load Diff

View File

@@ -58,90 +58,92 @@
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_TOK = 312,
POINTSIZE = 313,
POSITION = 314,
PRIMARY = 315,
PROGRAM = 316,
PROJECTION = 317,
RANGE = 318,
RESULT = 319,
ROW = 320,
SCENECOLOR = 321,
SECONDARY = 322,
SHININESS = 323,
SIZE_TOK = 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
TXD_OP = 277,
INTEGER = 278,
REAL = 279,
AMBIENT = 280,
ATTENUATION = 281,
BACK = 282,
CLIP = 283,
COLOR = 284,
DEPTH = 285,
DIFFUSE = 286,
DIRECTION = 287,
EMISSION = 288,
ENV = 289,
EYE = 290,
FOG = 291,
FOGCOORD = 292,
FRAGMENT = 293,
FRONT = 294,
HALF = 295,
INVERSE = 296,
INVTRANS = 297,
LIGHT = 298,
LIGHTMODEL = 299,
LIGHTPROD = 300,
LOCAL = 301,
MATERIAL = 302,
MAT_PROGRAM = 303,
MATRIX = 304,
MATRIXINDEX = 305,
MODELVIEW = 306,
MVP = 307,
NORMAL = 308,
OBJECT = 309,
PALETTE = 310,
PARAMS = 311,
PLANE = 312,
POINT_TOK = 313,
POINTSIZE = 314,
POSITION = 315,
PRIMARY = 316,
PROGRAM = 317,
PROJECTION = 318,
RANGE = 319,
RESULT = 320,
ROW = 321,
SCENECOLOR = 322,
SECONDARY = 323,
SHININESS = 324,
SIZE_TOK = 325,
SPECULAR = 326,
SPOT = 327,
STATE = 328,
TEXCOORD = 329,
TEXENV = 330,
TEXGEN = 331,
TEXGEN_Q = 332,
TEXGEN_R = 333,
TEXGEN_S = 334,
TEXGEN_T = 335,
TEXTURE = 336,
TRANSPOSE = 337,
TEXTURE_UNIT = 338,
TEX_1D = 339,
TEX_2D = 340,
TEX_3D = 341,
TEX_CUBE = 342,
TEX_RECT = 343,
TEX_SHADOW1D = 344,
TEX_SHADOW2D = 345,
TEX_SHADOWRECT = 346,
TEX_ARRAY1D = 347,
TEX_ARRAY2D = 348,
TEX_ARRAYSHADOW1D = 349,
TEX_ARRAYSHADOW2D = 350,
VERTEX = 351,
VTXATTRIB = 352,
WEIGHT = 353,
IDENTIFIER = 354,
USED_IDENTIFIER = 355,
MASK4 = 356,
MASK3 = 357,
MASK2 = 358,
MASK1 = 359,
SWIZZLE = 360,
DOT_DOT = 361,
DOT = 362
};
#endif
@@ -152,7 +154,7 @@ typedef union YYSTYPE
{
/* Line 1676 of yacc.c */
#line 107 "program_parse.y"
#line 116 "program_parse.y"
struct asm_instruction *inst;
struct asm_symbol *sym;
@@ -181,7 +183,7 @@ typedef union YYSTYPE
/* Line 1676 of yacc.c */
#line 185 "program_parse.tab.h"
#line 187 "program_parse.tab.h"
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */

View File

@@ -68,10 +68,19 @@ static void init_dst_reg(struct prog_dst_register *r);
static void init_src_reg(struct asm_src_register *r);
static void asm_instruction_set_operands(struct asm_instruction *inst,
const struct prog_dst_register *dst, const struct asm_src_register *src0,
const struct asm_src_register *src1, const struct asm_src_register *src2);
static struct asm_instruction *asm_instruction_ctor(gl_inst_opcode op,
const struct prog_dst_register *dst, const struct asm_src_register *src0,
const struct asm_src_register *src1, const struct asm_src_register *src2);
static struct asm_instruction *asm_instruction_copy_ctor(
const struct prog_instruction *base, const struct prog_dst_register *dst,
const struct asm_src_register *src0, const struct asm_src_register *src1,
const struct asm_src_register *src2);
#ifndef FALSE
#define FALSE 0
#define TRUE (!FALSE)
@@ -142,7 +151,7 @@ static struct asm_instruction *asm_instruction_ctor(gl_inst_opcode op,
/* Tokens for instructions */
%token <temp_inst> BIN_OP BINSC_OP SAMPLE_OP SCALAR_OP TRI_OP VECTOR_OP
%token <temp_inst> ARL KIL SWZ
%token <temp_inst> ARL KIL SWZ TXD_OP
%token <integer> INTEGER
%token <real> REAL
@@ -169,7 +178,8 @@ static struct asm_instruction *asm_instruction_ctor(gl_inst_opcode op,
%token VERTEX VTXATTRIB
%token WEIGHT
%token <string> IDENTIFIER
%token <string> IDENTIFIER USED_IDENTIFIER
%type <string> string
%token <swiz_mask> MASK4 MASK3 MASK2 MASK1 SWIZZLE
%token DOT_DOT
%token DOT
@@ -177,11 +187,11 @@ static struct asm_instruction *asm_instruction_ctor(gl_inst_opcode op,
%type <inst> instruction ALU_instruction TexInstruction
%type <inst> ARL_instruction VECTORop_instruction
%type <inst> SCALARop_instruction BINSCop_instruction BINop_instruction
%type <inst> TRIop_instruction SWZ_instruction SAMPLE_instruction
%type <inst> TRIop_instruction TXD_instruction SWZ_instruction SAMPLE_instruction
%type <inst> KIL_instruction
%type <dst_reg> dstReg maskedDstReg maskedAddrReg
%type <src_reg> srcReg scalarSrcReg swizzleSrcReg
%type <src_reg> srcReg scalarUse scalarSrcReg swizzleSrcReg
%type <swiz_mask> scalarSuffix swizzleSuffix extendedSwizzle
%type <ext_swizzle> extSwizComp extSwizSel
%type <swiz_mask> optionalMask
@@ -192,6 +202,8 @@ static struct asm_instruction *asm_instruction_ctor(gl_inst_opcode op,
%type <sym> addrReg
%type <swiz_mask> addrComponent addrWriteMask
%type <dst_reg> ccMaskRule ccTest ccMaskRule2 ccTest2 optionalCcMask
%type <result> resultBinding resultColBinding
%type <integer> optFaceType optColorType
%type <integer> optResultFaceType optResultColorType
@@ -280,7 +292,7 @@ optionSequence: optionSequence option
|
;
option: OPTION IDENTIFIER ';'
option: OPTION string ';'
{
int valid = 0;
@@ -347,6 +359,7 @@ ALU_instruction: ARL_instruction
TexInstruction: SAMPLE_instruction
| KIL_instruction
| TXD_instruction
;
ARL_instruction: ARL maskedAddrReg ',' scalarSrcReg
@@ -357,51 +370,45 @@ ARL_instruction: ARL maskedAddrReg ',' scalarSrcReg
VECTORop_instruction: VECTOR_OP maskedDstReg ',' swizzleSrcReg
{
$$ = asm_instruction_ctor($1.Opcode, & $2, & $4, NULL, NULL);
$$->Base.SaturateMode = $1.SaturateMode;
$$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL);
}
;
SCALARop_instruction: SCALAR_OP maskedDstReg ',' scalarSrcReg
{
$$ = asm_instruction_ctor($1.Opcode, & $2, & $4, NULL, NULL);
$$->Base.SaturateMode = $1.SaturateMode;
$$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL);
}
;
BINSCop_instruction: BINSC_OP maskedDstReg ',' scalarSrcReg ',' scalarSrcReg
{
$$ = asm_instruction_ctor($1.Opcode, & $2, & $4, & $6, NULL);
$$->Base.SaturateMode = $1.SaturateMode;
$$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, NULL);
}
;
BINop_instruction: BIN_OP maskedDstReg ',' swizzleSrcReg ',' swizzleSrcReg
{
$$ = asm_instruction_ctor($1.Opcode, & $2, & $4, & $6, NULL);
$$->Base.SaturateMode = $1.SaturateMode;
$$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, NULL);
}
;
TRIop_instruction: TRI_OP maskedDstReg ','
swizzleSrcReg ',' swizzleSrcReg ',' swizzleSrcReg
{
$$ = asm_instruction_ctor($1.Opcode, & $2, & $4, & $6, & $8);
$$->Base.SaturateMode = $1.SaturateMode;
$$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, & $8);
}
;
SAMPLE_instruction: SAMPLE_OP maskedDstReg ',' swizzleSrcReg ',' texImageUnit ',' texTarget
{
$$ = asm_instruction_ctor($1.Opcode, & $2, & $4, NULL, NULL);
$$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL);
if ($$ != NULL) {
const GLbitfield tex_mask = (1U << $6);
GLbitfield shadow_tex = 0;
GLbitfield target_mask = 0;
$$->Base.SaturateMode = $1.SaturateMode;
$$->Base.TexSrcUnit = $6;
if ($8 < 0) {
@@ -442,6 +449,58 @@ KIL_instruction: KIL swizzleSrcReg
$$ = asm_instruction_ctor(OPCODE_KIL, NULL, & $2, NULL, NULL);
state->fragment.UsesKill = 1;
}
| KIL ccTest
{
$$ = asm_instruction_ctor(OPCODE_KIL_NV, NULL, NULL, NULL, NULL);
$$->Base.DstReg.CondMask = $2.CondMask;
$$->Base.DstReg.CondSwizzle = $2.CondSwizzle;
$$->Base.DstReg.CondSrc = $2.CondSrc;
state->fragment.UsesKill = 1;
}
;
TXD_instruction: TXD_OP maskedDstReg ',' swizzleSrcReg ',' swizzleSrcReg ',' swizzleSrcReg ',' texImageUnit ',' texTarget
{
$$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, & $8);
if ($$ != NULL) {
const GLbitfield tex_mask = (1U << $10);
GLbitfield shadow_tex = 0;
GLbitfield target_mask = 0;
$$->Base.TexSrcUnit = $10;
if ($12 < 0) {
shadow_tex = tex_mask;
$$->Base.TexSrcTarget = -$12;
$$->Base.TexShadow = 1;
} else {
$$->Base.TexSrcTarget = $12;
}
target_mask = (1U << $$->Base.TexSrcTarget);
/* If this texture unit was previously accessed and that access
* had a different texture target, generate an error.
*
* If this texture unit was previously accessed and that access
* had a different shadow mode, generate an error.
*/
if ((state->prog->TexturesUsed[$10] != 0)
&& ((state->prog->TexturesUsed[$10] != target_mask)
|| ((state->prog->ShadowSamplers & tex_mask)
!= shadow_tex))) {
yyerror(& @12, state,
"multiple targets used on one texture image unit");
YYERROR;
}
state->prog->TexturesUsed[$10] |= target_mask;
state->prog->ShadowSamplers |= shadow_tex;
}
}
;
texImageUnit: TEXTURE_UNIT optTexImageUnitNum
@@ -472,21 +531,58 @@ SWZ_instruction: SWZ maskedDstReg ',' srcReg ',' extendedSwizzle
$4.Base.Swizzle = $6.swizzle;
$4.Base.Negate = $6.mask;
$$ = asm_instruction_ctor(OPCODE_SWZ, & $2, & $4, NULL, NULL);
$$->Base.SaturateMode = $1.SaturateMode;
$$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL);
}
;
scalarSrcReg: optionalSign srcReg scalarSuffix
scalarSrcReg: optionalSign scalarUse
{
$$ = $2;
if ($1) {
$$.Base.Negate = ~$$.Base.Negate;
}
}
| optionalSign '|' scalarUse '|'
{
$$ = $3;
if (!state->option.NV_fragment) {
yyerror(& @2, state, "unexpected character '|'");
YYERROR;
}
if ($1) {
$$.Base.Negate = ~$$.Base.Negate;
}
$$.Base.Abs = 1;
}
;
scalarUse: srcReg scalarSuffix
{
$$ = $1;
$$.Base.Swizzle = _mesa_combine_swizzles($$.Base.Swizzle,
$3.swizzle);
$2.swizzle);
}
| paramConstScalarUse
{
struct asm_symbol temp_sym;
if (!state->option.NV_fragment) {
yyerror(& @1, state, "expected scalar suffix");
YYERROR;
}
memset(& temp_sym, 0, sizeof(temp_sym));
temp_sym.param_binding_begin = ~0;
initialize_symbol_from_const(state->prog, & temp_sym, & $1);
init_src_reg(& $$);
$$.Base.File = PROGRAM_CONSTANT;
$$.Base.Index = temp_sym.param_binding_begin;
}
;
@@ -501,12 +597,33 @@ swizzleSrcReg: optionalSign srcReg swizzleSuffix
$$.Base.Swizzle = _mesa_combine_swizzles($$.Base.Swizzle,
$3.swizzle);
}
| optionalSign '|' srcReg swizzleSuffix '|'
{
$$ = $3;
if (!state->option.NV_fragment) {
yyerror(& @2, state, "unexpected character '|'");
YYERROR;
}
if ($1) {
$$.Base.Negate = ~$$.Base.Negate;
}
$$.Base.Abs = 1;
$$.Base.Swizzle = _mesa_combine_swizzles($$.Base.Swizzle,
$4.swizzle);
}
;
maskedDstReg: dstReg optionalMask
maskedDstReg: dstReg optionalMask optionalCcMask
{
$$ = $1;
$$.WriteMask = $2.mask;
$$.CondMask = $3.CondMask;
$$.CondSwizzle = $3.CondSwizzle;
$$.CondSrc = $3.CondSrc;
if ($$.File == PROGRAM_OUTPUT) {
/* Technically speaking, this should check that it is in
@@ -589,7 +706,7 @@ extSwizSel: INTEGER
$$.xyzw_valid = 1;
$$.rgba_valid = 1;
}
| IDENTIFIER
| string
{
if (strlen($1) > 1) {
yyerror(& @1, state, "invalid extended swizzle selector");
@@ -639,7 +756,7 @@ extSwizSel: INTEGER
}
;
srcReg: IDENTIFIER /* temporaryReg | progParamSingle */
srcReg: USED_IDENTIFIER /* temporaryReg | progParamSingle */
{
struct asm_symbol *const s = (struct asm_symbol *)
_mesa_symbol_table_find_symbol(state->st, 0, $1);
@@ -729,7 +846,7 @@ dstReg: resultBinding
$$.File = PROGRAM_OUTPUT;
$$.Index = $1;
}
| IDENTIFIER /* temporaryReg | vertexResultReg */
| USED_IDENTIFIER /* temporaryReg | vertexResultReg */
{
struct asm_symbol *const s = (struct asm_symbol *)
_mesa_symbol_table_find_symbol(state->st, 0, $1);
@@ -760,7 +877,7 @@ dstReg: resultBinding
}
;
progParamArray: IDENTIFIER
progParamArray: USED_IDENTIFIER
{
struct asm_symbol *const s = (struct asm_symbol *)
_mesa_symbol_table_find_symbol(state->st, 0, $1);
@@ -831,7 +948,7 @@ addrRegNegOffset: INTEGER
}
;
addrReg: IDENTIFIER
addrReg: USED_IDENTIFIER
{
struct asm_symbol *const s = (struct asm_symbol *)
_mesa_symbol_table_find_symbol(state->st, 0, $1);
@@ -884,6 +1001,82 @@ optionalMask: MASK4 | MASK3 | MASK2 | MASK1
| { $$.swizzle = SWIZZLE_NOOP; $$.mask = WRITEMASK_XYZW; }
;
optionalCcMask: '(' ccTest ')'
{
$$ = $2;
}
| '(' ccTest2 ')'
{
$$ = $2;
}
|
{
$$.CondMask = COND_TR;
$$.CondSwizzle = SWIZZLE_NOOP;
$$.CondSrc = 0;
}
;
ccTest: ccMaskRule swizzleSuffix
{
$$ = $1;
$$.CondSwizzle = $2.swizzle;
}
;
ccTest2: ccMaskRule2 swizzleSuffix
{
$$ = $1;
$$.CondSwizzle = $2.swizzle;
}
;
ccMaskRule: IDENTIFIER
{
const int cond = _mesa_parse_cc($1);
if ((cond == 0) || ($1[2] != '\0')) {
char *const err_str =
make_error_string("invalid condition code \"%s\"", $1);
yyerror(& @1, state, (err_str != NULL)
? err_str : "invalid condition code");
if (err_str != NULL) {
_mesa_free(err_str);
}
YYERROR;
}
$$.CondMask = cond;
$$.CondSwizzle = SWIZZLE_NOOP;
$$.CondSrc = 0;
}
;
ccMaskRule2: USED_IDENTIFIER
{
const int cond = _mesa_parse_cc($1);
if ((cond == 0) || ($1[2] != '\0')) {
char *const err_str =
make_error_string("invalid condition code \"%s\"", $1);
yyerror(& @1, state, (err_str != NULL)
? err_str : "invalid condition code");
if (err_str != NULL) {
_mesa_free(err_str);
}
YYERROR;
}
$$.CondMask = cond;
$$.CondSwizzle = SWIZZLE_NOOP;
$$.CondSrc = 0;
}
;
namingStatement: ATTRIB_statement
| PARAM_statement
| TEMP_statement
@@ -1712,7 +1905,46 @@ optionalSign: '+' { $$ = FALSE; }
| { $$ = FALSE; }
;
TEMP_statement: TEMP { $<integer>$ = $1; } varNameList
TEMP_statement: optVarSize TEMP { $<integer>$ = $2; } varNameList
;
optVarSize: string
{
/* NV_fragment_program_option defines the size qualifiers in a
* fairly broken way. "SHORT" or "LONG" can optionally be used
* before TEMP or OUTPUT. However, neither is a reserved word!
* This means that we have to parse it as an identifier, then check
* to make sure it's one of the valid values. *sigh*
*
* In addition, the grammar in the extension spec does *not* allow
* the size specifier to be optional, but all known implementations
* do.
*/
if (!state->option.NV_fragment) {
yyerror(& @1, state, "unexpected IDENTIFIER");
YYERROR;
}
if (strcmp("SHORT", $1) == 0) {
} else if (strcmp("LONG", $1) == 0) {
} else {
char *const err_str =
make_error_string("invalid storage size specifier \"%s\"",
$1);
yyerror(& @1, state, (err_str != NULL)
? err_str : "invalid storage size specifier");
if (err_str != NULL) {
_mesa_free(err_str);
}
YYERROR;
}
}
|
{
}
;
ADDRESS_statement: ADDRESS { $<integer>$ = $1; } varNameList
@@ -1732,15 +1964,15 @@ varNameList: varNameList ',' IDENTIFIER
}
;
OUTPUT_statement: OUTPUT IDENTIFIER '=' resultBinding
OUTPUT_statement: optVarSize OUTPUT IDENTIFIER '=' resultBinding
{
struct asm_symbol *const s =
declare_variable(state, $2, at_output, & @2);
declare_variable(state, $3, at_output, & @3);
if (s == NULL) {
YYERROR;
} else {
s->output_binding = $4;
s->output_binding = $5;
}
}
;
@@ -1907,7 +2139,7 @@ legacyTexUnitNum: INTEGER
}
;
ALIAS_statement: ALIAS IDENTIFIER '=' IDENTIFIER
ALIAS_statement: ALIAS IDENTIFIER '=' USED_IDENTIFIER
{
struct asm_symbol *exist = (struct asm_symbol *)
_mesa_symbol_table_find_symbol(state->st, 0, $2);
@@ -1928,8 +2160,54 @@ ALIAS_statement: ALIAS IDENTIFIER '=' IDENTIFIER
}
;
string: IDENTIFIER
| USED_IDENTIFIER
;
%%
void
asm_instruction_set_operands(struct asm_instruction *inst,
const struct prog_dst_register *dst,
const struct asm_src_register *src0,
const struct asm_src_register *src1,
const struct asm_src_register *src2)
{
/* In the core ARB extensions only the KIL instruction doesn't have a
* destination register.
*/
if (dst == NULL) {
init_dst_reg(& inst->Base.DstReg);
} else {
inst->Base.DstReg = *dst;
}
/* The only instruction that doesn't have any source registers is the
* condition-code based KIL instruction added by NV_fragment_program_option.
*/
if (src0 != NULL) {
inst->Base.SrcReg[0] = src0->Base;
inst->SrcReg[0] = *src0;
} else {
init_src_reg(& inst->SrcReg[0]);
}
if (src1 != NULL) {
inst->Base.SrcReg[1] = src1->Base;
inst->SrcReg[1] = *src1;
} else {
init_src_reg(& inst->SrcReg[1]);
}
if (src2 != NULL) {
inst->Base.SrcReg[2] = src2->Base;
inst->SrcReg[2] = *src2;
} else {
init_src_reg(& inst->SrcReg[2]);
}
}
struct asm_instruction *
asm_instruction_ctor(gl_inst_opcode op,
const struct prog_dst_register *dst,
@@ -1937,37 +2215,37 @@ asm_instruction_ctor(gl_inst_opcode op,
const struct asm_src_register *src1,
const struct asm_src_register *src2)
{
struct asm_instruction *inst = calloc(1, sizeof(struct asm_instruction));
struct asm_instruction *inst = CALLOC_STRUCT(asm_instruction);
if (inst) {
_mesa_init_instructions(& inst->Base, 1);
inst->Base.Opcode = op;
/* In the core ARB extensions only the KIL instruction doesn't have a
* destination register.
*/
if (dst == NULL) {
init_dst_reg(& inst->Base.DstReg);
} else {
inst->Base.DstReg = *dst;
}
asm_instruction_set_operands(inst, dst, src0, src1, src2);
}
inst->Base.SrcReg[0] = src0->Base;
inst->SrcReg[0] = *src0;
return inst;
}
if (src1 != NULL) {
inst->Base.SrcReg[1] = src1->Base;
inst->SrcReg[1] = *src1;
} else {
init_src_reg(& inst->SrcReg[1]);
}
if (src2 != NULL) {
inst->Base.SrcReg[2] = src2->Base;
inst->SrcReg[2] = *src2;
} else {
init_src_reg(& inst->SrcReg[2]);
}
struct asm_instruction *
asm_instruction_copy_ctor(const struct prog_instruction *base,
const struct prog_dst_register *dst,
const struct asm_src_register *src0,
const struct asm_src_register *src1,
const struct asm_src_register *src2)
{
struct asm_instruction *inst = CALLOC_STRUCT(asm_instruction);
if (inst) {
_mesa_init_instructions(& inst->Base, 1);
inst->Base.Opcode = base->Opcode;
inst->Base.CondUpdate = base->CondUpdate;
inst->Base.CondDst = base->CondDst;
inst->Base.SaturateMode = base->SaturateMode;
inst->Base.Precision = base->Precision;
asm_instruction_set_operands(inst, dst, src0, src1, src2);
}
return inst;

View File

@@ -33,6 +33,121 @@
* \author Ian Romanick <ian.d.romanick@intel.com>
*/
int
_mesa_parse_instruction_suffix(const struct asm_parser_state *state,
const char *suffix,
struct prog_instruction *inst)
{
inst->CondUpdate = 0;
inst->CondDst = 0;
inst->SaturateMode = SATURATE_OFF;
inst->Precision = FLOAT32;
/* The first possible suffix element is the precision specifier from
* NV_fragment_program_option.
*/
if (state->option.NV_fragment) {
switch (suffix[0]) {
case 'H':
inst->Precision = FLOAT16;
suffix++;
break;
case 'R':
inst->Precision = FLOAT32;
suffix++;
break;
case 'X':
inst->Precision = FIXED12;
suffix++;
break;
default:
break;
}
}
/* The next possible suffix element is the condition code modifier selection
* from NV_fragment_program_option.
*/
if (state->option.NV_fragment) {
if (suffix[0] == 'C') {
inst->CondUpdate = 1;
suffix++;
}
}
/* The final possible suffix element is the saturation selector from
* ARB_fragment_program.
*/
if (state->mode == ARB_fragment) {
if (strcmp(suffix, "_SAT") == 0) {
inst->SaturateMode = SATURATE_ZERO_ONE;
suffix += 4;
}
}
/* It is an error for all of the suffix string not to be consumed.
*/
return suffix[0] == '\0';
}
int
_mesa_parse_cc(const char *s)
{
int cond = 0;
switch (s[0]) {
case 'E':
if (s[1] == 'Q') {
cond = COND_EQ;
}
break;
case 'F':
if (s[1] == 'L') {
cond = COND_FL;
}
break;
case 'G':
if (s[1] == 'E') {
cond = COND_GE;
} else if (s[1] == 'T') {
cond = COND_GT;
}
break;
case 'L':
if (s[1] == 'E') {
cond = COND_LE;
} else if (s[1] == 'T') {
cond = COND_LT;
}
break;
case 'N':
if (s[1] == 'E') {
cond = COND_NE;
}
break;
case 'T':
if (s[1] == 'R') {
cond = COND_TR;
}
break;
default:
break;
}
return ((cond == 0) || (s[2] != '\0')) ? 0 : cond;
}
int
_mesa_ARBvp_parse_option(struct asm_parser_state *state, const char *option)
{
@@ -102,6 +217,17 @@ _mesa_ARBfp_parse_option(struct asm_parser_state *state, const char *option)
return 1;
}
}
} else if (strncmp(option, "NV_fragment_program", 19) == 0) {
option += 19;
/* Other NV_fragment_program strings may be supported later.
*/
if (option[0] == '\0') {
if (state->ctx->Extensions.NV_fragment_program_option) {
state->option.NV_fragment = 1;
return 1;
}
}
} else if (strncmp(option, "MESA_", 5) == 0) {
option += 5;

View File

@@ -202,6 +202,7 @@ struct asm_parser_state {
unsigned Shadow:1;
unsigned TexRect:1;
unsigned TexArray:1;
unsigned NV_fragment:1;
} option;
struct {
@@ -263,4 +264,31 @@ extern int _mesa_ARBvp_parse_option(struct asm_parser_state *state,
extern int _mesa_ARBfp_parse_option(struct asm_parser_state *state,
const char *option);
/**
* Parses and processes instruction suffixes
*
* Instruction suffixes, such as \c _SAT, are processed. The relevant bits
* are set in \c inst. If suffixes are encountered that are either not known
* or not supported by the modes and options set in \c state, zero will be
* returned.
*
* \return
* Non-zero on success, zero on failure.
*/
extern int _mesa_parse_instruction_suffix(const struct asm_parser_state *state,
const char *suffix, struct prog_instruction *inst);
/**
* Parses a condition code name
*
* The condition code names (e.g., \c LT, \c GT, \c NE) were added to assembly
* shaders with the \c GL_NV_fragment_program_option extension. This function
* converts a string representation into one of the \c COND_ macros.
*
* \return
* One of the \c COND_ macros defined in prog_instruction.h on success or zero
* on failure.
*/
extern int _mesa_parse_cc(const char *s);
/*@}*/