[2/2] d3dx9: Shader assembler ps_3_0 support.

Matteo Bruni matteo.mystral at gmail.com
Wed May 19 08:02:45 CDT 2010


-------------- next part --------------
From 8d13547861140cc1f14144e86d7d2d2527601c58 Mon Sep 17 00:00:00 2001
From: Matteo Bruni <matteo.mystral at gmail.com>
Date: Wed, 19 May 2010 14:57:38 +0200
Subject: d3dx9: Shader assembler ps_3_0 support.

---
 dlls/d3dx9_36/asmparser.c        |   79 ++++++++++++++++++++++++++++++++++++++
 dlls/d3dx9_36/asmshader.y        |    3 +-
 dlls/d3dx9_36/bytecodewriter.c   |   78 +++++++++++++++++++++++++++++++++++++-
 dlls/d3dx9_36/d3dx9_36_private.h |    1 +
 dlls/d3dx9_36/tests/asm.c        |   21 ++++++++++-
 5 files changed, 178 insertions(+), 4 deletions(-)

diff --git a/dlls/d3dx9_36/asmparser.c b/dlls/d3dx9_36/asmparser.c
index bcdc85a..3062639 100644
--- a/dlls/d3dx9_36/asmparser.c
+++ b/dlls/d3dx9_36/asmparser.c
@@ -248,6 +248,36 @@ static void asmparser_srcreg_vs_3(struct asm_parser *This,
     memcpy(&instr->src[num], src, sizeof(*src));
 }
 
+static const struct allowed_reg_type ps_3_reg_allowed[] = {
+    { BWRITERSPR_INPUT,        10 },
+    { BWRITERSPR_TEMP,         32 },
+    { BWRITERSPR_CONST,       224 },
+    { BWRITERSPR_CONSTINT,     16 },
+    { BWRITERSPR_CONSTBOOL,    16 },
+    { BWRITERSPR_PREDICATE,     1 },
+    { BWRITERSPR_SAMPLER,      16 },
+    { BWRITERSPR_MISCTYPE,      2 }, /* vPos and vFace */
+    { BWRITERSPR_LOOP,          1 },
+    { BWRITERSPR_LABEL,      2048 },
+    { BWRITERSPR_COLOROUT,    ~0U },
+    { BWRITERSPR_DEPTHOUT,      1 },
+    { ~0U, 0 } /* End tag */
+};
+
+static void asmparser_srcreg_ps_3(struct asm_parser *This,
+                                  struct instruction *instr, int num,
+                                  const struct shader_reg *src) {
+    if(!check_reg_type(src, ps_3_reg_allowed)) {
+        asmparser_message(This, "Line %u: Source register %s not supported in PS 3.0\n",
+                          This->line_no,
+                          debug_print_srcreg(src, ST_PIXEL));
+        set_parse_status(This, PARSE_ERR);
+    }
+    check_loop_swizzle(This, src);
+    check_legacy_srcmod(This, src->srcmod);
+    memcpy(&instr->src[num], src, sizeof(*src));
+}
+
 static void asmparser_dstreg_vs_3(struct asm_parser *This,
                                   struct instruction *instr,
                                   const struct shader_reg *dst) {
@@ -263,6 +293,20 @@ static void asmparser_dstreg_vs_3(struct asm_parser *This,
     instr->has_dst = TRUE;
 }
 
+static void asmparser_dstreg_ps_3(struct asm_parser *This,
+                                  struct instruction *instr,
+                                  const struct shader_reg *dst) {
+    if(!check_reg_type(dst, ps_3_reg_allowed)) {
+        asmparser_message(This, "Line %u: Destination register %s not supported in PS 3.0\n",
+                          This->line_no,
+                          debug_print_dstreg(dst, ST_PIXEL));
+        set_parse_status(This, PARSE_ERR);
+    }
+    check_shift_dstmod(This, instr->shift);
+    memcpy(&instr->dst, dst, sizeof(*dst));
+    instr->has_dst = TRUE;
+}
+
 static void asmparser_predicate_supported(struct asm_parser *This,
                                           const struct shader_reg *predicate) {
     /* this sets the predicate of the last instruction added to the shader */
@@ -305,6 +349,26 @@ static const struct asmparser_backend parser_vs_3 = {
     asmparser_instr,
 };
 
+static const struct asmparser_backend parser_ps_3 = {
+    asmparser_constF,
+    asmparser_constI,
+    asmparser_constB,
+
+    asmparser_dstreg_ps_3,
+    asmparser_srcreg_ps_3,
+
+    asmparser_predicate_supported,
+    asmparser_coissue_unsupported,
+
+    asmparser_dcl_output,
+    asmparser_dcl_input,
+    asmparser_dcl_sampler,
+
+    asmparser_end,
+
+    asmparser_instr,
+};
+
 void create_vs30_parser(struct asm_parser *ret) {
     TRACE_(parsed_shader)("vs_3_0\n");
 
@@ -319,3 +383,18 @@ void create_vs30_parser(struct asm_parser *ret) {
     ret->shader->version = BWRITERVS_VERSION(3, 0);
     ret->funcs = &parser_vs_3;
 }
+
+void create_ps30_parser(struct asm_parser *ret) {
+    TRACE_(parsed_shader)("ps_3_0\n");
+
+    ret->shader = asm_alloc(sizeof(*ret->shader));
+    if(!ret->shader) {
+        ERR("Failed to allocate memory for the shader\n");
+        set_parse_status(ret, PARSE_ERR);
+        return;
+    }
+
+    ret->shader->type = ST_PIXEL;
+    ret->shader->version = BWRITERPS_VERSION(3, 0);
+    ret->funcs = &parser_ps_3;
+}
diff --git a/dlls/d3dx9_36/asmshader.y b/dlls/d3dx9_36/asmshader.y
index 657ce3c..06a6825 100644
--- a/dlls/d3dx9_36/asmshader.y
+++ b/dlls/d3dx9_36/asmshader.y
@@ -342,8 +342,7 @@ version_marker:       VER_VS10
                     | VER_PS30
                         {
                             TRACE("Pixel  shader 3.0\n");
-                            set_parse_status(&asm_ctx, PARSE_ERR);
-                            YYABORT;
+                            create_ps30_parser(&asm_ctx);
                         }
 
 instructions:         /* empty */
diff --git a/dlls/d3dx9_36/bytecodewriter.c b/dlls/d3dx9_36/bytecodewriter.c
index 087422f..464ec52 100644
--- a/dlls/d3dx9_36/bytecodewriter.c
+++ b/dlls/d3dx9_36/bytecodewriter.c
@@ -641,11 +641,87 @@ static const struct bytecode_backend vs_3_backend = {
     vs_3_handlers
 };
 
+static const struct instr_handler_table ps_3_handlers[] = {
+    {BWRITERSIO_ADD,            instr_handler},
+    {BWRITERSIO_NOP,            instr_handler},
+    {BWRITERSIO_MOV,            instr_handler},
+    {BWRITERSIO_SUB,            instr_handler},
+    {BWRITERSIO_MAD,            instr_handler},
+    {BWRITERSIO_MUL,            instr_handler},
+    {BWRITERSIO_RCP,            instr_handler},
+    {BWRITERSIO_RSQ,            instr_handler},
+    {BWRITERSIO_DP3,            instr_handler},
+    {BWRITERSIO_DP4,            instr_handler},
+    {BWRITERSIO_MIN,            instr_handler},
+    {BWRITERSIO_MAX,            instr_handler},
+    {BWRITERSIO_ABS,            instr_handler},
+    {BWRITERSIO_EXP,            instr_handler},
+    {BWRITERSIO_LOG,            instr_handler},
+    {BWRITERSIO_EXPP,           instr_handler},
+    {BWRITERSIO_LOGP,           instr_handler},
+    {BWRITERSIO_LRP,            instr_handler},
+    {BWRITERSIO_FRC,            instr_handler},
+    {BWRITERSIO_CRS,            instr_handler},
+    {BWRITERSIO_NRM,            instr_handler},
+    {BWRITERSIO_SINCOS,         instr_handler},
+    {BWRITERSIO_M4x4,           instr_handler},
+    {BWRITERSIO_M4x3,           instr_handler},
+    {BWRITERSIO_M3x4,           instr_handler},
+    {BWRITERSIO_M3x3,           instr_handler},
+    {BWRITERSIO_M3x2,           instr_handler},
+    {BWRITERSIO_POW,            instr_handler},
+    {BWRITERSIO_DP2ADD,         instr_handler},
+    {BWRITERSIO_CMP,            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_IFC,            instr_handler},
+    {BWRITERSIO_ELSE,           instr_handler},
+    {BWRITERSIO_ENDIF,          instr_handler},
+    {BWRITERSIO_BREAK,          instr_handler},
+    {BWRITERSIO_BREAKC,         instr_handler},
+    {BWRITERSIO_LOOP,           instr_handler},
+    {BWRITERSIO_RET,            instr_handler},
+    {BWRITERSIO_ENDLOOP,        instr_handler},
+
+    {BWRITERSIO_SETP,           instr_handler},
+    {BWRITERSIO_BREAKP,         instr_handler},
+    {BWRITERSIO_TEXLDL,         instr_handler},
+
+    {BWRITERSIO_TEX,            instr_handler},
+    {BWRITERSIO_TEX | ( BWRITERSI_TEXLD_PROJECT << BWRITER_OPCODESPECIFICCONTROL_SHIFT ),                       instr_handler},
+    {BWRITERSIO_TEX | ( BWRITERSI_TEXLD_BIAS << BWRITER_OPCODESPECIFICCONTROL_SHIFT ),                          instr_handler},
+    {BWRITERSIO_TEXKILL,        instr_handler},
+    {BWRITERSIO_DSX,            instr_handler},
+    {BWRITERSIO_DSY,            instr_handler},
+    {BWRITERSIO_TEXLDD,         instr_handler},
+
+    {BWRITERSIO_END,            NULL},
+};
+
+static const struct bytecode_backend ps_3_backend = {
+    sm_3_header,
+    end,
+    sm_3_srcreg,
+    sm_3_dstreg,
+    sm_2_opcode,
+    ps_3_handlers
+};
+
 static void init_vs30_dx9_writer(struct bc_writer *writer) {
     TRACE("Creating DirectX9 vertex shader 3.0 writer\n");
     writer->funcs = &vs_3_backend;
 }
 
+static void init_ps30_dx9_writer(struct bc_writer *writer) {
+    TRACE("Creating DirectX9 pixel shader 3.0 writer\n");
+    writer->funcs = &ps_3_backend;
+}
+
 static struct bc_writer *create_writer(DWORD version, DWORD dxversion) {
     struct bc_writer *ret = asm_alloc(sizeof(*ret));
 
@@ -748,7 +824,7 @@ static struct bc_writer *create_writer(DWORD version, DWORD dxversion) {
                 WARN("Unsupported dxversion for pixel shader 3.0 requested: %u\n", dxversion);
                 goto fail;
             }
-            /* TODO: Set the appropriate writer backend */
+            init_ps30_dx9_writer(ret);
             break;
 
         default:
diff --git a/dlls/d3dx9_36/d3dx9_36_private.h b/dlls/d3dx9_36/d3dx9_36_private.h
index e5816b3..923a0df 100644
--- a/dlls/d3dx9_36/d3dx9_36_private.h
+++ b/dlls/d3dx9_36/d3dx9_36_private.h
@@ -312,6 +312,7 @@ struct asm_parser {
 extern struct asm_parser asm_ctx;
 
 void create_vs30_parser(struct asm_parser *ret);
+void create_ps30_parser(struct asm_parser *ret);
 
 struct bwriter_shader *parse_asm_shader(char **messages);
 
diff --git a/dlls/d3dx9_36/tests/asm.c b/dlls/d3dx9_36/tests/asm.c
index b4e0ee5..54894df 100644
--- a/dlls/d3dx9_36/tests/asm.c
+++ b/dlls/d3dx9_36/tests/asm.c
@@ -1125,6 +1125,22 @@ static void ps_3_0_test(void) {
             "texldl r0, v0, s0\n",
             {0xffff0300, 0x0300005f, 0x800f0000, 0x90e40000, 0xa0e40800, 0x0000ffff}
         },
+        {   /* shader 7 */
+            "ps_3_0\n"
+            "add_pp r0, r0, r1\n",
+            {0xffff0300, 0x03000002, 0x802f0000, 0x80e40000, 0x80e40001, 0x0000ffff}
+        },
+        {   /* shader 8 */
+            "ps_3_0\n"
+            "dsx_sat r0, r1\n",
+            {0xffff0300, 0x0200005b, 0x801f0000, 0x80e40001, 0x0000ffff}
+        },
+        {   /* shader 9 */
+            "ps_3_0\n"
+            "texldd_pp r0, r1, r2, r3, r4\n",
+            {0xffff0300, 0x0500005d, 0x802f0000, 0x80e40001, 0x80e40002, 0x80e40003,
+	     0x80e40004, 0x0000ffff}
+        },
     };
 
     exec_tests("ps_3_0", tests, sizeof(tests) / sizeof(tests[0]));
@@ -1212,6 +1228,9 @@ static void failure_test(void) {
         /* shader 24: _pp instruction modifier not allowed in vertex shaders */
         "vs_3_0\n"
         "add_pp r0, r0, r1\n",
+        /* shader 25: _x4 instruction modified not allowed in > ps_1_x */
+        "ps_3_0\n"
+        "add_x4 r0, r0, r1\n",
     };
     HRESULT hr;
     unsigned int i;
@@ -1437,7 +1456,7 @@ START_TEST(asm)
     todo_wine ps_2_0_test();
     todo_wine ps_2_x_test();
     vs_3_0_test();
-    todo_wine ps_3_0_test();
+    ps_3_0_test();
 
     failure_test();
 
-- 
1.6.4.4


More information about the wine-patches mailing list