d3dx9_36: Make {is,make}_pow2() static.
[wine/wine-gecko.git] / dlls / d3dx9_36 / texture.c
blob8895a8fb8eef5ba0254b554750b4f13b3cdaf54a
1 /*
2 * Copyright 2009 Tony Wasserka
3 * Copyright 2010 Christian Costa
4 * Copyright 2010 Owen Rudge for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "wine/debug.h"
22 #include "d3dx9_36_private.h"
24 WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
26 /* Returns TRUE if num is a power of 2, FALSE if not, or if 0 */
27 static BOOL is_pow2(UINT num)
29 return !(num & (num - 1));
32 /* Returns the smallest power of 2 which is greater than or equal to num */
33 static UINT make_pow2(UINT num)
35 UINT result = 1;
37 /* In the unlikely event somebody passes a large value, make sure we don't enter an infinite loop */
38 if (num >= 0x80000000)
39 return 0x80000000;
41 while (result < num)
42 result <<= 1;
44 return result;
47 HRESULT WINAPI D3DXFilterTexture(LPDIRECT3DBASETEXTURE9 texture,
48 CONST PALETTEENTRY *palette,
49 UINT srclevel,
50 DWORD filter)
52 UINT level = srclevel + 1;
53 HRESULT hr;
55 TRACE("(%p, %p, %d, %d)\n", texture, palette, srclevel, filter);
57 if (!texture)
58 return D3DERR_INVALIDCALL;
60 if ((filter & 0xFFFF) > D3DX_FILTER_BOX && filter != D3DX_DEFAULT)
61 return D3DERR_INVALIDCALL;
63 if (srclevel >= IDirect3DBaseTexture9_GetLevelCount(texture))
64 return D3DERR_INVALIDCALL;
66 switch (IDirect3DBaseTexture9_GetType(texture))
68 case D3DRTYPE_TEXTURE:
70 IDirect3DSurface9 *topsurf, *mipsurf;
71 D3DSURFACE_DESC desc;
73 if (filter == D3DX_DEFAULT)
75 IDirect3DTexture9_GetLevelDesc((IDirect3DTexture9*) texture, srclevel, &desc);
77 if (is_pow2(desc.Width) && is_pow2(desc.Height))
78 filter = D3DX_FILTER_BOX;
79 else
80 filter = D3DX_FILTER_BOX | D3DX_FILTER_DITHER;
83 hr = IDirect3DTexture9_GetSurfaceLevel((IDirect3DTexture9*) texture, srclevel, &topsurf);
85 if (FAILED(hr))
86 return D3DERR_INVALIDCALL;
88 while (IDirect3DTexture9_GetSurfaceLevel((IDirect3DTexture9*) texture, level, &mipsurf) == D3D_OK)
90 hr = D3DXLoadSurfaceFromSurface(mipsurf, palette, NULL, topsurf, palette, NULL, filter, 0);
91 IDirect3DSurface9_Release(mipsurf);
93 if (FAILED(hr))
94 break;
96 level++;
99 IDirect3DSurface9_Release(topsurf);
101 if (level == srclevel + 1)
102 return D3DERR_INVALIDCALL;
104 return D3D_OK;
107 default:
108 FIXME("Implement volume and cube texture filtering\n");
109 return E_NOTIMPL;
113 HRESULT WINAPI D3DXCheckTextureRequirements(LPDIRECT3DDEVICE9 device,
114 UINT* width,
115 UINT* height,
116 UINT* miplevels,
117 DWORD usage,
118 D3DFORMAT* format,
119 D3DPOOL pool)
121 UINT w = (width && *width) ? *width : 1;
122 UINT h = (height && *height) ? *height : 1;
123 D3DCAPS9 caps;
125 TRACE("(%p, %p, %p, %p, %u, %p, %u)\n", device, width, height, miplevels, usage, format, pool);
127 if (!device)
128 return D3DERR_INVALIDCALL;
130 /* usage */
131 if ((usage != D3DX_DEFAULT) &&
132 (usage & (D3DUSAGE_WRITEONLY | D3DUSAGE_DONOTCLIP | D3DUSAGE_POINTS | D3DUSAGE_RTPATCHES | D3DUSAGE_NPATCHES)))
133 return D3DERR_INVALIDCALL;
135 /* pool */
136 if ((pool != D3DPOOL_DEFAULT) && (pool != D3DPOOL_MANAGED) && (pool != D3DPOOL_SYSTEMMEM) && (pool != D3DPOOL_SCRATCH))
137 return D3DERR_INVALIDCALL;
139 /* width and height */
140 if (FAILED(IDirect3DDevice9_GetDeviceCaps(device, &caps)))
141 return D3DERR_INVALIDCALL;
143 /* 256 x 256 default width/height */
144 if ((w == D3DX_DEFAULT) && (h == D3DX_DEFAULT))
145 w = h = 256;
146 else if (w == D3DX_DEFAULT)
147 w = (height ? h : 256);
148 else if (h == D3DX_DEFAULT)
149 h = (width ? w : 256);
151 /* ensure width/height is power of 2 */
152 if ((caps.TextureCaps & D3DPTEXTURECAPS_POW2) && (!is_pow2(w)))
153 w = make_pow2(w);
155 if (w > caps.MaxTextureWidth)
156 w = caps.MaxTextureWidth;
158 if ((caps.TextureCaps & D3DPTEXTURECAPS_POW2) && (!is_pow2(h)))
159 h = make_pow2(h);
161 if (h > caps.MaxTextureHeight)
162 h = caps.MaxTextureHeight;
164 /* texture must be square? */
165 if (caps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY)
167 if (w > h)
168 h = w;
169 else
170 w = h;
173 if (width)
174 *width = w;
176 if (height)
177 *height = h;
179 /* miplevels */
180 if (miplevels)
182 UINT max_mipmaps = 1;
184 if (!width && !height)
185 max_mipmaps = 9; /* number of mipmaps in a 256x256 texture */
186 else
188 UINT max_dimen = max(w, h);
190 while (max_dimen > 1)
192 max_dimen >>= 1;
193 max_mipmaps++;
197 if (*miplevels == 0 || *miplevels > max_mipmaps)
198 *miplevels = max_mipmaps;
201 /* format */
202 if (format)
204 D3DDEVICE_CREATION_PARAMETERS params;
205 IDirect3D9 *d3d = NULL;
206 D3DDISPLAYMODE mode;
207 HRESULT hr;
209 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
211 if (FAILED(hr))
212 goto cleanup;
214 hr = IDirect3DDevice9_GetCreationParameters(device, &params);
216 if (FAILED(hr))
217 goto cleanup;
219 hr = IDirect3DDevice9_GetDisplayMode(device, 0, &mode);
221 if (FAILED(hr))
222 goto cleanup;
224 if ((*format == D3DFMT_UNKNOWN) || (*format == D3DX_DEFAULT))
225 *format = D3DFMT_A8R8G8B8;
227 hr = IDirect3D9_CheckDeviceFormat(d3d, params.AdapterOrdinal, params.DeviceType, mode.Format, usage,
228 D3DRTYPE_TEXTURE, *format);
230 if (FAILED(hr))
231 FIXME("Pixel format adjustment not implemented yet\n");
233 cleanup:
235 if (d3d)
236 IDirect3D9_Release(d3d);
238 if (FAILED(hr))
239 return D3DERR_INVALIDCALL;
242 return D3D_OK;
245 HRESULT WINAPI D3DXCreateTexture(LPDIRECT3DDEVICE9 pDevice,
246 UINT width,
247 UINT height,
248 UINT miplevels,
249 DWORD usage,
250 D3DFORMAT format,
251 D3DPOOL pool,
252 LPDIRECT3DTEXTURE9 *ppTexture)
254 HRESULT hr;
256 TRACE("(%p, %u, %u, %u, %x, %x, %x, %p)\n", pDevice, width, height, miplevels, usage, format,
257 pool, ppTexture);
259 if (!pDevice || !ppTexture)
260 return D3DERR_INVALIDCALL;
262 hr = D3DXCheckTextureRequirements(pDevice, &width, &height, &miplevels, usage, &format, pool);
264 if (FAILED(hr))
265 return hr;
267 return IDirect3DDevice9_CreateTexture(pDevice, width, height, miplevels, usage, format, pool, ppTexture, NULL);
270 HRESULT WINAPI D3DXCreateTextureFromFileInMemoryEx(LPDIRECT3DDEVICE9 device,
271 LPCVOID srcdata,
272 UINT srcdatasize,
273 UINT width,
274 UINT height,
275 UINT miplevels,
276 DWORD usage,
277 D3DFORMAT format,
278 D3DPOOL pool,
279 DWORD filter,
280 DWORD mipfilter,
281 D3DCOLOR colorkey,
282 D3DXIMAGE_INFO* srcinfo,
283 PALETTEENTRY* palette,
284 LPDIRECT3DTEXTURE9* texture)
286 FIXME("(%p, %p, %u, %u, %u, %u, %x, %x, %x, %u, %u, %x, %p, %p, %p): stub\n", device, srcdata, srcdatasize, width,
287 height, miplevels, usage, format, pool, filter, mipfilter, colorkey, srcinfo, palette, texture);
289 return E_NOTIMPL;
292 HRESULT WINAPI D3DXCreateTextureFromFileExW(LPDIRECT3DDEVICE9 device,
293 LPCWSTR srcfile,
294 UINT width,
295 UINT height,
296 UINT miplevels,
297 DWORD usage,
298 D3DFORMAT format,
299 D3DPOOL pool,
300 DWORD filter,
301 DWORD mipfilter,
302 D3DCOLOR colorkey,
303 D3DXIMAGE_INFO *srcinfo,
304 PALETTEENTRY *palette,
305 LPDIRECT3DTEXTURE9 *texture)
307 HRESULT hr;
308 DWORD size;
309 LPVOID buffer;
311 TRACE("(%p, %p, %u, %u, %u, %x, %x, %x, %u, %u, %x, %p, %p, %p): relay\n", device, debugstr_w(srcfile), width,
312 height, miplevels, usage, format, pool, filter, mipfilter, colorkey, srcinfo, palette, texture);
314 if (!srcfile)
315 return D3DERR_INVALIDCALL;
317 hr = map_view_of_file(srcfile, &buffer, &size);
318 if (FAILED(hr))
319 return D3DXERR_INVALIDDATA;
321 hr = D3DXCreateTextureFromFileInMemoryEx(device, buffer, size, width, height, miplevels, usage, format, pool,
322 filter, mipfilter, colorkey, srcinfo, palette, texture);
324 UnmapViewOfFile(buffer);
326 return hr;
329 HRESULT WINAPI D3DXCreateTextureFromFileA(LPDIRECT3DDEVICE9 device,
330 LPCSTR srcfile,
331 LPDIRECT3DTEXTURE9 *texture)
333 FIXME("(%p, %s, %p): stub\n", device, debugstr_a(srcfile), texture);
335 return E_NOTIMPL;