Rico Schüller : d3dx9: Handle pool and device in ID3DXEffect.

Alexandre Julliard julliard at winehq.org
Tue Mar 29 11:43:07 CDT 2011


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

Author: Rico Schüller <kgbricola at web.de>
Date:   Sun Mar 27 22:12:28 2011 +0200

d3dx9: Handle pool and device in ID3DXEffect.

---

 dlls/d3dx9_36/effect.c       |   39 ++++++++++++++++++++++++++++++++++++---
 dlls/d3dx9_36/tests/effect.c |   42 +++++++++++++++++++++++++++++++++++-------
 2 files changed, 71 insertions(+), 10 deletions(-)

diff --git a/dlls/d3dx9_36/effect.c b/dlls/d3dx9_36/effect.c
index 15683df..fec95be 100644
--- a/dlls/d3dx9_36/effect.c
+++ b/dlls/d3dx9_36/effect.c
@@ -32,6 +32,9 @@ typedef struct ID3DXEffectImpl {
     ID3DXEffect ID3DXEffect_iface;
     LONG ref;
 
+    LPDIRECT3DDEVICE9 device;
+    LPD3DXEFFECTPOOL pool;
+
     UINT parameter_count;
     UINT technique_count;
 } ID3DXEffectImpl;
@@ -55,6 +58,18 @@ static void skip_dword_unknown(const char **ptr, unsigned int count)
     }
 }
 
+static void free_effect(struct ID3DXEffectImpl *effect)
+{
+    TRACE("Free effect %p\n", effect);
+
+    if (effect->pool)
+    {
+        effect->pool->lpVtbl->Release(effect->pool);
+    }
+
+    IDirect3DDevice9_Release(effect->device);
+}
+
 static inline DWORD d3dx9_effect_version(DWORD major, DWORD minor)
 {
     return (0xfeff0000 | ((major) << 8) | (minor));
@@ -103,7 +118,10 @@ static ULONG WINAPI ID3DXEffectImpl_Release(ID3DXEffect* iface)
     TRACE("(%p)->(): Release from %u\n", This, ref + 1);
 
     if (!ref)
+    {
+        free_effect(This);
         HeapFree(GetProcessHeap(), 0, This);
+    }
 
     return ref;
 }
@@ -899,15 +917,24 @@ static HRESULT d3dx9_parse_effect(ID3DXEffectImpl *effect, const char *data, UIN
     return S_OK;
 }
 
-static HRESULT d3dx9_effect_init(ID3DXEffectImpl *effect, const char *data, SIZE_T data_size)
+static HRESULT d3dx9_effect_init(ID3DXEffectImpl *effect, LPDIRECT3DDEVICE9 device,
+        const char *data, SIZE_T data_size, LPD3DXEFFECTPOOL pool)
 {
     DWORD tag, offset;
     const char *ptr = data;
     HRESULT hr;
 
+    TRACE("effect %p, device %p, data %p, data_size %lu, pool %p\n", effect, device, data, data_size, pool);
+
     effect->ID3DXEffect_iface.lpVtbl = &ID3DXEffect_Vtbl;
     effect->ref = 1;
 
+    if (pool) pool->lpVtbl->AddRef(pool);
+    effect->pool = pool;
+
+    IDirect3DDevice9_AddRef(device);
+    effect->device = device;
+
     read_dword(&ptr, &tag);
     TRACE("Tag: %x\n", tag);
 
@@ -928,11 +955,17 @@ static HRESULT d3dx9_effect_init(ID3DXEffectImpl *effect, const char *data, SIZE
         if (hr != S_OK)
         {
             FIXME("Failed to parse effect.\n");
-            return hr;
+            goto err_out;
         }
     }
 
     return S_OK;
+
+err_out:
+
+    free_effect(effect);
+
+    return hr;
 }
 
 HRESULT WINAPI D3DXCreateEffectEx(LPDIRECT3DDEVICE9 device,
@@ -969,7 +1002,7 @@ HRESULT WINAPI D3DXCreateEffectEx(LPDIRECT3DDEVICE9 device,
         return E_OUTOFMEMORY;
     }
 
-    hr = d3dx9_effect_init(object, srcdata, srcdatalen);
+    hr = d3dx9_effect_init(object, device, srcdata, srcdatalen, pool);
     if (FAILED(hr))
     {
         WARN("Failed to initialize shader reflection\n");
diff --git a/dlls/d3dx9_36/tests/effect.c b/dlls/d3dx9_36/tests/effect.c
index 8b23536..f4e0f9a 100644
--- a/dlls/d3dx9_36/tests/effect.c
+++ b/dlls/d3dx9_36/tests/effect.c
@@ -16,6 +16,8 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#define COBJMACROS
+#include "initguid.h"
 #include "wine/test.h"
 #include "d3dx9.h"
 
@@ -24,10 +26,11 @@ static const char effect_desc[] =
 "{\n"
 "}\n";
 
-static void test_create_effect(IDirect3DDevice9* device)
+static void test_create_effect(IDirect3DDevice9 *device)
 {
     HRESULT hr;
-    ID3DXEffect* effect;
+    ID3DXEffect *effect;
+    ULONG count;
 
     hr = D3DXCreateEffect(NULL, effect_desc, sizeof(effect_desc), NULL, NULL, 0, NULL, NULL, NULL);
     ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3D_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
@@ -44,13 +47,16 @@ static void test_create_effect(IDirect3DDevice9* device)
     hr = D3DXCreateEffect(device, effect_desc, sizeof(effect_desc), NULL, NULL, 0, NULL, &effect, NULL);
     ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
 
-    effect->lpVtbl->Release(effect);
+    count = effect->lpVtbl->Release(effect);
+    ok(count == 0, "Release failed %u\n", count);
 }
 
-static void test_create_effect_pool(void)
+static void test_create_effect_pool(IDirect3DDevice9 *device)
 {
     HRESULT hr;
-    ID3DXEffectPool* pool;
+    ID3DXEffectPool *pool, *pool2;
+    ULONG count;
+    IDirect3DDevice9 *device2;
 
     hr = D3DXCreateEffectPool(NULL);
     ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3D_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
@@ -58,7 +64,29 @@ static void test_create_effect_pool(void)
     hr = D3DXCreateEffectPool(&pool);
     ok(hr == S_OK, "Got result %x, expected 0 (S_OK)\n", hr);
 
-    pool->lpVtbl->Release(pool);
+    count = pool->lpVtbl->Release(pool);
+    ok(count == 0, "Release failed %u\n", count);
+
+    hr = D3DXCreateEffectPool(&pool);
+    ok(hr == S_OK, "Got result %x, expected 0 (S_OK)\n", hr);
+
+    hr = D3DXCreateEffect(device, effect_desc, sizeof(effect_desc), NULL, NULL, 0, pool, NULL, NULL);
+    ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+
+    hr = pool->lpVtbl->QueryInterface(pool, &IID_ID3DXEffectPool, (void **)&pool2);
+    ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+
+    count = pool2->lpVtbl->Release(pool2);
+    ok(count == 1, "Release failed, got %u, expected 1\n", count);
+
+    hr = device->lpVtbl->QueryInterface(device, &IID_IDirect3DDevice9, (void **)&device2);
+    ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+
+    count = device2->lpVtbl->Release(device2);
+    ok(count == 1, "Release failed, got %u, expected 1\n", count);
+
+    count = pool->lpVtbl->Release(pool);
+    ok(count == 0, "Release failed %u\n", count);
 }
 
 START_TEST(effect)
@@ -93,7 +121,7 @@ START_TEST(effect)
     }
 
     test_create_effect(device);
-    test_create_effect_pool();
+    test_create_effect_pool(device);
 
     IDirect3DDevice9_Release(device);
     IDirect3D9_Release(d3d);




More information about the wine-cvs mailing list