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 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 UINT
make_pow2(UINT num
)
37 /* In the unlikely event somebody passes a large value, make sure we don't enter an infinite loop */
38 if (num
>= 0x80000000)
47 HRESULT WINAPI
D3DXFilterTexture(LPDIRECT3DBASETEXTURE9 texture
,
48 CONST PALETTEENTRY
*palette
,
52 UINT level
= srclevel
+ 1;
55 TRACE("(%p, %p, %d, %d)\n", texture
, palette
, srclevel
, filter
);
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
;
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
;
80 filter
= D3DX_FILTER_BOX
| D3DX_FILTER_DITHER
;
83 hr
= IDirect3DTexture9_GetSurfaceLevel((IDirect3DTexture9
*) texture
, srclevel
, &topsurf
);
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
);
99 IDirect3DSurface9_Release(topsurf
);
101 if (level
== srclevel
+ 1)
102 return D3DERR_INVALIDCALL
;
108 FIXME("Implement volume and cube texture filtering\n");
113 HRESULT WINAPI
D3DXCheckTextureRequirements(LPDIRECT3DDEVICE9 device
,
121 UINT w
= (width
&& *width
) ? *width
: 1;
122 UINT h
= (height
&& *height
) ? *height
: 1;
125 TRACE("(%p, %p, %p, %p, %u, %p, %u)\n", device
, width
, height
, miplevels
, usage
, format
, pool
);
128 return D3DERR_INVALIDCALL
;
131 if ((usage
!= D3DX_DEFAULT
) &&
132 (usage
& (D3DUSAGE_WRITEONLY
| D3DUSAGE_DONOTCLIP
| D3DUSAGE_POINTS
| D3DUSAGE_RTPATCHES
| D3DUSAGE_NPATCHES
)))
133 return D3DERR_INVALIDCALL
;
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
))
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
)))
155 if (w
> caps
.MaxTextureWidth
)
156 w
= caps
.MaxTextureWidth
;
158 if ((caps
.TextureCaps
& D3DPTEXTURECAPS_POW2
) && (!is_pow2(h
)))
161 if (h
> caps
.MaxTextureHeight
)
162 h
= caps
.MaxTextureHeight
;
164 /* texture must be square? */
165 if (caps
.TextureCaps
& D3DPTEXTURECAPS_SQUAREONLY
)
182 UINT max_mipmaps
= 1;
184 if (!width
&& !height
)
185 max_mipmaps
= 9; /* number of mipmaps in a 256x256 texture */
188 UINT max_dimen
= max(w
, h
);
190 while (max_dimen
> 1)
197 if (*miplevels
== 0 || *miplevels
> max_mipmaps
)
198 *miplevels
= max_mipmaps
;
204 D3DDEVICE_CREATION_PARAMETERS params
;
205 IDirect3D9
*d3d
= NULL
;
209 hr
= IDirect3DDevice9_GetDirect3D(device
, &d3d
);
214 hr
= IDirect3DDevice9_GetCreationParameters(device
, ¶ms
);
219 hr
= IDirect3DDevice9_GetDisplayMode(device
, 0, &mode
);
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
);
231 FIXME("Pixel format adjustment not implemented yet\n");
236 IDirect3D9_Release(d3d
);
239 return D3DERR_INVALIDCALL
;
245 HRESULT WINAPI
D3DXCreateTexture(LPDIRECT3DDEVICE9 pDevice
,
252 LPDIRECT3DTEXTURE9
*ppTexture
)
256 TRACE("(%p, %u, %u, %u, %x, %x, %x, %p)\n", pDevice
, width
, height
, miplevels
, usage
, format
,
259 if (!pDevice
|| !ppTexture
)
260 return D3DERR_INVALIDCALL
;
262 hr
= D3DXCheckTextureRequirements(pDevice
, &width
, &height
, &miplevels
, usage
, &format
, pool
);
267 return IDirect3DDevice9_CreateTexture(pDevice
, width
, height
, miplevels
, usage
, format
, pool
, ppTexture
, NULL
);
270 HRESULT WINAPI
D3DXCreateTextureFromFileInMemoryEx(LPDIRECT3DDEVICE9 device
,
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
);
292 HRESULT WINAPI
D3DXCreateTextureFromFileExW(LPDIRECT3DDEVICE9 device
,
303 D3DXIMAGE_INFO
*srcinfo
,
304 PALETTEENTRY
*palette
,
305 LPDIRECT3DTEXTURE9
*texture
)
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
);
315 return D3DERR_INVALIDCALL
;
317 hr
= map_view_of_file(srcfile
, &buffer
, &size
);
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
);
329 HRESULT WINAPI
D3DXCreateTextureFromFileA(LPDIRECT3DDEVICE9 device
,
331 LPDIRECT3DTEXTURE9
*texture
)
333 FIXME("(%p, %s, %p): stub\n", device
, debugstr_a(srcfile
), texture
);