Matteo Bruni : d3dx9: Add DEF instruction support in the shader assembler.

Alexandre Julliard julliard at winehq.org
Mon May 17 09:39:27 CDT 2010


Module: wine
Branch: master
Commit: dc1fa014ac59f635884c0aeb0117a31d26e1ab4a
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=dc1fa014ac59f635884c0aeb0117a31d26e1ab4a

Author: Matteo Bruni <matteo.mystral at gmail.com>
Date:   Fri May 14 17:21:42 2010 +0200

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]));




More information about the wine-cvs mailing list