Commit 25c929ab authored by Matteo Bruni's avatar Matteo Bruni Committed by Alexandre Julliard

d3dx9: Support some flow control instructions in the shader assembler.

parent 5fd618a0
......@@ -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);
......
......@@ -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> 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 */
{
......
......@@ -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";
......
......@@ -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},
......
......@@ -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
......
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