Rico Schüller : d3dx9_36: Start effect parsing.

Alexandre Julliard julliard at winehq.org
Tue Mar 15 11:33:58 CDT 2011


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

Author: Rico Schüller <kgbricola at web.de>
Date:   Mon Mar 14 22:53:08 2011 +0100

d3dx9_36: Start effect parsing.

---

 dlls/d3dx9_36/effect.c |   98 ++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 94 insertions(+), 4 deletions(-)

diff --git a/dlls/d3dx9_36/effect.c b/dlls/d3dx9_36/effect.c
index 8c3c756..2697782 100644
--- a/dlls/d3dx9_36/effect.c
+++ b/dlls/d3dx9_36/effect.c
@@ -31,8 +31,35 @@ static const struct ID3DXEffectVtbl ID3DXEffect_Vtbl;
 typedef struct ID3DXEffectImpl {
     ID3DXEffect ID3DXEffect_iface;
     LONG ref;
+
+    UINT parameter_count;
+    UINT technique_count;
 } ID3DXEffectImpl;
 
+static inline void read_dword(const char **ptr, DWORD *d)
+{
+    memcpy(d, *ptr, sizeof(*d));
+    *ptr += sizeof(*d);
+}
+
+static void skip_dword_unknown(const char **ptr, unsigned int count)
+{
+    unsigned int i;
+    DWORD d;
+
+    FIXME("Skipping %u unknown DWORDs:\n", count);
+    for (i = 0; i < count; ++i)
+    {
+        read_dword(ptr, &d);
+        FIXME("\t0x%08x\n", d);
+    }
+}
+
+static inline DWORD d3dx9_effect_version(DWORD major, DWORD minor)
+{
+    return (0xfeff0000 | ((major) << 8) | (minor));
+}
+
 static inline ID3DXEffectImpl *impl_from_ID3DXEffect(ID3DXEffect *iface)
 {
     return CONTAINING_RECORD(iface, ID3DXEffectImpl, ID3DXEffect_iface);
@@ -853,6 +880,61 @@ static const struct ID3DXEffectVtbl ID3DXEffect_Vtbl =
     ID3DXEffectImpl_SetRawValue
 };
 
+static HRESULT d3dx9_parse_effect(ID3DXEffectImpl *effect, const char *data, UINT data_size, DWORD start)
+{
+    const char *ptr = data + start;
+
+    read_dword(&ptr, &effect->parameter_count);
+    TRACE("Parameter count: %u\n", effect->parameter_count);
+
+    read_dword(&ptr, &effect->technique_count);
+    TRACE("Technique count: %u\n", effect->technique_count);
+
+    skip_dword_unknown(&ptr, 2);
+
+    /* todo: Parse parameter */
+
+    /* todo: Parse techniques */
+
+    return S_OK;
+}
+
+static HRESULT d3dx9_effect_init(ID3DXEffectImpl *effect, const char *data, SIZE_T data_size)
+{
+    DWORD tag, offset;
+    const char *ptr = data;
+    HRESULT hr;
+
+    effect->ID3DXEffect_iface.lpVtbl = &ID3DXEffect_Vtbl;
+    effect->ref = 1;
+
+    read_dword(&ptr, &tag);
+    TRACE("Tag: %x\n", tag);
+
+    if (tag != d3dx9_effect_version(9, 1))
+    {
+        /* todo: compile hlsl ascii code */
+        FIXME("HLSL ascii effects not supported, yet\n");
+
+        /* Show the start of the shader for debugging info. */
+        TRACE("effect:\n%s\n", debugstr_an(data, data_size > 40 ? 40 : data_size));
+    }
+    else
+    {
+        read_dword(&ptr, &offset);
+        TRACE("Offset: %x\n", offset);
+
+        hr = d3dx9_parse_effect(effect, ptr, data_size, offset);
+        if (hr != S_OK)
+        {
+            FIXME("Failed to parse effect.\n");
+            return hr;
+        }
+    }
+
+    return S_OK;
+}
+
 HRESULT WINAPI D3DXCreateEffectEx(LPDIRECT3DDEVICE9 device,
                                   LPCVOID srcdata,
                                   UINT srcdatalen,
@@ -864,7 +946,8 @@ HRESULT WINAPI D3DXCreateEffectEx(LPDIRECT3DDEVICE9 device,
                                   LPD3DXEFFECT* effect,
                                   LPD3DXBUFFER* compilation_errors)
 {
-    ID3DXEffectImpl* object;
+    ID3DXEffectImpl *object;
+    HRESULT hr;
 
     FIXME("(%p, %p, %u, %p, %p, %p, %#x, %p, %p, %p): semi-stub\n", device, srcdata, srcdatalen, defines, include,
         skip_constants, flags, pool, effect, compilation_errors);
@@ -879,18 +962,25 @@ HRESULT WINAPI D3DXCreateEffectEx(LPDIRECT3DDEVICE9 device,
     if (!effect)
         return D3D_OK;
 
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ID3DXEffectImpl));
+    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
     if (!object)
     {
         ERR("Out of memory\n");
         return E_OUTOFMEMORY;
     }
 
-    object->ID3DXEffect_iface.lpVtbl = &ID3DXEffect_Vtbl;
-    object->ref = 1;
+    hr = d3dx9_effect_init(object, srcdata, srcdatalen);
+    if (FAILED(hr))
+    {
+        WARN("Failed to initialize shader reflection\n");
+        HeapFree(GetProcessHeap(), 0, object);
+        return hr;
+    }
 
     *effect = &object->ID3DXEffect_iface;
 
+    TRACE("Created ID3DXEffect %p\n", object);
+
     return D3D_OK;
 }
 




More information about the wine-cvs mailing list