Commit 93b2648c authored by Matteo Bruni's avatar Matteo Bruni Committed by Alexandre Julliard

d3dx9: Add other flow control instructions in the shader assembler.

parent 25c929ab
...@@ -50,8 +50,9 @@ static void asmparser_instr(struct asm_parser *This, DWORD opcode, ...@@ -50,8 +50,9 @@ static void asmparser_instr(struct asm_parser *This, DWORD opcode,
if(!This->shader) return; if(!This->shader) return;
TRACE_(parsed_shader)("%s%s ", debug_print_opcode(opcode), TRACE_(parsed_shader)("%s%s%s ", debug_print_opcode(opcode),
debug_print_dstmod(mod)); debug_print_dstmod(mod),
debug_print_comp(comp));
if(dst) { if(dst) {
TRACE_(parsed_shader)("%s", debug_print_dstreg(dst, This->shader->type)); TRACE_(parsed_shader)("%s", debug_print_dstreg(dst, This->shader->type));
firstreg = FALSE; firstreg = FALSE;
......
...@@ -243,6 +243,14 @@ ps_3_0 {return VER_PS30; } ...@@ -243,6 +243,14 @@ ps_3_0 {return VER_PS30; }
\_pp {return MOD_PP; } \_pp {return MOD_PP; }
\_centroid {return MOD_CENTROID; } \_centroid {return MOD_CENTROID; }
/* compare params */
\_gt {return COMP_GT; }
\_lt {return COMP_LT; }
\_ge {return COMP_GE; }
\_le {return COMP_LE; }
\_eq {return COMP_EQ; }
\_ne {return COMP_NE; }
{IMMVAL} { {IMMVAL} {
asmshader_lval.immval.val = atof(yytext); asmshader_lval.immval.val = atof(yytext);
asmshader_lval.immval.integer = ((strstr(yytext, ".") == NULL) && (strstr(yytext, "f") == NULL)); asmshader_lval.immval.integer = ((strstr(yytext, ".") == NULL) && (strstr(yytext, "f") == NULL));
......
...@@ -79,6 +79,7 @@ void set_rel_reg(struct shader_reg *reg, struct rel_reg *rel) { ...@@ -79,6 +79,7 @@ void set_rel_reg(struct shader_reg *reg, struct rel_reg *rel) {
DWORD mod; DWORD mod;
DWORD shift; DWORD shift;
} modshift; } modshift;
BWRITER_COMPARISON_TYPE comptype;
struct rel_reg rel_reg; struct rel_reg rel_reg;
struct src_regs sregs; struct src_regs sregs;
} }
...@@ -178,6 +179,14 @@ void set_rel_reg(struct shader_reg *reg, struct rel_reg *rel) { ...@@ -178,6 +179,14 @@ void set_rel_reg(struct shader_reg *reg, struct rel_reg *rel) {
%token MOD_PP %token MOD_PP
%token MOD_CENTROID %token MOD_CENTROID
/* Compare tokens */
%token COMP_GT
%token COMP_LT
%token COMP_GE
%token COMP_LE
%token COMP_EQ
%token COMP_NE
/* Source register modifiers */ /* Source register modifiers */
%token SMOD_ABS %token SMOD_ABS
%token SMOD_NOT %token SMOD_NOT
...@@ -198,6 +207,7 @@ void set_rel_reg(struct shader_reg *reg, struct rel_reg *rel) { ...@@ -198,6 +207,7 @@ void set_rel_reg(struct shader_reg *reg, struct rel_reg *rel) {
%type <sw_components> sw_components %type <sw_components> sw_components
%type <modshift> omods %type <modshift> omods
%type <modshift> omodifier %type <modshift> omodifier
%type <comptype> comp
%type <rel_reg> rel_reg %type <rel_reg> rel_reg
%type <immval> immsum %type <immval> immsum
%type <sregs> sregs %type <sregs> sregs
...@@ -473,6 +483,11 @@ instruction: INSTR_ADD omods dreg ',' sregs ...@@ -473,6 +483,11 @@ instruction: INSTR_ADD omods dreg ',' sregs
TRACE("IF\n"); TRACE("IF\n");
asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_IF, 0, 0, 0, 0, &$2, 1); asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_IF, 0, 0, 0, 0, &$2, 1);
} }
| INSTR_IF comp sregs
{
TRACE("IFC\n");
asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_IFC, 0, 0, $2, 0, &$3, 2);
}
| INSTR_ELSE | INSTR_ELSE
{ {
TRACE("ELSE\n"); TRACE("ELSE\n");
...@@ -488,6 +503,11 @@ instruction: INSTR_ADD omods dreg ',' sregs ...@@ -488,6 +503,11 @@ instruction: INSTR_ADD omods dreg ',' sregs
TRACE("BREAK\n"); TRACE("BREAK\n");
asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_BREAK, 0, 0, 0, 0, 0, 0); asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_BREAK, 0, 0, 0, 0, 0, 0);
} }
| INSTR_BREAK comp sregs
{
TRACE("BREAKC\n");
asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_BREAKC, 0, 0, $2, 0, &$3, 2);
}
| INSTR_CALL sregs | INSTR_CALL sregs
{ {
TRACE("CALL\n"); TRACE("CALL\n");
...@@ -996,6 +1016,13 @@ sreg_name: REG_TEMP ...@@ -996,6 +1016,13 @@ sreg_name: REG_TEMP
$$.regnum = $1; $$.type = BWRITERSPR_LABEL; $$.regnum = $1; $$.type = BWRITERSPR_LABEL;
} }
comp: COMP_GT { $$ = BWRITER_COMPARISON_GT; }
| COMP_LT { $$ = BWRITER_COMPARISON_LT; }
| COMP_GE { $$ = BWRITER_COMPARISON_GE; }
| COMP_LE { $$ = BWRITER_COMPARISON_LE; }
| COMP_EQ { $$ = BWRITER_COMPARISON_EQ; }
| COMP_NE { $$ = BWRITER_COMPARISON_NE; }
%% %%
void asmshader_error (char const *s) { void asmshader_error (char const *s) {
......
...@@ -91,6 +91,20 @@ DWORD d3d9_dstmod(DWORD bwriter_mod) { ...@@ -91,6 +91,20 @@ DWORD d3d9_dstmod(DWORD bwriter_mod) {
return ret; return ret;
} }
DWORD d3d9_comparetype(DWORD asmshader_comparetype) {
switch(asmshader_comparetype) {
case BWRITER_COMPARISON_GT: return D3DSPC_GT;
case BWRITER_COMPARISON_EQ: return D3DSPC_EQ;
case BWRITER_COMPARISON_GE: return D3DSPC_GE;
case BWRITER_COMPARISON_LT: return D3DSPC_LT;
case BWRITER_COMPARISON_NE: return D3DSPC_NE;
case BWRITER_COMPARISON_LE: return D3DSPC_LE;
default:
FIXME("Unexpected BWRITER_COMPARISON type %u\n", asmshader_comparetype);
return 0;
}
}
DWORD d3d9_register(DWORD bwriter_register) { DWORD d3d9_register(DWORD bwriter_register) {
if(bwriter_register == BWRITERSPR_TEMP) return D3DSPR_TEMP; if(bwriter_register == BWRITERSPR_TEMP) return D3DSPR_TEMP;
if(bwriter_register == BWRITERSPR_INPUT) return D3DSPR_INPUT; if(bwriter_register == BWRITERSPR_INPUT) return D3DSPR_INPUT;
...@@ -157,9 +171,11 @@ DWORD d3d9_opcode(DWORD bwriter_opcode) { ...@@ -157,9 +171,11 @@ DWORD d3d9_opcode(DWORD bwriter_opcode) {
case BWRITERSIO_REP: return D3DSIO_REP; case BWRITERSIO_REP: return D3DSIO_REP;
case BWRITERSIO_ENDREP: return D3DSIO_ENDREP; case BWRITERSIO_ENDREP: return D3DSIO_ENDREP;
case BWRITERSIO_IF: return D3DSIO_IF; case BWRITERSIO_IF: return D3DSIO_IF;
case BWRITERSIO_IFC: return D3DSIO_IFC;
case BWRITERSIO_ELSE: return D3DSIO_ELSE; case BWRITERSIO_ELSE: return D3DSIO_ELSE;
case BWRITERSIO_ENDIF: return D3DSIO_ENDIF; case BWRITERSIO_ENDIF: return D3DSIO_ENDIF;
case BWRITERSIO_BREAK: return D3DSIO_BREAK; case BWRITERSIO_BREAK: return D3DSIO_BREAK;
case BWRITERSIO_BREAKC: return D3DSIO_BREAKC;
case BWRITERSIO_MOVA: return D3DSIO_MOVA; case BWRITERSIO_MOVA: return D3DSIO_MOVA;
case BWRITERSIO_EXPP: return D3DSIO_EXPP; case BWRITERSIO_EXPP: return D3DSIO_EXPP;
case BWRITERSIO_LOGP: return D3DSIO_LOGP; case BWRITERSIO_LOGP: return D3DSIO_LOGP;
...@@ -362,6 +378,19 @@ const char *debug_print_srcreg(const struct shader_reg *reg, shader_type st) { ...@@ -362,6 +378,19 @@ const char *debug_print_srcreg(const struct shader_reg *reg, shader_type st) {
return "Unknown modifier"; return "Unknown modifier";
} }
const char *debug_print_comp(DWORD comp) {
switch(comp) {
case BWRITER_COMPARISON_NONE: return "";
case BWRITER_COMPARISON_GT: return "_gt";
case BWRITER_COMPARISON_EQ: return "_eq";
case BWRITER_COMPARISON_GE: return "_ge";
case BWRITER_COMPARISON_LT: return "_lt";
case BWRITER_COMPARISON_NE: return "_ne";
case BWRITER_COMPARISON_LE: return "_le";
default: return "_unknown";
}
}
const char *debug_print_opcode(DWORD opcode) { const char *debug_print_opcode(DWORD opcode) {
switch(opcode){ switch(opcode){
case BWRITERSIO_NOP: return "nop"; case BWRITERSIO_NOP: return "nop";
...@@ -404,9 +433,11 @@ const char *debug_print_opcode(DWORD opcode) { ...@@ -404,9 +433,11 @@ const char *debug_print_opcode(DWORD opcode) {
case BWRITERSIO_REP: return "rep"; case BWRITERSIO_REP: return "rep";
case BWRITERSIO_ENDREP: return "endrep"; case BWRITERSIO_ENDREP: return "endrep";
case BWRITERSIO_IF: return "if"; case BWRITERSIO_IF: return "if";
case BWRITERSIO_IFC: return "ifc";
case BWRITERSIO_ELSE: return "else"; case BWRITERSIO_ELSE: return "else";
case BWRITERSIO_ENDIF: return "endif"; case BWRITERSIO_ENDIF: return "endif";
case BWRITERSIO_BREAK: return "break"; case BWRITERSIO_BREAK: return "break";
case BWRITERSIO_BREAKC: return "breakc";
case BWRITERSIO_MOVA: return "mova"; case BWRITERSIO_MOVA: return "mova";
case BWRITERSIO_EXPP: return "expp"; case BWRITERSIO_EXPP: return "expp";
case BWRITERSIO_LOGP: return "logp"; case BWRITERSIO_LOGP: return "logp";
......
...@@ -196,6 +196,8 @@ static void sm_2_opcode(struct bc_writer *This, ...@@ -196,6 +196,8 @@ static void sm_2_opcode(struct bc_writer *This,
/* From sm 2 onwards instruction length is encoded in the opcode field */ /* From sm 2 onwards instruction length is encoded in the opcode field */
int dsts = instr->has_dst ? 1 : 0; int dsts = instr->has_dst ? 1 : 0;
token |= instrlen(instr, instr->num_srcs, dsts) << D3DSI_INSTLENGTH_SHIFT; token |= instrlen(instr, instr->num_srcs, dsts) << D3DSI_INSTLENGTH_SHIFT;
if(instr->comptype)
token |= (d3d9_comparetype(instr->comptype) << 16) & (0xf << 16);
put_dword(buffer,token); put_dword(buffer,token);
} }
...@@ -324,9 +326,11 @@ static const struct instr_handler_table vs_3_handlers[] = { ...@@ -324,9 +326,11 @@ static const struct instr_handler_table vs_3_handlers[] = {
{BWRITERSIO_ENDREP, instr_handler}, {BWRITERSIO_ENDREP, instr_handler},
{BWRITERSIO_IF, instr_handler}, {BWRITERSIO_IF, instr_handler},
{BWRITERSIO_LABEL, instr_handler}, {BWRITERSIO_LABEL, instr_handler},
{BWRITERSIO_IFC, instr_handler},
{BWRITERSIO_ELSE, instr_handler}, {BWRITERSIO_ELSE, instr_handler},
{BWRITERSIO_ENDIF, instr_handler}, {BWRITERSIO_ENDIF, instr_handler},
{BWRITERSIO_BREAK, instr_handler}, {BWRITERSIO_BREAK, instr_handler},
{BWRITERSIO_BREAKC, instr_handler},
{BWRITERSIO_LOOP, instr_handler}, {BWRITERSIO_LOOP, instr_handler},
{BWRITERSIO_RET, instr_handler}, {BWRITERSIO_RET, instr_handler},
{BWRITERSIO_ENDLOOP, instr_handler}, {BWRITERSIO_ENDLOOP, instr_handler},
......
...@@ -137,7 +137,13 @@ typedef enum _shader_type { ...@@ -137,7 +137,13 @@ typedef enum _shader_type {
} shader_type; } shader_type;
typedef enum BWRITER_COMPARISON_TYPE { typedef enum BWRITER_COMPARISON_TYPE {
BWRITER_COMPARISON_NONE = 0, BWRITER_COMPARISON_NONE,
BWRITER_COMPARISON_GT,
BWRITER_COMPARISON_EQ,
BWRITER_COMPARISON_GE,
BWRITER_COMPARISON_LT,
BWRITER_COMPARISON_NE,
BWRITER_COMPARISON_LE
} BWRITER_COMPARISON_TYPE; } BWRITER_COMPARISON_TYPE;
struct shader_reg { struct shader_reg {
...@@ -345,6 +351,7 @@ const char *debug_print_dstreg(const struct shader_reg *reg, shader_type st); ...@@ -345,6 +351,7 @@ const char *debug_print_dstreg(const struct shader_reg *reg, shader_type st);
const char *debug_print_srcreg(const struct shader_reg *reg, shader_type st); const char *debug_print_srcreg(const struct shader_reg *reg, shader_type st);
const char *debug_print_swizzle(DWORD swizzle); const char *debug_print_swizzle(DWORD swizzle);
const char *debug_print_writemask(DWORD mask); const char *debug_print_writemask(DWORD mask);
const char *debug_print_comp(DWORD comp);
const char *debug_print_opcode(DWORD opcode); const char *debug_print_opcode(DWORD opcode);
/* Utilities for internal->d3d constant mapping */ /* Utilities for internal->d3d constant mapping */
...@@ -352,6 +359,7 @@ DWORD d3d9_swizzle(DWORD bwriter_swizzle); ...@@ -352,6 +359,7 @@ DWORD d3d9_swizzle(DWORD bwriter_swizzle);
DWORD d3d9_writemask(DWORD bwriter_writemask); DWORD d3d9_writemask(DWORD bwriter_writemask);
DWORD d3d9_srcmod(DWORD bwriter_srcmod); DWORD d3d9_srcmod(DWORD bwriter_srcmod);
DWORD d3d9_dstmod(DWORD bwriter_mod); DWORD d3d9_dstmod(DWORD bwriter_mod);
DWORD d3d9_comparetype(DWORD bwriter_comparetype);
DWORD d3d9_register(DWORD bwriter_register); DWORD d3d9_register(DWORD bwriter_register);
DWORD d3d9_opcode(DWORD bwriter_opcode); DWORD d3d9_opcode(DWORD bwriter_opcode);
...@@ -403,9 +411,11 @@ typedef enum _BWRITERSHADER_INSTRUCTION_OPCODE_TYPE { ...@@ -403,9 +411,11 @@ typedef enum _BWRITERSHADER_INSTRUCTION_OPCODE_TYPE {
BWRITERSIO_REP, BWRITERSIO_REP,
BWRITERSIO_ENDREP, BWRITERSIO_ENDREP,
BWRITERSIO_IF, BWRITERSIO_IF,
BWRITERSIO_IFC,
BWRITERSIO_ELSE, BWRITERSIO_ELSE,
BWRITERSIO_ENDIF, BWRITERSIO_ENDIF,
BWRITERSIO_BREAK, BWRITERSIO_BREAK,
BWRITERSIO_BREAKC,
BWRITERSIO_MOVA, BWRITERSIO_MOVA,
BWRITERSIO_EXPP, BWRITERSIO_EXPP,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment