[2/3] d3dx9: Add other flow control instructions in the shader assembler.

Matteo Bruni matteo.mystral at gmail.com
Tue May 11 19:00:13 CDT 2010


-------------- next part --------------
From e07d8051e0f7a2663cd21122d8ec6ec73f3e3ba7 Mon Sep 17 00:00:00 2001
From: Matteo Bruni <matteo.mystral at gmail.com>
Date: Tue, 24 Nov 2009 02:08:32 +0100
Subject: d3dx9: Add other flow control instructions in the shader assembler.

---
 dlls/d3dx9_36/asmparser.c        |    5 +++--
 dlls/d3dx9_36/asmshader.l        |    8 ++++++++
 dlls/d3dx9_36/asmshader.y        |   27 +++++++++++++++++++++++++++
 dlls/d3dx9_36/asmutils.c         |   31 +++++++++++++++++++++++++++++++
 dlls/d3dx9_36/bytecodewriter.c   |    4 ++++
 dlls/d3dx9_36/d3dx9_36_private.h |   12 +++++++++++-
 6 files changed, 84 insertions(+), 3 deletions(-)

diff --git a/dlls/d3dx9_36/asmparser.c b/dlls/d3dx9_36/asmparser.c
index c810cbb..15ac7ea 100644
--- a/dlls/d3dx9_36/asmparser.c
+++ b/dlls/d3dx9_36/asmparser.c
@@ -50,8 +50,9 @@ static void asmparser_instr(struct asm_parser *This, DWORD opcode,
 
     if(!This->shader) return;
 
-    TRACE_(parsed_shader)("%s%s ", debug_print_opcode(opcode),
-                          debug_print_dstmod(mod));
+    TRACE_(parsed_shader)("%s%s%s ", debug_print_opcode(opcode),
+                          debug_print_dstmod(mod),
+                          debug_print_comp(comp));
     if(dst) {
         TRACE_(parsed_shader)("%s", debug_print_dstreg(dst, This->shader->type));
         firstreg = FALSE;
diff --git a/dlls/d3dx9_36/asmshader.l b/dlls/d3dx9_36/asmshader.l
index 1cc28b8..a62f668 100644
--- a/dlls/d3dx9_36/asmshader.l
+++ b/dlls/d3dx9_36/asmshader.l
@@ -243,6 +243,14 @@ ps_3_0                  {return VER_PS30;       }
 \_pp                    {return MOD_PP;             }
 \_centroid              {return MOD_CENTROID;       }
 
+    /* compare params */
+\_gt                    {return COMP_GT;            }
+\_lt                    {return COMP_LT;            }
+\_ge                    {return COMP_GE;            }
+\_le                    {return COMP_LE;            }
+\_eq                    {return COMP_EQ;            }
+\_ne                    {return COMP_NE;            }
+
 {IMMVAL}                {
                             asmshader_lval.immval.val = atof(yytext);
                             asmshader_lval.immval.integer = ((strstr(yytext, ".") == NULL) && (strstr(yytext, "f") == NULL));
diff --git a/dlls/d3dx9_36/asmshader.y b/dlls/d3dx9_36/asmshader.y
index ef09307..ed4dd71 100644
--- a/dlls/d3dx9_36/asmshader.y
+++ b/dlls/d3dx9_36/asmshader.y
@@ -79,6 +79,7 @@ void set_rel_reg(struct shader_reg *reg, struct rel_reg *rel) {
         DWORD           mod;
         DWORD           shift;
     } modshift;
+    BWRITER_COMPARISON_TYPE comptype;
     struct rel_reg      rel_reg;
     struct src_regs     sregs;
 }
@@ -178,6 +179,14 @@ void set_rel_reg(struct shader_reg *reg, struct rel_reg *rel) {
 %token MOD_PP
 %token MOD_CENTROID
 
+/* Compare tokens */
+%token COMP_GT
+%token COMP_LT
+%token COMP_GE
+%token COMP_LE
+%token COMP_EQ
+%token COMP_NE
+
 /* Source register modifiers */
 %token SMOD_ABS
 %token SMOD_NOT
@@ -198,6 +207,7 @@ void set_rel_reg(struct shader_reg *reg, struct rel_reg *rel) {
 %type <sw_components> sw_components
 %type <modshift> omods
 %type <modshift> omodifier
+%type <comptype> comp
 %type <rel_reg> rel_reg
 %type <immval> immsum
 %type <sregs> sregs
@@ -473,6 +483,11 @@ instruction:          INSTR_ADD omods dreg ',' sregs
                                 TRACE("IF\n");
                                 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_IF, 0, 0, 0, 0, &$2, 1);
                             }
+                    | INSTR_IF comp sregs
+                            {
+                                TRACE("IFC\n");
+                                asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_IFC, 0, 0, $2, 0, &$3, 2);
+                            }
                     | INSTR_ELSE
                             {
                                 TRACE("ELSE\n");
@@ -488,6 +503,11 @@ instruction:          INSTR_ADD omods dreg ',' sregs
                                 TRACE("BREAK\n");
                                 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_BREAK, 0, 0, 0, 0, 0, 0);
                             }
+                    | INSTR_BREAK comp sregs
+                            {
+                                TRACE("BREAKC\n");
+                                asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_BREAKC, 0, 0, $2, 0, &$3, 2);
+                            }
                     | INSTR_CALL sregs
                             {
                                 TRACE("CALL\n");
@@ -996,6 +1016,13 @@ sreg_name:            REG_TEMP
                             $$.regnum = $1; $$.type = BWRITERSPR_LABEL;
                         }
 
+comp:                 COMP_GT           { $$ = BWRITER_COMPARISON_GT;       }
+                    | COMP_LT           { $$ = BWRITER_COMPARISON_LT;       }
+                    | COMP_GE           { $$ = BWRITER_COMPARISON_GE;       }
+                    | COMP_LE           { $$ = BWRITER_COMPARISON_LE;       }
+                    | COMP_EQ           { $$ = BWRITER_COMPARISON_EQ;       }
+                    | COMP_NE           { $$ = BWRITER_COMPARISON_NE;       }
+
 %%
 
 void asmshader_error (char const *s) {
diff --git a/dlls/d3dx9_36/asmutils.c b/dlls/d3dx9_36/asmutils.c
index 5d12e4e..229fa5e 100644
--- a/dlls/d3dx9_36/asmutils.c
+++ b/dlls/d3dx9_36/asmutils.c
@@ -91,6 +91,20 @@ DWORD d3d9_dstmod(DWORD bwriter_mod) {
     return ret;
 }
 
+DWORD d3d9_comparetype(DWORD asmshader_comparetype) {
+    switch(asmshader_comparetype) {
+        case BWRITER_COMPARISON_GT:     return D3DSPC_GT;
+        case BWRITER_COMPARISON_EQ:     return D3DSPC_EQ;
+        case BWRITER_COMPARISON_GE:     return D3DSPC_GE;
+        case BWRITER_COMPARISON_LT:     return D3DSPC_LT;
+        case BWRITER_COMPARISON_NE:     return D3DSPC_NE;
+        case BWRITER_COMPARISON_LE:     return D3DSPC_LE;
+        default:
+            FIXME("Unexpected BWRITER_COMPARISON type %u\n", asmshader_comparetype);
+            return 0;
+    }
+}
+
 DWORD d3d9_register(DWORD bwriter_register) {
     if(bwriter_register == BWRITERSPR_TEMP)         return D3DSPR_TEMP;
     if(bwriter_register == BWRITERSPR_INPUT)        return D3DSPR_INPUT;
@@ -157,9 +171,11 @@ DWORD d3d9_opcode(DWORD bwriter_opcode) {
         case BWRITERSIO_REP:         return D3DSIO_REP;
         case BWRITERSIO_ENDREP:      return D3DSIO_ENDREP;
         case BWRITERSIO_IF:          return D3DSIO_IF;
+        case BWRITERSIO_IFC:         return D3DSIO_IFC;
         case BWRITERSIO_ELSE:        return D3DSIO_ELSE;
         case BWRITERSIO_ENDIF:       return D3DSIO_ENDIF;
         case BWRITERSIO_BREAK:       return D3DSIO_BREAK;
+        case BWRITERSIO_BREAKC:      return D3DSIO_BREAKC;
         case BWRITERSIO_MOVA:        return D3DSIO_MOVA;
         case BWRITERSIO_EXPP:        return D3DSIO_EXPP;
         case BWRITERSIO_LOGP:        return D3DSIO_LOGP;
@@ -362,6 +378,19 @@ const char *debug_print_srcreg(const struct shader_reg *reg, shader_type st) {
     return "Unknown modifier";
 }
 
+const char *debug_print_comp(DWORD comp) {
+    switch(comp) {
+        case BWRITER_COMPARISON_NONE: return "";
+        case BWRITER_COMPARISON_GT:   return "_gt";
+        case BWRITER_COMPARISON_EQ:   return "_eq";
+        case BWRITER_COMPARISON_GE:   return "_ge";
+        case BWRITER_COMPARISON_LT:   return "_lt";
+        case BWRITER_COMPARISON_NE:   return "_ne";
+        case BWRITER_COMPARISON_LE:   return "_le";
+        default: return "_unknown";
+    }
+}
+
 const char *debug_print_opcode(DWORD opcode) {
     switch(opcode){
         case BWRITERSIO_NOP:          return "nop";
@@ -404,9 +433,11 @@ const char *debug_print_opcode(DWORD opcode) {
         case BWRITERSIO_REP:          return "rep";
         case BWRITERSIO_ENDREP:       return "endrep";
         case BWRITERSIO_IF:           return "if";
+        case BWRITERSIO_IFC:          return "ifc";
         case BWRITERSIO_ELSE:         return "else";
         case BWRITERSIO_ENDIF:        return "endif";
         case BWRITERSIO_BREAK:        return "break";
+        case BWRITERSIO_BREAKC:       return "breakc";
         case BWRITERSIO_MOVA:         return "mova";
         case BWRITERSIO_EXPP:         return "expp";
         case BWRITERSIO_LOGP:         return "logp";
diff --git a/dlls/d3dx9_36/bytecodewriter.c b/dlls/d3dx9_36/bytecodewriter.c
index c30ae67..17bc3d5 100644
--- a/dlls/d3dx9_36/bytecodewriter.c
+++ b/dlls/d3dx9_36/bytecodewriter.c
@@ -196,6 +196,8 @@ static void sm_2_opcode(struct bc_writer *This,
     /* From sm 2 onwards instruction length is encoded in the opcode field */
     int dsts = instr->has_dst ? 1 : 0;
     token |= instrlen(instr, instr->num_srcs, dsts) << D3DSI_INSTLENGTH_SHIFT;
+    if(instr->comptype)
+        token |= (d3d9_comparetype(instr->comptype) << 16) & (0xf << 16);
     put_dword(buffer,token);
 }
 
@@ -324,9 +326,11 @@ static const struct instr_handler_table vs_3_handlers[] = {
     {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},
diff --git a/dlls/d3dx9_36/d3dx9_36_private.h b/dlls/d3dx9_36/d3dx9_36_private.h
index 22b4714..b83ee49 100644
--- a/dlls/d3dx9_36/d3dx9_36_private.h
+++ b/dlls/d3dx9_36/d3dx9_36_private.h
@@ -137,7 +137,13 @@ typedef enum _shader_type {
 } shader_type;
 
 typedef enum BWRITER_COMPARISON_TYPE {
-    BWRITER_COMPARISON_NONE = 0,
+    BWRITER_COMPARISON_NONE,
+    BWRITER_COMPARISON_GT,
+    BWRITER_COMPARISON_EQ,
+    BWRITER_COMPARISON_GE,
+    BWRITER_COMPARISON_LT,
+    BWRITER_COMPARISON_NE,
+    BWRITER_COMPARISON_LE
 } BWRITER_COMPARISON_TYPE;
 
 struct shader_reg {
@@ -345,6 +351,7 @@ const char *debug_print_dstreg(const struct shader_reg *reg, shader_type st);
 const char *debug_print_srcreg(const struct shader_reg *reg, shader_type st);
 const char *debug_print_swizzle(DWORD swizzle);
 const char *debug_print_writemask(DWORD mask);
+const char *debug_print_comp(DWORD comp);
 const char *debug_print_opcode(DWORD opcode);
 
 /* Utilities for internal->d3d constant mapping */
@@ -352,6 +359,7 @@ DWORD d3d9_swizzle(DWORD bwriter_swizzle);
 DWORD d3d9_writemask(DWORD bwriter_writemask);
 DWORD d3d9_srcmod(DWORD bwriter_srcmod);
 DWORD d3d9_dstmod(DWORD bwriter_mod);
+DWORD d3d9_comparetype(DWORD bwriter_comparetype);
 DWORD d3d9_register(DWORD bwriter_register);
 DWORD d3d9_opcode(DWORD bwriter_opcode);
 
@@ -403,9 +411,11 @@ typedef enum _BWRITERSHADER_INSTRUCTION_OPCODE_TYPE {
     BWRITERSIO_REP,
     BWRITERSIO_ENDREP,
     BWRITERSIO_IF,
+    BWRITERSIO_IFC,
     BWRITERSIO_ELSE,
     BWRITERSIO_ENDIF,
     BWRITERSIO_BREAK,
+    BWRITERSIO_BREAKC,
     BWRITERSIO_MOVA,
 
     BWRITERSIO_EXPP,
-- 
1.6.4.4


More information about the wine-patches mailing list