From 93b2648c49497ef1fd55fb09b67227e8e3ad319f Mon Sep 17 00:00:00 2001 From: Matteo Bruni Date: Tue, 24 Nov 2009 02:08:32 +0100 Subject: [PATCH] d3dx9: Add other flow control instructions in the shader assembler. --- dlls/d3dx9_36/asmparser.c | 5 +++-- dlls/d3dx9_36/asmshader.l | 8 ++++++++ dlls/d3dx9_36/asmshader.y | 27 +++++++++++++++++++++++++++ dlls/d3dx9_36/asmutils.c | 31 +++++++++++++++++++++++++++++++ dlls/d3dx9_36/bytecodewriter.c | 4 ++++ dlls/d3dx9_36/d3dx9_36_private.h | 12 +++++++++++- 6 files changed, 84 insertions(+), 3 deletions(-) diff --git a/dlls/d3dx9_36/asmparser.c b/dlls/d3dx9_36/asmparser.c index c810cbbcd0b..15ac7eac3f7 100644 --- a/dlls/d3dx9_36/asmparser.c +++ b/dlls/d3dx9_36/asmparser.c @@ -50,8 +50,9 @@ static void asmparser_instr(struct asm_parser *This, DWORD opcode, if(!This->shader) return; - TRACE_(parsed_shader)("%s%s ", debug_print_opcode(opcode), - debug_print_dstmod(mod)); + TRACE_(parsed_shader)("%s%s%s ", debug_print_opcode(opcode), + debug_print_dstmod(mod), + debug_print_comp(comp)); if(dst) { TRACE_(parsed_shader)("%s", debug_print_dstreg(dst, This->shader->type)); firstreg = FALSE; diff --git a/dlls/d3dx9_36/asmshader.l b/dlls/d3dx9_36/asmshader.l index 1cc28b8008b..a62f668ed3f 100644 --- a/dlls/d3dx9_36/asmshader.l +++ b/dlls/d3dx9_36/asmshader.l @@ -243,6 +243,14 @@ ps_3_0 {return VER_PS30; } \_pp {return MOD_PP; } \_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} { asmshader_lval.immval.val = atof(yytext); asmshader_lval.immval.integer = ((strstr(yytext, ".") == NULL) && (strstr(yytext, "f") == NULL)); diff --git a/dlls/d3dx9_36/asmshader.y b/dlls/d3dx9_36/asmshader.y index ef09307d94f..ed4dd719aaf 100644 --- a/dlls/d3dx9_36/asmshader.y +++ b/dlls/d3dx9_36/asmshader.y @@ -79,6 +79,7 @@ void set_rel_reg(struct shader_reg *reg, struct rel_reg *rel) { DWORD mod; DWORD shift; } modshift; + BWRITER_COMPARISON_TYPE comptype; struct rel_reg rel_reg; struct src_regs sregs; } @@ -178,6 +179,14 @@ void set_rel_reg(struct shader_reg *reg, struct rel_reg *rel) { %token MOD_PP %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 */ %token SMOD_ABS %token SMOD_NOT @@ -198,6 +207,7 @@ void set_rel_reg(struct shader_reg *reg, struct rel_reg *rel) { %type sw_components %type omods %type omodifier +%type comp %type rel_reg %type immsum %type sregs @@ -473,6 +483,11 @@ instruction: INSTR_ADD omods dreg ',' sregs TRACE("IF\n"); 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 { TRACE("ELSE\n"); @@ -488,6 +503,11 @@ instruction: INSTR_ADD omods dreg ',' sregs TRACE("BREAK\n"); 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 { TRACE("CALL\n"); @@ -996,6 +1016,13 @@ sreg_name: REG_TEMP $$.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) { diff --git a/dlls/d3dx9_36/asmutils.c b/dlls/d3dx9_36/asmutils.c index 5d12e4e5c03..229fa5eb109 100644 --- a/dlls/d3dx9_36/asmutils.c +++ b/dlls/d3dx9_36/asmutils.c @@ -91,6 +91,20 @@ DWORD d3d9_dstmod(DWORD bwriter_mod) { 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) { if(bwriter_register == BWRITERSPR_TEMP) return D3DSPR_TEMP; if(bwriter_register == BWRITERSPR_INPUT) return D3DSPR_INPUT; @@ -157,9 +171,11 @@ DWORD d3d9_opcode(DWORD bwriter_opcode) { case BWRITERSIO_REP: return D3DSIO_REP; case BWRITERSIO_ENDREP: return D3DSIO_ENDREP; case BWRITERSIO_IF: return D3DSIO_IF; + case BWRITERSIO_IFC: return D3DSIO_IFC; case BWRITERSIO_ELSE: return D3DSIO_ELSE; case BWRITERSIO_ENDIF: return D3DSIO_ENDIF; case BWRITERSIO_BREAK: return D3DSIO_BREAK; + case BWRITERSIO_BREAKC: return D3DSIO_BREAKC; case BWRITERSIO_MOVA: return D3DSIO_MOVA; case BWRITERSIO_EXPP: return D3DSIO_EXPP; case BWRITERSIO_LOGP: return D3DSIO_LOGP; @@ -362,6 +378,19 @@ const char *debug_print_srcreg(const struct shader_reg *reg, shader_type st) { 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) { switch(opcode){ case BWRITERSIO_NOP: return "nop"; @@ -404,9 +433,11 @@ const char *debug_print_opcode(DWORD opcode) { case BWRITERSIO_REP: return "rep"; case BWRITERSIO_ENDREP: return "endrep"; case BWRITERSIO_IF: return "if"; + case BWRITERSIO_IFC: return "ifc"; case BWRITERSIO_ELSE: return "else"; case BWRITERSIO_ENDIF: return "endif"; case BWRITERSIO_BREAK: return "break"; + case BWRITERSIO_BREAKC: return "breakc"; 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 c30ae67dc56..17bc3d56b43 100644 --- a/dlls/d3dx9_36/bytecodewriter.c +++ b/dlls/d3dx9_36/bytecodewriter.c @@ -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 */ int dsts = instr->has_dst ? 1 : 0; 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); } @@ -324,9 +326,11 @@ static const struct instr_handler_table vs_3_handlers[] = { {BWRITERSIO_ENDREP, instr_handler}, {BWRITERSIO_IF, instr_handler}, {BWRITERSIO_LABEL, instr_handler}, + {BWRITERSIO_IFC, instr_handler}, {BWRITERSIO_ELSE, instr_handler}, {BWRITERSIO_ENDIF, instr_handler}, {BWRITERSIO_BREAK, instr_handler}, + {BWRITERSIO_BREAKC, instr_handler}, {BWRITERSIO_LOOP, instr_handler}, {BWRITERSIO_RET, instr_handler}, {BWRITERSIO_ENDLOOP, instr_handler}, diff --git a/dlls/d3dx9_36/d3dx9_36_private.h b/dlls/d3dx9_36/d3dx9_36_private.h index 22b47148dc6..b83ee496752 100644 --- a/dlls/d3dx9_36/d3dx9_36_private.h +++ b/dlls/d3dx9_36/d3dx9_36_private.h @@ -137,7 +137,13 @@ typedef enum _shader_type { } shader_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; struct shader_reg { @@ -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_swizzle(DWORD swizzle); const char *debug_print_writemask(DWORD mask); +const char *debug_print_comp(DWORD comp); const char *debug_print_opcode(DWORD opcode); /* Utilities for internal->d3d constant mapping */ @@ -352,6 +359,7 @@ DWORD d3d9_swizzle(DWORD bwriter_swizzle); DWORD d3d9_writemask(DWORD bwriter_writemask); DWORD d3d9_srcmod(DWORD bwriter_srcmod); DWORD d3d9_dstmod(DWORD bwriter_mod); +DWORD d3d9_comparetype(DWORD bwriter_comparetype); DWORD d3d9_register(DWORD bwriter_register); DWORD d3d9_opcode(DWORD bwriter_opcode); @@ -403,9 +411,11 @@ typedef enum _BWRITERSHADER_INSTRUCTION_OPCODE_TYPE { BWRITERSIO_REP, BWRITERSIO_ENDREP, BWRITERSIO_IF, + BWRITERSIO_IFC, BWRITERSIO_ELSE, BWRITERSIO_ENDIF, BWRITERSIO_BREAK, + BWRITERSIO_BREAKC, BWRITERSIO_MOVA, BWRITERSIO_EXPP,