[PATCH 2/5] d3dx9: Enforce minimum texture dimensions for block-based pixel formats.

Matteo Bruni mbruni at codeweavers.com
Fri Feb 14 08:53:10 CST 2014


---
 dlls/d3dx9_36/tests/texture.c |  11 ++++
 dlls/d3dx9_36/texture.c       | 149 ++++++++++++++++++++++--------------------
 2 files changed, 89 insertions(+), 71 deletions(-)

diff --git a/dlls/d3dx9_36/tests/texture.c b/dlls/d3dx9_36/tests/texture.c
index afc7144..4a93ac6 100644
--- a/dlls/d3dx9_36/tests/texture.c
+++ b/dlls/d3dx9_36/tests/texture.c
@@ -340,6 +340,17 @@ static void test_D3DXCheckTextureRequirements(IDirect3DDevice9 *device)
     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
     ok(format == expected, "Returned format %u, expected %u\n", format, expected);
 
+    /* Block-based texture formats and size < block size. */
+    format = D3DFMT_DXT1;
+    width = 2; height = 2;
+    mipmaps = 1;
+    hr = D3DXCheckTextureRequirements(device, &width, &height, &mipmaps, 0, &format, D3DPOOL_DEFAULT);
+    ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+    ok(width == 4, "Returned width %d, expected %d\n", width, 4);
+    ok(height == 4, "Returned height %d, expected %d\n", height, 4);
+    ok(mipmaps == 1, "Returned mipmaps %d, expected %d\n", mipmaps, 1);
+    ok(format == D3DFMT_DXT1, "Returned format %u, expected %u\n", format, D3DFMT_DXT1);
+
     IDirect3D9_Release(d3d);
 }
 
diff --git a/dlls/d3dx9_36/texture.c b/dlls/d3dx9_36/texture.c
index f96536a..be86347 100644
--- a/dlls/d3dx9_36/texture.c
+++ b/dlls/d3dx9_36/texture.c
@@ -195,6 +195,7 @@ HRESULT WINAPI D3DXCheckTextureRequirements(struct IDirect3DDevice9 *device, UIN
     D3DDISPLAYMODE mode;
     HRESULT hr;
     D3DFORMAT usedformat = D3DFMT_UNKNOWN;
+    const struct pixel_format_desc *fmt;
 
     TRACE("(%p, %p, %p, %p, %u, %p, %u)\n", device, width, height, miplevels, usage, format, pool);
 
@@ -211,73 +212,6 @@ HRESULT WINAPI D3DXCheckTextureRequirements(struct IDirect3DDevice9 *device, UIN
     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 && (usage & D3DUSAGE_AUTOGENMIPMAP))
-    {
-        if (*miplevels > 1)
-            *miplevels = 0;
-    }
-    else 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)
     {
@@ -303,17 +237,18 @@ HRESULT WINAPI D3DXCheckTextureRequirements(struct IDirect3DDevice9 *device, UIN
     if ((usedformat == D3DFMT_UNKNOWN) || (usedformat == D3DX_DEFAULT))
         usedformat = D3DFMT_A8R8G8B8;
 
+    fmt = get_format_info(usedformat);
+
     hr = IDirect3D9_CheckDeviceFormat(d3d, params.AdapterOrdinal, params.DeviceType, mode.Format,
         usage, D3DRTYPE_TEXTURE, usedformat);
-
     if (FAILED(hr))
     {
-        /* Heuristic to choose the fallback format */
-        const struct pixel_format_desc *fmt = get_format_info(usedformat);
         BOOL allow_24bits;
         int bestscore = INT_MIN, i = 0, j;
         unsigned int channels;
-        const struct pixel_format_desc *curfmt;
+        const struct pixel_format_desc *curfmt, *bestfmt = NULL;
+
+        TRACE("Requested format not supported, looking for a fallback.\n");
 
         if (!fmt)
         {
@@ -358,11 +293,83 @@ HRESULT WINAPI D3DXCheckTextureRequirements(struct IDirect3DDevice9 *device, UIN
             {
                 bestscore = score;
                 usedformat = curfmt->format;
+                bestfmt = curfmt;
             }
         }
+        fmt = bestfmt;
         hr = D3D_OK;
     }
 
+    if (FAILED(IDirect3DDevice9_GetDeviceCaps(device, &caps)))
+        return D3DERR_INVALIDCALL;
+
+    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);
+
+    if (fmt->block_width != 1 || fmt->block_height != 1)
+    {
+        if (w < fmt->block_width)
+            w = fmt->block_width;
+        if (h < fmt->block_height)
+            h = fmt->block_height;
+    }
+
+    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;
+
+    if (caps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY)
+    {
+        if (w > h)
+            h = w;
+        else
+            w = h;
+    }
+
+    if (width)
+        *width = w;
+
+    if (height)
+        *height = h;
+
+    if (miplevels && (usage & D3DUSAGE_AUTOGENMIPMAP))
+    {
+        if (*miplevels > 1)
+            *miplevels = 0;
+    }
+    else 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;
+    }
+
 cleanup:
 
     if (d3d)
-- 
1.8.3.2




More information about the wine-patches mailing list