From 25c929ab6191eb1ccb158f676e5cbcbcf29d6f19 Mon Sep 17 00:00:00 2001 From: Matteo Bruni Date: Tue, 11 May 2010 20:29:07 +0200 Subject: [PATCH] d3dx9: Support some flow control instructions in the shader assembler. --- dlls/d3dx9_36/asmshader.l | 14 ++++++ dlls/d3dx9_36/asmshader.y | 81 ++++++++++++++++++++++++++++++++ dlls/d3dx9_36/asmutils.c | 30 ++++++++++++ dlls/d3dx9_36/bytecodewriter.c | 13 +++++ dlls/d3dx9_36/d3dx9_36_private.h | 13 +++++ 5 files changed, 151 insertions(+) diff --git a/dlls/d3dx9_36/asmshader.l b/dlls/d3dx9_36/asmshader.l index 9d399c835d7..1cc28b8008b 100644 --- a/dlls/d3dx9_36/asmshader.l +++ b/dlls/d3dx9_36/asmshader.l @@ -117,6 +117,18 @@ m4x3 {return INSTR_M4x3; } m3x4 {return INSTR_M3x4; } m3x3 {return INSTR_M3x3; } m3x2 {return INSTR_M3x2; } +rep {return INSTR_REP; } +endrep {return INSTR_ENDREP; } +if {return INSTR_IF; } +else {return INSTR_ELSE; } +endif {return INSTR_ENDIF; } +break {return INSTR_BREAK; } +call {return INSTR_CALL; } +callnz {return INSTR_CALLNZ; } +loop {return INSTR_LOOP; } +ret {return INSTR_RET; } +endloop {return INSTR_ENDLOOP; } +label {return INSTR_LABEL; } texldl {return INSTR_TEXLDL; } /* Vertex shader only instructions */ @@ -247,6 +259,8 @@ ps_3_0 {return VER_PS30; } \_abs {return SMOD_ABS; } +! {return SMOD_NOT; } + {PREPROCESSORDIRECTIVE} { /* TODO: update current line information */ TRACE("line info update: %s", yytext); diff --git a/dlls/d3dx9_36/asmshader.y b/dlls/d3dx9_36/asmshader.y index feb370b0cdc..ef09307d94f 100644 --- a/dlls/d3dx9_36/asmshader.y +++ b/dlls/d3dx9_36/asmshader.y @@ -116,6 +116,18 @@ void set_rel_reg(struct shader_reg *reg, struct rel_reg *rel) { %token INSTR_M3x4 %token INSTR_M3x3 %token INSTR_M3x2 +%token INSTR_REP +%token INSTR_ENDREP +%token INSTR_IF +%token INSTR_ELSE +%token INSTR_ENDIF +%token INSTR_BREAK +%token INSTR_CALL +%token INSTR_CALLNZ +%token INSTR_LOOP +%token INSTR_RET +%token INSTR_ENDLOOP +%token INSTR_LABEL %token INSTR_TEXLDL /* Vertex shader only instructions */ @@ -168,6 +180,7 @@ void set_rel_reg(struct shader_reg *reg, struct rel_reg *rel) { /* Source register modifiers */ %token SMOD_ABS +%token SMOD_NOT /* Misc stuff */ %token COMPONENT @@ -445,6 +458,66 @@ instruction: INSTR_ADD omods dreg ',' sregs TRACE("M3x2\n"); asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_M3x2, $2.mod, $2.shift, 0, &$3, &$5, 2); } + | INSTR_REP sregs + { + TRACE("REP\n"); + asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_REP, 0, 0, 0, 0, &$2, 1); + } + | INSTR_ENDREP + { + TRACE("ENDREP\n"); + asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_ENDREP, 0, 0, 0, 0, 0, 0); + } + | INSTR_IF sregs + { + TRACE("IF\n"); + asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_IF, 0, 0, 0, 0, &$2, 1); + } + | INSTR_ELSE + { + TRACE("ELSE\n"); + asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_ELSE, 0, 0, 0, 0, 0, 0); + } + | INSTR_ENDIF + { + TRACE("ENDIF\n"); + asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_ENDIF, 0, 0, 0, 0, 0, 0); + } + | INSTR_BREAK + { + TRACE("BREAK\n"); + asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_BREAK, 0, 0, 0, 0, 0, 0); + } + | INSTR_CALL sregs + { + TRACE("CALL\n"); + asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_CALL, 0, 0, 0, 0, &$2, 1); + } + | INSTR_CALLNZ sregs + { + TRACE("CALLNZ\n"); + asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_CALLNZ, 0, 0, 0, 0, &$2, 2); + } + | INSTR_LOOP sregs + { + TRACE("LOOP\n"); + asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_LOOP, 0, 0, 0, 0, &$2, 2); + } + | INSTR_RET + { + TRACE("RET\n"); + asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_RET, 0, 0, 0, 0, 0, 0); + } + | INSTR_ENDLOOP + { + TRACE("ENDLOOP\n"); + asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_ENDLOOP, 0, 0, 0, 0, 0, 0); + } + | INSTR_LABEL sregs + { + TRACE("LABEL\n"); + asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_LABEL, 0, 0, 0, 0, &$2, 1); + } | INSTR_TEXLDL omods dreg ',' sregs { TRACE("TEXLDL\n"); @@ -743,6 +816,14 @@ sreg: sreg_name rel_reg swizzle } $$.swizzle = $5; } + | SMOD_NOT sreg_name swizzle + { + $$.type = $2.type; + $$.regnum = $2.regnum; + $$.rel_reg = NULL; + $$.srcmod = BWRITERSPSM_NOT; + $$.swizzle = $3; + } rel_reg: /* empty */ { diff --git a/dlls/d3dx9_36/asmutils.c b/dlls/d3dx9_36/asmutils.c index 47291e389df..5d12e4e5c03 100644 --- a/dlls/d3dx9_36/asmutils.c +++ b/dlls/d3dx9_36/asmutils.c @@ -74,6 +74,7 @@ DWORD d3d9_srcmod(DWORD bwriter_srcmod) { case BWRITERSPSM_NEG: return D3DSPSM_NEG; case BWRITERSPSM_ABS: return D3DSPSM_ABS; case BWRITERSPSM_ABSNEG: return D3DSPSM_ABSNEG; + case BWRITERSPSM_NOT: return D3DSPSM_NOT; default: FIXME("Unhandled BWRITERSPSM token %u\n", bwriter_srcmod); return 0; @@ -141,12 +142,24 @@ DWORD d3d9_opcode(DWORD bwriter_opcode) { case BWRITERSIO_M3x4: return D3DSIO_M3x4; case BWRITERSIO_M3x3: return D3DSIO_M3x3; case BWRITERSIO_M3x2: return D3DSIO_M3x2; + case BWRITERSIO_CALL: return D3DSIO_CALL; + case BWRITERSIO_CALLNZ: return D3DSIO_CALLNZ; + case BWRITERSIO_LOOP: return D3DSIO_LOOP; + case BWRITERSIO_RET: return D3DSIO_RET; + case BWRITERSIO_ENDLOOP: return D3DSIO_ENDLOOP; + case BWRITERSIO_LABEL: return D3DSIO_LABEL; case BWRITERSIO_POW: return D3DSIO_POW; case BWRITERSIO_CRS: return D3DSIO_CRS; case BWRITERSIO_SGN: return D3DSIO_SGN; case BWRITERSIO_ABS: return D3DSIO_ABS; case BWRITERSIO_NRM: return D3DSIO_NRM; case BWRITERSIO_SINCOS: return D3DSIO_SINCOS; + case BWRITERSIO_REP: return D3DSIO_REP; + case BWRITERSIO_ENDREP: return D3DSIO_ENDREP; + case BWRITERSIO_IF: return D3DSIO_IF; + case BWRITERSIO_ELSE: return D3DSIO_ELSE; + case BWRITERSIO_ENDIF: return D3DSIO_ENDIF; + case BWRITERSIO_BREAK: return D3DSIO_BREAK; case BWRITERSIO_MOVA: return D3DSIO_MOVA; case BWRITERSIO_EXPP: return D3DSIO_EXPP; case BWRITERSIO_LOGP: return D3DSIO_LOGP; @@ -167,6 +180,7 @@ const char *debug_print_srcmod(DWORD mod) { case BWRITERSPSM_NEG: return "D3DSPSM_NEG"; case BWRITERSPSM_ABS: return "D3DSPSM_ABS"; case BWRITERSPSM_ABSNEG: return "D3DSPSM_ABSNEG"; + case BWRITERSPSM_NOT: return "D3DSPSM_NOT"; default: return "Unknown source modifier\n"; } } @@ -340,6 +354,10 @@ const char *debug_print_srcreg(const struct shader_reg *reg, shader_type st) { return wine_dbg_sprintf("-%s%s_abs%s", get_regname(reg, st), debug_print_relarg(reg), debug_print_swizzle(reg->swizzle)); + case BWRITERSPSM_NOT: + return wine_dbg_sprintf("!%s%s%s", get_regname(reg, st), + debug_print_relarg(reg), + debug_print_swizzle(reg->swizzle)); } return "Unknown modifier"; } @@ -371,12 +389,24 @@ const char *debug_print_opcode(DWORD opcode) { case BWRITERSIO_M3x4: return "m3x4"; case BWRITERSIO_M3x3: return "m3x3"; case BWRITERSIO_M3x2: return "m3x2"; + case BWRITERSIO_CALL: return "call"; + case BWRITERSIO_CALLNZ: return "callnz"; + case BWRITERSIO_LOOP: return "loop"; + case BWRITERSIO_RET: return "ret"; + case BWRITERSIO_ENDLOOP: return "endloop"; + case BWRITERSIO_LABEL: return "label"; case BWRITERSIO_POW: return "pow"; case BWRITERSIO_CRS: return "crs"; case BWRITERSIO_SGN: return "sgn"; case BWRITERSIO_ABS: return "abs"; case BWRITERSIO_NRM: return "nrm"; case BWRITERSIO_SINCOS: return "sincos"; + case BWRITERSIO_REP: return "rep"; + case BWRITERSIO_ENDREP: return "endrep"; + case BWRITERSIO_IF: return "if"; + case BWRITERSIO_ELSE: return "else"; + case BWRITERSIO_ENDIF: return "endif"; + case BWRITERSIO_BREAK: return "break"; case BWRITERSIO_MOVA: return "mova"; case BWRITERSIO_EXPP: return "expp"; case BWRITERSIO_LOGP: return "logp"; diff --git a/dlls/d3dx9_36/bytecodewriter.c b/dlls/d3dx9_36/bytecodewriter.c index 7205e76e76a..c30ae67dc56 100644 --- a/dlls/d3dx9_36/bytecodewriter.c +++ b/dlls/d3dx9_36/bytecodewriter.c @@ -318,6 +318,19 @@ static const struct instr_handler_table vs_3_handlers[] = { {BWRITERSIO_POW, instr_handler}, {BWRITERSIO_MOVA, instr_handler}, + {BWRITERSIO_CALL, instr_handler}, + {BWRITERSIO_CALLNZ, instr_handler}, + {BWRITERSIO_REP, instr_handler}, + {BWRITERSIO_ENDREP, instr_handler}, + {BWRITERSIO_IF, instr_handler}, + {BWRITERSIO_LABEL, instr_handler}, + {BWRITERSIO_ELSE, instr_handler}, + {BWRITERSIO_ENDIF, instr_handler}, + {BWRITERSIO_BREAK, instr_handler}, + {BWRITERSIO_LOOP, instr_handler}, + {BWRITERSIO_RET, instr_handler}, + {BWRITERSIO_ENDLOOP, instr_handler}, + {BWRITERSIO_TEXLDL, instr_handler}, {BWRITERSIO_END, NULL}, diff --git a/dlls/d3dx9_36/d3dx9_36_private.h b/dlls/d3dx9_36/d3dx9_36_private.h index fd1cbca9816..22b47148dc6 100644 --- a/dlls/d3dx9_36/d3dx9_36_private.h +++ b/dlls/d3dx9_36/d3dx9_36_private.h @@ -388,12 +388,24 @@ typedef enum _BWRITERSHADER_INSTRUCTION_OPCODE_TYPE { BWRITERSIO_M3x4, BWRITERSIO_M3x3, BWRITERSIO_M3x2, + BWRITERSIO_CALL, + BWRITERSIO_CALLNZ, + BWRITERSIO_LOOP, + BWRITERSIO_RET, + BWRITERSIO_ENDLOOP, + BWRITERSIO_LABEL, BWRITERSIO_POW, BWRITERSIO_CRS, BWRITERSIO_SGN, BWRITERSIO_ABS, BWRITERSIO_NRM, BWRITERSIO_SINCOS, + BWRITERSIO_REP, + BWRITERSIO_ENDREP, + BWRITERSIO_IF, + BWRITERSIO_ELSE, + BWRITERSIO_ENDIF, + BWRITERSIO_BREAK, BWRITERSIO_MOVA, BWRITERSIO_EXPP, @@ -450,6 +462,7 @@ typedef enum _BWRITERSHADER_PARAM_SRCMOD_TYPE { BWRITERSPSM_NEG, BWRITERSPSM_ABS, BWRITERSPSM_ABSNEG, + BWRITERSPSM_NOT, } BWRITERSHADER_PARAM_SRCMOD_TYPE; #define BWRITER_SM1_VS 0xfffe