Explorar o código

Syntax change to BSL: neater names & structure

BearishSun %!s(int64=8) %!d(string=hai) anos
pai
achega
6f672dcf21

+ 89 - 85
Source/BansheeSL/BsLexerFX.l

@@ -46,101 +46,109 @@ true			{ yylval->intValue = 1; return TOKEN_BOOLEAN; }
 false			{ yylval->intValue = 0; return TOKEN_BOOLEAN; }
 false			{ yylval->intValue = 0; return TOKEN_BOOLEAN; }
 
 
 	/* Shader keywords */
 	/* Shader keywords */
-Separable		{ return TOKEN_SEPARABLE; }
-Sort			{ return TOKEN_SORT; }
-Priority		{ return TOKEN_PRIORITY; }
-Transparent		{ return TOKEN_TRANSPARENT; }
-Technique		{ return TOKEN_TECHNIQUE; }
+options			{ return TOKEN_OPTIONS; }
+technique		{ return TOKEN_TECHNIQUE; }
+
+	/* Options keywords */
+separable		{ return TOKEN_SEPARABLE; }
+sort			{ return TOKEN_SORT; }
+priority		{ return TOKEN_PRIORITY; }
+transparent		{ return TOKEN_TRANSPARENT; }
 
 
 	/* Technique keywords */
 	/* Technique keywords */
-Renderer		{ return TOKEN_RENDERER; }
-Tags			{ return TOKEN_TAGS; }
-Pass			{ return TOKEN_PASS; }
+renderer		{ return TOKEN_RENDERER; }
+tags			{ return TOKEN_TAGS; }
+pass			{ return TOKEN_PASS; }
 
 
 	/* Pass keywords */
 	/* Pass keywords */
-StencilRef		{ return TOKEN_STENCILREF; }
+blend			{ return TOKEN_BLEND; }
+raster			{ return TOKEN_RASTER; }
+depth			{ return TOKEN_DEPTH; }
+stencil			{ return TOKEN_STENCIL; }
 
 
 	/* Rasterizer state keywords */
 	/* Rasterizer state keywords */
-Fill			{ return TOKEN_FILLMODE; }
-Cull			{ return TOKEN_CULLMODE; }
-DepthBias		{ return TOKEN_DEPTHBIAS; }
-ScaledDepthBias	{ return TOKEN_SDEPTHBIAS; }
-DepthClip		{ return TOKEN_DEPTHCLIP; }
-Scissor			{ return TOKEN_SCISSOR; }
-Multisample		{ return TOKEN_MULTISAMPLE; }
-AALine			{ return TOKEN_AALINE; }
-
-	/* Depth-stencil state keywords */
-DepthRead			{ return TOKEN_DEPTHREAD; }
-DepthWrite			{ return TOKEN_DEPTHWRITE; }
-CompareFunc			{ return TOKEN_COMPAREFUNC; }
-Stencil				{ return TOKEN_STENCIL; }
-StencilReadMask		{ return TOKEN_STENCILREADMASK; }
-StencilWriteMask	{ return TOKEN_STENCILWRITEMASK; }
-StencilOpFront		{ return TOKEN_STENCILOPFRONT; }
-StencilOpBack		{ return TOKEN_STENCILOPBACK; }
-Fail				{ return TOKEN_FAIL; }
-ZFail				{ return TOKEN_ZFAIL; }
+fill			{ return TOKEN_FILLMODE; }
+cull			{ return TOKEN_CULLMODE; }
+bias			{ return TOKEN_DEPTHBIAS; }
+scaledbias		{ return TOKEN_SDEPTHBIAS; }
+clip			{ return TOKEN_DEPTHCLIP; }
+scissor			{ return TOKEN_SCISSOR; }
+multisample		{ return TOKEN_MULTISAMPLE; }
+lineaa			{ return TOKEN_AALINE; }
+
+	/* Depth state keywords */
+read			{ return TOKEN_DEPTHREAD; }
+write			{ return TOKEN_DEPTHWRITE; }
+compare			{ return TOKEN_COMPAREFUNC; }
+
+	/* Stencil state keywords */
+reference			{ return TOKEN_STENCILREF; }
+enabled				{ return TOKEN_ENABLED; }
+readmask			{ return TOKEN_READMASK; }
+writemask			{ return TOKEN_WRITEMASK; }
+front				{ return TOKEN_STENCILOPFRONT; }
+back				{ return TOKEN_STENCILOPBACK; }
+fail				{ return TOKEN_FAIL; }
+zfail				{ return TOKEN_ZFAIL; }
 
 
 	/* Blend state keywords */
 	/* Blend state keywords */
-AlphaToCoverage		{ return TOKEN_ALPHATOCOVERAGE; }
-IndependantBlend	{ return TOKEN_INDEPENDANTBLEND; }
-Target				{ return TOKEN_TARGET; }
-Index				{ return TOKEN_INDEX; }
-Blend				{ return TOKEN_BLEND; }
-Color				{ return TOKEN_COLOR; }
-Alpha				{ return TOKEN_ALPHA; }
-WriteMask			{ return TOKEN_WRITEMASK; }
-Source				{ return TOKEN_SOURCE; }
-Dest				{ return TOKEN_DEST; }
-Op					{ return TOKEN_OP; }
+dither				{ return TOKEN_ALPHATOCOVERAGE; }
+independant			{ return TOKEN_INDEPENDANTBLEND; }
+target				{ return TOKEN_TARGET; }
+index				{ return TOKEN_INDEX; }
+color				{ return TOKEN_COLOR; }
+alpha				{ return TOKEN_ALPHA; }
+source				{ return TOKEN_SOURCE; }
+dest				{ return TOKEN_DEST; }
+op					{ return TOKEN_OP; }
 
 
 	/* Qualifiers */
 	/* Qualifiers */
 base				{ return TOKEN_BASE; }
 base				{ return TOKEN_BASE; }
 inherits			{ return TOKEN_INHERITS; }
 inherits			{ return TOKEN_INHERITS; }
 
 
 	/* State values */
 	/* State values */
-WIRE			{ yylval->intValue = FMV_Wire; return TOKEN_FILLMODEVALUE; }
-SOLID			{ yylval->intValue = FMV_Solid; return TOKEN_FILLMODEVALUE; }
-
-NOCULL			{ yylval->intValue = CMV_None; return TOKEN_CULLMODEVALUE; }
-CW				{ yylval->intValue = CMV_CW; return TOKEN_CULLMODEVALUE; }
-CCW				{ yylval->intValue = CMV_CCW; return TOKEN_CULLMODEVALUE; }
-
-FAIL			{ yylval->intValue = CFV_Fail; return TOKEN_COMPFUNCVALUE; }
-PASS			{ yylval->intValue = CFV_Pass; return TOKEN_COMPFUNCVALUE; }
-LT				{ yylval->intValue = CFV_LT; return TOKEN_COMPFUNCVALUE; }
-LTE				{ yylval->intValue = CFV_LTE; return TOKEN_COMPFUNCVALUE; }
-EQ				{ yylval->intValue = CFV_EQ; return TOKEN_COMPFUNCVALUE; }
-NEQ				{ yylval->intValue = CFV_NEQ; return TOKEN_COMPFUNCVALUE; }
-GTE				{ yylval->intValue = CFV_GTE; return TOKEN_COMPFUNCVALUE; }
-GT				{ yylval->intValue = CFV_GT; return TOKEN_COMPFUNCVALUE; }
-
-KEEP				{ yylval->intValue = OV_Keep; return TOKEN_OPVALUE; }
-ZERO				{ yylval->intValue = OV_Zero; return TOKEN_OPVALUE; }
-REPLACE				{ yylval->intValue = OV_Replace; return TOKEN_OPVALUE; }
-INC					{ yylval->intValue = OV_Incr; return TOKEN_OPVALUE; }
-DEC					{ yylval->intValue = OV_Decr; return TOKEN_OPVALUE; }
-INCWRAP				{ yylval->intValue = OV_IncrWrap; return TOKEN_OPVALUE; }
-DECWRAP				{ yylval->intValue = OV_DecrWrap; return TOKEN_OPVALUE; }
-INV					{ yylval->intValue = OV_Invert; return TOKEN_OPVALUE; }
-ONE					{ yylval->intValue = OV_One; return TOKEN_OPVALUE; }
-DSTRGB				{ yylval->intValue = OV_DestColor; return TOKEN_OPVALUE; }
-SRCRGB				{ yylval->intValue = OV_SrcColor; return TOKEN_OPVALUE; }
-DSTIRGB				{ yylval->intValue = OV_InvDestColor; return TOKEN_OPVALUE; }
-SRCIRGB				{ yylval->intValue = OV_InvSrcColor; return TOKEN_OPVALUE; }
-DSTA				{ yylval->intValue = OV_DestAlpha; return TOKEN_OPVALUE; }
-SRCA				{ yylval->intValue = OV_SrcAlpha; return TOKEN_OPVALUE; }
-DSTIA				{ yylval->intValue = OV_InvDestAlpha; return TOKEN_OPVALUE; }
-SRCIA				{ yylval->intValue = OV_InvSrcAlpha; return TOKEN_OPVALUE; }
-
-ADD					{ yylval->intValue = BOV_Add; return TOKEN_BLENDOPVALUE; }
-SUB					{ yylval->intValue = BOV_Subtract; return TOKEN_BLENDOPVALUE; }
-RSUB				{ yylval->intValue = BOV_RevSubtract; return TOKEN_BLENDOPVALUE; }
-MIN					{ yylval->intValue = BOV_Min; return TOKEN_BLENDOPVALUE; }
-MAX					{ yylval->intValue = BOV_Max; return TOKEN_BLENDOPVALUE; }
-
-NOCOLOR			{ yylval->intValue = 0x0; return TOKEN_COLORMASK; }
+wire			{ yylval->intValue = FMV_Wire; return TOKEN_FILLMODEVALUE; }
+solid			{ yylval->intValue = FMV_Solid; return TOKEN_FILLMODEVALUE; }
+
+none			{ yylval->intValue = CASV_None; return TOKEN_CULLANDQUEUEVALUE; }
+cw				{ yylval->intValue = CASV_CW; return TOKEN_CULLANDQUEUEVALUE; }
+ccw				{ yylval->intValue = CASV_CCW; return TOKEN_CULLANDQUEUEVALUE; }
+fronttoback		{ yylval->intValue = CASV_FrontToBack; return TOKEN_CULLANDQUEUEVALUE; }
+backtofront		{ yylval->intValue = CASV_BackToFront; return TOKEN_CULLANDQUEUEVALUE; }
+
+never			{ yylval->intValue = CFV_Fail; return TOKEN_COMPFUNCVALUE; }
+always			{ yylval->intValue = CFV_Pass; return TOKEN_COMPFUNCVALUE; }
+lt				{ yylval->intValue = CFV_LT; return TOKEN_COMPFUNCVALUE; }
+lte				{ yylval->intValue = CFV_LTE; return TOKEN_COMPFUNCVALUE; }
+eq				{ yylval->intValue = CFV_EQ; return TOKEN_COMPFUNCVALUE; }
+neq				{ yylval->intValue = CFV_NEQ; return TOKEN_COMPFUNCVALUE; }
+gte				{ yylval->intValue = CFV_GTE; return TOKEN_COMPFUNCVALUE; }
+gt				{ yylval->intValue = CFV_GT; return TOKEN_COMPFUNCVALUE; }
+
+keep			{ yylval->intValue = OV_Keep; return TOKEN_OPVALUE; }
+zero			{ yylval->intValue = OV_Zero; return TOKEN_OPVALUE; }
+replace			{ yylval->intValue = OV_Replace; return TOKEN_OPVALUE; }
+inc				{ yylval->intValue = OV_Incr; return TOKEN_OPVALUE; }
+dec				{ yylval->intValue = OV_Decr; return TOKEN_OPVALUE; }
+incwrap			{ yylval->intValue = OV_IncrWrap; return TOKEN_OPVALUE; }
+decwrap			{ yylval->intValue = OV_DecrWrap; return TOKEN_OPVALUE; }
+inverse			{ yylval->intValue = OV_Invert; return TOKEN_OPVALUE; }
+one				{ yylval->intValue = OV_One; return TOKEN_OPVALUE; }
+dstRGB			{ yylval->intValue = OV_DestColor; return TOKEN_OPVALUE; }
+srcRGB			{ yylval->intValue = OV_SrcColor; return TOKEN_OPVALUE; }
+dstiRGB			{ yylval->intValue = OV_InvDestColor; return TOKEN_OPVALUE; }
+srciRGB			{ yylval->intValue = OV_InvSrcColor; return TOKEN_OPVALUE; }
+dstA			{ yylval->intValue = OV_DestAlpha; return TOKEN_OPVALUE; }
+srcA			{ yylval->intValue = OV_SrcAlpha; return TOKEN_OPVALUE; }
+dstIA			{ yylval->intValue = OV_InvDestAlpha; return TOKEN_OPVALUE; }
+srcIA			{ yylval->intValue = OV_InvSrcAlpha; return TOKEN_OPVALUE; }
+
+add				{ yylval->intValue = BOV_Add; return TOKEN_BLENDOPVALUE; }
+sub				{ yylval->intValue = BOV_Subtract; return TOKEN_BLENDOPVALUE; }
+rsub			{ yylval->intValue = BOV_RevSubtract; return TOKEN_BLENDOPVALUE; }
+min				{ yylval->intValue = BOV_Min; return TOKEN_BLENDOPVALUE; }
+max				{ yylval->intValue = BOV_Max; return TOKEN_BLENDOPVALUE; }
+
 R				{ yylval->intValue = 0x1; return TOKEN_COLORMASK; }
 R				{ yylval->intValue = 0x1; return TOKEN_COLORMASK; }
 G				{ yylval->intValue = 0x2; return TOKEN_COLORMASK; }
 G				{ yylval->intValue = 0x2; return TOKEN_COLORMASK; }
 B				{ yylval->intValue = 0x4; return TOKEN_COLORMASK; }
 B				{ yylval->intValue = 0x4; return TOKEN_COLORMASK; }
@@ -157,10 +165,6 @@ RBA				{ yylval->intValue = 0xD; return TOKEN_COLORMASK; }
 GBA				{ yylval->intValue = 0xE; return TOKEN_COLORMASK; }
 GBA				{ yylval->intValue = 0xE; return TOKEN_COLORMASK; }
 RGBA			{ yylval->intValue = 0xF; return TOKEN_COLORMASK; }
 RGBA			{ yylval->intValue = 0xF; return TOKEN_COLORMASK; }
 
 
-FRONTTOBACK		{ yylval->intValue = QST_FrontToBack; return TOKEN_QUEUETYPE; }
-BACKTOFRONT		{ yylval->intValue = QST_BackToFront; return TOKEN_QUEUETYPE; }
-NOSORT			{ yylval->intValue = QST_None; return TOKEN_QUEUETYPE; }
-
 	/* Preprocessor */
 	/* Preprocessor */
 #include				{ BEGIN(INCLUDE); }
 #include				{ BEGIN(INCLUDE); }
 
 

+ 174 - 44
Source/BansheeSL/BsParserFX.y

@@ -72,42 +72,51 @@ typedef struct YYLTYPE {
 %token <strValue>	TOKEN_STRING
 %token <strValue>	TOKEN_STRING
 %token <strValue>	TOKEN_IDENTIFIER
 %token <strValue>	TOKEN_IDENTIFIER
 
 
+	/* State value types */
 %token <intValue>	TOKEN_FILLMODEVALUE
 %token <intValue>	TOKEN_FILLMODEVALUE
-%token <intValue>	TOKEN_CULLMODEVALUE
+%token <intValue>	TOKEN_CULLANDQUEUEVALUE
 %token <intValue>	TOKEN_COMPFUNCVALUE
 %token <intValue>	TOKEN_COMPFUNCVALUE
 %token <intValue>	TOKEN_OPVALUE
 %token <intValue>	TOKEN_OPVALUE
-%token <intValue>	TOKEN_COLORMASK
 %token <intValue>	TOKEN_BLENDOPVALUE
 %token <intValue>	TOKEN_BLENDOPVALUE
-%token <intValue>	TOKEN_QUEUETYPE
+%token <intValue>	TOKEN_COLORMASK
 
 
 	/* Qualifiers */
 	/* Qualifiers */
 %token TOKEN_BASE TOKEN_INHERITS
 %token TOKEN_BASE TOKEN_INHERITS
 
 
 	/* Shader keywords */
 	/* Shader keywords */
-%token TOKEN_SEPARABLE TOKEN_SORT TOKEN_PRIORITY TOKEN_TRANSPARENT
-%token TOKEN_TECHNIQUE
+%token TOKEN_OPTIONS TOKEN_TECHNIQUE
 
 
+	/* Options keywords */
+%token TOKEN_SEPARABLE TOKEN_SORT TOKEN_PRIORITY TOKEN_TRANSPARENT
+	
 	/* Technique keywords */
 	/* Technique keywords */
-%token	TOKEN_RENDERER TOKEN_PASS TOKEN_TAGS
+%token TOKEN_RENDERER TOKEN_PASS TOKEN_TAGS
 
 
 	/* Pass keywords */
 	/* Pass keywords */
-%token	TOKEN_VERTEX TOKEN_FRAGMENT TOKEN_GEOMETRY TOKEN_HULL TOKEN_DOMAIN TOKEN_COMPUTE TOKEN_COMMON
-%token	TOKEN_STENCILREF
+%token TOKEN_VERTEX TOKEN_FRAGMENT TOKEN_GEOMETRY TOKEN_HULL TOKEN_DOMAIN TOKEN_COMPUTE TOKEN_COMMON
+%token TOKEN_BLEND TOKEN_RASTER TOKEN_DEPTH TOKEN_STENCIL
 
 
+	/* Rasterizer state keywords */
 %token	TOKEN_FILLMODE TOKEN_CULLMODE TOKEN_DEPTHBIAS TOKEN_SDEPTHBIAS
 %token	TOKEN_FILLMODE TOKEN_CULLMODE TOKEN_DEPTHBIAS TOKEN_SDEPTHBIAS
 %token	TOKEN_DEPTHCLIP TOKEN_SCISSOR TOKEN_MULTISAMPLE TOKEN_AALINE
 %token	TOKEN_DEPTHCLIP TOKEN_SCISSOR TOKEN_MULTISAMPLE TOKEN_AALINE
 
 
-%token	TOKEN_DEPTHREAD TOKEN_DEPTHWRITE TOKEN_COMPAREFUNC TOKEN_STENCIL
-%token	TOKEN_STENCILREADMASK TOKEN_STENCILWRITEMASK TOKEN_STENCILOPFRONT TOKEN_STENCILOPBACK
-%token	TOKEN_FAIL TOKEN_ZFAIL
+	/* Depth state keywords */
+%token	TOKEN_DEPTHREAD TOKEN_DEPTHWRITE TOKEN_COMPAREFUNC
 
 
+	/* Stencil state keywords */
+%token TOKEN_STENCILREF TOKEN_ENABLED TOKEN_READMASK TOKEN_WRITEMASK 
+%token TOKEN_STENCILOPFRONT TOKEN_STENCILOPBACK TOKEN_FAIL TOKEN_ZFAIL
+
+	/* Blend state keywords */
 %token	TOKEN_ALPHATOCOVERAGE TOKEN_INDEPENDANTBLEND TOKEN_TARGET TOKEN_INDEX
 %token	TOKEN_ALPHATOCOVERAGE TOKEN_INDEPENDANTBLEND TOKEN_TARGET TOKEN_INDEX
-%token	TOKEN_BLEND TOKEN_COLOR TOKEN_ALPHA TOKEN_WRITEMASK
-%token	TOKEN_SOURCE TOKEN_DEST TOKEN_OP
+%token	TOKEN_COLOR TOKEN_ALPHA TOKEN_SOURCE TOKEN_DEST TOKEN_OP
 
 
 %type <nodePtr>		shader;
 %type <nodePtr>		shader;
 %type <nodeOption>	shader_statement;
 %type <nodeOption>	shader_statement;
-%type <nodeOption>	shader_option;
+
+%type <nodePtr>		options;
+%type <nodePtr>		options_header;
+%type <nodeOption>	options_option;
 
 
 %type <nodePtr>		technique;
 %type <nodePtr>		technique;
 %type <nodePtr>		technique_header;
 %type <nodePtr>		technique_header;
@@ -121,6 +130,22 @@ typedef struct YYLTYPE {
 %type <nodeOption>	pass_statement;
 %type <nodeOption>	pass_statement;
 %type <nodeOption>	pass_option;
 %type <nodeOption>	pass_option;
 
 
+%type <nodePtr>		raster;
+%type <nodePtr>		raster_header;
+%type <nodeOption>	raster_option;
+
+%type <nodePtr>		depth;
+%type <nodePtr>		depth_header;
+%type <nodeOption>	depth_option;
+
+%type <nodePtr>		stencil;
+%type <nodePtr>		stencil_header;
+%type <nodeOption>	stencil_option;
+
+%type <nodePtr>		blend;
+%type <nodePtr>		blend_header;
+%type <nodeOption>	blend_option;
+
 %type <nodePtr>		code;
 %type <nodePtr>		code;
 %type <nodePtr>		code_header;
 %type <nodePtr>		code_header;
 
 
@@ -149,21 +174,39 @@ shader
 	;
 	;
 
 
 shader_statement
 shader_statement
-	: shader_option
+	: options			{ $$.type = OT_Options; $$.value.nodePtr = $1; }
 	| technique			{ $$.type = OT_Technique; $$.value.nodePtr = $1; }
 	| technique			{ $$.type = OT_Technique; $$.value.nodePtr = $1; }
 	;
 	;
 
 
-shader_option
-	: TOKEN_SEPARABLE '=' TOKEN_BOOLEAN ';'		{ $$.type = OT_Separable; $$.value.intValue = $3; }
-	| TOKEN_SORT '=' TOKEN_QUEUETYPE ';'		{ $$.type = OT_Sort; $$.value.intValue = $3; }
-	| TOKEN_PRIORITY '=' TOKEN_INTEGER ';'		{ $$.type = OT_Priority; $$.value.intValue = $3; }
-	| TOKEN_TRANSPARENT '=' TOKEN_BOOLEAN ';'	{ $$.type = OT_Transparent; $$.value.intValue = $3; }
+	/* Options */
+options
+	: options_header '{' options_body '}' ';' { nodePop(parse_state); $$ = $1; }
+	;
+
+options_header
+	: TOKEN_OPTIONS
+		{ 
+			$$ = nodeCreate(parse_state->memContext, NT_Options); 
+			nodePush(parse_state, $$);
+		}
+	;	
+	
+options_body
+	: /* empty */
+	| options_option options_body		{ nodeOptionsAdd(parse_state->memContext, parse_state->topNode->options, &$1); }
+	;
+	
+options_option
+	: TOKEN_SEPARABLE '=' TOKEN_BOOLEAN ';'			{ $$.type = OT_Separable; $$.value.intValue = $3; }
+	| TOKEN_SORT '=' TOKEN_CULLANDQUEUEVALUE ';'	{ $$.type = OT_Sort; $$.value.intValue = $3; }
+	| TOKEN_PRIORITY '=' TOKEN_INTEGER ';'			{ $$.type = OT_Priority; $$.value.intValue = $3; }
+	| TOKEN_TRANSPARENT '=' TOKEN_BOOLEAN ';'		{ $$.type = OT_Transparent; $$.value.intValue = $3; }
 	;
 	;
 
 
 	/* Technique */
 	/* Technique */
 
 
 technique
 technique
-	: technique_header technique_qualifier_list '=' '{' technique_body '}' ';' { nodePop(parse_state); $$ = $1; }
+	: technique_header technique_qualifier_list '{' technique_body '}' ';' { nodePop(parse_state); $$ = $1; }
 	;
 	;
 
 
 technique_header
 technique_header
@@ -236,7 +279,7 @@ pass
 	;
 	;
 
 
 pass_header
 pass_header
-	: TOKEN_PASS '=' 
+	: TOKEN_PASS
 		{ 
 		{ 
 			$$ = nodeCreate(parse_state->memContext, NT_Pass); 
 			$$ = nodeCreate(parse_state->memContext, NT_Pass); 
 			nodePush(parse_state, $$);
 			nodePush(parse_state, $$);
@@ -250,35 +293,122 @@ pass_body
 
 
 pass_statement
 pass_statement
 	: pass_option
 	: pass_option
-	| code				{ $$.type = OT_Code; $$.value.nodePtr = $1; }
+	| code							{ $$.type = OT_Code; $$.value.nodePtr = $1; }
 	;
 	;
 
 
 pass_option
 pass_option
-	: TOKEN_INDEX '=' TOKEN_INTEGER ';'							{ $$.type = OT_Index; $$.value.intValue = $3; }
-	| TOKEN_FILLMODE '=' TOKEN_FILLMODEVALUE ';'				{ $$.type = OT_FillMode; $$.value.intValue = $3; }
-	| TOKEN_CULLMODE '=' TOKEN_CULLMODEVALUE ';'				{ $$.type = OT_CullMode; $$.value.intValue = $3; }
+	: raster						{ $$.type = OT_Raster; $$.value.nodePtr = $1; }
+	| depth							{ $$.type = OT_Depth; $$.value.nodePtr = $1; }
+	| stencil						{ $$.type = OT_Stencil; $$.value.nodePtr = $1; }
+	| blend							{ $$.type = OT_Blend; $$.value.nodePtr = $1; }
+	;
+
+	/* Raster state */
+raster
+	: raster_header '{' raster_body '}' ';' { nodePop(parse_state); $$ = $1; }
+	;
+
+raster_header
+	: TOKEN_RASTER
+		{ 
+			$$ = nodeCreate(parse_state->memContext, NT_Raster); 
+			nodePush(parse_state, $$);
+		}
+	;
+
+raster_body
+	: /* empty */
+	| raster_option raster_body		{ nodeOptionsAdd(parse_state->memContext, parse_state->topNode->options, &$1); }
+	;
+
+raster_option
+	: TOKEN_FILLMODE '=' TOKEN_FILLMODEVALUE ';'				{ $$.type = OT_FillMode; $$.value.intValue = $3; }
+	| TOKEN_CULLMODE '=' TOKEN_CULLANDQUEUEVALUE ';'			{ $$.type = OT_CullMode; $$.value.intValue = $3; }
 	| TOKEN_DEPTHBIAS '=' TOKEN_FLOAT ';'						{ $$.type = OT_DepthBias; $$.value.floatValue = $3; }
 	| TOKEN_DEPTHBIAS '=' TOKEN_FLOAT ';'						{ $$.type = OT_DepthBias; $$.value.floatValue = $3; }
 	| TOKEN_SDEPTHBIAS '=' TOKEN_FLOAT ';'						{ $$.type = OT_SDepthBias; $$.value.floatValue = $3; }
 	| TOKEN_SDEPTHBIAS '=' TOKEN_FLOAT ';'						{ $$.type = OT_SDepthBias; $$.value.floatValue = $3; }
 	| TOKEN_DEPTHCLIP '=' TOKEN_BOOLEAN ';'						{ $$.type = OT_DepthClip; $$.value.intValue = $3; }
 	| TOKEN_DEPTHCLIP '=' TOKEN_BOOLEAN ';'						{ $$.type = OT_DepthClip; $$.value.intValue = $3; }
 	| TOKEN_SCISSOR '=' TOKEN_BOOLEAN ';'						{ $$.type = OT_Scissor; $$.value.intValue = $3; }
 	| TOKEN_SCISSOR '=' TOKEN_BOOLEAN ';'						{ $$.type = OT_Scissor; $$.value.intValue = $3; }
 	| TOKEN_MULTISAMPLE '=' TOKEN_BOOLEAN ';'					{ $$.type = OT_Multisample; $$.value.intValue = $3; }
 	| TOKEN_MULTISAMPLE '=' TOKEN_BOOLEAN ';'					{ $$.type = OT_Multisample; $$.value.intValue = $3; }
 	| TOKEN_AALINE '=' TOKEN_BOOLEAN ';'						{ $$.type = OT_AALine; $$.value.intValue = $3; }
 	| TOKEN_AALINE '=' TOKEN_BOOLEAN ';'						{ $$.type = OT_AALine; $$.value.intValue = $3; }
-	| TOKEN_DEPTHREAD '=' TOKEN_BOOLEAN ';'						{ $$.type = OT_DepthRead; $$.value.intValue = $3; }
+	;	
+	
+	/* Depth state */
+depth
+	: depth_header '{' depth_body '}' ';' { nodePop(parse_state); $$ = $1; }
+	;
+
+depth_header
+	: TOKEN_DEPTH
+		{ 
+			$$ = nodeCreate(parse_state->memContext, NT_Depth); 
+			nodePush(parse_state, $$);
+		}
+	;
+
+depth_body
+	: /* empty */
+	| depth_option depth_body		{ nodeOptionsAdd(parse_state->memContext, parse_state->topNode->options, &$1); }
+	;
+
+depth_option
+	: TOKEN_DEPTHREAD '=' TOKEN_BOOLEAN ';'						{ $$.type = OT_DepthRead; $$.value.intValue = $3; }
 	| TOKEN_DEPTHWRITE '=' TOKEN_BOOLEAN ';'					{ $$.type = OT_DepthWrite; $$.value.intValue = $3; }
 	| TOKEN_DEPTHWRITE '=' TOKEN_BOOLEAN ';'					{ $$.type = OT_DepthWrite; $$.value.intValue = $3; }
 	| TOKEN_COMPAREFUNC '=' TOKEN_COMPFUNCVALUE ';'				{ $$.type = OT_CompareFunc; $$.value.intValue = $3; }
 	| TOKEN_COMPAREFUNC '=' TOKEN_COMPFUNCVALUE ';'				{ $$.type = OT_CompareFunc; $$.value.intValue = $3; }
-	| TOKEN_STENCIL '=' TOKEN_BOOLEAN ';'						{ $$.type = OT_Stencil; $$.value.intValue = $3; }
-	| TOKEN_STENCILREADMASK '=' TOKEN_INTEGER ';'				{ $$.type = OT_StencilReadMask; $$.value.intValue = $3; }
-	| TOKEN_STENCILWRITEMASK '=' TOKEN_INTEGER ';'				{ $$.type = OT_StencilWriteMask; $$.value.intValue = $3; }
+	;
+	
+	/* Stencil state */
+stencil
+	: stencil_header '{' stencil_body '}' ';' { nodePop(parse_state); $$ = $1; }
+	;
+
+stencil_header
+	: TOKEN_STENCIL
+		{ 
+			$$ = nodeCreate(parse_state->memContext, NT_Stencil); 
+			nodePush(parse_state, $$);
+		}
+	;
+
+stencil_body
+	: /* empty */
+	| stencil_option stencil_body		{ nodeOptionsAdd(parse_state->memContext, parse_state->topNode->options, &$1); }
+	;
+
+stencil_option
+	: TOKEN_ENABLED '=' TOKEN_BOOLEAN ';'						{ $$.type = OT_Enabled; $$.value.intValue = $3; }
+	| TOKEN_READMASK '=' TOKEN_INTEGER ';'						{ $$.type = OT_StencilReadMask; $$.value.intValue = $3; }
+	| TOKEN_WRITEMASK '=' TOKEN_INTEGER ';'						{ $$.type = OT_StencilWriteMask; $$.value.intValue = $3; }
 	| stencil_op_front_header '{' stencil_op_body '}' ';'		{ nodePop(parse_state); $$.type = OT_StencilOpFront; $$.value.nodePtr = $1; }
 	| stencil_op_front_header '{' stencil_op_body '}' ';'		{ nodePop(parse_state); $$.type = OT_StencilOpFront; $$.value.nodePtr = $1; }
 	| stencil_op_back_header '{' stencil_op_body '}' ';'		{ nodePop(parse_state); $$.type = OT_StencilOpBack; $$.value.nodePtr = $1; }
 	| stencil_op_back_header '{' stencil_op_body '}' ';'		{ nodePop(parse_state); $$.type = OT_StencilOpBack; $$.value.nodePtr = $1; }
 	| stencil_op_front_header '{' stencil_op_body_init '}' ';'	{ nodePop(parse_state); $$.type = OT_StencilOpFront; $$.value.nodePtr = $1; }
 	| stencil_op_front_header '{' stencil_op_body_init '}' ';'	{ nodePop(parse_state); $$.type = OT_StencilOpFront; $$.value.nodePtr = $1; }
 	| stencil_op_back_header '{' stencil_op_body_init '}' ';'	{ nodePop(parse_state); $$.type = OT_StencilOpBack; $$.value.nodePtr = $1; }
 	| stencil_op_back_header '{' stencil_op_body_init '}' ';'	{ nodePop(parse_state); $$.type = OT_StencilOpBack; $$.value.nodePtr = $1; }
-	| TOKEN_ALPHATOCOVERAGE '=' TOKEN_BOOLEAN ';'				{ $$.type = OT_AlphaToCoverage; $$.value.intValue = $3; }
-	| TOKEN_INDEPENDANTBLEND '=' TOKEN_BOOLEAN ';'				{ $$.type = OT_IndependantBlend; $$.value.intValue = $3; }
-	| target													{ $$.type = OT_Target; $$.value.nodePtr = $1; }
 	| TOKEN_STENCILREF '=' TOKEN_INTEGER ';'					{ $$.type = OT_StencilRef; $$.value.intValue = $3; }
 	| TOKEN_STENCILREF '=' TOKEN_INTEGER ';'					{ $$.type = OT_StencilRef; $$.value.intValue = $3; }
+	;	
+	
+	/* Blend state */
+blend
+	: blend_header '{' blend_body '}' ';' { nodePop(parse_state); $$ = $1; }
+	;
+
+blend_header
+	: TOKEN_BLEND
+		{ 
+			$$ = nodeCreate(parse_state->memContext, NT_Blend); 
+			nodePush(parse_state, $$);
+		}
+	;
+
+blend_body
+	: /* empty */
+	| blend_option blend_body		{ nodeOptionsAdd(parse_state->memContext, parse_state->topNode->options, &$1); }
 	;
 	;
 
 
+blend_option
+	: TOKEN_ALPHATOCOVERAGE '=' TOKEN_BOOLEAN ';'				{ $$.type = OT_AlphaToCoverage; $$.value.intValue = $3; }
+	| TOKEN_INDEPENDANTBLEND '=' TOKEN_BOOLEAN ';'				{ $$.type = OT_IndependantBlend; $$.value.intValue = $3; }
+	| target													{ $$.type = OT_Target; $$.value.nodePtr = $1; }
+	;
+	
 	/* Code blocks */
 	/* Code blocks */
 
 
 code
 code
@@ -296,37 +426,37 @@ code
 	;
 	;
 
 
 code_header
 code_header
-	: TOKEN_VERTEX '='
+	: TOKEN_VERTEX
 		{ 
 		{ 
 			$$ = nodeCreate(parse_state->memContext, NT_CodeVertex); 
 			$$ = nodeCreate(parse_state->memContext, NT_CodeVertex); 
 			nodePush(parse_state, $$);
 			nodePush(parse_state, $$);
 		}
 		}
-	| TOKEN_FRAGMENT '='
+	| TOKEN_FRAGMENT
 		{ 
 		{ 
 			$$ = nodeCreate(parse_state->memContext, NT_CodeFragment); 
 			$$ = nodeCreate(parse_state->memContext, NT_CodeFragment); 
 			nodePush(parse_state, $$);
 			nodePush(parse_state, $$);
 		}
 		}
-	| TOKEN_GEOMETRY '='
+	| TOKEN_GEOMETRY
 		{ 
 		{ 
 			$$ = nodeCreate(parse_state->memContext, NT_CodeGeometry); 
 			$$ = nodeCreate(parse_state->memContext, NT_CodeGeometry); 
 			nodePush(parse_state, $$);
 			nodePush(parse_state, $$);
 		}
 		}
-	| TOKEN_HULL '='
+	| TOKEN_HULL
 		{ 
 		{ 
 			$$ = nodeCreate(parse_state->memContext, NT_CodeHull); 
 			$$ = nodeCreate(parse_state->memContext, NT_CodeHull); 
 			nodePush(parse_state, $$);
 			nodePush(parse_state, $$);
 		}
 		}
-	| TOKEN_DOMAIN '='
+	| TOKEN_DOMAIN
 		{ 
 		{ 
 			$$ = nodeCreate(parse_state->memContext, NT_CodeDomain); 
 			$$ = nodeCreate(parse_state->memContext, NT_CodeDomain); 
 			nodePush(parse_state, $$);
 			nodePush(parse_state, $$);
 		}
 		}
-	| TOKEN_COMPUTE '='
+	| TOKEN_COMPUTE
 		{ 
 		{ 
 			$$ = nodeCreate(parse_state->memContext, NT_CodeCompute); 
 			$$ = nodeCreate(parse_state->memContext, NT_CodeCompute); 
 			nodePush(parse_state, $$);
 			nodePush(parse_state, $$);
 		}
 		}
-	| TOKEN_COMMON '='
+	| TOKEN_COMMON
 		{ 
 		{ 
 			$$ = nodeCreate(parse_state->memContext, NT_CodeCommon); 
 			$$ = nodeCreate(parse_state->memContext, NT_CodeCommon); 
 			nodePush(parse_state, $$);
 			nodePush(parse_state, $$);
@@ -384,7 +514,7 @@ target
 	;
 	;
 
 
 target_header
 target_header
-	: TOKEN_TARGET '='
+	: TOKEN_TARGET
 		{ 
 		{ 
 			$$ = nodeCreate(parse_state->memContext, NT_Target); 
 			$$ = nodeCreate(parse_state->memContext, NT_Target); 
 			nodePush(parse_state, $$);
 			nodePush(parse_state, $$);
@@ -402,11 +532,11 @@ target_statement
 
 
 target_option
 target_option
 	: TOKEN_INDEX '=' TOKEN_INTEGER ';'					{ $$.type = OT_Index; $$.value.intValue = $3; }
 	: TOKEN_INDEX '=' TOKEN_INTEGER ';'					{ $$.type = OT_Index; $$.value.intValue = $3; }
-	| TOKEN_BLEND '=' TOKEN_BOOLEAN ';'					{ $$.type = OT_Blend; $$.value.intValue = $3; }
+	| TOKEN_ENABLED '=' TOKEN_BOOLEAN ';'				{ $$.type = OT_Enabled; $$.value.intValue = $3; }
 	| blend_color_header '{' blenddef_body '}' ';'		{ nodePop(parse_state); $$.type = OT_Color; $$.value.nodePtr = $1; }
 	| blend_color_header '{' blenddef_body '}' ';'		{ nodePop(parse_state); $$.type = OT_Color; $$.value.nodePtr = $1; }
 	| blend_alpha_header '{' blenddef_body '}' ';'		{ nodePop(parse_state); $$.type = OT_Alpha; $$.value.nodePtr = $1; }
 	| blend_alpha_header '{' blenddef_body '}' ';'		{ nodePop(parse_state); $$.type = OT_Alpha; $$.value.nodePtr = $1; }
-	| blend_color_header '{' blenddef_body_init '}' ';'		{ nodePop(parse_state); $$.type = OT_Color; $$.value.nodePtr = $1; }
-	| blend_alpha_header '{' blenddef_body_init '}' ';'		{ nodePop(parse_state); $$.type = OT_Alpha; $$.value.nodePtr = $1; }
+	| blend_color_header '{' blenddef_body_init '}' ';'	{ nodePop(parse_state); $$.type = OT_Color; $$.value.nodePtr = $1; }
+	| blend_alpha_header '{' blenddef_body_init '}' ';'	{ nodePop(parse_state); $$.type = OT_Alpha; $$.value.nodePtr = $1; }
 	| TOKEN_WRITEMASK '=' TOKEN_COLORMASK ';'			{ $$.type = OT_WriteMask; $$.value.intValue = $3; }
 	| TOKEN_WRITEMASK '=' TOKEN_COLORMASK ';'			{ $$.type = OT_WriteMask; $$.value.intValue = $3; }
 	;
 	;
 
 

+ 15 - 13
Source/BansheeSL/Include/BsASTFX.h

@@ -9,12 +9,16 @@
 enum tagNodeType
 enum tagNodeType
 {
 {
 	NT_Shader,
 	NT_Shader,
+	NT_Options,
 	NT_Technique,
 	NT_Technique,
 	NT_Pass,
 	NT_Pass,
-	NT_StencilOp,
+	NT_Blend,
+	NT_Raster,
+	NT_Depth,
+	NT_Stencil,
 	NT_Target,
 	NT_Target,
+	NT_StencilOp,
 	NT_BlendDef,
 	NT_BlendDef,
-	NT_AddrMode,
 	NT_Tags,
 	NT_Tags,
 	NT_CodeVertex,
 	NT_CodeVertex,
 	NT_CodeFragment,
 	NT_CodeFragment,
@@ -28,11 +32,16 @@ enum tagNodeType
 enum tagOptionType
 enum tagOptionType
 {
 {
 	OT_None = 0,
 	OT_None = 0,
+	OT_Options,
 	OT_Separable,
 	OT_Separable,
 	OT_Priority,
 	OT_Priority,
 	OT_Sort,
 	OT_Sort,
 	OT_Transparent,
 	OT_Transparent,
 	OT_Technique,
 	OT_Technique,
+	OT_Raster,
+	OT_Depth,
+	OT_Stencil,
+	OT_Blend,
 	OT_Renderer,
 	OT_Renderer,
 	OT_Pass,
 	OT_Pass,
 	OT_FillMode,
 	OT_FillMode,
@@ -46,7 +55,6 @@ enum tagOptionType
 	OT_DepthRead,
 	OT_DepthRead,
 	OT_DepthWrite,
 	OT_DepthWrite,
 	OT_CompareFunc,
 	OT_CompareFunc,
-	OT_Stencil,
 	OT_StencilReadMask,
 	OT_StencilReadMask,
 	OT_StencilWriteMask,
 	OT_StencilWriteMask,
 	OT_StencilOpFront,
 	OT_StencilOpFront,
@@ -58,7 +66,7 @@ enum tagOptionType
 	OT_IndependantBlend,
 	OT_IndependantBlend,
 	OT_Target,
 	OT_Target,
 	OT_Index,
 	OT_Index,
-	OT_Blend,
+	OT_Enabled,
 	OT_Color,
 	OT_Color,
 	OT_Alpha,
 	OT_Alpha,
 	OT_WriteMask,
 	OT_WriteMask,
@@ -90,9 +98,9 @@ enum tagFillModeValue
 	FMV_Wire, FMV_Solid 
 	FMV_Wire, FMV_Solid 
 };
 };
 
 
-enum tagCullModeValue 
+enum tagCullAndSortModeValue 
 { 
 { 
-	CMV_None, CMV_CW, CMV_CCW 
+	CASV_None, CASV_CW, CASV_CCW, CASV_FrontToBack, CASV_BackToFront
 };
 };
 
 
 enum tagCompFuncValue
 enum tagCompFuncValue
@@ -115,11 +123,6 @@ enum tagBlendOpValue
 	BOV_Min, BOV_Max 
 	BOV_Min, BOV_Max 
 };
 };
 
 
-enum tagQueueSortTypeValue
-{
-	QST_FrontToBack, QST_BackToFront, QST_None
-};
-
 typedef enum tagNodeType NodeType;
 typedef enum tagNodeType NodeType;
 typedef enum tagOptionType OptionType;
 typedef enum tagOptionType OptionType;
 typedef enum tagOptionDataType OptionDataType;
 typedef enum tagOptionDataType OptionDataType;
@@ -136,11 +139,10 @@ typedef struct tagConditionalData ConditionalData;
 typedef struct tagCodeString CodeString;
 typedef struct tagCodeString CodeString;
 typedef struct tagDefineEntry DefineEntry;
 typedef struct tagDefineEntry DefineEntry;
 typedef enum tagFillModeValue FillModeValue;
 typedef enum tagFillModeValue FillModeValue;
-typedef enum tagCullModeValue CullModeValue;
+typedef enum tagCullAndSortModeValue CullAndSortModeValue;
 typedef enum tagCompFuncValue CompFuncValue;
 typedef enum tagCompFuncValue CompFuncValue;
 typedef enum tagOpValue OpValue;
 typedef enum tagOpValue OpValue;
 typedef enum tagBlendOpValue BlendOpValue;
 typedef enum tagBlendOpValue BlendOpValue;
-typedef enum tagQueueSortTypeValue QueueSortTypeValue;
 
 
 struct tagNodeLink
 struct tagNodeLink
 {
 {

+ 25 - 12
Source/BansheeSL/Include/BsSLFXCompiler.h

@@ -94,7 +94,7 @@ namespace bs
 		static StringID parseRenderer(const String& name);
 		static StringID parseRenderer(const String& name);
 
 
 		/**	Maps FX queue sort type enum into in-engine queue sort type mode. */
 		/**	Maps FX queue sort type enum into in-engine queue sort type mode. */
-		static QueueSortType parseSortType(QueueSortTypeValue sortType);
+		static QueueSortType parseSortType(CullAndSortModeValue sortType);
 
 
 		/**	Maps FX comparison function enum into in-engine compare function. */
 		/**	Maps FX comparison function enum into in-engine compare function. */
 		static CompareFunction parseCompFunc(CompFuncValue compFunc);
 		static CompareFunction parseCompFunc(CompFuncValue compFunc);
@@ -109,7 +109,7 @@ namespace bs
 		static StencilOperation parseStencilOp(OpValue op);
 		static StencilOperation parseStencilOp(OpValue op);
 		
 		
 		/**	Maps FX cull mode enum to in-engine cull mode. */
 		/**	Maps FX cull mode enum to in-engine cull mode. */
-		static CullingMode parseCullMode(CullModeValue cm);
+		static CullingMode parseCullMode(CullAndSortModeValue cm);
 
 
 		/**	Maps FX fill mode enum to in-engine fill mode. */
 		/**	Maps FX fill mode enum to in-engine fill mode. */
 		static PolygonMode parseFillMode(FillModeValue fm);
 		static PolygonMode parseFillMode(FillModeValue fm);
@@ -139,22 +139,28 @@ namespace bs
 		static void parseRenderTargetBlendState(BLEND_STATE_DESC& desc, ASTFXNode* targetNode);
 		static void parseRenderTargetBlendState(BLEND_STATE_DESC& desc, ASTFXNode* targetNode);
 
 
 		/**
 		/**
-		 * Parses the blend state AST node and outputs a blend state descriptor. Returns false if the descriptor wasn't 
-		 * modified.
+		 * Parses the blend state AST node and populates the pass' blend state descriptor. Returns false if the descriptor
+		 * wasn't modified.
 		 */
 		 */
-		static bool parseBlendState(BLEND_STATE_DESC& desc, ASTFXNode* passNode);
+		static bool parseBlendState(PassData& passData, ASTFXNode* blendNode);
 
 
 		/**
 		/**
-		 * Parses the rasterizer state AST node and outputs a rasterizer state descriptor. Returns false if the descriptor
-		 * wasn't modified.
+		 * Parses the rasterizer state AST node and populates the pass' rasterizer state descriptor. Returns false if the
+		 * descriptor wasn't modified.
 		 */
 		 */
-		static bool parseRasterizerState(RASTERIZER_STATE_DESC& desc, ASTFXNode* passNode);
+		static bool parseRasterizerState(PassData& passData, ASTFXNode* rasterNode);
 
 
 		/**
 		/**
-		 * Parses the depth-stencil state AST node and outputs a depth-stencil state descriptor. Returns false if the 
+		 * Parses the depth state AST node and populates the pass' depth-stencil state descriptor. Returns false if the 
 		 * descriptor wasn't modified.
 		 * descriptor wasn't modified.
 		 */
 		 */
-		static bool parseDepthStencilState(DEPTH_STENCIL_STATE_DESC& desc, ASTFXNode* passNode);
+		static bool parseDepthState(PassData& passData, ASTFXNode* depthNode);
+
+		/**
+		* Parses the stencil state AST node and populates the pass' depth-stencil state descriptor. Returns false if the
+		* descriptor wasn't modified.
+		*/
+		static bool parseStencilState(PassData& passData, ASTFXNode* stencilNode);
 
 
 		/**
 		/**
 		 * Parses a code AST node and outputs the result in one of the streams within the provided pass data.
 		 * Parses a code AST node and outputs the result in one of the streams within the provided pass data.
@@ -176,8 +182,7 @@ namespace bs
 		static void parsePass(ASTFXNode* passNode, const Vector<String>& codeBlocks, PassData& passData);
 		static void parsePass(ASTFXNode* passNode, const Vector<String>& codeBlocks, PassData& passData);
 
 
 		/**
 		/**
-		 * Parses the technique AST node and generates a single technique object. Returns null if no technique can be 
-		 * parsed.
+		 * Parses the technique AST node and generates a single technique object.
 		 *
 		 *
 		 * @param[in]	techniqueNode	Node to parse.
 		 * @param[in]	techniqueNode	Node to parse.
 		 * @param[in]	codeBlocks		GPU program source code.
 		 * @param[in]	codeBlocks		GPU program source code.
@@ -185,6 +190,14 @@ namespace bs
 		 */
 		 */
 		static void parseTechnique(ASTFXNode* techniqueNode, const Vector<String>& codeBlocks, TechniqueData& techniqueData);
 		static void parseTechnique(ASTFXNode* techniqueNode, const Vector<String>& codeBlocks, TechniqueData& techniqueData);
 
 
+		/**
+		 * Parser the options AST node that contains global shader options.
+		 * 
+		 * @param[in]	optionsNode			Node to parse.
+		 * @param[in]	shaderDesc			Descriptor to apply the found options to.
+		 */
+		static void parseOptions(ASTFXNode* optionsNode, SHADER_DESC& shaderDesc);
+
 		/**
 		/**
 		 * Parses the AST node hierarchy and generates a shader object.
 		 * Parses the AST node hierarchy and generates a shader object.
 		 *
 		 *

+ 6 - 2
Source/BansheeSL/Source/BsASTFX.c

@@ -7,11 +7,16 @@
 OptionInfo OPTION_LOOKUP[] =
 OptionInfo OPTION_LOOKUP[] =
 {
 {
 	{ OT_None, ODT_Int },
 	{ OT_None, ODT_Int },
+	{ OT_Options, ODT_Complex },
 	{ OT_Separable, ODT_Bool },
 	{ OT_Separable, ODT_Bool },
 	{ OT_Priority, ODT_Int },
 	{ OT_Priority, ODT_Int },
 	{ OT_Sort, ODT_Int },
 	{ OT_Sort, ODT_Int },
 	{ OT_Transparent, ODT_Bool },
 	{ OT_Transparent, ODT_Bool },
 	{ OT_Technique, ODT_Complex }, 
 	{ OT_Technique, ODT_Complex }, 
+	{ OT_Raster, ODT_Complex },
+	{ OT_Depth, ODT_Complex },
+	{ OT_Stencil, ODT_Complex },
+	{ OT_Blend, ODT_Complex },
 	{ OT_Renderer, ODT_String }, 
 	{ OT_Renderer, ODT_String }, 
 	{ OT_Pass, ODT_Complex }, 
 	{ OT_Pass, ODT_Complex }, 
 	{ OT_FillMode, ODT_Int }, 
 	{ OT_FillMode, ODT_Int }, 
@@ -25,7 +30,6 @@ OptionInfo OPTION_LOOKUP[] =
 	{ OT_DepthRead, ODT_Bool },
 	{ OT_DepthRead, ODT_Bool },
 	{ OT_DepthWrite, ODT_Bool },
 	{ OT_DepthWrite, ODT_Bool },
 	{ OT_CompareFunc, ODT_Int },
 	{ OT_CompareFunc, ODT_Int },
-	{ OT_Stencil, ODT_Bool },
 	{ OT_StencilReadMask, ODT_Int },
 	{ OT_StencilReadMask, ODT_Int },
 	{ OT_StencilWriteMask, ODT_Int },
 	{ OT_StencilWriteMask, ODT_Int },
 	{ OT_StencilOpFront, ODT_Complex },
 	{ OT_StencilOpFront, ODT_Complex },
@@ -37,7 +41,7 @@ OptionInfo OPTION_LOOKUP[] =
 	{ OT_IndependantBlend, ODT_Bool },
 	{ OT_IndependantBlend, ODT_Bool },
 	{ OT_Target, ODT_Complex },
 	{ OT_Target, ODT_Complex },
 	{ OT_Index, ODT_Int },
 	{ OT_Index, ODT_Int },
-	{ OT_Blend, ODT_Bool },
+	{ OT_Enabled, ODT_Bool },
 	{ OT_Color, ODT_Complex },
 	{ OT_Color, ODT_Complex },
 	{ OT_Alpha, ODT_Complex },
 	{ OT_Alpha, ODT_Complex },
 	{ OT_WriteMask, ODT_Int },
 	{ OT_WriteMask, ODT_Int },

+ 139 - 78
Source/BansheeSL/Source/BsSLFXCompiler.cpp

@@ -464,15 +464,15 @@ namespace bs
 		return RendererAny;
 		return RendererAny;
 	}
 	}
 
 
-	QueueSortType BSLFXCompiler::parseSortType(QueueSortTypeValue sortType)
+	QueueSortType BSLFXCompiler::parseSortType(CullAndSortModeValue sortType)
 	{
 	{
 		switch (sortType)
 		switch (sortType)
 		{
 		{
-		case QST_BackToFront:
+		case CASV_BackToFront:
 			return QueueSortType::BackToFront;
 			return QueueSortType::BackToFront;
-		case QST_FrontToBack:
+		case CASV_FrontToBack:
 			return QueueSortType::FrontToBack;
 			return QueueSortType::FrontToBack;
-		case QST_None:
+		case CASV_None:
 			return QueueSortType::None;
 			return QueueSortType::None;
 		}
 		}
 
 
@@ -581,15 +581,15 @@ namespace bs
 		return SOP_KEEP;
 		return SOP_KEEP;
 	}
 	}
 
 
-	CullingMode BSLFXCompiler::parseCullMode(CullModeValue cm)
+	CullingMode BSLFXCompiler::parseCullMode(CullAndSortModeValue cm)
 	{
 	{
 		switch (cm)
 		switch (cm)
 		{
 		{
-		case CMV_None:
+		case CASV_None:
 			return CULL_NONE;
 			return CULL_NONE;
-		case CMV_CW:
+		case CASV_CW:
 			return CULL_CLOCKWISE;
 			return CULL_CLOCKWISE;
-		case CMV_CCW:
+		case CASV_CCW:
 			return CULL_COUNTERCLOCKWISE;
 			return CULL_COUNTERCLOCKWISE;
 		}
 		}
 
 
@@ -745,7 +745,7 @@ namespace bs
 
 
 			switch (option->type)
 			switch (option->type)
 			{
 			{
-			case OT_Blend:
+			case OT_Enabled:
 				rtDesc.blendEnable = option->value.intValue > 0;
 				rtDesc.blendEnable = option->value.intValue > 0;
 				break;
 				break;
 			case OT_Color:
 			case OT_Color:
@@ -763,29 +763,29 @@ namespace bs
 		}
 		}
 	}
 	}
 
 
-	bool BSLFXCompiler::parseBlendState(BLEND_STATE_DESC& desc, ASTFXNode* passNode)
+	bool BSLFXCompiler::parseBlendState(PassData& desc, ASTFXNode* blendNode)
 	{
 	{
-		if (passNode == nullptr || (passNode->type != NT_Pass && passNode->type != NT_Technique))
+		if (blendNode == nullptr || blendNode->type != NT_Blend)
 			return false;
 			return false;
 
 
 		bool isDefault = true;
 		bool isDefault = true;
 
 
-		for (int i = 0; i < passNode->options->count; i++)
+		for (int i = 0; i < blendNode->options->count; i++)
 		{
 		{
-			NodeOption* option = &passNode->options->entries[i];
+			NodeOption* option = &blendNode->options->entries[i];
 
 
 			switch (option->type)
 			switch (option->type)
 			{
 			{
 			case OT_AlphaToCoverage:
 			case OT_AlphaToCoverage:
-				desc.alphaToCoverageEnable = option->value.intValue > 0;
+				desc.blendDesc.alphaToCoverageEnable = option->value.intValue > 0;
 				isDefault = false;
 				isDefault = false;
 				break;
 				break;
 			case OT_IndependantBlend:
 			case OT_IndependantBlend:
-				desc.independantBlendEnable = option->value.intValue > 0;
+				desc.blendDesc.independantBlendEnable = option->value.intValue > 0;
 				isDefault = false;
 				isDefault = false;
 				break;
 				break;
 			case OT_Target:
 			case OT_Target:
-				parseRenderTargetBlendState(desc, option->value.nodePtr);
+				parseRenderTargetBlendState(desc.blendDesc, option->value.nodePtr);
 				isDefault = false;
 				isDefault = false;
 				break;
 				break;
 			default:
 			default:
@@ -796,49 +796,49 @@ namespace bs
 		return !isDefault;
 		return !isDefault;
 	}
 	}
 
 
-	bool BSLFXCompiler::parseRasterizerState(RASTERIZER_STATE_DESC& desc, ASTFXNode* passNode)
+	bool BSLFXCompiler::parseRasterizerState(PassData& desc, ASTFXNode* rasterNode)
 	{
 	{
-		if (passNode == nullptr || (passNode->type != NT_Pass && passNode->type != NT_Technique))
+		if (rasterNode == nullptr || rasterNode->type != NT_Raster)
 			return false;
 			return false;
 
 
 		bool isDefault = true;
 		bool isDefault = true;
 
 
-		for (int i = 0; i < passNode->options->count; i++)
+		for (int i = 0; i < rasterNode->options->count; i++)
 		{
 		{
-			NodeOption* option = &passNode->options->entries[i];
+			NodeOption* option = &rasterNode->options->entries[i];
 
 
 			switch (option->type)
 			switch (option->type)
 			{
 			{
 			case OT_FillMode:
 			case OT_FillMode:
-				desc.polygonMode = parseFillMode((FillModeValue)option->value.intValue);
+				desc.rasterizerDesc.polygonMode = parseFillMode((FillModeValue)option->value.intValue);
 				isDefault = false;
 				isDefault = false;
 				break;
 				break;
 			case OT_CullMode:
 			case OT_CullMode:
-				desc.cullMode = parseCullMode((CullModeValue)option->value.intValue);
+				desc.rasterizerDesc.cullMode = parseCullMode((CullAndSortModeValue)option->value.intValue);
 				isDefault = false;
 				isDefault = false;
 				break;
 				break;
 			case OT_DepthBias:
 			case OT_DepthBias:
-				desc.depthBias = option->value.floatValue;
+				desc.rasterizerDesc.depthBias = option->value.floatValue;
 				isDefault = false;
 				isDefault = false;
 				break;
 				break;
 			case OT_SDepthBias:
 			case OT_SDepthBias:
-				desc.slopeScaledDepthBias = option->value.floatValue;
+				desc.rasterizerDesc.slopeScaledDepthBias = option->value.floatValue;
 				isDefault = false;
 				isDefault = false;
 				break;
 				break;
 			case OT_DepthClip:
 			case OT_DepthClip:
-				desc.depthClipEnable = option->value.intValue > 0;
+				desc.rasterizerDesc.depthClipEnable = option->value.intValue > 0;
 				isDefault = false;
 				isDefault = false;
 				break;
 				break;
 			case OT_Scissor:
 			case OT_Scissor:
-				desc.scissorEnable = option->value.intValue > 0;
+				desc.rasterizerDesc.scissorEnable = option->value.intValue > 0;
 				isDefault = false;
 				isDefault = false;
 				break;
 				break;
 			case OT_Multisample:
 			case OT_Multisample:
-				desc.multisampleEnable = option->value.intValue > 0;
+				desc.rasterizerDesc.multisampleEnable = option->value.intValue > 0;
 				isDefault = false;
 				isDefault = false;
 				break;
 				break;
 			case OT_AALine:
 			case OT_AALine:
-				desc.antialiasedLineEnable = option->value.intValue > 0;
+				desc.rasterizerDesc.antialiasedLineEnable = option->value.intValue > 0;
 				isDefault = false;
 				isDefault = false;
 				break;
 				break;
 			default:
 			default:
@@ -849,51 +849,75 @@ namespace bs
 		return !isDefault;
 		return !isDefault;
 	}
 	}
 
 
-	bool BSLFXCompiler::parseDepthStencilState(DEPTH_STENCIL_STATE_DESC& desc, ASTFXNode* passNode)
+	bool BSLFXCompiler::parseDepthState(PassData& passData, ASTFXNode* depthNode)
 	{
 	{
-		if (passNode == nullptr || (passNode->type != NT_Pass && passNode->type != NT_Technique))
+		if (depthNode == nullptr || depthNode->type != NT_Depth)
 			return false;
 			return false;
 
 
 		bool isDefault = true;
 		bool isDefault = true;
 
 
-		for (int i = 0; i < passNode->options->count; i++)
+		for (int i = 0; i < depthNode->options->count; i++)
 		{
 		{
-			NodeOption* option = &passNode->options->entries[i];
+			NodeOption* option = &depthNode->options->entries[i];
 
 
 			switch (option->type)
 			switch (option->type)
 			{
 			{
 			case OT_DepthRead:
 			case OT_DepthRead:
-				desc.depthReadEnable = option->value.intValue > 0;
+				passData.depthStencilDesc.depthReadEnable = option->value.intValue > 0;
 				isDefault = false;
 				isDefault = false;
 				break;
 				break;
 			case OT_DepthWrite:
 			case OT_DepthWrite:
-				desc.depthWriteEnable = option->value.intValue > 0;
+				passData.depthStencilDesc.depthWriteEnable = option->value.intValue > 0;
 				isDefault = false;
 				isDefault = false;
 				break;
 				break;
 			case OT_CompareFunc:
 			case OT_CompareFunc:
-				desc.depthComparisonFunc = parseCompFunc((CompFuncValue)option->value.intValue);
+				passData.depthStencilDesc.depthComparisonFunc = parseCompFunc((CompFuncValue)option->value.intValue);
 				isDefault = false;
 				isDefault = false;
 				break;
 				break;
-			case OT_Stencil:
-				desc.stencilEnable = option->value.intValue > 0;
+			default:
+				break;
+			}
+		}
+
+		return !isDefault;
+	}
+
+	bool BSLFXCompiler::parseStencilState(PassData& passData, ASTFXNode* stencilNode)
+	{
+		if (stencilNode == nullptr || stencilNode->type != NT_Stencil)
+			return false;
+
+		bool isDefault = true;
+
+		for (int i = 0; i < stencilNode->options->count; i++)
+		{
+			NodeOption* option = &stencilNode->options->entries[i];
+
+			switch (option->type)
+			{
+			case OT_Enabled:
+				passData.depthStencilDesc.stencilEnable = option->value.intValue > 0;
 				isDefault = false;
 				isDefault = false;
 				break;
 				break;
 			case OT_StencilReadMask:
 			case OT_StencilReadMask:
-				desc.stencilReadMask = (UINT8)option->value.intValue;
+				passData.depthStencilDesc.stencilReadMask = (UINT8)option->value.intValue;
 				isDefault = false;
 				isDefault = false;
 				break;
 				break;
 			case OT_StencilWriteMask:
 			case OT_StencilWriteMask:
-				desc.stencilWriteMask = (UINT8)option->value.intValue;
+				passData.depthStencilDesc.stencilWriteMask = (UINT8)option->value.intValue;
 				isDefault = false;
 				isDefault = false;
 				break;
 				break;
 			case OT_StencilOpFront:
 			case OT_StencilOpFront:
-				parseStencilFront(desc, option->value.nodePtr);
+				parseStencilFront(passData.depthStencilDesc, option->value.nodePtr);
 				isDefault = false;
 				isDefault = false;
 				break;
 				break;
 			case OT_StencilOpBack:
 			case OT_StencilOpBack:
-				parseStencilBack(desc, option->value.nodePtr);
+				parseStencilBack(passData.depthStencilDesc, option->value.nodePtr);
 				isDefault = false;
 				isDefault = false;
 				break;
 				break;
+			case OT_StencilRef:
+				passData.stencilRefValue = option->value.intValue;
+				break;
 			default:
 			default:
 				break;
 				break;
 			}
 			}
@@ -954,18 +978,23 @@ namespace bs
 		if (passNode == nullptr || passNode->type != NT_Pass)
 		if (passNode == nullptr || passNode->type != NT_Pass)
 			return;
 			return;
 
 
-		passData.blendIsDefault &= !parseBlendState(passData.blendDesc, passNode);
-		passData.rasterizerIsDefault &= !parseRasterizerState(passData.rasterizerDesc, passNode);
-		passData.depthStencilIsDefault &= !parseDepthStencilState(passData.depthStencilDesc, passNode);
-
 		for (int i = 0; i < passNode->options->count; i++)
 		for (int i = 0; i < passNode->options->count; i++)
 		{
 		{
 			NodeOption* option = &passNode->options->entries[i];
 			NodeOption* option = &passNode->options->entries[i];
 
 
 			switch (option->type)
 			switch (option->type)
 			{
 			{
-			case OT_StencilRef:
-				passData.stencilRefValue = option->value.intValue;
+			case OT_Blend:
+				passData.blendIsDefault &= !parseBlendState(passData, option->value.nodePtr);
+				break;
+			case OT_Raster:
+				passData.rasterizerIsDefault &= !parseRasterizerState(passData, option->value.nodePtr);
+				break;
+			case OT_Depth:
+				passData.depthStencilIsDefault &= !parseDepthState(passData, option->value.nodePtr);
+				break;
+			case OT_Stencil:
+				passData.depthStencilIsDefault &= !parseStencilState(passData, option->value.nodePtr);
 				break;
 				break;
 			case OT_Code:
 			case OT_Code:
 				parseCodeBlock(option->value.nodePtr, codeBlocks, passData);
 				parseCodeBlock(option->value.nodePtr, codeBlocks, passData);
@@ -981,6 +1010,13 @@ namespace bs
 		if (techniqueNode == nullptr || techniqueNode->type != NT_Technique)
 		if (techniqueNode == nullptr || techniqueNode->type != NT_Technique)
 			return;
 			return;
 
 
+		// There must always be at least one pass
+		if(techniqueData.passes.empty())
+		{
+			techniqueData.passes.push_back(PassData());
+			techniqueData.passes.back().seqIdx = 0;
+		}
+
 		PassData combinedCommonPassData;
 		PassData combinedCommonPassData;
 
 
 		UINT32 nextPassIdx = 0;
 		UINT32 nextPassIdx = 0;
@@ -994,22 +1030,6 @@ namespace bs
 			case OT_Pass:
 			case OT_Pass:
 			{
 			{
 				UINT32 passIdx = nextPassIdx;
 				UINT32 passIdx = nextPassIdx;
-
-				ASTFXNode* passNode = option->value.nodePtr;
-				for (int j = 0; j < passNode->options->count; j++)
-				{
-					NodeOption* passOption = &passNode->options->entries[j];
-
-					switch (passOption->type)
-					{
-					case OT_Index:
-						passIdx = passOption->value.intValue;
-						break;
-					default:
-						break;
-					}
-				}
-
 				PassData* passData = nullptr;
 				PassData* passData = nullptr;
 				for (auto& entry : techniqueData.passes)
 				for (auto& entry : techniqueData.passes)
 				{
 				{
@@ -1035,6 +1055,7 @@ namespace bs
 				passData->computeCode = combinedCommonPassData.computeCode + passData->computeCode;
 				passData->computeCode = combinedCommonPassData.computeCode + passData->computeCode;
 				passData->commonCode = combinedCommonPassData.commonCode + passData->commonCode;
 				passData->commonCode = combinedCommonPassData.commonCode + passData->commonCode;
 				
 				
+				ASTFXNode* passNode = option->value.nodePtr;
 				parsePass(passNode, codeBlocks, *passData);
 				parsePass(passNode, codeBlocks, *passData);
 			}
 			}
 				break;
 				break;
@@ -1069,11 +1090,60 @@ namespace bs
 		}
 		}
 
 
 		// Parse common pass states
 		// Parse common pass states
-		for (auto& passData : techniqueData.passes)
+		for (int i = 0; i < techniqueNode->options->count; i++)
 		{
 		{
-			passData.blendIsDefault &= !parseBlendState(passData.blendDesc, techniqueNode);
-			passData.rasterizerIsDefault &= !parseRasterizerState(passData.rasterizerDesc, techniqueNode);
-			passData.depthStencilIsDefault &= !parseDepthStencilState(passData.depthStencilDesc, techniqueNode);
+			NodeOption* option = &techniqueNode->options->entries[i];
+
+			switch (option->type)
+			{
+			case OT_Blend:
+				for (auto& passData : techniqueData.passes)
+					passData.blendIsDefault &= !parseBlendState(passData, option->value.nodePtr);
+				break;
+			case OT_Raster:
+				for (auto& passData : techniqueData.passes)
+					passData.rasterizerIsDefault &= !parseRasterizerState(passData, option->value.nodePtr);
+				break;
+			case OT_Depth:
+				for (auto& passData : techniqueData.passes)
+					passData.depthStencilIsDefault &= !parseDepthState(passData, option->value.nodePtr);
+				break;
+			case OT_Stencil:
+				for (auto& passData : techniqueData.passes)
+					passData.depthStencilIsDefault &= !parseStencilState(passData, option->value.nodePtr);
+				break;
+			default:
+				break;
+			}
+		}
+	}
+
+	void BSLFXCompiler::parseOptions(ASTFXNode* optionsNode, SHADER_DESC& shaderDesc)
+	{
+		if (optionsNode == nullptr || optionsNode->type != NT_Options)
+			return;
+
+		for (int i = optionsNode->options->count - 1; i >= 0; i--)
+		{
+			NodeOption* option = &optionsNode->options->entries[i];
+
+			switch (option->type)
+			{
+			case OT_Separable:
+				shaderDesc.separablePasses = option->value.intValue > 1;
+				break;
+			case OT_Sort:
+				shaderDesc.queueSortType = parseSortType((CullAndSortModeValue)option->value.intValue);
+				break;
+			case OT_Priority:
+				shaderDesc.queuePriority = option->value.intValue;
+				break;
+			case OT_Transparent:
+				shaderDesc.flags |= (UINT32)ShaderFlags::Transparent;
+				break;
+			default:
+				break;
+			}
 		}
 		}
 	}
 	}
 
 
@@ -1099,17 +1169,8 @@ namespace bs
 
 
 			switch (option->type)
 			switch (option->type)
 			{
 			{
-			case OT_Separable:
-				shaderDesc.separablePasses = option->value.intValue > 1;
-				break;
-			case OT_Sort:
-				shaderDesc.queueSortType = parseSortType((QueueSortTypeValue)option->value.intValue);
-				break;
-			case OT_Priority:
-				shaderDesc.queuePriority = option->value.intValue;
-				break;
-			case OT_Transparent:
-				shaderDesc.flags |= (UINT32)ShaderFlags::Transparent;
+			case OT_Options:
+				parseOptions(option->value.nodePtr, shaderDesc);
 				break;
 				break;
 			case OT_Technique:
 			case OT_Technique:
 			{
 			{