[1/3] d3dx9: Support some flow control instructions in the shader assembler.
Matteo Bruni
matteo.mystral at gmail.com
Tue May 11 19:00:05 CDT 2010
-------------- next part --------------
From 247ab7b256ec4a5a6085f148ce347371e056b9c9 Mon Sep 17 00:00:00 2001
From: Matteo Bruni <matteo.mystral at gmail.com>
Date: Tue, 11 May 2010 20:29:07 +0200
Subject: [PATCH 1/3] 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(+), 0 deletions(-)
diff --git a/dlls/d3dx9_36/asmshader.l b/dlls/d3dx9_36/asmshader.l
index 9d399c8..1cc28b8 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 feb370b..ef09307 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> 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 47291e3..5d12e4e 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 7205e76..c30ae67 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 fd1cbca..22b4714 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
--
1.6.4.4
More information about the wine-patches
mailing list