[1/2] d3dx9: Allow modifiers on the ps dcl input instruction.

Matteo Bruni matteo.mystral at gmail.com
Mon May 31 08:21:00 CDT 2010


Seems like you can't ever have enough tests...
-------------- next part --------------
From fe56c3b3e942bbec42bfc36be67ad9d6e49ed2f9 Mon Sep 17 00:00:00 2001
From: Matteo Bruni <matteo.mystral at gmail.com>
Date: Sun, 30 May 2010 22:24:54 +0200
Subject: d3dx9: Allow modifiers on the ps dcl input instruction.

---
 dlls/d3dx9_36/asmparser.c        |   60 +++++++++++++++++++++----------------
 dlls/d3dx9_36/asmshader.y        |   24 +++++++++++----
 dlls/d3dx9_36/bytecodewriter.c   |    4 ++-
 dlls/d3dx9_36/d3dx9_36_private.h |    5 ++-
 dlls/d3dx9_36/tests/asm.c        |   14 +++++++++
 5 files changed, 71 insertions(+), 36 deletions(-)

diff --git a/dlls/d3dx9_36/asmparser.c b/dlls/d3dx9_36/asmparser.c
index 39240f3..3c29da8 100644
--- a/dlls/d3dx9_36/asmparser.c
+++ b/dlls/d3dx9_36/asmparser.c
@@ -110,16 +110,24 @@ static void asmparser_dcl_output(struct asm_parser *This, DWORD usage, DWORD num
         asmparser_message(This, "Line %u: Output register declared in a pixel shader\n", This->line_no);
         set_parse_status(This, PARSE_ERR);
     }
-    if(!record_declaration(This->shader, usage, num, TRUE, reg->regnum, reg->writemask)) {
+    if(!record_declaration(This->shader, usage, num, 0, TRUE, reg->regnum, reg->writemask)) {
         ERR("Out of memory\n");
         set_parse_status(This, PARSE_ERR);
     }
 }
 
 static void asmparser_dcl_input(struct asm_parser *This, DWORD usage, DWORD num,
-                                const struct shader_reg *reg) {
+                                DWORD mod, const struct shader_reg *reg) {
     if(!This->shader) return;
-    if(!record_declaration(This->shader, usage, num, FALSE, reg->regnum, reg->writemask)) {
+    if(mod != 0 &&
+       (This->shader->version != BWRITERPS_VERSION(3, 0) ||
+        (mod != BWRITERSPDM_MSAMPCENTROID &&
+         mod != BWRITERSPDM_PARTIALPRECISION))) {
+        asmparser_message(This, "Line %u: Unsupported modifier in dcl instruction\n", This->line_no);
+        set_parse_status(This, PARSE_ERR);
+        return;
+    }
+    if(!record_declaration(This->shader, usage, num, mod, FALSE, reg->regnum, reg->writemask)) {
         ERR("Out of memory\n");
         set_parse_status(This, PARSE_ERR);
     }
@@ -842,34 +850,34 @@ static const struct asmparser_backend parser_ps_3 = {
 };
 
 static void gen_oldvs_output(struct bwriter_shader *shader) {
-    record_declaration(shader, BWRITERDECLUSAGE_POSITION, 0, TRUE, OPOS_REG, BWRITERSP_WRITEMASK_ALL);
-    record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 0, TRUE, OT0_REG, BWRITERSP_WRITEMASK_ALL);
-    record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 1, TRUE, OT1_REG, BWRITERSP_WRITEMASK_ALL);
-    record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 2, TRUE, OT2_REG, BWRITERSP_WRITEMASK_ALL);
-    record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 3, TRUE, OT3_REG, BWRITERSP_WRITEMASK_ALL);
-    record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 4, TRUE, OT4_REG, BWRITERSP_WRITEMASK_ALL);
-    record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 5, TRUE, OT5_REG, BWRITERSP_WRITEMASK_ALL);
-    record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 6, TRUE, OT6_REG, BWRITERSP_WRITEMASK_ALL);
-    record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 7, TRUE, OT7_REG, BWRITERSP_WRITEMASK_ALL);
-    record_declaration(shader, BWRITERDECLUSAGE_FOG, 0, TRUE, OFOG_REG, OFOG_WRITEMASK);
-    record_declaration(shader, BWRITERDECLUSAGE_PSIZE, 0, TRUE, OPTS_REG, OPTS_WRITEMASK);
-    record_declaration(shader, BWRITERDECLUSAGE_COLOR, 0, TRUE, OD0_REG, BWRITERSP_WRITEMASK_ALL);
-    record_declaration(shader, BWRITERDECLUSAGE_COLOR, 1, TRUE, OD1_REG, BWRITERSP_WRITEMASK_ALL);
+    record_declaration(shader, BWRITERDECLUSAGE_POSITION, 0, 0, TRUE, OPOS_REG, BWRITERSP_WRITEMASK_ALL);
+    record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 0, 0, TRUE, OT0_REG, BWRITERSP_WRITEMASK_ALL);
+    record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 1, 0, TRUE, OT1_REG, BWRITERSP_WRITEMASK_ALL);
+    record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 2, 0, TRUE, OT2_REG, BWRITERSP_WRITEMASK_ALL);
+    record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 3, 0, TRUE, OT3_REG, BWRITERSP_WRITEMASK_ALL);
+    record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 4, 0, TRUE, OT4_REG, BWRITERSP_WRITEMASK_ALL);
+    record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 5, 0, TRUE, OT5_REG, BWRITERSP_WRITEMASK_ALL);
+    record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 6, 0, TRUE, OT6_REG, BWRITERSP_WRITEMASK_ALL);
+    record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 7, 0, TRUE, OT7_REG, BWRITERSP_WRITEMASK_ALL);
+    record_declaration(shader, BWRITERDECLUSAGE_FOG, 0, 0, TRUE, OFOG_REG, OFOG_WRITEMASK);
+    record_declaration(shader, BWRITERDECLUSAGE_PSIZE, 0, 0, TRUE, OPTS_REG, OPTS_WRITEMASK);
+    record_declaration(shader, BWRITERDECLUSAGE_COLOR, 0, 0, TRUE, OD0_REG, BWRITERSP_WRITEMASK_ALL);
+    record_declaration(shader, BWRITERDECLUSAGE_COLOR, 1, 0, TRUE, OD1_REG, BWRITERSP_WRITEMASK_ALL);
 }
 
 static void gen_oldps_input(struct bwriter_shader *shader, DWORD texcoords) {
     switch(texcoords) {
-        case 8: record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 7, FALSE, T7_VARYING, BWRITERSP_WRITEMASK_ALL);
-        case 7: record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 6, FALSE, T6_VARYING, BWRITERSP_WRITEMASK_ALL);
-        case 6: record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 5, FALSE, T5_VARYING, BWRITERSP_WRITEMASK_ALL);
-        case 5: record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 4, FALSE, T4_VARYING, BWRITERSP_WRITEMASK_ALL);
-        case 4: record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 3, FALSE, T3_VARYING, BWRITERSP_WRITEMASK_ALL);
-        case 3: record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 2, FALSE, T2_VARYING, BWRITERSP_WRITEMASK_ALL);
-        case 2: record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 1, FALSE, T1_VARYING, BWRITERSP_WRITEMASK_ALL);
-        case 1: record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 0, FALSE, T0_VARYING, BWRITERSP_WRITEMASK_ALL);
+        case 8: record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 7, 0, FALSE, T7_VARYING, BWRITERSP_WRITEMASK_ALL);
+        case 7: record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 6, 0, FALSE, T6_VARYING, BWRITERSP_WRITEMASK_ALL);
+        case 6: record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 5, 0, FALSE, T5_VARYING, BWRITERSP_WRITEMASK_ALL);
+        case 5: record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 4, 0, FALSE, T4_VARYING, BWRITERSP_WRITEMASK_ALL);
+        case 4: record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 3, 0, FALSE, T3_VARYING, BWRITERSP_WRITEMASK_ALL);
+        case 3: record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 2, 0, FALSE, T2_VARYING, BWRITERSP_WRITEMASK_ALL);
+        case 2: record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 1, 0, FALSE, T1_VARYING, BWRITERSP_WRITEMASK_ALL);
+        case 1: record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 0, 0, FALSE, T0_VARYING, BWRITERSP_WRITEMASK_ALL);
     };
-    record_declaration(shader, BWRITERDECLUSAGE_COLOR, 0, FALSE, C0_VARYING, BWRITERSP_WRITEMASK_ALL);
-    record_declaration(shader, BWRITERDECLUSAGE_COLOR, 1, FALSE, C1_VARYING, BWRITERSP_WRITEMASK_ALL);
+    record_declaration(shader, BWRITERDECLUSAGE_COLOR, 0, 0, FALSE, C0_VARYING, BWRITERSP_WRITEMASK_ALL);
+    record_declaration(shader, BWRITERDECLUSAGE_COLOR, 1, 0, FALSE, C1_VARYING, BWRITERSP_WRITEMASK_ALL);
 }
 
 void create_vs10_parser(struct asm_parser *ret) {
diff --git a/dlls/d3dx9_36/asmshader.y b/dlls/d3dx9_36/asmshader.y
index 9fe6311..c0c289c 100644
--- a/dlls/d3dx9_36/asmshader.y
+++ b/dlls/d3dx9_36/asmshader.y
@@ -539,29 +539,39 @@ instruction:          INSTR_ADD omods dreg ',' sregs
                                 reg.writemask = $4;
                                 asm_ctx.funcs->dcl_output(&asm_ctx, $2.dclusage, $2.regnum, &reg);
                             }
-                    | INSTR_DCL dclusage REG_INPUT
+                    | INSTR_DCL dclusage omods REG_INPUT
                             {
                                 struct shader_reg reg;
                                 TRACE("Input reg declaration\n");
+                                if($3.shift != 0) {
+                                    asmparser_message(&asm_ctx, "Line %u: Shift modifier not allowed here\n",
+                                                      asm_ctx.line_no);
+                                    set_parse_status(&asm_ctx, PARSE_ERR);
+                                }
                                 ZeroMemory(&reg, sizeof(reg));
                                 reg.type = BWRITERSPR_INPUT;
-                                reg.regnum = $3;
+                                reg.regnum = $4;
                                 reg.rel_reg = NULL;
                                 reg.srcmod = 0;
                                 reg.writemask = BWRITERSP_WRITEMASK_ALL;
-                                asm_ctx.funcs->dcl_input(&asm_ctx, $2.dclusage, $2.regnum, &reg);
+                                asm_ctx.funcs->dcl_input(&asm_ctx, $2.dclusage, $2.regnum, $3.mod, &reg);
                             }
-                    | INSTR_DCL dclusage REG_INPUT writemask
+                    | INSTR_DCL dclusage omods REG_INPUT writemask
                             {
                                 struct shader_reg reg;
                                 TRACE("Input reg declaration\n");
+                                if($3.shift != 0) {
+                                    asmparser_message(&asm_ctx, "Line %u: Shift modifier not allowed here\n",
+                                                      asm_ctx.line_no);
+                                    set_parse_status(&asm_ctx, PARSE_ERR);
+                                }
                                 ZeroMemory(&reg, sizeof(reg));
                                 reg.type = BWRITERSPR_INPUT;
-                                reg.regnum = $3;
+                                reg.regnum = $4;
                                 reg.rel_reg = NULL;
                                 reg.srcmod = 0;
-                                reg.writemask = $4;
-                                asm_ctx.funcs->dcl_input(&asm_ctx, $2.dclusage, $2.regnum, &reg);
+                                reg.writemask = $5;
+                                asm_ctx.funcs->dcl_input(&asm_ctx, $2.dclusage, $2.regnum, $3.mod, &reg);
                             }
                     | INSTR_DCL sampdcl REG_SAMPLER
                             {
diff --git a/dlls/d3dx9_36/bytecodewriter.c b/dlls/d3dx9_36/bytecodewriter.c
index 3bd003b..3d05dad 100644
--- a/dlls/d3dx9_36/bytecodewriter.c
+++ b/dlls/d3dx9_36/bytecodewriter.c
@@ -209,7 +209,7 @@ BOOL add_constB(struct bwriter_shader *shader, DWORD reg, BOOL x) {
     return TRUE;
 }
 
-BOOL record_declaration(struct bwriter_shader *shader, DWORD usage, DWORD usage_idx, BOOL output, DWORD regnum, DWORD writemask) {
+BOOL record_declaration(struct bwriter_shader *shader, DWORD usage, DWORD usage_idx, DWORD mod, BOOL output, DWORD regnum, DWORD writemask) {
     unsigned int *num;
     struct declaration **decl;
     unsigned int i;
@@ -250,6 +250,7 @@ BOOL record_declaration(struct bwriter_shader *shader, DWORD usage, DWORD usage_
     (*decl)[*num].usage = usage;
     (*decl)[*num].usage_idx = usage_idx;
     (*decl)[*num].regnum = regnum;
+    (*decl)[*num].mod = mod;
     (*decl)[*num].writemask = writemask;
     (*num)++;
 
@@ -363,6 +364,7 @@ static void write_declarations(struct bytecode_buffer *buffer, BOOL len,
         token |= (type << D3DSP_REGTYPE_SHIFT) & D3DSP_REGTYPE_MASK;
         token |= (d3d9_writemask(decls[i].writemask)) & D3DSP_WRITEMASK_ALL;
         token |= decls[i].regnum & D3DSP_REGNUM_MASK;
+        token |= d3d9_dstmod(decls[i].mod);
         put_dword(buffer, token);
     }
 }
diff --git a/dlls/d3dx9_36/d3dx9_36_private.h b/dlls/d3dx9_36/d3dx9_36_private.h
index 96e0533..c1a4195 100644
--- a/dlls/d3dx9_36/d3dx9_36_private.h
+++ b/dlls/d3dx9_36/d3dx9_36_private.h
@@ -184,6 +184,7 @@ struct instruction {
 struct declaration {
     DWORD                   usage, usage_idx;
     DWORD                   regnum;
+    DWORD                   mod;
     DWORD                   writemask;
 };
 
@@ -270,7 +271,7 @@ struct asmparser_backend {
     void (*dcl_output)(struct asm_parser *This, DWORD usage, DWORD num,
                        const struct shader_reg *reg);
     void (*dcl_input)(struct asm_parser *This, DWORD usage, DWORD num,
-                      const struct shader_reg *reg);
+                      DWORD mod, const struct shader_reg *reg);
     void (*dcl_sampler)(struct asm_parser *This, DWORD samptype, DWORD regnum,
                         unsigned int line_no);
 
@@ -286,7 +287,7 @@ 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 add_constB(struct bwriter_shader *shader, DWORD reg, BOOL x);
-BOOL record_declaration(struct bwriter_shader *shader, DWORD usage, DWORD usage_idx, BOOL output, DWORD regnum, DWORD writemask);
+BOOL record_declaration(struct bwriter_shader *shader, DWORD usage, DWORD usage_idx, DWORD mod, BOOL output, DWORD regnum, DWORD writemask);
 BOOL record_sampler(struct bwriter_shader *shader, DWORD samptype, DWORD regnum);
 
 #define MESSAGEBUFFER_INITIAL_SIZE 256
diff --git a/dlls/d3dx9_36/tests/asm.c b/dlls/d3dx9_36/tests/asm.c
index 1be2c55..59ed942 100644
--- a/dlls/d3dx9_36/tests/asm.c
+++ b/dlls/d3dx9_36/tests/asm.c
@@ -1180,6 +1180,11 @@ static void ps_3_0_test(void) {
             "add oC3, r0, r1\n",
             {0xffff0300, 0x03000002, 0x800f0803, 0x80e40000, 0x80e40001, 0x0000ffff}
         },
+        {   /* shader 12 */
+            "ps_3_0\n"
+            "dcl_texcoord0_centroid v0\n",
+            {0xffff0300, 0x0200001f, 0x80000005, 0x904f0000, 0x0000ffff}
+        },
     };
 
     exec_tests("ps_3_0", tests, sizeof(tests) / sizeof(tests[0]));
@@ -1309,6 +1314,15 @@ static void failure_test(void) {
         /* shader 38: only a0.x accepted in vs_1_1 */
         "vs_1_1\n"
         "mov r0, c0[ a0 ]\n",
+        /* shader 39: invalid modifier for dcl instruction */
+        "ps_3_0\n"
+        "dcl_texcoord0_sat v0\n",
+        /* shader 40: shift not allowed */
+        "ps_3_0\n"
+        "dcl_texcoord0_x2 v0\n",
+        /* shader 41: no modifier allowed with dcl instruction in vs */
+        "vs_3_0\n"
+        "dcl_texcoord0_centroid v0\n",
     };
     HRESULT hr;
     unsigned int i;
-- 
1.6.4.4


More information about the wine-patches mailing list