diff --git a/dlls/d3dx9_36/d3dx9_36.spec b/dlls/d3dx9_36/d3dx9_36.spec index fbcce68c242..e4d49e8a52e 100644 --- a/dlls/d3dx9_36/d3dx9_36.spec +++ b/dlls/d3dx9_36/d3dx9_36.spec @@ -61,7 +61,7 @@ @ stub D3DXCreateEffectFromResourceExA @ stub D3DXCreateEffectFromResourceExW @ stub D3DXCreateEffectFromResourceW -@ stub D3DXCreateEffectPool +@ stdcall D3DXCreateEffectPool(ptr) @ stdcall D3DXCreateFontA(ptr long long long long long long long long long str ptr) @ stdcall D3DXCreateFontIndirectA(ptr ptr ptr) @ stdcall D3DXCreateFontIndirectW(ptr ptr ptr) diff --git a/dlls/d3dx9_36/effect.c b/dlls/d3dx9_36/effect.c index 59993232f93..6c544d26780 100644 --- a/dlls/d3dx9_36/effect.c +++ b/dlls/d3dx9_36/effect.c @@ -889,3 +889,84 @@ HRESULT WINAPI D3DXCreateEffect(LPDIRECT3DDEVICE9 device, return D3D_OK; } + +static const struct ID3DXEffectPoolVtbl ID3DXEffectPool_Vtbl; + +typedef struct ID3DXEffectPoolImpl { + const ID3DXEffectPoolVtbl *lpVtbl; + LONG ref; +} ID3DXEffectPoolImpl; + +/*** IUnknown methods ***/ +static HRESULT WINAPI ID3DXEffectPoolImpl_QueryInterface(ID3DXEffectPool* iface, REFIID riid, void** object) +{ + ID3DXEffectPoolImpl *This = (ID3DXEffectPoolImpl *)iface; + + TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), object); + + if (IsEqualGUID(riid, &IID_IUnknown) || + IsEqualGUID(riid, &IID_ID3DXEffectPool)) + { + This->lpVtbl->AddRef(iface); + *object = This; + return S_OK; + } + + WARN("Interface %s not found\n", debugstr_guid(riid)); + + return E_NOINTERFACE; +} + +static ULONG WINAPI ID3DXEffectPoolImpl_AddRef(ID3DXEffectPool* iface) +{ + ID3DXEffectPoolImpl *This = (ID3DXEffectPoolImpl *)iface; + + TRACE("(%p)->(): AddRef from %u\n", This, This->ref); + + return InterlockedIncrement(&This->ref); +} + +static ULONG WINAPI ID3DXEffectPoolImpl_Release(ID3DXEffectPool* iface) +{ + ID3DXEffectPoolImpl *This = (ID3DXEffectPoolImpl *)iface; + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p)->(): Release from %u\n", This, ref + 1); + + if (!ref) + HeapFree(GetProcessHeap(), 0, This); + + return ref; +} + +static const struct ID3DXEffectPoolVtbl ID3DXEffectPool_Vtbl = +{ + /*** IUnknown methods ***/ + ID3DXEffectPoolImpl_QueryInterface, + ID3DXEffectPoolImpl_AddRef, + ID3DXEffectPoolImpl_Release +}; + +HRESULT WINAPI D3DXCreateEffectPool(LPD3DXEFFECTPOOL* pool) +{ + ID3DXEffectPoolImpl* object; + + TRACE("(%p)\n", pool); + + if (!pool) + return D3DERR_INVALIDCALL; + + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ID3DXEffectImpl)); + if (!object) + { + ERR("Out of memory\n"); + return E_OUTOFMEMORY; + } + + object->lpVtbl = &ID3DXEffectPool_Vtbl; + object->ref = 1; + + *pool = (LPD3DXEFFECTPOOL)object; + + return S_OK; +} diff --git a/dlls/d3dx9_36/tests/effect.c b/dlls/d3dx9_36/tests/effect.c index 40a2f181cc5..8b23536a2e3 100644 --- a/dlls/d3dx9_36/tests/effect.c +++ b/dlls/d3dx9_36/tests/effect.c @@ -47,6 +47,20 @@ static void test_create_effect(IDirect3DDevice9* device) effect->lpVtbl->Release(effect); } +static void test_create_effect_pool(void) +{ + HRESULT hr; + ID3DXEffectPool* pool; + + hr = D3DXCreateEffectPool(NULL); + ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3D_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL); + + hr = D3DXCreateEffectPool(&pool); + ok(hr == S_OK, "Got result %x, expected 0 (S_OK)\n", hr); + + pool->lpVtbl->Release(pool); +} + START_TEST(effect) { HWND wnd; @@ -79,6 +93,7 @@ START_TEST(effect) } test_create_effect(device); + test_create_effect_pool(); IDirect3DDevice9_Release(device); IDirect3D9_Release(d3d); diff --git a/include/d3dx9effect.h b/include/d3dx9effect.h index b372c259515..eb8a9a88e87 100644 --- a/include/d3dx9effect.h +++ b/include/d3dx9effect.h @@ -278,6 +278,8 @@ DECLARE_INTERFACE_(ID3DXEffect, ID3DXBaseEffect) extern "C" { #endif +HRESULT WINAPI D3DXCreateEffectPool(LPD3DXEFFECTPOOL* pool); + HRESULT WINAPI D3DXCreateEffect(LPDIRECT3DDEVICE9 device, LPCVOID srcdata, UINT srcdatalen,