From abb489b29d73cb13f07103b3d871cdbd84d11b03 Mon Sep 17 00:00:00 2001 From: Matteo Bruni Date: Wed, 19 May 2010 14:57:38 +0200 Subject: [PATCH] d3dx9: Add ps_3_0 instructions parsing to the shader assembler. --- dlls/d3dx9_36/asmshader.l | 10 ++++++ dlls/d3dx9_36/asmshader.y | 57 ++++++++++++++++++++++++++++++++ dlls/d3dx9_36/asmutils.c | 21 ++++++++++++ dlls/d3dx9_36/d3dx9_36_private.h | 13 ++++++++ 4 files changed, 101 insertions(+) diff --git a/dlls/d3dx9_36/asmshader.l b/dlls/d3dx9_36/asmshader.l index e65c6f9d0b3..e1aac2686e5 100644 --- a/dlls/d3dx9_36/asmshader.l +++ b/dlls/d3dx9_36/asmshader.l @@ -161,6 +161,16 @@ texldl {return INSTR_TEXLDL; } lit {return INSTR_LIT; } mova {return INSTR_MOVA; } + /* Pixel shader only instructions */ +cmp {return INSTR_CMP; } +dp2add {return INSTR_DP2ADD; } +texkill {return INSTR_TEXKILL; } +texld {return INSTR_TEXLD; } +dsx {return INSTR_DSX; } +dsy {return INSTR_DSY; } +texldp {return INSTR_TEXLDP; } +texldb {return INSTR_TEXLDB; } +texldd {return INSTR_TEXLDD; } {REG_TEMP} { asmshader_lval.regnum = atoi(yytext + 1); diff --git a/dlls/d3dx9_36/asmshader.y b/dlls/d3dx9_36/asmshader.y index f8dd716ae6c..657ce3c6c89 100644 --- a/dlls/d3dx9_36/asmshader.y +++ b/dlls/d3dx9_36/asmshader.y @@ -147,6 +147,17 @@ void set_rel_reg(struct shader_reg *reg, struct rel_reg *rel) { %token INSTR_LIT %token INSTR_MOVA +/* Pixel shader only instructions */ +%token INSTR_CMP +%token INSTR_DP2ADD +%token INSTR_TEXKILL +%token INSTR_TEXLD +%token INSTR_DSX +%token INSTR_DSY +%token INSTR_TEXLDP +%token INSTR_TEXLDB +%token INSTR_TEXLDD + /* Registers */ %token REG_TEMP %token REG_OUTPUT @@ -685,6 +696,52 @@ instruction: INSTR_ADD omods dreg ',' sregs TRACE("MOVA\n"); asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_MOVA, $2.mod, $2.shift, 0, &$3, &$5, 1); } + | INSTR_CMP omods dreg ',' sregs + { + TRACE("CMP\n"); + asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_CMP, $2.mod, $2.shift, 0, &$3, &$5, 3); + } + | INSTR_DP2ADD omods dreg ',' sregs + { + TRACE("DP2ADD\n"); + asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_DP2ADD, $2.mod, $2.shift, 0, &$3, &$5, 3); + } + | INSTR_TEXLD omods dreg ',' sregs + { + TRACE("TEXLD\n"); + /* There is more than one acceptable syntax for texld: + with 1 sreg (PS 1.4) or + with 2 sregs (PS 2.0+) + Moreover, texld shares the same opcode as the tex instruction, + so there are a total of 3 valid syntaxes + These variations are handled in asmparser.c */ + asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEX, $2.mod, $2.shift, 0, &$3, &$5, 2); + } + | INSTR_TEXLDP omods dreg ',' sregs + { + TRACE("TEXLDP\n"); + asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEX | ( BWRITERSI_TEXLD_PROJECT << BWRITER_OPCODESPECIFICCONTROL_SHIFT ), $2.mod, $2.shift, 0, &$3, &$5, 2); + } + | INSTR_TEXLDB omods dreg ',' sregs + { + TRACE("TEXLDB\n"); + asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEX | ( BWRITERSI_TEXLD_BIAS << BWRITER_OPCODESPECIFICCONTROL_SHIFT ), $2.mod, $2.shift, 0, &$3, &$5, 2); + } + | INSTR_DSX omods dreg ',' sregs + { + TRACE("DSX\n"); + asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_DSX, $2.mod, $2.shift, 0, &$3, &$5, 1); + } + | INSTR_DSY omods dreg ',' sregs + { + TRACE("DSY\n"); + asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_DSY, $2.mod, $2.shift, 0, &$3, &$5, 1); + } + | INSTR_TEXLDD omods dreg ',' sregs + { + TRACE("TEXLDD\n"); + asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXLDD, $2.mod, $2.shift, 0, &$3, &$5, 4); + } dreg: dreg_name rel_reg { diff --git a/dlls/d3dx9_36/asmutils.c b/dlls/d3dx9_36/asmutils.c index c5ef6c2dc90..e000a5faacb 100644 --- a/dlls/d3dx9_36/asmutils.c +++ b/dlls/d3dx9_36/asmutils.c @@ -191,9 +191,17 @@ DWORD d3d9_opcode(DWORD bwriter_opcode) { case BWRITERSIO_MOVA: return D3DSIO_MOVA; case BWRITERSIO_DEFB: return D3DSIO_DEFB; case BWRITERSIO_DEFI: return D3DSIO_DEFI; + + case BWRITERSIO_TEXKILL: return D3DSIO_TEXKILL; + case BWRITERSIO_TEX: return D3DSIO_TEX; case BWRITERSIO_EXPP: return D3DSIO_EXPP; case BWRITERSIO_LOGP: return D3DSIO_LOGP; case BWRITERSIO_DEF: return D3DSIO_DEF; + case BWRITERSIO_CMP: return D3DSIO_CMP; + case BWRITERSIO_DP2ADD: return D3DSIO_DP2ADD; + case BWRITERSIO_DSX: return D3DSIO_DSX; + case BWRITERSIO_DSY: return D3DSIO_DSY; + case BWRITERSIO_TEXLDD: return D3DSIO_TEXLDD; case BWRITERSIO_SETP: return D3DSIO_SETP; case BWRITERSIO_TEXLDL: return D3DSIO_TEXLDL; case BWRITERSIO_BREAKP: return D3DSIO_BREAKP; @@ -201,6 +209,9 @@ DWORD d3d9_opcode(DWORD bwriter_opcode) { case BWRITERSIO_COMMENT: return D3DSIO_COMMENT; case BWRITERSIO_END: return D3DSIO_END; + case BWRITERSIO_TEX | ( BWRITERSI_TEXLD_PROJECT << BWRITER_OPCODESPECIFICCONTROL_SHIFT ): return D3DSIO_TEX | D3DSI_TEXLD_PROJECT; + case BWRITERSIO_TEX | ( BWRITERSI_TEXLD_BIAS << BWRITER_OPCODESPECIFICCONTROL_SHIFT ): return D3DSIO_TEX | D3DSI_TEXLD_BIAS; + default: FIXME("Unhandled BWRITERSIO token %u\n", bwriter_opcode); return -1; @@ -459,13 +470,23 @@ const char *debug_print_opcode(DWORD opcode) { case BWRITERSIO_MOVA: return "mova"; case BWRITERSIO_DEFB: return "defb"; case BWRITERSIO_DEFI: return "defi"; + case BWRITERSIO_TEXKILL: return "texkill"; + case BWRITERSIO_TEX: return "tex"; case BWRITERSIO_EXPP: return "expp"; case BWRITERSIO_LOGP: return "logp"; case BWRITERSIO_DEF: return "def"; + case BWRITERSIO_CMP: return "cmp"; + case BWRITERSIO_DP2ADD: return "dp2add"; + case BWRITERSIO_DSX: return "dsx"; + case BWRITERSIO_DSY: return "dsy"; + case BWRITERSIO_TEXLDD: return "texldd"; case BWRITERSIO_SETP: return "setp"; case BWRITERSIO_TEXLDL: return "texldl"; case BWRITERSIO_BREAKP: return "breakp"; + case BWRITERSIO_TEX | ( BWRITERSI_TEXLD_PROJECT << BWRITER_OPCODESPECIFICCONTROL_SHIFT ): return "texldp"; + case BWRITERSIO_TEX | ( BWRITERSI_TEXLD_BIAS << BWRITER_OPCODESPECIFICCONTROL_SHIFT ): return "texldb"; + default: return "unknown"; } } diff --git a/dlls/d3dx9_36/d3dx9_36_private.h b/dlls/d3dx9_36/d3dx9_36_private.h index ffecd314f2e..e5816b335ce 100644 --- a/dlls/d3dx9_36/d3dx9_36_private.h +++ b/dlls/d3dx9_36/d3dx9_36_private.h @@ -448,9 +448,16 @@ typedef enum _BWRITERSHADER_INSTRUCTION_OPCODE_TYPE { BWRITERSIO_DEFB, BWRITERSIO_DEFI, + BWRITERSIO_TEXKILL, + BWRITERSIO_TEX, BWRITERSIO_EXPP, BWRITERSIO_LOGP, BWRITERSIO_DEF, + BWRITERSIO_CMP, + BWRITERSIO_DP2ADD, + BWRITERSIO_DSX, + BWRITERSIO_DSY, + BWRITERSIO_TEXLDD, BWRITERSIO_SETP, BWRITERSIO_TEXLDL, BWRITERSIO_BREAKP, @@ -508,6 +515,9 @@ typedef enum _BWRITERSAMPLER_TEXTURE_TYPE { BWRITERSTT_VOLUME = 4, } BWRITERSAMPLER_TEXTURE_TYPE; +#define BWRITERSI_TEXLD_PROJECT 1 +#define BWRITERSI_TEXLD_BIAS 2 + typedef enum _BWRITERSHADER_PARAM_SRCMOD_TYPE { BWRITERSPSM_NONE = 0, BWRITERSPSM_NEG, @@ -578,6 +588,9 @@ typedef enum _BWRITERDECLUSAGE { BWRITERDECLUSAGE_SAMPLE } BWRITERDECLUSAGE; +#define BWRITER_OPCODESPECIFICCONTROL_SHIFT 16 +#define BWRITER_OPCODESPECIFICCONTROL_MASK (0xff << BWRITER_OPCODESPECIFICCONTROL_SHIFT) + struct bwriter_shader *SlAssembleShader(const char *text, char **messages); DWORD SlWriteBytecode(const struct bwriter_shader *shader, int dxversion, DWORD **result); void SlDeleteShader(struct bwriter_shader *shader);