Module: wine Branch: master Commit: 190877422e644eb1eb7f43c2e817a7d163853175 URL: http://source.winehq.org/git/wine.git/?a=commit;h=190877422e644eb1eb7f43c2e8...
Author: Matteo Bruni mbruni@codeweavers.com Date: Fri Feb 14 15:53:10 2014 +0100
d3dx9: Enforce minimum texture dimensions for block-based pixel formats.
---
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)