From: Owen Rudge Subject: [4/4] d3dx9: Add basic implementation of D3DXFilterTexture, plus tests Message-Id: <4C4C872C.4020104@owenrudge.net> Date: Sun, 25 Jul 2010 19:49:16 +0100 --- dlls/d3dx9_36/d3dx9_36.spec | 2 +- dlls/d3dx9_36/tests/texture.c | 55 ++++++++++++++++++++++++++++++++++ dlls/d3dx9_36/texture.c | 66 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 122 insertions(+), 1 deletions(-) diff --git a/dlls/d3dx9_36/d3dx9_36.spec b/dlls/d3dx9_36/d3dx9_36.spec index b9a00da..622a03c 100644 --- a/dlls/d3dx9_36/d3dx9_36.spec +++ b/dlls/d3dx9_36/d3dx9_36.spec @@ -128,7 +128,7 @@ @ stub D3DXFillTextureTX @ stub D3DXFillVolumeTexture @ stub D3DXFillVolumeTextureTX -@ stub D3DXFilterTexture +@ stdcall D3DXFilterTexture(ptr ptr long long) @ stdcall D3DXFindShaderComment(ptr long ptr ptr) @ stub D3DXFloat16To32Array @ stub D3DXFloat32To16Array diff --git a/dlls/d3dx9_36/tests/texture.c b/dlls/d3dx9_36/tests/texture.c index ff4aa15..6a26237 100644 --- a/dlls/d3dx9_36/tests/texture.c +++ b/dlls/d3dx9_36/tests/texture.c @@ -315,6 +315,60 @@ static void test_D3DXCreateTexture(IDirect3DDevice9 *device) } } +static void test_D3DXFilterTexture(IDirect3DDevice9 *device) +{ + IDirect3DTexture9 *tex; + HRESULT hr; + + hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 5, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex, NULL); + + if (SUCCEEDED(hr)) + { + hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 0, D3DX_FILTER_NONE); + ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK); + + hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 0, D3DX_FILTER_BOX + 1); /* Invalid filter */ + ok(hr == D3DERR_INVALIDCALL, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL); + + hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 5, D3DX_FILTER_NONE); /* Last miplevel */ + ok(hr == D3DERR_INVALIDCALL, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL); + + hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 20, D3DX_FILTER_NONE); /* Invalid miplevel */ + ok(hr == D3DERR_INVALIDCALL, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL); + } + else + skip("Failed to create texture\n"); + + IDirect3DTexture9_Release(tex); + + hr = D3DXFilterTexture(NULL, NULL, 0, D3DX_FILTER_NONE); + ok(hr == D3DERR_INVALIDCALL, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL); + + /* Test different pools */ + hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &tex, NULL); + + if (SUCCEEDED(hr)) + { + hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 0, D3DX_FILTER_NONE); + ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK); + IDirect3DTexture9_Release(tex); + } + else + skip("Failed to create texture\n"); + + + hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &tex, NULL); + + if (SUCCEEDED(hr)) + { + hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 0, D3DX_FILTER_NONE); + ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK); + IDirect3DTexture9_Release(tex); + } + else + skip("Failed to create texture\n"); +} + START_TEST(texture) { HWND wnd; @@ -348,6 +402,7 @@ START_TEST(texture) test_D3DXCheckTextureRequirements(device); test_D3DXCreateTexture(device); + test_D3DXFilterTexture(device); IDirect3DDevice9_Release(device); IDirect3D9_Release(d3d); diff --git a/dlls/d3dx9_36/texture.c b/dlls/d3dx9_36/texture.c index 9d547ce..8992399 100644 --- a/dlls/d3dx9_36/texture.c +++ b/dlls/d3dx9_36/texture.c @@ -44,6 +44,72 @@ UINT make_pow2(UINT num) return result; } +HRESULT WINAPI D3DXFilterTexture(LPDIRECT3DBASETEXTURE9 texture, + CONST PALETTEENTRY *palette, + UINT srclevel, + DWORD filter) +{ + UINT level = srclevel + 1; + HRESULT hr; + + TRACE("(%p, %p, %d, %d)\n", texture, palette, srclevel, filter); + + if (!texture) + return D3DERR_INVALIDCALL; + + if ((filter & 0xFFFF) > D3DX_FILTER_BOX && filter != D3DX_DEFAULT) + return D3DERR_INVALIDCALL; + + if (srclevel >= IDirect3DBaseTexture9_GetLevelCount(texture)) + return D3DERR_INVALIDCALL; + + switch (IDirect3DBaseTexture9_GetType(texture)) + { + case D3DRTYPE_TEXTURE: + { + IDirect3DSurface9 *topsurf, *mipsurf; + D3DSURFACE_DESC desc; + + if (filter == D3DX_DEFAULT) + { + IDirect3DTexture9_GetLevelDesc((IDirect3DTexture9*) texture, srclevel, &desc); + + if (is_pow2(desc.Width) && is_pow2(desc.Height)) + filter = D3DX_FILTER_BOX; + else + filter = D3DX_FILTER_BOX | D3DX_FILTER_DITHER; + } + + hr = IDirect3DTexture9_GetSurfaceLevel((IDirect3DTexture9*) texture, srclevel, &topsurf); + + if (FAILED(hr)) + return D3DERR_INVALIDCALL; + + while (IDirect3DTexture9_GetSurfaceLevel((IDirect3DTexture9*) texture, level, &mipsurf) == D3D_OK) + { + hr = D3DXLoadSurfaceFromSurface(mipsurf, palette, NULL, topsurf, palette, NULL, filter, 0); + IDirect3DSurface9_Release(mipsurf); + + if (FAILED(hr)) + break; + + level++; + } + + IDirect3DSurface9_Release(topsurf); + + if (level == srclevel + 1) + return D3DERR_INVALIDCALL; + + return D3D_OK; + } + + default: + FIXME("Implement volume and cube texture filtering\n"); + return E_NOTIMPL; + } +} + HRESULT WINAPI D3DXCheckTextureRequirements(LPDIRECT3DDEVICE9 device, UINT* width, UINT* height,