Owen Rudge : d3dx9: Implement D3DXCheckTextureRequirements.

Alexandre Julliard julliard at winehq.org
Mon Jul 26 13:22:26 CDT 2010


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

Author: Owen Rudge <owen at owenrudge.net>
Date:   Thu Jul 22 20:38:04 2010 +0100

d3dx9: Implement D3DXCheckTextureRequirements.

---

 dlls/d3dx9_36/tests/texture.c |    4 -
 dlls/d3dx9_36/texture.c       |  146 ++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 144 insertions(+), 6 deletions(-)

diff --git a/dlls/d3dx9_36/tests/texture.c b/dlls/d3dx9_36/tests/texture.c
index de7ccf4..15b3e78 100644
--- a/dlls/d3dx9_36/tests/texture.c
+++ b/dlls/d3dx9_36/tests/texture.c
@@ -27,8 +27,6 @@ static void test_D3DXCheckTextureRequirements(IDirect3DDevice9 *device)
 {
     HRESULT hr;
 
-    todo_wine {
-
     /* 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);
@@ -38,8 +36,6 @@ static void test_D3DXCheckTextureRequirements(IDirect3DDevice9 *device)
 
     hr = D3DXCheckTextureRequirements(NULL, NULL, NULL, NULL, D3DX_DEFAULT, NULL, D3DPOOL_DEFAULT);
     ok(hr == D3DERR_INVALIDCALL, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
-
-    } /* todo_wine */
 }
 
 START_TEST(texture)
diff --git a/dlls/d3dx9_36/texture.c b/dlls/d3dx9_36/texture.c
index 9454615..ad3a1c2 100644
--- a/dlls/d3dx9_36/texture.c
+++ b/dlls/d3dx9_36/texture.c
@@ -1,5 +1,7 @@
 /*
+ * Copyright 2009 Tony Wasserka
  * Copyright 2010 Christian Costa
+ * Copyright 2010 Owen Rudge for CodeWeavers
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -21,6 +23,27 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
 
+/* Returns TRUE if num is a power of 2, FALSE if not, or if 0 */
+BOOL is_pow2(UINT num)
+{
+    return !(num & (num - 1));
+}
+
+/* Returns the smallest power of 2 which is greater than or equal to num */
+UINT make_pow2(UINT num)
+{
+    UINT result = 1;
+
+    /* In the unlikely event somebody passes a large value, make sure we don't enter an infinite loop */
+    if (num >= 0x80000000)
+        return 0x80000000;
+
+    while (result < num)
+        result <<= 1;
+
+    return result;
+}
+
 HRESULT WINAPI D3DXCheckTextureRequirements(LPDIRECT3DDEVICE9 device,
                                             UINT* width,
                                             UINT* height,
@@ -29,9 +52,128 @@ 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);
+    UINT w = (width && *width) ? *width : 1;
+    UINT h = (height && *height) ? *height : 1;
+    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 */
+    if (FAILED(IDirect3DDevice9_GetDeviceCaps(device, &caps)))
+        return D3DERR_INVALIDCALL;
+
+    /* 256 x 256 default width/height */
+    if ((w == D3DX_DEFAULT) && (h == D3DX_DEFAULT))
+        w = h = 256;
+    else if (w == D3DX_DEFAULT)
+        w = (height ? h : 256);
+    else if (h == D3DX_DEFAULT)
+        h = (width ? w : 256);
+
+    /* ensure width/height is power of 2 */
+    if ((caps.TextureCaps & D3DPTEXTURECAPS_POW2) && (!is_pow2(w)))
+        w = make_pow2(w);
+
+    if (w > caps.MaxTextureWidth)
+        w = caps.MaxTextureWidth;
+
+    if ((caps.TextureCaps & D3DPTEXTURECAPS_POW2) && (!is_pow2(h)))
+        h = make_pow2(h);
+
+    if (h > caps.MaxTextureHeight)
+        h = caps.MaxTextureHeight;
+
+    /* texture must be square? */
+    if (caps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY)
+    {
+        if (w > h)
+            h = w;
+        else
+            w = h;
+    }
+
+    if (width)
+        *width = w;
+
+    if (height)
+        *height = h;
+
+    /* miplevels */
+    if (miplevels)
+    {
+        UINT max_mipmaps = 1;
+
+        if (!width && !height)
+            max_mipmaps = 9;    /* number of mipmaps in a 256x256 texture */
+        else
+        {
+            UINT max_dimen = max(w, h);
+
+            while (max_dimen > 1)
+            {
+                max_dimen >>= 1;
+                max_mipmaps++;
+            }
+        }
+
+        if (*miplevels == 0 || *miplevels > max_mipmaps)
+            *miplevels = max_mipmaps;
+    }
+
+    /* format */
+    if (format)
+    {
+        D3DDEVICE_CREATION_PARAMETERS params;
+        IDirect3D9 *d3d = NULL;
+        D3DDISPLAYMODE mode;
+        HRESULT hr;
+
+        hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
+
+        if (FAILED(hr))
+            goto cleanup;
+
+        hr = IDirect3DDevice9_GetCreationParameters(device, &params);
+
+        if (FAILED(hr))
+            goto cleanup;
+
+        hr = IDirect3DDevice9_GetDisplayMode(device, 0, &mode);
+
+        if (FAILED(hr))
+            goto cleanup;
+
+        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");
+
+cleanup:
+
+        if (d3d)
+            IDirect3D9_Release(d3d);
+
+        if (FAILED(hr))
+            return D3DERR_INVALIDCALL;
+    }
+
+    return D3D_OK;
 }
 
 HRESULT WINAPI D3DXCreateTexture(LPDIRECT3DDEVICE9 pDevice,




More information about the wine-cvs mailing list