Ivan Gyurdiev : wined3d: Add shader_get_param() fn, which processes address tokens.

Alexandre Julliard julliard at wine.codeweavers.com
Wed May 17 04:46:48 CDT 2006


Module: wine
Branch: refs/heads/master
Commit: 404eff792fc679cca6040163a8b1cc643b75b608
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=404eff792fc679cca6040163a8b1cc643b75b608

Author: Ivan Gyurdiev <ivg2 at cornell.edu>
Date:   Wed May 17 02:02:36 2006 -0400

wined3d: Add shader_get_param() fn, which processes address tokens.

Add a new function to process parameters.
On shaders 1.0, processing parameters amounts to *pToken++.
On shaders 2.0+, we have a relative addressing token to account for.
This function should be used, instead of relying on num_params everywhere.

---

 dlls/wined3d/baseshader.c      |   61 +++++++++++++++++++++++++++++++++++++---
 dlls/wined3d/pixelshader.c     |   21 ++++++--------
 dlls/wined3d/vertexshader.c    |   48 ++++++++++++++-----------------
 dlls/wined3d/wined3d_private.h |   10 +++++++
 4 files changed, 96 insertions(+), 44 deletions(-)

diff --git a/dlls/wined3d/baseshader.c b/dlls/wined3d/baseshader.c
index 6ea5e9d..abf5019 100644
--- a/dlls/wined3d/baseshader.c
+++ b/dlls/wined3d/baseshader.c
@@ -85,6 +85,29 @@ const SHADER_OPCODE* shader_get_opcode(
     return NULL;
 }
 
+/* Read a parameter opcode from the input stream,
+ * and possibly a relative addressing token.
+ * Return the number of tokens read */
+int shader_get_param(
+    IWineD3DBaseShader* iface,
+    const DWORD* pToken,
+    DWORD* param,
+    DWORD* addr_token) {
+
+    /* PS >= 3.0 have relative addressing (with token)
+     * VS >= 2.0 have relative addressing (with token)
+     * VS >= 1.0 < 2.0 have relative addressing (without token)
+     * The version check below should work in general */
+
+    IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
+    char rel_token = D3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) >= 2 &&
+        ((*pToken & D3DSHADER_ADDRESSMODE_MASK) == D3DSHADER_ADDRMODE_RELATIVE);
+
+    *param = *pToken;
+    *addr_token = rel_token? *(pToken + 1): 0;
+    return rel_token? 2:1;
+}
+
 /* Return the number of parameters to skip for an opcode */
 static inline int shader_skip_opcode(
     IWineD3DBaseShaderImpl* This,
@@ -99,6 +122,36 @@ static inline int shader_skip_opcode(
         curOpcode->num_params;
 }
 
+/* Read the parameters of an unrecognized opcode from the input stream
+ * Return the number of tokens read. 
+ * 
+ * Note: This function assumes source or destination token format.
+ * It will not work with specially-formatted tokens like DEF or DCL, 
+ * but hopefully those would be recognized */
+
+int shader_skip_unrecognized(
+    IWineD3DBaseShader* iface,
+    const DWORD* pToken) {
+
+    int tokens_read = 0;
+    int i = 0;
+
+    /* TODO: Think of a good name for 0x80000000 and replace it with a constant */
+    while (*pToken & 0x80000000) {
+
+        DWORD param, addr_token;
+        tokens_read += shader_get_param(iface, pToken, &param, &addr_token);
+        pToken += tokens_read;
+
+        FIXME("Unrecognized opcode param: token=%08lX "
+            "addr_token=%08lX name=", param, addr_token);
+        shader_dump_param(iface, param, i);
+        FIXME("\n");
+        ++i;
+    }
+    return tokens_read;
+}
+
 /* Note: For vertex shaders,
  * texUsed = addrUsed, and 
  * D3DSPR_TEXTURE = D3DSPR_ADDR. 
@@ -484,11 +537,9 @@ void generate_base_shader(
             curOpcode = shader_get_opcode(iface, opcode_token);
 
             /* Unknown opcode and its parameters */
-            if (NULL == curOpcode) {
-                while (*pToken & 0x80000000) { /* TODO: Think of a sensible name for 0x80000000 */
-                    FIXME("unrecognized opcode: %08lx\n", *pToken);
-                    ++pToken;
-                }
+           if (NULL == curOpcode) {
+              FIXME("Unrecognized opcode: token=%08lX\n", opcode_token);
+              pToken += shader_skip_unrecognized(iface, pToken); 
 
             /* Using GLSL & no generator function exists */
             } else if (USING_GLSL && curOpcode->hw_glsl_fct == NULL) {
diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c
index 99c1fc9..4c109e2 100644
--- a/dlls/wined3d/pixelshader.c
+++ b/dlls/wined3d/pixelshader.c
@@ -1376,6 +1376,7 @@ HRESULT WINAPI IWineD3DPixelShaderImpl_S
     IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface;
     const DWORD* pToken = pFunction;
     const SHADER_OPCODE *curOpcode = NULL;
+    DWORD opcode_token;
     DWORD len = 0;
     DWORD i;
     TRACE("(%p) : Parsing programme\n", This);
@@ -1399,20 +1400,16 @@ HRESULT WINAPI IWineD3DPixelShaderImpl_S
             if (!This->baseShader.version) {
                 WARN("(%p) : pixel shader doesn't have a valid version identifier\n", This);
             }
-            curOpcode = shader_get_opcode((IWineD3DBaseShader*) This, *pToken);
-            ++pToken;
-            ++len;
+            opcode_token = *pToken++;
+            curOpcode = shader_get_opcode((IWineD3DBaseShader*) This, opcode_token);
+            len++;
             if (NULL == curOpcode) {
+                int tokens_read;
 
-                /* TODO: Think of a good name for 0x80000000 and replace it with a constant */
-                while (*pToken & 0x80000000) {
-
-                    /* unknown current opcode ... */
-                    TRACE("unrecognized opcode: %08lx", *pToken);
-                    ++pToken;
-                    ++len;
-                    TRACE("\n");
-                }
+                FIXME("Unrecognized opcode: token=%08lX\n", opcode_token);
+                tokens_read = shader_skip_unrecognized((IWineD3DBaseShader*) This, pToken);
+                pToken += tokens_read;
+                len += tokens_read;
 
             } else {
                 if (curOpcode->opcode == D3DSIO_DCL) {
diff --git a/dlls/wined3d/vertexshader.c b/dlls/wined3d/vertexshader.c
index 4c8eb14..fc68c71 100644
--- a/dlls/wined3d/vertexshader.c
+++ b/dlls/wined3d/vertexshader.c
@@ -1116,7 +1116,8 @@ BOOL IWineD3DVertexShaderImpl_ExecuteHAL
 
 HRESULT WINAPI IWineD3DVertexShaderImpl_ExecuteSW(IWineD3DVertexShader* iface, WINEVSHADERINPUTDATA* input, WINEVSHADEROUTPUTDATA* output) {
     IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
-        
+    DWORD opcode_token;   
+ 
     /** Vertex Shader Temporary Registers */
     WINED3DSHADERVECTOR R[12];
       /*D3DSHADERSCALAR A0;*/
@@ -1175,23 +1176,15 @@ #endif
             pToken += comment_len;
             continue ;
         }
-        curOpcode = shader_get_opcode((IWineD3DBaseShader*) This, *pToken);
-        ++pToken;
+
+        opcode_token = *pToken++;
+        curOpcode = shader_get_opcode((IWineD3DBaseShader*) This, opcode_token);
+
         if (NULL == curOpcode) {
-            i = 0;
-            /* unknown current opcode ... */
-            /* TODO: Think of a name for 0x80000000 and replace its use with a constant */
-            while (*pToken & 0x80000000) {
-                if (i == 0) {
-                    FIXME("unrecognized opcode: pos=%d token=%08lX\n", (pToken - 1) - This->baseShader.function, *(pToken - 1));
-                }
-                FIXME("unrecognized opcode param: pos=%d token=%08lX what=", pToken - This->baseShader.function, *pToken);
-                shader_dump_param((IWineD3DBaseShader*) This, *pToken, i);
-                TRACE("\n");
-                ++i;
-                ++pToken;
-            }
+            FIXME("Unrecognized opcode: token=%08lX\n", opcode_token);
+            pToken += shader_skip_unrecognized((IWineD3DBaseShader*) This, pToken);
             /* return FALSE; */
+
         } else {
             if (curOpcode->num_params > 0) {
                 /* TRACE(">> execting opcode: pos=%d opcode_name=%s token=%08lX\n", pToken - vshader->function, curOpcode->name, *pToken); */
@@ -1505,6 +1498,7 @@ HRESULT WINAPI IWineD3DVertexShaderImpl_
     IWineD3DVertexShaderImpl *This =(IWineD3DVertexShaderImpl *)iface;
     const DWORD* pToken = pFunction;
     const SHADER_OPCODE* curOpcode = NULL;
+    DWORD opcode_token;
     DWORD len = 0;
     DWORD i;
     TRACE("(%p) : Parsing programme\n", This);
@@ -1531,18 +1525,18 @@ HRESULT WINAPI IWineD3DVertexShaderImpl_
                 len += comment_len + 1;
                 continue;
             }
-            curOpcode = shader_get_opcode((IWineD3DBaseShader*) This, *pToken);
-            ++pToken;
-            ++len;
+
+            opcode_token = *pToken++;
+            curOpcode = shader_get_opcode((IWineD3DBaseShader*) This, opcode_token);
+            len++;
+
             if (NULL == curOpcode) {
-                /* TODO: Think of a good name for 0x80000000 and replace it with a constant */
-                while (*pToken & 0x80000000) {
-                    /* unknown current opcode ... */
-                    FIXME("unrecognized opcode: %08lx", *pToken);
-                    ++pToken;
-                    ++len;
-                    TRACE("\n");
-                }
+                int tokens_read;
+
+                FIXME("Unrecognized opcode: token=%08lX\n", opcode_token);
+                tokens_read = shader_skip_unrecognized((IWineD3DBaseShader*) This, pToken);
+                pToken += tokens_read;
+                len += tokens_read;
 
             } else {
                 if (curOpcode->opcode == D3DSIO_DCL) {
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index aa875e6..34d512e 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1372,6 +1372,16 @@ extern void shader_dump_param(
     const DWORD param,
     int input);
 
+extern int shader_get_param(
+    IWineD3DBaseShader* iface,
+    const DWORD* pToken,
+    DWORD* param,
+    DWORD* addr_token);
+
+extern int shader_skip_unrecognized(
+    IWineD3DBaseShader* iface,
+    const DWORD* pToken);
+
 inline static int shader_get_regtype(const DWORD param) {
     return (((param & D3DSP_REGTYPE_MASK) >> D3DSP_REGTYPE_SHIFT) |
             ((param & D3DSP_REGTYPE_MASK2) >> D3DSP_REGTYPE_SHIFT2));




More information about the wine-cvs mailing list