[v5 2/8] d3dx9: Introduce preshaders in effect.

Paul Gofman gofmanp at gmail.com
Mon Mar 21 08:55:53 CDT 2016


Signed-off-by: Paul Gofman <gofmanp at gmail.com>
---
- Splitted into 3 patches (introducing preshaders without implementation,
    basic implementation and adding preshader disasm code tracing)

 dlls/d3dx9_36/Makefile.in     |  1 +
 dlls/d3dx9_36/d3dx9_private.h | 36 +++++++++++++++++++
 dlls/d3dx9_36/effect.c        | 80 ++++++++++++++++++++++++++-----------------
 dlls/d3dx9_36/preshader.c     | 41 ++++++++++++++++++++++
 4 files changed, 126 insertions(+), 32 deletions(-)
 create mode 100644 dlls/d3dx9_36/preshader.c

diff --git a/dlls/d3dx9_36/Makefile.in b/dlls/d3dx9_36/Makefile.in
index 95e3045..83f7d1c 100644
--- a/dlls/d3dx9_36/Makefile.in
+++ b/dlls/d3dx9_36/Makefile.in
@@ -11,6 +11,7 @@ C_SRCS = \
 	line.c \
 	math.c \
 	mesh.c \
+	preshader.c \
 	render.c \
 	shader.c \
 	skin.c \
diff --git a/dlls/d3dx9_36/d3dx9_private.h b/dlls/d3dx9_36/d3dx9_private.h
index bc9581d..5ba93ac 100644
--- a/dlls/d3dx9_36/d3dx9_private.h
+++ b/dlls/d3dx9_36/d3dx9_private.h
@@ -108,4 +108,40 @@ const char *debug_d3dxparameter_registerset(D3DXREGISTER_SET r) DECLSPEC_HIDDEN;
 void set_number(void *outdata, D3DXPARAMETER_TYPE outtype,
         const void *indata, D3DXPARAMETER_TYPE intype) DECLSPEC_HIDDEN;
 
+struct d3dx_param_eval;
+
+struct d3dx_parameter
+{
+    char *name;
+    char *semantic;
+    void *data;
+    D3DXPARAMETER_CLASS class;
+    D3DXPARAMETER_TYPE  type;
+    UINT rows;
+    UINT columns;
+    UINT element_count;
+    UINT annotation_count;
+    UINT member_count;
+    DWORD flags;
+    UINT bytes;
+    DWORD object_id;
+
+    D3DXHANDLE handle;
+
+    struct d3dx_parameter *annotations;
+    struct d3dx_parameter *members;
+
+    struct d3dx_parameter *referenced_param;
+    struct d3dx_param_eval *param_eval;
+};
+
+struct d3dx9_base_effect;
+
+struct d3dx_parameter *get_parameter_by_name(struct d3dx9_base_effect *base,
+        struct d3dx_parameter *parameter, const char *name) DECLSPEC_HIDDEN;
+
+HRESULT d3dx_create_param_eval(struct d3dx9_base_effect *base_effect, void *byte_code,
+        unsigned int byte_code_size, D3DXPARAMETER_TYPE type, struct d3dx_param_eval **peval) DECLSPEC_HIDDEN;
+void d3dx_free_param_eval(struct d3dx_param_eval *peval) DECLSPEC_HIDDEN;
+
 #endif /* __WINE_D3DX9_PRIVATE_H */
diff --git a/dlls/d3dx9_36/effect.c b/dlls/d3dx9_36/effect.c
index 8f82784..964139f 100644
--- a/dlls/d3dx9_36/effect.c
+++ b/dlls/d3dx9_36/effect.c
@@ -94,30 +94,6 @@ enum STATE_TYPE
     ST_ARRAY_SELECTOR,
 };
 
-struct d3dx_parameter
-{
-    char *name;
-    char *semantic;
-    void *data;
-    D3DXPARAMETER_CLASS class;
-    D3DXPARAMETER_TYPE  type;
-    UINT rows;
-    UINT columns;
-    UINT element_count;
-    UINT annotation_count;
-    UINT member_count;
-    DWORD flags;
-    UINT bytes;
-    DWORD object_id;
-
-    D3DXHANDLE handle;
-
-    struct d3dx_parameter *annotations;
-    struct d3dx_parameter *members;
-
-    struct d3dx_parameter *referenced_param;
-};
-
 struct d3dx_object
 {
     UINT size;
@@ -206,8 +182,6 @@ struct ID3DXEffectCompilerImpl
     struct d3dx9_base_effect base_effect;
 };
 
-static struct d3dx_parameter *get_parameter_by_name(struct d3dx9_base_effect *base,
-        struct d3dx_parameter *parameter, const char *name);
 static struct d3dx_parameter *get_annotation_by_name(UINT count, struct d3dx_parameter *parameters,
         const char *name);
 static HRESULT d3dx9_parse_state(struct d3dx9_base_effect *base, struct d3dx_state *state,
@@ -535,6 +509,12 @@ static void free_parameter(struct d3dx_parameter *param, BOOL element, BOOL chil
     TRACE("Free parameter %p, name %s, type %s, child %s\n", param, param->name,
             debug_d3dxparameter_type(param->type), child ? "yes" : "no");
 
+    if (param->param_eval)
+    {
+        d3dx_free_param_eval(param->param_eval);
+        param->param_eval = NULL;
+    }
+
     if (param->annotations)
     {
         for (i = 0; i < param->annotation_count; ++i)
@@ -886,7 +866,7 @@ static struct d3dx_parameter *get_annotation_by_name(UINT count, struct d3dx_par
     return NULL;
 }
 
-static struct d3dx_parameter *get_parameter_by_name(struct d3dx9_base_effect *base,
+struct d3dx_parameter *get_parameter_by_name(struct d3dx9_base_effect *base,
         struct d3dx_parameter *parameter, const char *name)
 {
     UINT i, count, length;
@@ -5419,6 +5399,7 @@ static HRESULT d3dx9_parse_array_selector(struct d3dx9_base_effect *base, struct
     DWORD string_size;
     struct d3dx_object *object = &base->objects[param->object_id];
     char *ptr = object->data;
+    HRESULT ret;
 
     TRACE("Parsing array entry selection state for parameter %p.\n", param);
 
@@ -5435,9 +5416,30 @@ static HRESULT d3dx9_parse_array_selector(struct d3dx9_base_effect *base, struct
     }
     TRACE("Unknown DWORD: 0x%.8x.\n", *(DWORD *)(ptr + string_size));
 
-    FIXME("Parse preshader.\n");
+    d3dx_create_param_eval(base, (DWORD *)(ptr + string_size) + 1, object->size - (string_size + 1),
+            D3DXPT_INT, &param->param_eval);
+    ret = D3D_OK;
+    param = param->referenced_param;
+    if (param->type == D3DXPT_VERTEXSHADER || param->type == D3DXPT_PIXELSHADER)
+    {
+        unsigned int i;
 
-    return D3D_OK;
+        for (i = 0; i < param->element_count; i++)
+        {
+            if (param->members[i].type != param->type)
+            {
+                FIXME("Unexpected member parameter type %u, expected %u.\n", param->members[i].type, param->type);
+                return D3DXERR_INVALIDDATA;
+            }
+            if (!param->members[i].param_eval)
+            {
+                TRACE("Creating preshader for object %u.\n", param->members[i].object_id);
+                object = &base->objects[param->members[i].object_id];
+                d3dx_create_param_eval(base, object->data, object->size, param->type, &param->members[i].param_eval);
+            }
+        }
+    }
+    return ret;
 }
 
 static HRESULT d3dx9_parse_resource(struct d3dx9_base_effect *base, const char *data, const char **ptr)
@@ -5543,7 +5545,11 @@ static HRESULT d3dx9_parse_resource(struct d3dx9_base_effect *base, const char *
                         return hr;
 
                     if (object->data)
-                        hr = d3dx9_create_object(base, object);
+                    {
+                        if (FAILED(hr = d3dx9_create_object(base, object)))
+                            return hr;
+                        d3dx_create_param_eval(base, object->data, object->size, param->type, &param->param_eval);
+                    }
                     break;
 
                 case D3DXPT_BOOL:
@@ -5551,7 +5557,9 @@ static HRESULT d3dx9_parse_resource(struct d3dx9_base_effect *base, const char *
                 case D3DXPT_FLOAT:
                 case D3DXPT_STRING:
                     state->type = ST_FXLC;
-                    hr = d3dx9_copy_data(&base->objects[param->object_id], ptr);
+                    if (FAILED(hr = d3dx9_copy_data(&base->objects[param->object_id], ptr)))
+                        return hr;
+                    d3dx_create_param_eval(base, object->data, object->size, param->type, &param->param_eval);
                     break;
 
                 default:
@@ -5569,7 +5577,15 @@ static HRESULT d3dx9_parse_resource(struct d3dx9_base_effect *base, const char *
             param->referenced_param = get_parameter_by_name(base, NULL, object->data);
             if (param->referenced_param)
             {
-                TRACE("Mapping to parameter %p.\n", param->referenced_param);
+                struct d3dx_parameter *refpar = param->referenced_param;
+
+                TRACE("Mapping to parameter %p, having object id %u.\n", refpar, refpar->object_id);
+                if (refpar->type == D3DXPT_VERTEXSHADER || refpar->type == D3DXPT_PIXELSHADER)
+                {
+                    struct d3dx_object *refobj = &base->objects[refpar->object_id];
+
+                    d3dx_create_param_eval(base, refobj->data, refobj->size, refpar->type, &refpar->param_eval);
+                }
             }
             else
             {
diff --git a/dlls/d3dx9_36/preshader.c b/dlls/d3dx9_36/preshader.c
new file mode 100644
index 0000000..d865fd0
--- /dev/null
+++ b/dlls/d3dx9_36/preshader.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2016 Paul Gofman
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include "d3dx9_private.h"
+
+#include <float.h>
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
+
+HRESULT d3dx_create_param_eval(struct d3dx9_base_effect *base_effect, void *byte_code, unsigned int byte_code_size,
+        D3DXPARAMETER_TYPE type, struct d3dx_param_eval **peval_out)
+{
+    FIXME("stub, base_effect %p, byte_code %p, byte_code_size %u, type %u, peval_out %p.\n",
+            base_effect, byte_code, byte_code_size, type, peval_out);
+
+    *peval_out = NULL;
+    return E_NOTIMPL;
+}
+
+void d3dx_free_param_eval(struct d3dx_param_eval *peval)
+{
+    FIXME("stub, peval %p.\n", peval);
+}
-- 
2.5.5




More information about the wine-patches mailing list