[1/3] d3dx9: Support some flow control instructions in the shader assembler.

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


-------------- next part --------------
From 247ab7b256ec4a5a6085f148ce347371e056b9c9 Mon Sep 17 00:00:00 2001
From: Matteo Bruni <matteo.mystral at gmail.com>
Date: Tue, 11 May 2010 20:29:07 +0200
Subject: [PATCH 1/3] d3dx9: Support some flow control instructions in the shader assembler.

---
 dlls/d3dx9_36/asmshader.l        |   14 +++++++
 dlls/d3dx9_36/asmshader.y        |   81 ++++++++++++++++++++++++++++++++++++++
 dlls/d3dx9_36/asmutils.c         |   30 ++++++++++++++
 dlls/d3dx9_36/bytecodewriter.c   |   13 ++++++
 dlls/d3dx9_36/d3dx9_36_private.h |   13 ++++++
 5 files changed, 151 insertions(+), 0 deletions(-)

diff --git a/dlls/d3dx9_36/asmshader.l b/dlls/d3dx9_36/asmshader.l
index 9d399c8..1cc28b8 100644
--- a/dlls/d3dx9_36/asmshader.l
+++ b/dlls/d3dx9_36/asmshader.l
@@ -117,6 +117,18 @@ m4x3                    {return INSTR_M4x3;         }
 m3x4                    {return INSTR_M3x4;         }
 m3x3                    {return INSTR_M3x3;         }
 m3x2                    {return INSTR_M3x2;         }
+rep                     {return INSTR_REP;          }
+endrep                  {return INSTR_ENDREP;       }
+if                      {return INSTR_IF;           }
+else                    {return INSTR_ELSE;         }
+endif                   {return INSTR_ENDIF;        }
+break                   {return INSTR_BREAK;        }
+call                    {return INSTR_CALL;         }
+callnz                  {return INSTR_CALLNZ;       }
+loop                    {return INSTR_LOOP;         }
+ret                     {return INSTR_RET;          }
+endloop                 {return INSTR_ENDLOOP;      }
+label                   {return INSTR_LABEL;        }
 texldl                  {return INSTR_TEXLDL;       }
 
     /* Vertex shader only instructions  */
@@ -247,6 +259,8 @@ ps_3_0                  {return VER_PS30;       }
 
 \_abs                   {return SMOD_ABS;           }
 
+!                       {return SMOD_NOT;           }
+
 {PREPROCESSORDIRECTIVE} {
                             /* TODO: update current line information */
                             TRACE("line info update: %s", yytext);
diff --git a/dlls/d3dx9_36/asmshader.y b/dlls/d3dx9_36/asmshader.y
index feb370b..ef09307 100644
--- a/dlls/d3dx9_36/asmshader.y
+++ b/dlls/d3dx9_36/asmshader.y
@@ -116,6 +116,18 @@ void set_rel_reg(struct shader_reg *reg, struct rel_reg *rel) {
 %token INSTR_M3x4
 %token INSTR_M3x3
 %token INSTR_M3x2
+%token INSTR_REP
+%token INSTR_ENDREP
+%token INSTR_IF
+%token INSTR_ELSE
+%token INSTR_ENDIF
+%token INSTR_BREAK
+%token INSTR_CALL
+%token INSTR_CALLNZ
+%token INSTR_LOOP
+%token INSTR_RET
+%token INSTR_ENDLOOP
+%token INSTR_LABEL
 %token INSTR_TEXLDL
 
 /* Vertex shader only instructions  */
@@ -168,6 +180,7 @@ void set_rel_reg(struct shader_reg *reg, struct rel_reg *rel) {
 
 /* Source register modifiers */
 %token SMOD_ABS
+%token SMOD_NOT
 
 /* Misc stuff */
 %token <component> COMPONENT
@@ -445,6 +458,66 @@ instruction:          INSTR_ADD omods dreg ',' sregs
                                 TRACE("M3x2\n");
                                 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_M3x2, $2.mod, $2.shift, 0, &$3, &$5, 2);
                             }
+                    | INSTR_REP sregs
+                            {
+                                TRACE("REP\n");
+                                asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_REP, 0, 0, 0, 0, &$2, 1);
+                            }
+                    | INSTR_ENDREP
+                            {
+                                TRACE("ENDREP\n");
+                                asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_ENDREP, 0, 0, 0, 0, 0, 0);
+                            }
+                    | INSTR_IF sregs
+                            {
+                                TRACE("IF\n");
+                                asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_IF, 0, 0, 0, 0, &$2, 1);
+                            }
+                    | INSTR_ELSE
+                            {
+                                TRACE("ELSE\n");
+                                asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_ELSE, 0, 0, 0, 0, 0, 0);
+                            }
+                    | INSTR_ENDIF
+                            {
+                                TRACE("ENDIF\n");
+                                asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_ENDIF, 0, 0, 0, 0, 0, 0);
+                            }
+                    | INSTR_BREAK
+                            {
+                                TRACE("BREAK\n");
+                                asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_BREAK, 0, 0, 0, 0, 0, 0);
+                            }
+                    | INSTR_CALL sregs
+                            {
+                                TRACE("CALL\n");
+                                asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_CALL, 0, 0, 0, 0, &$2, 1);
+                            }
+                    | INSTR_CALLNZ sregs
+                            {
+                                TRACE("CALLNZ\n");
+                                asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_CALLNZ, 0, 0, 0, 0, &$2, 2);
+                            }
+                    | INSTR_LOOP sregs
+                            {
+                                TRACE("LOOP\n");
+                                asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_LOOP, 0, 0, 0, 0, &$2, 2);
+                            }
+                    | INSTR_RET
+                            {
+                                TRACE("RET\n");
+                                asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_RET, 0, 0, 0, 0, 0, 0);
+                            }
+                    | INSTR_ENDLOOP
+                            {
+                                TRACE("ENDLOOP\n");
+                                asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_ENDLOOP, 0, 0, 0, 0, 0, 0);
+                            }
+                    | INSTR_LABEL sregs
+                            {
+                                TRACE("LABEL\n");
+                                asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_LABEL, 0, 0, 0, 0, &$2, 1);
+                            }
                     | INSTR_TEXLDL omods dreg ',' sregs
                             {
                                 TRACE("TEXLDL\n");
@@ -743,6 +816,14 @@ sreg:                   sreg_name rel_reg swizzle
                             }
                             $$.swizzle = $5;
                         }
+                    | SMOD_NOT sreg_name swizzle
+                        {
+                            $$.type = $2.type;
+                            $$.regnum = $2.regnum;
+                            $$.rel_reg = NULL;
+                            $$.srcmod = BWRITERSPSM_NOT;
+                            $$.swizzle = $3;
+                        }
 
 rel_reg:               /* empty */
                         {
diff --git a/dlls/d3dx9_36/asmutils.c b/dlls/d3dx9_36/asmutils.c
index 47291e3..5d12e4e 100644
--- a/dlls/d3dx9_36/asmutils.c
+++ b/dlls/d3dx9_36/asmutils.c
@@ -74,6 +74,7 @@ DWORD d3d9_srcmod(DWORD bwriter_srcmod) {
         case BWRITERSPSM_NEG:        return D3DSPSM_NEG;
         case BWRITERSPSM_ABS:        return D3DSPSM_ABS;
         case BWRITERSPSM_ABSNEG:     return D3DSPSM_ABSNEG;
+        case BWRITERSPSM_NOT:        return D3DSPSM_NOT;
         default:
             FIXME("Unhandled BWRITERSPSM token %u\n", bwriter_srcmod);
             return 0;
@@ -141,12 +142,24 @@ DWORD d3d9_opcode(DWORD bwriter_opcode) {
         case BWRITERSIO_M3x4:        return D3DSIO_M3x4;
         case BWRITERSIO_M3x3:        return D3DSIO_M3x3;
         case BWRITERSIO_M3x2:        return D3DSIO_M3x2;
+        case BWRITERSIO_CALL:        return D3DSIO_CALL;
+        case BWRITERSIO_CALLNZ:      return D3DSIO_CALLNZ;
+        case BWRITERSIO_LOOP:        return D3DSIO_LOOP;
+        case BWRITERSIO_RET:         return D3DSIO_RET;
+        case BWRITERSIO_ENDLOOP:     return D3DSIO_ENDLOOP;
+        case BWRITERSIO_LABEL:       return D3DSIO_LABEL;
         case BWRITERSIO_POW:         return D3DSIO_POW;
         case BWRITERSIO_CRS:         return D3DSIO_CRS;
         case BWRITERSIO_SGN:         return D3DSIO_SGN;
         case BWRITERSIO_ABS:         return D3DSIO_ABS;
         case BWRITERSIO_NRM:         return D3DSIO_NRM;
         case BWRITERSIO_SINCOS:      return D3DSIO_SINCOS;
+        case BWRITERSIO_REP:         return D3DSIO_REP;
+        case BWRITERSIO_ENDREP:      return D3DSIO_ENDREP;
+        case BWRITERSIO_IF:          return D3DSIO_IF;
+        case BWRITERSIO_ELSE:        return D3DSIO_ELSE;
+        case BWRITERSIO_ENDIF:       return D3DSIO_ENDIF;
+        case BWRITERSIO_BREAK:       return D3DSIO_BREAK;
         case BWRITERSIO_MOVA:        return D3DSIO_MOVA;
         case BWRITERSIO_EXPP:        return D3DSIO_EXPP;
         case BWRITERSIO_LOGP:        return D3DSIO_LOGP;
@@ -167,6 +180,7 @@ const char *debug_print_srcmod(DWORD mod) {
         case BWRITERSPSM_NEG:       return "D3DSPSM_NEG";
         case BWRITERSPSM_ABS:       return "D3DSPSM_ABS";
         case BWRITERSPSM_ABSNEG:    return "D3DSPSM_ABSNEG";
+        case BWRITERSPSM_NOT:       return "D3DSPSM_NOT";
         default:                    return "Unknown source modifier\n";
     }
 }
@@ -340,6 +354,10 @@ const char *debug_print_srcreg(const struct shader_reg *reg, shader_type st) {
             return wine_dbg_sprintf("-%s%s_abs%s", get_regname(reg, st),
                                     debug_print_relarg(reg),
                                     debug_print_swizzle(reg->swizzle));
+        case BWRITERSPSM_NOT:
+            return wine_dbg_sprintf("!%s%s%s", get_regname(reg, st),
+                                    debug_print_relarg(reg),
+                                    debug_print_swizzle(reg->swizzle));
     }
     return "Unknown modifier";
 }
@@ -371,12 +389,24 @@ const char *debug_print_opcode(DWORD opcode) {
         case BWRITERSIO_M3x4:         return "m3x4";
         case BWRITERSIO_M3x3:         return "m3x3";
         case BWRITERSIO_M3x2:         return "m3x2";
+        case BWRITERSIO_CALL:         return "call";
+        case BWRITERSIO_CALLNZ:       return "callnz";
+        case BWRITERSIO_LOOP:         return "loop";
+        case BWRITERSIO_RET:          return "ret";
+        case BWRITERSIO_ENDLOOP:      return "endloop";
+        case BWRITERSIO_LABEL:        return "label";
         case BWRITERSIO_POW:          return "pow";
         case BWRITERSIO_CRS:          return "crs";
         case BWRITERSIO_SGN:          return "sgn";
         case BWRITERSIO_ABS:          return "abs";
         case BWRITERSIO_NRM:          return "nrm";
         case BWRITERSIO_SINCOS:       return "sincos";
+        case BWRITERSIO_REP:          return "rep";
+        case BWRITERSIO_ENDREP:       return "endrep";
+        case BWRITERSIO_IF:           return "if";
+        case BWRITERSIO_ELSE:         return "else";
+        case BWRITERSIO_ENDIF:        return "endif";
+        case BWRITERSIO_BREAK:        return "break";
         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 7205e76..c30ae67 100644
--- a/dlls/d3dx9_36/bytecodewriter.c
+++ b/dlls/d3dx9_36/bytecodewriter.c
@@ -318,6 +318,19 @@ static const struct instr_handler_table vs_3_handlers[] = {
     {BWRITERSIO_POW,            instr_handler},
     {BWRITERSIO_MOVA,           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_ELSE,           instr_handler},
+    {BWRITERSIO_ENDIF,          instr_handler},
+    {BWRITERSIO_BREAK,          instr_handler},
+    {BWRITERSIO_LOOP,           instr_handler},
+    {BWRITERSIO_RET,            instr_handler},
+    {BWRITERSIO_ENDLOOP,        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 fd1cbca..22b4714 100644
--- a/dlls/d3dx9_36/d3dx9_36_private.h
+++ b/dlls/d3dx9_36/d3dx9_36_private.h
@@ -388,12 +388,24 @@ typedef enum _BWRITERSHADER_INSTRUCTION_OPCODE_TYPE {
     BWRITERSIO_M3x4,
     BWRITERSIO_M3x3,
     BWRITERSIO_M3x2,
+    BWRITERSIO_CALL,
+    BWRITERSIO_CALLNZ,
+    BWRITERSIO_LOOP,
+    BWRITERSIO_RET,
+    BWRITERSIO_ENDLOOP,
+    BWRITERSIO_LABEL,
     BWRITERSIO_POW,
     BWRITERSIO_CRS,
     BWRITERSIO_SGN,
     BWRITERSIO_ABS,
     BWRITERSIO_NRM,
     BWRITERSIO_SINCOS,
+    BWRITERSIO_REP,
+    BWRITERSIO_ENDREP,
+    BWRITERSIO_IF,
+    BWRITERSIO_ELSE,
+    BWRITERSIO_ENDIF,
+    BWRITERSIO_BREAK,
     BWRITERSIO_MOVA,
 
     BWRITERSIO_EXPP,
@@ -450,6 +462,7 @@ typedef enum _BWRITERSHADER_PARAM_SRCMOD_TYPE {
     BWRITERSPSM_NEG,
     BWRITERSPSM_ABS,
     BWRITERSPSM_ABSNEG,
+    BWRITERSPSM_NOT,
 } BWRITERSHADER_PARAM_SRCMOD_TYPE;
 
 #define BWRITER_SM1_VS  0xfffe
-- 
1.6.4.4


More information about the wine-patches mailing list