From fa44f242b52d8dee71ac067516ccefba7e7caa11 Mon Sep 17 00:00:00 2001 From: Matteo Bruni Date: Fri, 14 May 2010 17:21:42 +0200 Subject: [PATCH] d3dx9: Add DEFI instruction support in the shader assembler. --- dlls/d3dx9_36/asmparser.c | 11 ++++++ dlls/d3dx9_36/asmshader.l | 1 + dlls/d3dx9_36/asmshader.y | 5 +++ dlls/d3dx9_36/asmutils.c | 2 + dlls/d3dx9_36/bytecodewriter.c | 64 +++++++++++++++++++++++++++----- dlls/d3dx9_36/d3dx9_36_private.h | 3 ++ 6 files changed, 77 insertions(+), 9 deletions(-) diff --git a/dlls/d3dx9_36/asmparser.c b/dlls/d3dx9_36/asmparser.c index a2d57e0619e..68ee5cecb60 100644 --- a/dlls/d3dx9_36/asmparser.c +++ b/dlls/d3dx9_36/asmparser.c @@ -48,6 +48,16 @@ static void asmparser_constF(struct asm_parser *This, DWORD reg, float x, float } } +static void asmparser_constI(struct asm_parser *This, DWORD reg, INT x, INT y, INT z, INT w) { + if(!This->shader) return; + TRACE("Adding integer constant %u at pos %u\n", reg, This->shader->num_ci); + TRACE_(parsed_shader)("def i%u, %d, %d, %d, %d\n", reg, x, y, z, w); + if(!add_constI(This->shader, reg, x, y, z, w)) { + ERR("Out of memory\n"); + set_parse_status(This, PARSE_ERR); + } +} + static void asmparser_dcl_output(struct asm_parser *This, DWORD usage, DWORD num, const struct shader_reg *reg) { if(!This->shader) return; @@ -170,6 +180,7 @@ static void asmparser_coissue_unsupported(struct asm_parser *This) { static const struct asmparser_backend parser_vs_3 = { asmparser_constF, + asmparser_constI, asmparser_dstreg_vs_3, asmparser_srcreg_vs_3, diff --git a/dlls/d3dx9_36/asmshader.l b/dlls/d3dx9_36/asmshader.l index 690a5a7950a..e8037f708d1 100644 --- a/dlls/d3dx9_36/asmshader.l +++ b/dlls/d3dx9_36/asmshader.l @@ -139,6 +139,7 @@ m3x3 {return INSTR_M3x3; } m3x2 {return INSTR_M3x2; } dcl {return INSTR_DCL; } def {return INSTR_DEF; } +defi {return INSTR_DEFI; } rep {return INSTR_REP; } endrep {return INSTR_ENDREP; } if {return INSTR_IF; } diff --git a/dlls/d3dx9_36/asmshader.y b/dlls/d3dx9_36/asmshader.y index bb4c43f8be5..5321ad8f431 100644 --- a/dlls/d3dx9_36/asmshader.y +++ b/dlls/d3dx9_36/asmshader.y @@ -124,6 +124,7 @@ void set_rel_reg(struct shader_reg *reg, struct rel_reg *rel) { %token INSTR_M3x2 %token INSTR_DCL %token INSTR_DEF +%token INSTR_DEFI %token INSTR_REP %token INSTR_ENDREP %token INSTR_IF @@ -578,6 +579,10 @@ instruction: INSTR_ADD omods dreg ',' sregs { asm_ctx.funcs->constF(&asm_ctx, $2, $4.val, $6.val, $8.val, $10.val); } + | INSTR_DEFI REG_CONSTINT ',' IMMVAL ',' IMMVAL ',' IMMVAL ',' IMMVAL + { + asm_ctx.funcs->constI(&asm_ctx, $2, $4.val, $6.val, $8.val, $10.val); + } | INSTR_REP sregs { TRACE("REP\n"); diff --git a/dlls/d3dx9_36/asmutils.c b/dlls/d3dx9_36/asmutils.c index 3772c5fb96d..52fc2d04019 100644 --- a/dlls/d3dx9_36/asmutils.c +++ b/dlls/d3dx9_36/asmutils.c @@ -189,6 +189,7 @@ DWORD d3d9_opcode(DWORD bwriter_opcode) { case BWRITERSIO_BREAK: return D3DSIO_BREAK; case BWRITERSIO_BREAKC: return D3DSIO_BREAKC; case BWRITERSIO_MOVA: return D3DSIO_MOVA; + case BWRITERSIO_DEFI: return D3DSIO_DEFI; case BWRITERSIO_EXPP: return D3DSIO_EXPP; case BWRITERSIO_LOGP: return D3DSIO_LOGP; case BWRITERSIO_DEF: return D3DSIO_DEF; @@ -455,6 +456,7 @@ const char *debug_print_opcode(DWORD opcode) { case BWRITERSIO_BREAK: return "break"; case BWRITERSIO_BREAKC: return "breakc"; case BWRITERSIO_MOVA: return "mova"; + case BWRITERSIO_DEFI: return "defi"; case BWRITERSIO_EXPP: return "expp"; case BWRITERSIO_LOGP: return "logp"; case BWRITERSIO_DEF: return "def"; diff --git a/dlls/d3dx9_36/bytecodewriter.c b/dlls/d3dx9_36/bytecodewriter.c index c14f0223097..c6bdfd0513a 100644 --- a/dlls/d3dx9_36/bytecodewriter.c +++ b/dlls/d3dx9_36/bytecodewriter.c @@ -140,6 +140,42 @@ BOOL add_constF(struct bwriter_shader *shader, DWORD reg, float x, float y, floa return TRUE; } +BOOL add_constI(struct bwriter_shader *shader, DWORD reg, INT x, INT y, INT z, INT w) { + struct constant *newconst; + + if(shader->num_ci) { + struct constant **newarray; + newarray = asm_realloc(shader->constI, + sizeof(*shader->constI) * (shader->num_ci + 1)); + if(!newarray) { + ERR("Failed to grow the constants array\n"); + return FALSE; + } + shader->constI = newarray; + } else { + shader->constI = asm_alloc(sizeof(*shader->constI)); + if(!shader->constI) { + ERR("Failed to allocate the constants array\n"); + return FALSE; + } + } + + newconst = asm_alloc(sizeof(*newconst)); + if(!newconst) { + ERR("Failed to allocate a new constant\n"); + return FALSE; + } + newconst->regnum = reg; + newconst->value[0].i = x; + newconst->value[1].i = y; + newconst->value[2].i = z; + newconst->value[3].i = w; + shader->constI[shader->num_ci] = newconst; + + shader->num_ci++; + return TRUE; +} + BOOL record_declaration(struct bwriter_shader *shader, DWORD usage, DWORD usage_idx, BOOL output, DWORD regnum, DWORD writemask) { unsigned int *num; struct declaration **decl; @@ -298,29 +334,34 @@ static void write_declarations(struct bytecode_buffer *buffer, BOOL len, } } -static void write_constF(const struct bwriter_shader *shader, struct bytecode_buffer *buffer, BOOL len) { +static void write_const(struct constant **consts, int num, DWORD opcode, DWORD reg_type, struct bytecode_buffer *buffer, BOOL len) { DWORD i; - DWORD instr_def = D3DSIO_DEF; + DWORD instr_def = opcode; const DWORD reg = (1<<31) | - ((D3DSPR_CONST << D3DSP_REGTYPE_SHIFT) & D3DSP_REGTYPE_MASK) | + ((reg_type << D3DSP_REGTYPE_SHIFT) & D3DSP_REGTYPE_MASK) | + ((reg_type << D3DSP_REGTYPE_SHIFT2) & D3DSP_REGTYPE_MASK2) | D3DSP_WRITEMASK_ALL; if(len) { instr_def |= 5 << D3DSI_INSTLENGTH_SHIFT; } - for(i = 0; i < shader->num_cf; i++) { + for(i = 0; i < num; i++) { /* Write the DEF instruction */ put_dword(buffer, instr_def); - put_dword(buffer, reg | (shader->constF[i]->regnum & D3DSP_REGNUM_MASK)); - put_dword(buffer, shader->constF[i]->value[0].d); - put_dword(buffer, shader->constF[i]->value[1].d); - put_dword(buffer, shader->constF[i]->value[2].d); - put_dword(buffer, shader->constF[i]->value[3].d); + put_dword(buffer, reg | (consts[i]->regnum & D3DSP_REGNUM_MASK)); + put_dword(buffer, consts[i]->value[0].d); + put_dword(buffer, consts[i]->value[1].d); + put_dword(buffer, consts[i]->value[2].d); + put_dword(buffer, consts[i]->value[3].d); } } +static void write_constF(const struct bwriter_shader *shader, struct bytecode_buffer *buffer, BOOL len) { + write_const(shader->constF, shader->num_cf, D3DSIO_DEF, D3DSPR_CONST, buffer, len); +} + static void end(struct bc_writer *This, const struct bwriter_shader *shader, struct bytecode_buffer *buffer) { put_dword(buffer, D3DSIO_END); } @@ -364,6 +405,10 @@ static void instr_handler(struct bc_writer *This, write_srcregs(This, instr, buffer); } +static void write_constI(const struct bwriter_shader *shader, struct bytecode_buffer *buffer, BOOL len) { + write_const(shader->constI, shader->num_ci, D3DSIO_DEFI, D3DSPR_CONSTINT, buffer, len); +} + static void sm_2_opcode(struct bc_writer *This, const struct instruction *instr, DWORD token, struct bytecode_buffer *buffer) { @@ -404,6 +449,7 @@ static void sm_3_header(struct bc_writer *This, const struct bwriter_shader *sha write_declarations(buffer, TRUE, shader->inputs, shader->num_inputs, D3DSPR_INPUT); write_declarations(buffer, TRUE, shader->outputs, shader->num_outputs, D3DSPR_OUTPUT); write_constF(shader, buffer, TRUE); + write_constI(shader, buffer, TRUE); write_samplers(shader, buffer); return; } diff --git a/dlls/d3dx9_36/d3dx9_36_private.h b/dlls/d3dx9_36/d3dx9_36_private.h index c20119a0633..7aab8b14427 100644 --- a/dlls/d3dx9_36/d3dx9_36_private.h +++ b/dlls/d3dx9_36/d3dx9_36_private.h @@ -254,6 +254,7 @@ struct src_regs { struct asmparser_backend { void (*constF)(struct asm_parser *This, DWORD reg, float x, float y, float z, float w); + void (*constI)(struct asm_parser *This, DWORD reg, INT x, INT y, INT z, INT w); void (*dstreg)(struct asm_parser *This, struct instruction *instr, const struct shader_reg *dst); @@ -281,6 +282,7 @@ struct asmparser_backend { struct instruction *alloc_instr(unsigned int srcs); BOOL add_instruction(struct bwriter_shader *shader, struct instruction *instr); BOOL add_constF(struct bwriter_shader *shader, DWORD reg, float x, float y, float z, float w); +BOOL add_constI(struct bwriter_shader *shader, DWORD reg, INT x, INT y, INT z, INT w); BOOL record_declaration(struct bwriter_shader *shader, DWORD usage, DWORD usage_idx, BOOL output, DWORD regnum, DWORD writemask); BOOL record_sampler(struct bwriter_shader *shader, DWORD samptype, DWORD regnum); @@ -440,6 +442,7 @@ typedef enum _BWRITERSHADER_INSTRUCTION_OPCODE_TYPE { BWRITERSIO_BREAK, BWRITERSIO_BREAKC, BWRITERSIO_MOVA, + BWRITERSIO_DEFI, BWRITERSIO_EXPP, BWRITERSIO_LOGP,