[1/3] d3dx9: Add DEF instruction support in the shader assembler.
Matteo Bruni
matteo.mystral at gmail.com
Fri May 14 10:48:03 CDT 2010
-------------- next part --------------
From d416d26492d0d2b2161e90dbe372620578de0603 Mon Sep 17 00:00:00 2001
From: Matteo Bruni <matteo.mystral at gmail.com>
Date: Fri, 14 May 2010 17:21:42 +0200
Subject: d3dx9: Add DEF instruction support in the shader assembler.
---
dlls/d3dx9_36/asmparser.c | 12 +++++++
dlls/d3dx9_36/asmshader.l | 1 +
dlls/d3dx9_36/asmshader.y | 5 +++
dlls/d3dx9_36/asmutils.c | 2 +
dlls/d3dx9_36/bytecodewriter.c | 60 ++++++++++++++++++++++++++++++++++++++
dlls/d3dx9_36/d3dx9_36_private.h | 14 +++++++++
dlls/d3dx9_36/tests/asm.c | 6 ++++
7 files changed, 100 insertions(+), 0 deletions(-)
diff --git a/dlls/d3dx9_36/asmparser.c b/dlls/d3dx9_36/asmparser.c
index 6d0d31f..a2d57e0 100644
--- a/dlls/d3dx9_36/asmparser.c
+++ b/dlls/d3dx9_36/asmparser.c
@@ -38,6 +38,16 @@ static void asmparser_end(struct asm_parser *This) {
TRACE("Finalizing shader\n");
}
+static void asmparser_constF(struct asm_parser *This, DWORD reg, float x, float y, float z, float w) {
+ if(!This->shader) return;
+ TRACE("Adding float constant %u at pos %u\n", reg, This->shader->num_cf);
+ TRACE_(parsed_shader)("def c%u, %f, %f, %f, %f\n", reg, x, y, z, w);
+ if(!add_constF(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;
@@ -159,6 +169,8 @@ static void asmparser_coissue_unsupported(struct asm_parser *This) {
}
static const struct asmparser_backend parser_vs_3 = {
+ asmparser_constF,
+
asmparser_dstreg_vs_3,
asmparser_srcreg_vs_3,
diff --git a/dlls/d3dx9_36/asmshader.l b/dlls/d3dx9_36/asmshader.l
index 9486b53..690a5a7 100644
--- a/dlls/d3dx9_36/asmshader.l
+++ b/dlls/d3dx9_36/asmshader.l
@@ -138,6 +138,7 @@ m3x4 {return INSTR_M3x4; }
m3x3 {return INSTR_M3x3; }
m3x2 {return INSTR_M3x2; }
dcl {return INSTR_DCL; }
+def {return INSTR_DEF; }
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 a6ab57e..bb4c43f 100644
--- a/dlls/d3dx9_36/asmshader.y
+++ b/dlls/d3dx9_36/asmshader.y
@@ -123,6 +123,7 @@ void set_rel_reg(struct shader_reg *reg, struct rel_reg *rel) {
%token INSTR_M3x3
%token INSTR_M3x2
%token INSTR_DCL
+%token INSTR_DEF
%token INSTR_REP
%token INSTR_ENDREP
%token INSTR_IF
@@ -573,6 +574,10 @@ instruction: INSTR_ADD omods dreg ',' sregs
asm_ctx.line_no);
set_parse_status(&asm_ctx, PARSE_WARN);
}
+ | INSTR_DEF REG_CONSTFLOAT ',' IMMVAL ',' IMMVAL ',' IMMVAL ',' IMMVAL
+ {
+ asm_ctx.funcs->constF(&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 c34f5f5..3772c5f 100644
--- a/dlls/d3dx9_36/asmutils.c
+++ b/dlls/d3dx9_36/asmutils.c
@@ -191,6 +191,7 @@ DWORD d3d9_opcode(DWORD bwriter_opcode) {
case BWRITERSIO_MOVA: return D3DSIO_MOVA;
case BWRITERSIO_EXPP: return D3DSIO_EXPP;
case BWRITERSIO_LOGP: return D3DSIO_LOGP;
+ case BWRITERSIO_DEF: return D3DSIO_DEF;
case BWRITERSIO_SETP: return D3DSIO_SETP;
case BWRITERSIO_TEXLDL: return D3DSIO_TEXLDL;
case BWRITERSIO_BREAKP: return D3DSIO_BREAKP;
@@ -456,6 +457,7 @@ const char *debug_print_opcode(DWORD opcode) {
case BWRITERSIO_MOVA: return "mova";
case BWRITERSIO_EXPP: return "expp";
case BWRITERSIO_LOGP: return "logp";
+ case BWRITERSIO_DEF: return "def";
case BWRITERSIO_SETP: return "setp";
case BWRITERSIO_TEXLDL: return "texldl";
case BWRITERSIO_BREAKP: return "breakp";
diff --git a/dlls/d3dx9_36/bytecodewriter.c b/dlls/d3dx9_36/bytecodewriter.c
index 82a3655..c14f022 100644
--- a/dlls/d3dx9_36/bytecodewriter.c
+++ b/dlls/d3dx9_36/bytecodewriter.c
@@ -104,6 +104,42 @@ BOOL add_instruction(struct bwriter_shader *shader, struct instruction *instr) {
return TRUE;
}
+BOOL add_constF(struct bwriter_shader *shader, DWORD reg, float x, float y, float z, float w) {
+ struct constant *newconst;
+
+ if(shader->num_cf) {
+ struct constant **newarray;
+ newarray = asm_realloc(shader->constF,
+ sizeof(*shader->constF) * (shader->num_cf + 1));
+ if(!newarray) {
+ ERR("Failed to grow the constants array\n");
+ return FALSE;
+ }
+ shader->constF = newarray;
+ } else {
+ shader->constF = asm_alloc(sizeof(*shader->constF));
+ if(!shader->constF) {
+ 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].f = x;
+ newconst->value[1].f = y;
+ newconst->value[2].f = z;
+ newconst->value[3].f = w;
+ shader->constF[shader->num_cf] = newconst;
+
+ shader->num_cf++;
+ 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;
@@ -262,6 +298,29 @@ 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) {
+ DWORD i;
+ DWORD instr_def = D3DSIO_DEF;
+ const DWORD reg = (1<<31) |
+ ((D3DSPR_CONST << D3DSP_REGTYPE_SHIFT) & D3DSP_REGTYPE_MASK) |
+ D3DSP_WRITEMASK_ALL;
+
+ if(len) {
+ instr_def |= 5 << D3DSI_INSTLENGTH_SHIFT;
+ }
+
+ for(i = 0; i < shader->num_cf; 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);
+ }
+}
+
static void end(struct bc_writer *This, const struct bwriter_shader *shader, struct bytecode_buffer *buffer) {
put_dword(buffer, D3DSIO_END);
}
@@ -344,6 +403,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_samplers(shader, buffer);
return;
}
diff --git a/dlls/d3dx9_36/d3dx9_36_private.h b/dlls/d3dx9_36/d3dx9_36_private.h
index a102e65..c20119a 100644
--- a/dlls/d3dx9_36/d3dx9_36_private.h
+++ b/dlls/d3dx9_36/d3dx9_36_private.h
@@ -146,6 +146,16 @@ typedef enum BWRITER_COMPARISON_TYPE {
BWRITER_COMPARISON_LE
} BWRITER_COMPARISON_TYPE;
+struct constant {
+ DWORD regnum;
+ union {
+ float f;
+ INT i;
+ BOOL b;
+ DWORD d;
+ } value[4];
+};
+
struct shader_reg {
DWORD type;
DWORD regnum;
@@ -243,6 +253,8 @@ struct src_regs {
};
struct asmparser_backend {
+ void (*constF)(struct asm_parser *This, DWORD reg, float x, float y, float z, float w);
+
void (*dstreg)(struct asm_parser *This, struct instruction *instr,
const struct shader_reg *dst);
void (*srcreg)(struct asm_parser *This, struct instruction *instr, int num,
@@ -268,6 +280,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 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);
@@ -430,6 +443,7 @@ typedef enum _BWRITERSHADER_INSTRUCTION_OPCODE_TYPE {
BWRITERSIO_EXPP,
BWRITERSIO_LOGP,
+ BWRITERSIO_DEF,
BWRITERSIO_SETP,
BWRITERSIO_TEXLDL,
BWRITERSIO_BREAKP,
diff --git a/dlls/d3dx9_36/tests/asm.c b/dlls/d3dx9_36/tests/asm.c
index 21adb81..8a79dd4 100644
--- a/dlls/d3dx9_36/tests/asm.c
+++ b/dlls/d3dx9_36/tests/asm.c
@@ -1074,6 +1074,12 @@ static void vs_3_0_test(void) {
"sincos r0, r1\n",
{0xfffe0300, 0x02000025, 0x800f0000, 0x80e40001, 0x0000ffff}
},
+ { /* shader 13 */
+ "vs_3_0\n"
+ "def c0, 1.0f, 1.0f, 1.0f, 0.5f\n",
+ {0xfffe0300, 0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000,
+ 0x3f000000, 0x0000ffff}
+ },
};
exec_tests("vs_3_0", tests, sizeof(tests) / sizeof(tests[0]));
--
1.6.4.4
More information about the wine-patches
mailing list