[PATCH] d3dx9_36: Implement D3DXCheckTextureRequirements + tests (try 2)

Christian Costa titan.costa at wanadoo.fr
Tue Apr 20 02:03:34 CDT 2010


From: Tony Wasserka <tony.wasserka at freenet.de>

--
Simplify is_pow2 and make_pow2 and move them to util.c for reuse.
Display a FIXME when pixel format adjustment is needed.
Remove refcount checks in tests as well as useless resource.h inclusion.
---

 dlls/d3dx9_36/d3dx9_36_private.h |    2 
 dlls/d3dx9_36/tests/Makefile.in  |    3 -
 dlls/d3dx9_36/tests/texture.c    |  188 ++++++++++++++++++++++++++++++++++++++
 dlls/d3dx9_36/texture.c          |   98 +++++++++++++++++++-
 dlls/d3dx9_36/util.c             |   19 ++++
 5 files changed, 307 insertions(+), 3 deletions(-)
 create mode 100644 dlls/d3dx9_36/tests/texture.c
-------------- next part --------------
diff --git a/dlls/d3dx9_36/d3dx9_36_private.h b/dlls/d3dx9_36/d3dx9_36_private.h
index 275b153..f44780b 100644
--- a/dlls/d3dx9_36/d3dx9_36_private.h
+++ b/dlls/d3dx9_36/d3dx9_36_private.h
@@ -51,6 +51,8 @@ HRESULT load_resource_into_memory(HMODULE module, HRSRC resinfo, LPVOID *buffer,
 
 const PixelFormatDesc *get_format_info(D3DFORMAT format);
 
+BOOL is_pow2(UINT num);
+UINT make_pow2(UINT num);
 
 extern const ID3DXBufferVtbl D3DXBuffer_Vtbl;
 
diff --git a/dlls/d3dx9_36/tests/Makefile.in b/dlls/d3dx9_36/tests/Makefile.in
index b9ad40d..fda718c 100644
--- a/dlls/d3dx9_36/tests/Makefile.in
+++ b/dlls/d3dx9_36/tests/Makefile.in
@@ -13,7 +13,8 @@ C_SRCS = \
 	math.c \
 	mesh.c \
 	shader.c \
-	surface.c
+	surface.c \
+	texture.c
 
 RC_SRCS = rsrc.rc
 
diff --git a/dlls/d3dx9_36/tests/texture.c b/dlls/d3dx9_36/tests/texture.c
new file mode 100644
index 0000000..9b10c51
--- /dev/null
+++ b/dlls/d3dx9_36/tests/texture.c
@@ -0,0 +1,188 @@
+/*
+ * Tests for the D3DX9 texture functions
+ *
+ * Copyright 2009 Tony Wasserka
+ *
+ * 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
+ */
+
+#define COBJMACROS
+#include "wine/test.h"
+#include "d3dx9tex.h"
+
+static void test_D3DXCheckTextureRequirements(IDirect3DDevice9 *device)
+{
+    HRESULT hr;
+    D3DCAPS9 caps;
+    UINT width, height, mipmaps;
+    D3DFORMAT format;
+
+    IDirect3DDevice9_GetDeviceCaps(device, &caps);
+
+    /* general tests */
+    hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
+    ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+
+    hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, D3DX_DEFAULT, NULL, D3DPOOL_DEFAULT);
+    ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+
+    hr = D3DXCheckTextureRequirements(NULL, NULL, NULL, NULL, D3DX_DEFAULT, NULL, D3DPOOL_DEFAULT);
+    ok(hr == D3DERR_INVALIDCALL, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+    /* width & height */
+    width = height = D3DX_DEFAULT;
+    hr = D3DXCheckTextureRequirements(device, &width, &height, NULL, 0, NULL, D3DPOOL_DEFAULT);
+    ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+    ok(width == 256, "Returned width %d, expected %d\n", width, 256);
+    ok(height == 256, "Returned height %d, expected %d\n", height, 256);
+
+    width = D3DX_DEFAULT;
+    hr = D3DXCheckTextureRequirements(device, &width, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
+    ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+    ok(width == 256, "Returned width %d, expected %d\n", width, 256);
+
+    width = 62;
+    hr = D3DXCheckTextureRequirements(device, &width, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
+    ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+    ok(width == 62, "Returned width %d, expected %d\n", width, 62);
+
+    width = D3DX_DEFAULT; height = 63;
+    hr = D3DXCheckTextureRequirements(device, &width, &height, NULL, 0, NULL, D3DPOOL_DEFAULT);
+    ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+    ok(width == height, "Returned width %d, expected %d\n", width, height);
+    ok(height == 63, "Returned height %d, expected %d\n", height, 63);
+
+    width = D3DX_DEFAULT; height = 0;
+    hr = D3DXCheckTextureRequirements(device, &width, &height, NULL, 0, NULL, D3DPOOL_DEFAULT);
+    ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+    ok(width == 1, "Returned width %d, expected %d\n", width, 1);
+    ok(height == 1, "Returned height %d, expected %d\n", height, 1);
+
+    width = 0; height = 0;
+    hr = D3DXCheckTextureRequirements(device, &width, &height, NULL, 0, NULL, D3DPOOL_DEFAULT);
+    ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+    ok(width == 1, "Returned width %d, expected %d\n", width, 1);
+    ok(height == 1, "Returned height %d, expected %d\n", height, 1);
+
+    width = 0;
+    hr = D3DXCheckTextureRequirements(device, &width, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
+    ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+    ok(width == 1, "Returned width %d, expected %d\n", width, 1);
+
+    width = D3DX_DEFAULT;
+    hr = D3DXCheckTextureRequirements(device, &width, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
+    ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+    ok(width == 256, "Returned width %d, expected %d\n", width, 256);
+
+    width = 0xFFFFFFFE;
+    hr = D3DXCheckTextureRequirements(device, &width, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
+    ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+    ok(width == caps.MaxTextureWidth, "Returned width %d, expected %d\n", width, caps.MaxTextureWidth);
+
+    width = caps.MaxTextureWidth-1;
+    hr = D3DXCheckTextureRequirements(device, &width, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
+    ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+    ok(width == caps.MaxTextureWidth-1, "Returned width %d, expected %d\n", width, caps.MaxTextureWidth-1);
+
+    /* mipmaps */
+    width = 64; height = 63;
+    mipmaps = 9;
+    hr = D3DXCheckTextureRequirements(device, &width, &height, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
+    ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+    ok(mipmaps == 7, "Returned mipmaps %d, expected %d\n", mipmaps, 7);
+
+    width = 284; height = 137;
+    mipmaps = 20;
+    hr = D3DXCheckTextureRequirements(device, &width, &height, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
+    ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+    ok(mipmaps == 9, "Returned mipmaps %d, expected %d\n", mipmaps, 9);
+
+    width = height = 63;
+    mipmaps = 9;
+    hr = D3DXCheckTextureRequirements(device, &width, &height, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
+    ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+    ok(mipmaps == 6, "Returned mipmaps %d, expected %d\n", mipmaps, 6);
+
+    mipmaps = 20;
+    hr = D3DXCheckTextureRequirements(device, NULL, NULL, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
+    ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+    ok(mipmaps == 9, "Returned mipmaps %d, expected %d\n", mipmaps, 9);
+
+    mipmaps = 0;
+    hr = D3DXCheckTextureRequirements(device, NULL, NULL, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
+    ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+    ok(mipmaps == 9, "Returned mipmaps %d, expected %d\n", mipmaps, 9);
+
+    /* usage */
+    hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, D3DUSAGE_WRITEONLY, NULL, D3DPOOL_DEFAULT);
+    ok(hr == D3DERR_INVALIDCALL, "D3DXCheckTextureRequirements succeeded, but should've failed.\n");
+    hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, D3DUSAGE_DONOTCLIP, NULL, D3DPOOL_DEFAULT);
+    ok(hr == D3DERR_INVALIDCALL, "D3DXCheckTextureRequirements succeeded, but should've failed.\n");
+    hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, D3DUSAGE_POINTS, NULL, D3DPOOL_DEFAULT);
+    ok(hr == D3DERR_INVALIDCALL, "D3DXCheckTextureRequirements succeeded, but should've failed.\n");
+    hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, D3DUSAGE_RTPATCHES, NULL, D3DPOOL_DEFAULT);
+    ok(hr == D3DERR_INVALIDCALL, "D3DXCheckTextureRequirements succeeded, but should've failed.\n");
+    hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, D3DUSAGE_NPATCHES, NULL, D3DPOOL_DEFAULT);
+    ok(hr == D3DERR_INVALIDCALL, "D3DXCheckTextureRequirements succeeded, but should've failed.\n");
+
+    /* format */
+    format = D3DFMT_UNKNOWN;
+    hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
+    ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+    ok(format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", format, D3DFMT_A8R8G8B8);
+
+    format = 0;
+    hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
+    ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+    ok(format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", format, D3DFMT_A8R8G8B8);
+}
+
+START_TEST(texture)
+{
+    HWND wnd;
+    IDirect3D9 *d3d;
+    IDirect3DDevice9 *device;
+    D3DPRESENT_PARAMETERS d3dpp;
+    HRESULT hr;
+
+    wnd = CreateWindow("static", "d3dx9_test", 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL);
+    if (!wnd) {
+        skip("Couldn't create application window\n");
+        return;
+    }
+    d3d = Direct3DCreate9(D3D_SDK_VERSION);
+    if (!d3d) {
+        skip("Couldn't create IDirect3D9 object\n");
+        DestroyWindow(wnd);
+        return;
+    }
+
+    ZeroMemory(&d3dpp, sizeof(d3dpp));
+    d3dpp.Windowed   = TRUE;
+    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
+    hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, wnd, D3DCREATE_MIXED_VERTEXPROCESSING, &d3dpp, &device);
+    if (FAILED(hr)) {
+        skip("Failed to create IDirect3DDevice9 object %#x\n", hr);
+        IDirect3D9_Release(d3d);
+        DestroyWindow(wnd);
+        return;
+    }
+
+    test_D3DXCheckTextureRequirements(device);
+
+    IDirect3DDevice9_Release(device);
+    IDirect3D9_Release(d3d);
+    DestroyWindow(wnd);
+}
diff --git a/dlls/d3dx9_36/texture.c b/dlls/d3dx9_36/texture.c
index 9454615..7d3bd91 100644
--- a/dlls/d3dx9_36/texture.c
+++ b/dlls/d3dx9_36/texture.c
@@ -29,9 +29,103 @@ HRESULT WINAPI D3DXCheckTextureRequirements(LPDIRECT3DDEVICE9 device,
                                             D3DFORMAT* format,
                                             D3DPOOL pool)
 {
-    FIXME("(%p, %p, %p, %p, %u, %p, %u): stub\n", device, width, height, miplevels, usage, format, pool);
+    D3DCAPS9 caps;
 
-    return E_NOTIMPL;
+    TRACE("(%p, %p, %p, %p, %u, %p, %u)\n", device, width, height, miplevels, usage, format, pool);
+
+    if (!device)
+        return D3DERR_INVALIDCALL;
+
+    /* usage */
+    if (usage != D3DX_DEFAULT &&
+        usage & (D3DUSAGE_WRITEONLY | D3DUSAGE_DONOTCLIP | D3DUSAGE_POINTS | D3DUSAGE_RTPATCHES | D3DUSAGE_NPATCHES))
+        return D3DERR_INVALIDCALL;
+
+    /* pool */
+    if (pool != D3DPOOL_DEFAULT && pool != D3DPOOL_MANAGED && pool != D3DPOOL_SYSTEMMEM && pool != D3DPOOL_SCRATCH)
+        return D3DERR_INVALIDCALL;
+
+    /* width and height */
+    IDirect3DDevice9_GetDeviceCaps(device, &caps);
+    if (width && height) {
+        if (*width == D3DX_DEFAULT && *height == D3DX_DEFAULT) *width = *height = 256;
+        else if (*width == D3DX_DEFAULT) *width = *height;
+        else if (*height == D3DX_DEFAULT) *height = *width;
+
+        if (*width == 0) *width = 1;
+        if (*height == 0) *height = 1;
+    } else if (width) {
+        if (*width == D3DX_DEFAULT) *width = 256;
+        else if (*width == 0) *width = 1;
+    } else if (height) {
+        if (*height == D3DX_DEFAULT) *height = 256;
+        else if (*height == 0) *height = 1;
+    }
+
+    if (width) {
+        if ((caps.TextureCaps & D3DPTEXTURECAPS_POW2) && !is_pow2(*width)) make_pow2(*width);
+        if (*width > caps.MaxTextureWidth) *width = caps.MaxTextureWidth;
+    }
+    if (height) {
+        if ((caps.TextureCaps & D3DPTEXTURECAPS_POW2) && !is_pow2(*height)) make_pow2(*height);
+        if (*height > caps.MaxTextureHeight) *height = caps.MaxTextureHeight;
+    }
+    if (width && height && (caps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY)) {
+        if (*width > *height) *height = *width;
+        else *width = *height;
+    }
+
+    /* miplevels */
+    if (miplevels) {
+        UINT max_mipmaps = 1;
+
+        if (!width && !height)
+            max_mipmaps = 9;
+        else {
+            UINT buf_width = width ? *width : 1;
+            UINT buf_height = height ? *height : 1;
+
+            while (buf_width > 1 || buf_height > 1) {
+                buf_width >>= 1;
+                buf_height >>= 1;
+                max_mipmaps++;
+            }
+        }
+        if (*miplevels == 0 || *miplevels > max_mipmaps)
+            *miplevels = max_mipmaps;
+    }
+
+    /* format */
+    if (format) {
+        IDirect3D9 *d3d = NULL;
+        D3DDEVICE_CREATION_PARAMETERS params;
+        D3DDISPLAYMODE mode;
+        HRESULT hr;
+
+        hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
+        if (SUCCEEDED(hr))
+            IDirect3DDevice9_GetCreationParameters(device, &params);
+        if (SUCCEEDED(hr))
+            IDirect3DDevice9_GetDisplayMode(device, 0, &mode);
+
+        if (SUCCEEDED(hr)) {
+            if (*format == D3DFMT_UNKNOWN || *format == D3DX_DEFAULT) *format = D3DFMT_A8R8G8B8;
+
+            hr = IDirect3D9_CheckDeviceFormat(d3d, params.AdapterOrdinal, params.DeviceType, mode.Format, usage,
+                D3DRTYPE_TEXTURE, *format);
+
+            if (FAILED(hr))
+                FIXME("Pixel format adjustment not implemented yet\n");
+        }
+
+        if (d3d)
+            IDirect3D9_Release(d3d);
+
+        if (FAILED(hr))
+            return D3DERR_INVALIDCALL;
+    }
+
+    return D3D_OK;
 }
 
 HRESULT WINAPI D3DXCreateTexture(LPDIRECT3DDEVICE9 pDevice,
diff --git a/dlls/d3dx9_36/util.c b/dlls/d3dx9_36/util.c
index 748e6d1..c7f6b7f 100644
--- a/dlls/d3dx9_36/util.c
+++ b/dlls/d3dx9_36/util.c
@@ -152,3 +152,22 @@ const PixelFormatDesc *get_format_info(D3DFORMAT format)
     while(formats[i].format != format && formats[i].format != D3DFMT_UNKNOWN) i++;
     return &formats[i];
 }
+
+/* Return TRUE if num is a power of 2, FALSE otherwise */
+BOOL is_pow2(UINT num)
+{
+    if (!num) return FALSE;
+
+    return !(num & (num - 1));
+}
+
+/* Returns the smallest power of 2 which is greater than or equal num */
+UINT make_pow2(UINT num)
+{
+    UINT result = 1;
+
+    while (result < num)
+        result <<= 1;
+       
+    return result;
+}


More information about the wine-patches mailing list