Matteo Bruni : d3dx9: Add predicate support to the shader assembler.

Alexandre Julliard julliard at winehq.org
Wed May 12 12:33:21 CDT 2010


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

Author: Matteo Bruni <matteo.mystral at gmail.com>
Date:   Tue May 11 20:29:07 2010 +0200

d3dx9: Add predicate support to the shader assembler.

---

 dlls/d3dx9_36/asmparser.c        |   13 ++++++++++++-
 dlls/d3dx9_36/asmshader.l        |    2 ++
 dlls/d3dx9_36/asmshader.y        |   35 +++++++++++++++++++++++++++++++++++
 dlls/d3dx9_36/asmutils.c         |    4 ++++
 dlls/d3dx9_36/bytecodewriter.c   |    4 ++++
 dlls/d3dx9_36/d3dx9_36_private.h |    2 ++
 6 files changed, 59 insertions(+), 1 deletions(-)

diff --git a/dlls/d3dx9_36/asmparser.c b/dlls/d3dx9_36/asmparser.c
index 15ac7ea..e08c421 100644
--- a/dlls/d3dx9_36/asmparser.c
+++ b/dlls/d3dx9_36/asmparser.c
@@ -106,11 +106,22 @@ static void asmparser_dstreg_vs_3(struct asm_parser *This,
     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 */
+    if(!This->shader) return;
+    if(This->shader->num_instrs == 0) ERR("Predicate without an instruction\n");
+    This->shader->instr[This->shader->num_instrs - 1]->has_predicate = TRUE;
+    memcpy(&This->shader->instr[This->shader->num_instrs - 1]->predicate, predicate, sizeof(*predicate));
+}
+
+#if 0
 static void asmparser_predicate_unsupported(struct asm_parser *This,
                                             const struct shader_reg *predicate) {
     asmparser_message(This, "Line %u: Predicate not supported in < VS 2.0 or PS 2.x\n", This->line_no);
     set_parse_status(This, PARSE_ERR);
 }
+#endif
 
 static void asmparser_coissue_unsupported(struct asm_parser *This) {
     asmparser_message(This, "Line %u: Coissue is only supported in pixel shaders versions <= 1.4\n", This->line_no);
@@ -121,7 +132,7 @@ static const struct asmparser_backend parser_vs_3 = {
     asmparser_dstreg_vs_3,
     asmparser_srcreg_vs_3,
 
-    asmparser_predicate_unsupported,
+    asmparser_predicate_supported,
     asmparser_coissue_unsupported,
 
     asmparser_end,
diff --git a/dlls/d3dx9_36/asmshader.l b/dlls/d3dx9_36/asmshader.l
index a62f668..0fe0932 100644
--- a/dlls/d3dx9_36/asmshader.l
+++ b/dlls/d3dx9_36/asmshader.l
@@ -123,12 +123,14 @@ if                      {return INSTR_IF;           }
 else                    {return INSTR_ELSE;         }
 endif                   {return INSTR_ENDIF;        }
 break                   {return INSTR_BREAK;        }
+breakp                  {return INSTR_BREAKP;       }
 call                    {return INSTR_CALL;         }
 callnz                  {return INSTR_CALLNZ;       }
 loop                    {return INSTR_LOOP;         }
 ret                     {return INSTR_RET;          }
 endloop                 {return INSTR_ENDLOOP;      }
 label                   {return INSTR_LABEL;        }
+setp                    {return INSTR_SETP;         }
 texldl                  {return INSTR_TEXLDL;       }
 
     /* Vertex shader only instructions  */
diff --git a/dlls/d3dx9_36/asmshader.y b/dlls/d3dx9_36/asmshader.y
index ed4dd71..0c114e5 100644
--- a/dlls/d3dx9_36/asmshader.y
+++ b/dlls/d3dx9_36/asmshader.y
@@ -123,12 +123,14 @@ void set_rel_reg(struct shader_reg *reg, struct rel_reg *rel) {
 %token INSTR_ELSE
 %token INSTR_ENDIF
 %token INSTR_BREAK
+%token INSTR_BREAKP
 %token INSTR_CALL
 %token INSTR_CALLNZ
 %token INSTR_LOOP
 %token INSTR_RET
 %token INSTR_ENDLOOP
 %token INSTR_LABEL
+%token INSTR_SETP
 %token INSTR_TEXLDL
 
 /* Vertex shader only instructions  */
@@ -209,6 +211,7 @@ void set_rel_reg(struct shader_reg *reg, struct rel_reg *rel) {
 %type <modshift> omodifier
 %type <comptype> comp
 %type <rel_reg> rel_reg
+%type <reg> predicate
 %type <immval> immsum
 %type <sregs> sregs
 
@@ -307,6 +310,11 @@ complexinstr:         instruction
                             {
 
                             }
+                    | predicate instruction
+                            {
+                                TRACE("predicate\n");
+                                asm_ctx.funcs->predicate(&asm_ctx, &$1);
+                            }
 
 instruction:          INSTR_ADD omods dreg ',' sregs
                             {
@@ -508,6 +516,11 @@ instruction:          INSTR_ADD omods dreg ',' sregs
                                 TRACE("BREAKC\n");
                                 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_BREAKC, 0, 0, $2, 0, &$3, 2);
                             }
+                    | INSTR_BREAKP sregs
+                            {
+                                TRACE("BREAKP\n");
+                                asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_BREAKP, 0, 0, 0, 0, &$2, 1);
+                            }
                     | INSTR_CALL sregs
                             {
                                 TRACE("CALL\n");
@@ -538,6 +551,11 @@ instruction:          INSTR_ADD omods dreg ',' sregs
                                 TRACE("LABEL\n");
                                 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_LABEL, 0, 0, 0, 0, &$2, 1);
                             }
+                    | INSTR_SETP comp dreg ',' sregs
+                            {
+                                TRACE("SETP\n");
+                                asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_SETP, 0, 0, $2, &$3, &$5, 2);
+                            }
                     | INSTR_TEXLDL omods dreg ',' sregs
                             {
                                 TRACE("TEXLDL\n");
@@ -1023,6 +1041,23 @@ comp:                 COMP_GT           { $$ = BWRITER_COMPARISON_GT;       }
                     | COMP_EQ           { $$ = BWRITER_COMPARISON_EQ;       }
                     | COMP_NE           { $$ = BWRITER_COMPARISON_NE;       }
 
+predicate:            '(' REG_PREDICATE swizzle ')'
+                        {
+                            $$.type = BWRITERSPR_PREDICATE;
+                            $$.regnum = 0;
+                            $$.rel_reg = NULL;
+                            $$.srcmod = BWRITERSPSM_NONE;
+                            $$.swizzle = $3;
+                        }
+                    | '(' SMOD_NOT REG_PREDICATE swizzle ')'
+                        {
+                            $$.type = BWRITERSPR_PREDICATE;
+                            $$.regnum = 0;
+                            $$.rel_reg = NULL;
+                            $$.srcmod = BWRITERSPSM_NOT;
+                            $$.swizzle = $4;
+                        }
+
 %%
 
 void asmshader_error (char const *s) {
diff --git a/dlls/d3dx9_36/asmutils.c b/dlls/d3dx9_36/asmutils.c
index 229fa5e..9adb108 100644
--- a/dlls/d3dx9_36/asmutils.c
+++ b/dlls/d3dx9_36/asmutils.c
@@ -179,7 +179,9 @@ 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_SETP:        return D3DSIO_SETP;
         case BWRITERSIO_TEXLDL:      return D3DSIO_TEXLDL;
+        case BWRITERSIO_BREAKP:      return D3DSIO_BREAKP;
 
         case BWRITERSIO_COMMENT:     return D3DSIO_COMMENT;
         case BWRITERSIO_END:         return D3DSIO_END;
@@ -441,7 +443,9 @@ const char *debug_print_opcode(DWORD opcode) {
         case BWRITERSIO_MOVA:         return "mova";
         case BWRITERSIO_EXPP:         return "expp";
         case BWRITERSIO_LOGP:         return "logp";
+        case BWRITERSIO_SETP:         return "setp";
         case BWRITERSIO_TEXLDL:       return "texldl";
+        case BWRITERSIO_BREAKP:       return "breakp";
 
         default:                      return "unknown";
     }
diff --git a/dlls/d3dx9_36/bytecodewriter.c b/dlls/d3dx9_36/bytecodewriter.c
index 17bc3d5..64a7035 100644
--- a/dlls/d3dx9_36/bytecodewriter.c
+++ b/dlls/d3dx9_36/bytecodewriter.c
@@ -198,6 +198,8 @@ static void sm_2_opcode(struct bc_writer *This,
     token |= instrlen(instr, instr->num_srcs, dsts) << D3DSI_INSTLENGTH_SHIFT;
     if(instr->comptype)
         token |= (d3d9_comparetype(instr->comptype) << 16) & (0xf << 16);
+    if(instr->has_predicate)
+        token |= D3DSHADER_INSTRUCTION_PREDICATED;
     put_dword(buffer,token);
 }
 
@@ -335,6 +337,8 @@ static const struct instr_handler_table vs_3_handlers[] = {
     {BWRITERSIO_RET,            instr_handler},
     {BWRITERSIO_ENDLOOP,        instr_handler},
 
+    {BWRITERSIO_SETP,           instr_handler},
+    {BWRITERSIO_BREAKP,         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 b83ee49..6222d66 100644
--- a/dlls/d3dx9_36/d3dx9_36_private.h
+++ b/dlls/d3dx9_36/d3dx9_36_private.h
@@ -420,7 +420,9 @@ typedef enum _BWRITERSHADER_INSTRUCTION_OPCODE_TYPE {
 
     BWRITERSIO_EXPP,
     BWRITERSIO_LOGP,
+    BWRITERSIO_SETP,
     BWRITERSIO_TEXLDL,
+    BWRITERSIO_BREAKP,
 
     BWRITERSIO_COMMENT,
     BWRITERSIO_END,




More information about the wine-cvs mailing list