2 * Copyright 2009 Tony Wasserka
3 * Copyright 2010 Christian Costa
4 * Copyright 2010 Owen Rudge for CodeWeavers
5 * Copyright 2010 Matteo Bruni for CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "wine/unicode.h"
23 #include "wine/debug.h"
24 #include "d3dx9_36_private.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
28 /* Returns TRUE if num is a power of 2, FALSE if not, or if 0 */
29 static BOOL is_pow2(UINT num)
31 return !(num & (num - 1));
34 /* Returns the smallest power of 2 which is greater than or equal to num */
35 static UINT make_pow2(UINT num)
39 /* In the unlikely event somebody passes a large value, make sure we don't enter an infinite loop */
40 if (num >= 0x80000000)
49 static HRESULT get_surface(D3DRESOURCETYPE type, LPDIRECT3DBASETEXTURE9 tex,
50 int face, UINT level, LPDIRECT3DSURFACE9 *surf)
54 case D3DRTYPE_TEXTURE:
55 return IDirect3DTexture9_GetSurfaceLevel((IDirect3DTexture9*) tex, level, surf);
56 case D3DRTYPE_CUBETEXTURE:
57 return IDirect3DCubeTexture9_GetCubeMapSurface((IDirect3DCubeTexture9*) tex, face, level, surf);
59 ERR("Unexpected texture type\n");
64 HRESULT WINAPI D3DXFilterTexture(IDirect3DBaseTexture9 *texture,
65 const PALETTEENTRY *palette,
73 TRACE("(%p, %p, %u, %#x)\n", texture, palette, srclevel, filter);
76 return D3DERR_INVALIDCALL;
78 if ((filter & 0xFFFF) > D3DX_FILTER_BOX && filter != D3DX_DEFAULT)
79 return D3DERR_INVALIDCALL;
81 if (srclevel == D3DX_DEFAULT)
83 else if (srclevel >= IDirect3DBaseTexture9_GetLevelCount(texture))
84 return D3DERR_INVALIDCALL;
86 switch (type = IDirect3DBaseTexture9_GetType(texture))
88 case D3DRTYPE_TEXTURE:
89 case D3DRTYPE_CUBETEXTURE:
91 IDirect3DSurface9 *topsurf, *mipsurf;
95 if (type == D3DRTYPE_TEXTURE)
98 IDirect3DTexture9_GetLevelDesc((IDirect3DTexture9*) texture, srclevel, &desc);
103 IDirect3DCubeTexture9_GetLevelDesc((IDirect3DTexture9*) texture, srclevel, &desc);
106 if (filter == D3DX_DEFAULT)
108 if (is_pow2(desc.Width) && is_pow2(desc.Height))
109 filter = D3DX_FILTER_BOX;
111 filter = D3DX_FILTER_BOX | D3DX_FILTER_DITHER;
114 for (i = 0; i < numfaces; i++)
116 level = srclevel + 1;
117 hr = get_surface(type, texture, i, srclevel, &topsurf);
120 return D3DERR_INVALIDCALL;
122 while (get_surface(type, texture, i, level, &mipsurf) == D3D_OK)
124 hr = D3DXLoadSurfaceFromSurface(mipsurf, palette, NULL, topsurf, palette, NULL, filter, 0);
125 IDirect3DSurface9_Release(topsurf);
134 IDirect3DSurface9_Release(topsurf);
142 case D3DRTYPE_VOLUMETEXTURE:
145 int level, level_count;
146 IDirect3DVolume9 *top_volume, *mip_volume;
147 IDirect3DVolumeTexture9 *volume_texture = (IDirect3DVolumeTexture9*) texture;
149 IDirect3DVolumeTexture9_GetLevelDesc(volume_texture, srclevel, &desc);
151 if (filter == D3DX_DEFAULT)
153 if (is_pow2(desc.Width) && is_pow2(desc.Height) && is_pow2(desc.Depth))
154 filter = D3DX_FILTER_BOX;
156 filter = D3DX_FILTER_BOX | D3DX_FILTER_DITHER;
159 hr = IDirect3DVolumeTexture9_GetVolumeLevel(volume_texture, srclevel, &top_volume);
163 level_count = IDirect3DVolumeTexture9_GetLevelCount(volume_texture);
164 for (level = srclevel + 1; level < level_count; level++)
166 IDirect3DVolumeTexture9_GetVolumeLevel(volume_texture, level, &mip_volume);
167 hr = D3DXLoadVolumeFromVolume(mip_volume, palette, NULL, top_volume, palette, NULL, filter, 0);
168 IDirect3DVolume9_Release(top_volume);
169 top_volume = mip_volume;
175 IDirect3DVolume9_Release(top_volume);
183 return D3DERR_INVALIDCALL;
187 HRESULT WINAPI D3DXCheckTextureRequirements(LPDIRECT3DDEVICE9 device,
195 UINT w = (width && *width) ? *width : 1;
196 UINT h = (height && *height) ? *height : 1;
198 D3DDEVICE_CREATION_PARAMETERS params;
199 IDirect3D9 *d3d = NULL;
202 D3DFORMAT usedformat = D3DFMT_UNKNOWN;
204 TRACE("(%p, %p, %p, %p, %u, %p, %u)\n", device, width, height, miplevels, usage, format, pool);
207 return D3DERR_INVALIDCALL;
210 if (usage == D3DX_DEFAULT)
212 if (usage & (D3DUSAGE_WRITEONLY | D3DUSAGE_DONOTCLIP | D3DUSAGE_POINTS | D3DUSAGE_RTPATCHES | D3DUSAGE_NPATCHES))
213 return D3DERR_INVALIDCALL;
216 if ((pool != D3DPOOL_DEFAULT) && (pool != D3DPOOL_MANAGED) && (pool != D3DPOOL_SYSTEMMEM) && (pool != D3DPOOL_SCRATCH))
217 return D3DERR_INVALIDCALL;
219 /* width and height */
220 if (FAILED(IDirect3DDevice9_GetDeviceCaps(device, &caps)))
221 return D3DERR_INVALIDCALL;
223 /* 256 x 256 default width/height */
224 if ((w == D3DX_DEFAULT) && (h == D3DX_DEFAULT))
226 else if (w == D3DX_DEFAULT)
227 w = (height ? h : 256);
228 else if (h == D3DX_DEFAULT)
229 h = (width ? w : 256);
231 /* ensure width/height is power of 2 */
232 if ((caps.TextureCaps & D3DPTEXTURECAPS_POW2) && (!is_pow2(w)))
235 if (w > caps.MaxTextureWidth)
236 w = caps.MaxTextureWidth;
238 if ((caps.TextureCaps & D3DPTEXTURECAPS_POW2) && (!is_pow2(h)))
241 if (h > caps.MaxTextureHeight)
242 h = caps.MaxTextureHeight;
244 /* texture must be square? */
245 if (caps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY)
260 if (miplevels && (usage & D3DUSAGE_AUTOGENMIPMAP))
267 UINT max_mipmaps = 1;
269 if (!width && !height)
270 max_mipmaps = 9; /* number of mipmaps in a 256x256 texture */
273 UINT max_dimen = max(w, h);
275 while (max_dimen > 1)
282 if (*miplevels == 0 || *miplevels > max_mipmaps)
283 *miplevels = max_mipmaps;
289 TRACE("Requested format %x\n", *format);
290 usedformat = *format;
293 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
298 hr = IDirect3DDevice9_GetCreationParameters(device, ¶ms);
303 hr = IDirect3DDevice9_GetDisplayMode(device, 0, &mode);
308 if ((usedformat == D3DFMT_UNKNOWN) || (usedformat == D3DX_DEFAULT))
309 usedformat = D3DFMT_A8R8G8B8;
311 hr = IDirect3D9_CheckDeviceFormat(d3d, params.AdapterOrdinal, params.DeviceType, mode.Format,
312 usage, D3DRTYPE_TEXTURE, usedformat);
316 /* Heuristic to choose the fallback format */
317 const struct pixel_format_desc *fmt = get_format_info(usedformat);
319 int bestscore = INT_MIN, i = 0, j;
320 unsigned int channels;
321 const struct pixel_format_desc *curfmt;
325 FIXME("Pixel format %x not handled\n", usedformat);
329 allow_24bits = fmt->bytes_per_pixel == 3;
330 channels = (fmt->bits[0] ? 1 : 0) + (fmt->bits[1] ? 1 : 0)
331 + (fmt->bits[2] ? 1 : 0) + (fmt->bits[3] ? 1 : 0);
332 usedformat = D3DFMT_UNKNOWN;
334 while ((curfmt = get_format_info_idx(i)))
336 unsigned int curchannels = (curfmt->bits[0] ? 1 : 0) + (curfmt->bits[1] ? 1 : 0)
337 + (curfmt->bits[2] ? 1 : 0) + (curfmt->bits[3] ? 1 : 0);
342 if (curchannels < channels)
344 if (curfmt->bytes_per_pixel == 3 && !allow_24bits)
347 hr = IDirect3D9_CheckDeviceFormat(d3d, params.AdapterOrdinal, params.DeviceType,
348 mode.Format, usage, D3DRTYPE_TEXTURE, curfmt->format);
352 /* This format can be used, let's evaluate it.
353 Weights chosen quite arbitrarily... */
354 score = 16 - 4 * (curchannels - channels);
356 for (j = 0; j < 4; j++)
358 int diff = curfmt->bits[j] - fmt->bits[j];
359 score += 16 - (diff < 0 ? -diff * 4 : diff);
362 if (score > bestscore)
365 usedformat = curfmt->format;
374 IDirect3D9_Release(d3d);
379 if (usedformat == D3DFMT_UNKNOWN)
381 WARN("Couldn't find a suitable pixel format\n");
382 return D3DERR_NOTAVAILABLE;
385 TRACE("Format chosen: %x\n", usedformat);
387 *format = usedformat;
392 HRESULT WINAPI D3DXCheckCubeTextureRequirements(LPDIRECT3DDEVICE9 device,
400 UINT s = (size && *size) ? *size : 256;
403 TRACE("(%p, %p, %p, %u, %p, %u)\n", device, size, miplevels, usage, format, pool);
405 if (s == D3DX_DEFAULT)
408 if (!device || FAILED(IDirect3DDevice9_GetDeviceCaps(device, &caps)))
409 return D3DERR_INVALIDCALL;
411 if (!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP))
412 return D3DERR_NOTAVAILABLE;
414 /* ensure width/height is power of 2 */
415 if ((caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2) && (!is_pow2(s)))
418 hr = D3DXCheckTextureRequirements(device, &s, &s, miplevels, usage, format, pool);
420 if (!(caps.TextureCaps & D3DPTEXTURECAPS_MIPCUBEMAP))
432 HRESULT WINAPI D3DXCheckVolumeTextureRequirements(LPDIRECT3DDEVICE9 device,
442 UINT w = width ? *width : D3DX_DEFAULT;
443 UINT h = height ? *height : D3DX_DEFAULT;
444 UINT d = (depth && *depth) ? *depth : 1;
447 TRACE("(%p, %p, %p, %p, %p, %u, %p, %u)\n", device, width, height, depth, miplevels,
448 usage, format, pool);
450 if (!device || FAILED(IDirect3DDevice9_GetDeviceCaps(device, &caps)))
451 return D3DERR_INVALIDCALL;
453 if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
454 return D3DERR_NOTAVAILABLE;
456 hr = D3DXCheckTextureRequirements(device, &w, &h, NULL, usage, format, pool);
457 if (d == D3DX_DEFAULT)
460 /* ensure width/height is power of 2 */
461 if ((caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP_POW2) &&
462 (!is_pow2(w) || !is_pow2(h) || !is_pow2(d)))
469 if (w > caps.MaxVolumeExtent)
470 w = caps.MaxVolumeExtent;
471 if (h > caps.MaxVolumeExtent)
472 h = caps.MaxVolumeExtent;
473 if (d > caps.MaxVolumeExtent)
474 d = caps.MaxVolumeExtent;
478 if (!(caps.TextureCaps & D3DPTEXTURECAPS_MIPVOLUMEMAP))
480 else if ((usage & D3DUSAGE_AUTOGENMIPMAP))
487 UINT max_mipmaps = 1;
488 UINT max_dimen = max(max(w, h), d);
490 while (max_dimen > 1)
496 if (*miplevels == 0 || *miplevels > max_mipmaps)
497 *miplevels = max_mipmaps;
511 HRESULT WINAPI D3DXCreateTexture(LPDIRECT3DDEVICE9 pDevice,
518 LPDIRECT3DTEXTURE9 *ppTexture)
522 TRACE("(%p, %u, %u, %u, %x, %x, %x, %p)\n", pDevice, width, height, miplevels, usage, format,
525 if (!pDevice || !ppTexture)
526 return D3DERR_INVALIDCALL;
528 hr = D3DXCheckTextureRequirements(pDevice, &width, &height, &miplevels, usage, &format, pool);
533 return IDirect3DDevice9_CreateTexture(pDevice, width, height, miplevels, usage, format, pool, ppTexture, NULL);
536 HRESULT WINAPI D3DXCreateTextureFromFileInMemoryEx(LPDIRECT3DDEVICE9 device,
548 D3DXIMAGE_INFO* srcinfo,
549 PALETTEENTRY* palette,
550 LPDIRECT3DTEXTURE9* texture)
552 IDirect3DTexture9 **texptr;
553 IDirect3DTexture9 *buftex;
554 IDirect3DSurface9 *surface;
555 BOOL file_width = FALSE, file_height = FALSE;
556 BOOL file_format = FALSE, file_miplevels = FALSE;
557 BOOL dynamic_texture;
558 D3DXIMAGE_INFO imginfo;
559 UINT loaded_miplevels;
563 TRACE("(%p, %p, %u, %u, %u, %u, %x, %x, %x, %u, %u, %x, %p, %p, %p)\n", device, srcdata, srcdatasize, width,
564 height, miplevels, usage, format, pool, filter, mipfilter, colorkey, srcinfo, palette, texture);
566 /* check for invalid parameters */
567 if (!device || !texture || !srcdata || !srcdatasize)
568 return D3DERR_INVALIDCALL;
570 hr = D3DXGetImageInfoFromFileInMemory(srcdata, srcdatasize, &imginfo);
578 /* handle default values */
579 if (width == 0 || width == D3DX_DEFAULT_NONPOW2)
580 width = imginfo.Width;
582 if (height == 0 || height == D3DX_DEFAULT_NONPOW2)
583 height = imginfo.Height;
585 if (width == D3DX_DEFAULT)
586 width = make_pow2(imginfo.Width);
588 if (height == D3DX_DEFAULT)
589 height = make_pow2(imginfo.Height);
591 if (format == D3DFMT_UNKNOWN || format == D3DX_DEFAULT)
592 format = imginfo.Format;
594 if (width == D3DX_FROM_FILE)
597 width = imginfo.Width;
600 if (height == D3DX_FROM_FILE)
603 height = imginfo.Height;
606 if (format == D3DFMT_FROM_FILE)
609 format = imginfo.Format;
612 if (miplevels == D3DX_FROM_FILE)
614 file_miplevels = TRUE;
615 miplevels = imginfo.MipLevels;
618 /* fix texture creation parameters */
619 hr = D3DXCheckTextureRequirements(device, &width, &height, &miplevels, usage, &format, pool);
627 if (imginfo.MipLevels < miplevels && (D3DFMT_DXT1 <= imginfo.Format && imginfo.Format <= D3DFMT_DXT5))
629 FIXME("Generation of mipmaps for compressed pixel formats is not implemented yet\n");
630 miplevels = imginfo.MipLevels;
633 if (((file_width) && (width != imginfo.Width)) ||
634 ((file_height) && (height != imginfo.Height)) ||
635 ((file_format) && (format != imginfo.Format)) ||
636 ((file_miplevels) && (miplevels != imginfo.MipLevels)))
638 return D3DERR_NOTAVAILABLE;
641 if (FAILED(IDirect3DDevice9_GetDeviceCaps(device, &caps)))
642 return D3DERR_INVALIDCALL;
644 /* Create the to-be-filled texture */
645 dynamic_texture = (caps.Caps2 & D3DCAPS2_DYNAMICTEXTURES) && (usage & D3DUSAGE_DYNAMIC);
646 if (pool == D3DPOOL_DEFAULT && !dynamic_texture)
648 hr = D3DXCreateTexture(device, width, height, miplevels, usage, format, D3DPOOL_SYSTEMMEM, &buftex);
653 hr = D3DXCreateTexture(device, width, height, miplevels, usage, format, pool, texture);
664 if (imginfo.ImageFileFormat != D3DXIFF_DDS)
666 IDirect3DTexture9_GetSurfaceLevel(*texptr, 0, &surface);
667 hr = D3DXLoadSurfaceFromFileInMemory(surface, palette, NULL, srcdata, srcdatasize, NULL, filter, colorkey, NULL);
668 IDirect3DSurface9_Release(surface);
672 hr = load_texture_from_dds(*texptr, srcdata, palette, filter, colorkey, &imginfo);
677 IDirect3DTexture9_Release(*texptr);
682 loaded_miplevels = min(IDirect3DTexture9_GetLevelCount(*texptr), imginfo.MipLevels);
683 hr = D3DXFilterTexture((IDirect3DBaseTexture9*) *texptr, palette, loaded_miplevels - 1, mipfilter);
687 IDirect3DTexture9_Release(*texptr);
692 /* Move the data to the actual texture if necessary */
693 if (texptr == &buftex)
695 hr = D3DXCreateTexture(device, width, height, miplevels, usage, format, pool, texture);
699 IDirect3DTexture9_Release(buftex);
704 IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9*)buftex, (IDirect3DBaseTexture9*)(*texture));
705 IDirect3DTexture9_Release(buftex);
714 HRESULT WINAPI D3DXCreateTextureFromFileInMemory(LPDIRECT3DDEVICE9 device,
717 LPDIRECT3DTEXTURE9 *texture)
719 TRACE("(%p, %p, %d, %p)\n", device, srcdata, srcdatasize, texture);
721 return D3DXCreateTextureFromFileInMemoryEx(device, srcdata, srcdatasize, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN,
722 D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, texture);
725 HRESULT WINAPI D3DXCreateTextureFromFileExW(LPDIRECT3DDEVICE9 device,
736 D3DXIMAGE_INFO *srcinfo,
737 PALETTEENTRY *palette,
738 LPDIRECT3DTEXTURE9 *texture)
744 TRACE("(%p, %s, %u, %u, %u, %x, %x, %x, %u, %u, %x, %p, %p, %p): relay\n",
745 device, debugstr_w(srcfile), width, height, miplevels, usage, format, pool, filter,
746 mipfilter, colorkey, srcinfo, palette, texture);
749 return D3DERR_INVALIDCALL;
751 hr = map_view_of_file(srcfile, &buffer, &size);
753 return D3DXERR_INVALIDDATA;
755 hr = D3DXCreateTextureFromFileInMemoryEx(device, buffer, size, width, height, miplevels, usage, format, pool,
756 filter, mipfilter, colorkey, srcinfo, palette, texture);
758 UnmapViewOfFile(buffer);
763 HRESULT WINAPI D3DXCreateTextureFromFileExA(LPDIRECT3DDEVICE9 device,
774 D3DXIMAGE_INFO *srcinfo,
775 PALETTEENTRY *palette,
776 LPDIRECT3DTEXTURE9 *texture)
782 TRACE("(%p, %s, %u, %u, %u, %x, %x, %x, %u, %u, %x, %p, %p, %p): relay\n",
783 device, debugstr_a(srcfile), width, height, miplevels, usage, format, pool, filter,
784 mipfilter, colorkey, srcinfo, palette, texture);
786 if (!device || !srcfile || !texture)
787 return D3DERR_INVALIDCALL;
789 len = MultiByteToWideChar(CP_ACP, 0, srcfile, -1, NULL, 0);
790 widename = HeapAlloc(GetProcessHeap(), 0, len * sizeof(*widename));
791 MultiByteToWideChar(CP_ACP, 0, srcfile, -1, widename, len);
793 hr = D3DXCreateTextureFromFileExW(device, widename, width, height, miplevels,
794 usage, format, pool, filter, mipfilter,
795 colorkey, srcinfo, palette, texture);
797 HeapFree(GetProcessHeap(), 0, widename);
801 HRESULT WINAPI D3DXCreateTextureFromFileA(LPDIRECT3DDEVICE9 device,
803 LPDIRECT3DTEXTURE9 *texture)
805 TRACE("(%p, %s, %p)\n", device, debugstr_a(srcfile), texture);
807 return D3DXCreateTextureFromFileExA(device, srcfile, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN,
808 D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, texture);
811 HRESULT WINAPI D3DXCreateTextureFromFileW(LPDIRECT3DDEVICE9 device,
813 LPDIRECT3DTEXTURE9 *texture)
815 TRACE("(%p, %s, %p)\n", device, debugstr_w(srcfile), texture);
817 return D3DXCreateTextureFromFileExW(device, srcfile, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN,
818 D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, texture);
822 HRESULT WINAPI D3DXCreateTextureFromResourceA(LPDIRECT3DDEVICE9 device,
825 LPDIRECT3DTEXTURE9 *texture)
827 TRACE("(%p, %s): relay\n", srcmodule, debugstr_a(resource));
829 return D3DXCreateTextureFromResourceExA(device, srcmodule, resource, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN,
830 D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, texture);
833 HRESULT WINAPI D3DXCreateTextureFromResourceW(LPDIRECT3DDEVICE9 device,
836 LPDIRECT3DTEXTURE9 *texture)
838 TRACE("(%p, %s): relay\n", srcmodule, debugstr_w(resource));
840 return D3DXCreateTextureFromResourceExW(device, srcmodule, resource, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN,
841 D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, texture);
844 HRESULT WINAPI D3DXCreateTextureFromResourceExA(LPDIRECT3DDEVICE9 device,
856 D3DXIMAGE_INFO *srcinfo,
857 PALETTEENTRY *palette,
858 LPDIRECT3DTEXTURE9 *texture)
862 TRACE("(%p, %s): relay\n", srcmodule, debugstr_a(resource));
864 if (!device || !texture)
865 return D3DERR_INVALIDCALL;
867 resinfo = FindResourceA(srcmodule, resource, (LPCSTR) RT_RCDATA);
875 hr = load_resource_into_memory(srcmodule, resinfo, &buffer, &size);
878 return D3DXERR_INVALIDDATA;
880 return D3DXCreateTextureFromFileInMemoryEx(device, buffer, size, width,
881 height, miplevels, usage, format,
882 pool, filter, mipfilter, colorkey,
883 srcinfo, palette, texture);
886 /* Try loading the resource as bitmap data */
887 resinfo = FindResourceA(srcmodule, resource, (LPCSTR) RT_BITMAP);
891 FIXME("Implement loading bitmaps from resource type RT_BITMAP\n");
895 return D3DXERR_INVALIDDATA;
898 HRESULT WINAPI D3DXCreateTextureFromResourceExW(LPDIRECT3DDEVICE9 device,
910 D3DXIMAGE_INFO *srcinfo,
911 PALETTEENTRY *palette,
912 LPDIRECT3DTEXTURE9 *texture)
916 TRACE("(%p, %s): relay\n", srcmodule, debugstr_w(resource));
918 if (!device || !texture)
919 return D3DERR_INVALIDCALL;
921 resinfo = FindResourceW(srcmodule, resource, (LPCWSTR) RT_RCDATA);
929 hr = load_resource_into_memory(srcmodule, resinfo, &buffer, &size);
932 return D3DXERR_INVALIDDATA;
934 return D3DXCreateTextureFromFileInMemoryEx(device, buffer, size, width,
935 height, miplevels, usage, format,
936 pool, filter, mipfilter, colorkey,
937 srcinfo, palette, texture);
940 /* Try loading the resource as bitmap data */
941 resinfo = FindResourceW(srcmodule, resource, (LPCWSTR) RT_BITMAP);
945 FIXME("Implement loading bitmaps from resource type RT_BITMAP\n");
949 return D3DXERR_INVALIDDATA;
952 HRESULT WINAPI D3DXCreateCubeTexture(LPDIRECT3DDEVICE9 device,
958 LPDIRECT3DCUBETEXTURE9 *texture)
962 TRACE("(%p, %u, %u, %#x, %#x, %#x, %p)\n", device, size, miplevels, usage, format,
965 if (!device || !texture)
966 return D3DERR_INVALIDCALL;
968 hr = D3DXCheckCubeTextureRequirements(device, &size, &miplevels, usage, &format, pool);
972 TRACE("D3DXCheckCubeTextureRequirements failed\n");
976 return IDirect3DDevice9_CreateCubeTexture(device, size, miplevels, usage, format, pool, texture, NULL);
979 HRESULT WINAPI D3DXCreateCubeTextureFromFileInMemory(LPDIRECT3DDEVICE9 device,
982 LPDIRECT3DCUBETEXTURE9 *texture)
984 TRACE("(%p, %p, %u, %p)\n", device, data, datasize, texture);
986 return D3DXCreateCubeTextureFromFileInMemoryEx(device, data, datasize, D3DX_DEFAULT, D3DX_DEFAULT,
987 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, texture);
990 HRESULT WINAPI D3DXCreateVolumeTexture(LPDIRECT3DDEVICE9 device,
998 LPDIRECT3DVOLUMETEXTURE9 *texture)
1002 TRACE("(%p, %u, %u, %u, %u, %#x, %#x, %#x, %p)\n", device, width, height, depth,
1003 miplevels, usage, format, pool, texture);
1005 if (!device || !texture)
1006 return D3DERR_INVALIDCALL;
1008 hr = D3DXCheckVolumeTextureRequirements(device, &width, &height, &depth,
1009 &miplevels, usage, &format, pool);
1013 TRACE("D3DXCheckVolumeTextureRequirements failed\n");
1017 return IDirect3DDevice9_CreateVolumeTexture(device, width, height, depth, miplevels,
1018 usage, format, pool, texture, NULL);
1021 HRESULT WINAPI D3DXCreateVolumeTextureFromFileA(IDirect3DDevice9 *device,
1022 const char *filename,
1023 IDirect3DVolumeTexture9 **volume_texture)
1031 TRACE("(%p, %s, %p): relay\n",
1032 device, debugstr_a(filename), volume_texture);
1034 if (!filename) return D3DERR_INVALIDCALL;
1036 len = MultiByteToWideChar(CP_ACP, 0, filename, -1, NULL, 0);
1037 filenameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
1038 if (!filenameW) return E_OUTOFMEMORY;
1039 MultiByteToWideChar(CP_ACP, 0, filename, -1, filenameW, len);
1041 hr = map_view_of_file(filenameW, &data, &data_size);
1042 HeapFree(GetProcessHeap(), 0, filenameW);
1043 if (FAILED(hr)) return D3DXERR_INVALIDDATA;
1045 hr = D3DXCreateVolumeTextureFromFileInMemoryEx(device, data, data_size, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT,
1046 D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, volume_texture);
1048 UnmapViewOfFile(data);
1052 HRESULT WINAPI D3DXCreateVolumeTextureFromFileW(IDirect3DDevice9 *device,
1053 const WCHAR *filename,
1054 IDirect3DVolumeTexture9 **volume_texture)
1060 TRACE("(%p, %s, %p): relay\n",
1061 device, debugstr_w(filename), volume_texture);
1063 if (!filename) return D3DERR_INVALIDCALL;
1065 hr = map_view_of_file(filename, &data, &data_size);
1066 if (FAILED(hr)) return D3DXERR_INVALIDDATA;
1068 hr = D3DXCreateVolumeTextureFromFileInMemoryEx(device, data, data_size, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT,
1069 D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, volume_texture);
1071 UnmapViewOfFile(data);
1075 HRESULT WINAPI D3DXCreateVolumeTextureFromFileExA(IDirect3DDevice9 *device,
1076 const char *filename,
1087 D3DXIMAGE_INFO *src_info,
1088 PALETTEENTRY *palette,
1089 IDirect3DVolumeTexture9 **volume_texture)
1097 TRACE("(%p, %s, %u, %u, %u, %u, %#x, %#x, %#x, %#x, %#x, %#x, %p, %p, %p): relay\n",
1098 device, debugstr_a(filename), width, height, depth, mip_levels,
1099 usage, format, pool, filter, mip_filter, color_key, src_info,
1100 palette, volume_texture);
1102 if (!filename) return D3DERR_INVALIDCALL;
1104 len = MultiByteToWideChar(CP_ACP, 0, filename, -1, NULL, 0);
1105 filenameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
1106 if (!filenameW) return E_OUTOFMEMORY;
1107 MultiByteToWideChar(CP_ACP, 0, filename, -1, filenameW, len);
1109 hr = map_view_of_file(filenameW, &data, &data_size);
1110 HeapFree(GetProcessHeap(), 0, filenameW);
1111 if (FAILED(hr)) return D3DXERR_INVALIDDATA;
1113 hr = D3DXCreateVolumeTextureFromFileInMemoryEx(device, data, data_size, width, height, depth,
1114 mip_levels, usage, format, pool, filter, mip_filter, color_key, src_info, palette,
1117 UnmapViewOfFile(data);
1121 HRESULT WINAPI D3DXCreateVolumeTextureFromFileExW(IDirect3DDevice9 *device,
1122 const WCHAR *filename,
1133 D3DXIMAGE_INFO *src_info,
1134 PALETTEENTRY *palette,
1135 IDirect3DVolumeTexture9 **volume_texture)
1141 TRACE("(%p, %s, %u, %u, %u, %u, %#x, %#x, %#x, %#x, %#x, %#x, %p, %p, %p): relay\n",
1142 device, debugstr_w(filename), width, height, depth, mip_levels,
1143 usage, format, pool, filter, mip_filter, color_key, src_info,
1144 palette, volume_texture);
1146 if (!filename) return D3DERR_INVALIDCALL;
1148 hr = map_view_of_file(filename, &data, &data_size);
1149 if (FAILED(hr)) return D3DXERR_INVALIDDATA;
1151 hr = D3DXCreateVolumeTextureFromFileInMemoryEx(device, data, data_size, width, height, depth,
1152 mip_levels, usage, format, pool, filter, mip_filter, color_key, src_info, palette,
1155 UnmapViewOfFile(data);
1159 HRESULT WINAPI D3DXCreateVolumeTextureFromFileInMemory(IDirect3DDevice9 *device,
1162 IDirect3DVolumeTexture9 **volume_texture)
1164 TRACE("(%p, %p, %u, %p): relay\n", device, data, data_size, volume_texture);
1166 return D3DXCreateVolumeTextureFromFileInMemoryEx(device, data, data_size, D3DX_DEFAULT, D3DX_DEFAULT,
1167 D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT,
1168 0, NULL, NULL, volume_texture);
1171 HRESULT WINAPI D3DXCreateVolumeTextureFromFileInMemoryEx(IDirect3DDevice9 *device,
1184 D3DXIMAGE_INFO *info,
1185 PALETTEENTRY *palette,
1186 IDirect3DVolumeTexture9 **volume_texture)
1190 D3DXIMAGE_INFO image_info;
1191 BOOL dynamic_texture;
1192 BOOL file_width = FALSE;
1193 BOOL file_height = FALSE;
1194 BOOL file_depth = FALSE;
1195 BOOL file_format = FALSE;
1196 BOOL file_mip_levels = FALSE;
1197 IDirect3DVolumeTexture9 *tex, *buftex;
1199 TRACE("(%p, %p, %u, %u, %u, %u, %u, %#x, %#x, %#x, %#x, %#x, %#x, %p, %p, %p)\n",
1200 device, data, data_size, width, height, depth, mip_levels, usage, format, pool,
1201 filter, mip_filter, color_key, info, palette, volume_texture);
1203 if (!device || !data || !data_size || !volume_texture)
1204 return D3DERR_INVALIDCALL;
1206 hr = D3DXGetImageInfoFromFileInMemory(data, data_size, &image_info);
1207 if (FAILED(hr)) return hr;
1209 if (image_info.ImageFileFormat != D3DXIFF_DDS)
1210 return D3DXERR_INVALIDDATA;
1212 if (width == 0 || width == D3DX_DEFAULT_NONPOW2)
1213 width = image_info.Width;
1214 if (width == D3DX_DEFAULT)
1215 width = make_pow2(image_info.Width);
1217 if (height == 0 || height == D3DX_DEFAULT_NONPOW2)
1218 height = image_info.Height;
1219 if (height == D3DX_DEFAULT)
1220 height = make_pow2(image_info.Height);
1222 if (depth == 0 || depth == D3DX_DEFAULT_NONPOW2)
1223 depth = image_info.Depth;
1224 if (depth == D3DX_DEFAULT)
1225 depth = make_pow2(image_info.Depth);
1227 if (format == D3DFMT_UNKNOWN || format == D3DX_DEFAULT)
1228 format = image_info.Format;
1230 if (width == D3DX_FROM_FILE)
1233 width = image_info.Width;
1236 if (height == D3DX_FROM_FILE)
1239 height = image_info.Height;
1242 if (depth == D3DX_FROM_FILE)
1245 depth = image_info.Depth;
1248 if (format == D3DFMT_FROM_FILE)
1251 format = image_info.Format;
1254 if (mip_levels == D3DX_FROM_FILE)
1256 file_mip_levels = TRUE;
1257 mip_levels = image_info.MipLevels;
1260 hr = D3DXCheckVolumeTextureRequirements(device, &width, &height, &depth, &mip_levels, usage, &format, pool);
1261 if (FAILED(hr)) return hr;
1263 if ((file_width && width != image_info.Width)
1264 || (file_height && height != image_info.Height)
1265 || (file_depth && depth != image_info.Depth)
1266 || (file_format && format != image_info.Format)
1267 || (file_mip_levels && mip_levels != image_info.MipLevels))
1268 return D3DERR_NOTAVAILABLE;
1270 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1272 return D3DERR_INVALIDCALL;
1274 if (mip_levels > image_info.MipLevels)
1276 FIXME("Generation of mipmaps for volume textures is not implemented yet\n");
1277 mip_levels = image_info.MipLevels;
1280 dynamic_texture = (caps.Caps2 & D3DCAPS2_DYNAMICTEXTURES) && (usage & D3DUSAGE_DYNAMIC);
1281 if (pool == D3DPOOL_DEFAULT && !dynamic_texture)
1283 hr = D3DXCreateVolumeTexture(device, width, height, depth, mip_levels, usage, format, D3DPOOL_SYSTEMMEM, &buftex);
1288 hr = D3DXCreateVolumeTexture(device, width, height, depth, mip_levels, usage, format, pool, &tex);
1292 if (FAILED(hr)) return hr;
1294 hr = load_volume_texture_from_dds(tex, data, palette, filter, color_key, &image_info);
1297 IDirect3DVolumeTexture9_Release(tex);
1303 hr = D3DXCreateVolumeTexture(device, width, height, depth, mip_levels, usage, format, pool, &tex);
1306 IDirect3DVolumeTexture9_Release(buftex);
1310 IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)buftex, (IDirect3DBaseTexture9 *)tex);
1311 IDirect3DVolumeTexture9_Release(buftex);
1317 *volume_texture = tex;
1321 HRESULT WINAPI D3DXFillTexture(LPDIRECT3DTEXTURE9 texture,
1322 LPD3DXFILL2D function,
1326 DWORD m, i, x, y, c, v;
1327 D3DSURFACE_DESC desc;
1328 D3DLOCKED_RECT lock_rect;
1330 D3DXVECTOR2 coord, size;
1331 const struct pixel_format_desc *format;
1336 if (texture == NULL || function == NULL)
1337 return D3DERR_INVALIDCALL;
1339 miplevels = IDirect3DBaseTexture9_GetLevelCount(texture);
1341 for (m = 0; m < miplevels; m++)
1343 if (FAILED(IDirect3DTexture9_GetLevelDesc(texture, m, &desc)))
1344 return D3DERR_INVALIDCALL;
1346 format = get_format_info(desc.Format);
1347 if (format->format == D3DFMT_UNKNOWN)
1349 FIXME("Unsupported texture format %#x\n", desc.Format);
1350 return D3DERR_INVALIDCALL;
1353 if (FAILED(IDirect3DTexture9_LockRect(texture, m, &lock_rect, NULL, D3DLOCK_DISCARD)))
1354 return D3DERR_INVALIDCALL;
1356 size.x = 1.0f / desc.Width;
1357 size.y = 1.0f / desc.Height;
1359 data = lock_rect.pBits;
1361 for (y = 0; y < desc.Height; y++)
1363 /* The callback function expects the coordinates of the center
1365 coord.y = (y + 0.5f) / desc.Height;
1367 for (x = 0; x < desc.Width; x++)
1369 coord.x = (x + 0.5f) / desc.Width;
1371 function(&value, &coord, &size, funcdata);
1373 pos = data + y * lock_rect.Pitch + x * format->bytes_per_pixel;
1375 for (i = 0; i < format->bytes_per_pixel; i++)
1378 for (c = 0; c < 4; c++)
1383 comp_value = value.w;
1386 comp_value = value.x;
1389 comp_value = value.y;
1392 comp_value = value.z;
1396 v = comp_value * ((1 << format->bits[c]) - 1) + 0.5f;
1398 for (i = 0; i < format->bits[c] + format->shift[c]; i += 8)
1400 mask = ((1 << format->bits[c]) - 1) << format->shift[c] >> i;
1401 byte = (v << format->shift[c] >> i) & mask;
1407 IDirect3DTexture9_UnlockRect(texture, m);
1413 HRESULT WINAPI D3DXCreateCubeTextureFromFileInMemoryEx(IDirect3DDevice9 *device,
1414 const void *src_data,
1424 D3DXIMAGE_INFO *src_info,
1425 PALETTEENTRY *palette,
1426 IDirect3DCubeTexture9 **cube_texture)
1430 UINT loaded_miplevels;
1431 D3DXIMAGE_INFO img_info;
1432 BOOL dynamic_texture;
1433 BOOL file_size = FALSE;
1434 BOOL file_format = FALSE;
1435 BOOL file_mip_levels = FALSE;
1436 IDirect3DCubeTexture9 *tex, *buftex;
1438 TRACE("(%p, %p, %u, %u, %u, %#x, %#x, %#x, %#x, %#x, %#x, %p, %p, %p)\n", device,
1439 src_data, src_data_size, size, mip_levels, usage, format, pool, filter, mip_filter,
1440 color_key, src_info, palette, cube_texture);
1442 if (!device || !cube_texture || !src_data || !src_data_size)
1443 return D3DERR_INVALIDCALL;
1445 hr = D3DXGetImageInfoFromFileInMemory(src_data, src_data_size, &img_info);
1449 if (img_info.ImageFileFormat != D3DXIFF_DDS)
1450 return D3DXERR_INVALIDDATA;
1452 if (img_info.Width != img_info.Height)
1453 return D3DXERR_INVALIDDATA;
1455 if (size == 0 || size == D3DX_DEFAULT_NONPOW2)
1456 size = img_info.Width;
1457 if (size == D3DX_DEFAULT)
1458 size = make_pow2(img_info.Width);
1460 if (format == D3DFMT_UNKNOWN || format == D3DX_DEFAULT)
1461 format = img_info.Format;
1463 if (size == D3DX_FROM_FILE)
1466 size = img_info.Width;
1469 if (format == D3DFMT_FROM_FILE)
1472 format = img_info.Format;
1475 if (mip_levels == D3DX_FROM_FILE)
1477 file_mip_levels = TRUE;
1478 mip_levels = img_info.MipLevels;
1481 hr = D3DXCheckCubeTextureRequirements(device, &size, &mip_levels, usage, &format, pool);
1485 if ((file_size && size != img_info.Width)
1486 || (file_format && format != img_info.Format)
1487 || (file_mip_levels && mip_levels != img_info.MipLevels))
1488 return D3DERR_NOTAVAILABLE;
1490 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1492 return D3DERR_INVALIDCALL;
1494 if (mip_levels > img_info.MipLevels && (D3DFMT_DXT1 <= img_info.Format && img_info.Format <= D3DFMT_DXT5))
1496 FIXME("Generation of mipmaps for compressed pixel formats not supported yet\n");
1497 mip_levels = img_info.MipLevels;
1500 dynamic_texture = (caps.Caps2 & D3DCAPS2_DYNAMICTEXTURES) && (usage & D3DUSAGE_DYNAMIC);
1501 if (pool == D3DPOOL_DEFAULT && !dynamic_texture)
1503 hr = D3DXCreateCubeTexture(device, size, mip_levels, usage, format, D3DPOOL_SYSTEMMEM, &buftex);
1508 hr = D3DXCreateCubeTexture(device, size, mip_levels, usage, format, pool, &tex);
1514 hr = load_cube_texture_from_dds(tex, src_data, palette, filter, color_key, &img_info);
1517 IDirect3DCubeTexture9_Release(tex);
1521 loaded_miplevels = min(IDirect3DCubeTexture9_GetLevelCount(tex), img_info.MipLevels);
1522 hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, palette, loaded_miplevels - 1, mip_filter);
1525 IDirect3DCubeTexture9_Release(tex);
1531 hr = D3DXCreateCubeTexture(device, size, mip_levels, usage, format, pool, &tex);
1534 IDirect3DCubeTexture9_Release(buftex);
1538 IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)buftex, (IDirect3DBaseTexture9 *)tex);
1539 IDirect3DCubeTexture9_Release(buftex);
1543 *src_info = img_info;
1545 *cube_texture = tex;
1550 HRESULT WINAPI D3DXCreateCubeTextureFromFileA(IDirect3DDevice9 *device,
1551 const char *src_filename,
1552 IDirect3DCubeTexture9 **cube_texture)
1560 TRACE("(%p, %s, %p): relay\n", device, wine_dbgstr_a(src_filename), cube_texture);
1562 if (!src_filename) return D3DERR_INVALIDCALL;
1564 len = MultiByteToWideChar(CP_ACP, 0, src_filename, -1, NULL, 0);
1565 filename = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
1566 if (!filename) return E_OUTOFMEMORY;
1567 MultiByteToWideChar(CP_ACP, 0, src_filename, -1, filename, len);
1569 hr = map_view_of_file(filename, &data, &data_size);
1572 HeapFree(GetProcessHeap(), 0, filename);
1573 return D3DXERR_INVALIDDATA;
1576 hr = D3DXCreateCubeTextureFromFileInMemoryEx(device, data, data_size, D3DX_DEFAULT, D3DX_DEFAULT,
1577 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, cube_texture);
1579 UnmapViewOfFile(data);
1580 HeapFree(GetProcessHeap(), 0, filename);
1584 HRESULT WINAPI D3DXCreateCubeTextureFromFileW(IDirect3DDevice9 *device,
1585 const WCHAR *src_filename,
1586 IDirect3DCubeTexture9 **cube_texture)
1592 TRACE("(%p, %s, %p): relay\n", device, wine_dbgstr_w(src_filename), cube_texture);
1594 hr = map_view_of_file(src_filename, &data, &data_size);
1595 if (FAILED(hr)) return D3DXERR_INVALIDDATA;
1597 hr = D3DXCreateCubeTextureFromFileInMemoryEx(device, data, data_size, D3DX_DEFAULT, D3DX_DEFAULT,
1598 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, cube_texture);
1600 UnmapViewOfFile(data);
1604 HRESULT WINAPI D3DXCreateCubeTextureFromFileExA(IDirect3DDevice9 *device,
1605 const char *src_filename,
1614 D3DXIMAGE_INFO *image_info,
1615 PALETTEENTRY *palette,
1616 IDirect3DCubeTexture9 **cube_texture)
1624 TRACE("(%p, %s, %u, %u, %#x, %#x, %#x, %#x, %#x, %#x, %p, %p, %p): relay\n",
1625 device, wine_dbgstr_a(src_filename), size, mip_levels, usage, format,
1626 pool, filter, mip_filter, color_key, image_info, palette, cube_texture);
1628 if (!src_filename) return D3DERR_INVALIDCALL;
1630 len = MultiByteToWideChar(CP_ACP, 0, src_filename, -1, NULL, 0);
1631 filename = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
1632 if (!filename) return E_OUTOFMEMORY;
1633 MultiByteToWideChar(CP_ACP, 0, src_filename, -1, filename, len);
1635 hr = map_view_of_file(filename, &data, &data_size);
1638 HeapFree(GetProcessHeap(), 0, filename);
1639 return D3DXERR_INVALIDDATA;
1642 hr = D3DXCreateCubeTextureFromFileInMemoryEx(device, data, data_size, size, mip_levels,
1643 usage, format, pool, filter, mip_filter, color_key, image_info, palette, cube_texture);
1645 UnmapViewOfFile(data);
1646 HeapFree(GetProcessHeap(), 0, filename);
1650 HRESULT WINAPI D3DXCreateCubeTextureFromFileExW(IDirect3DDevice9 *device,
1651 const WCHAR *src_filename,
1660 D3DXIMAGE_INFO *image_info,
1661 PALETTEENTRY *palette,
1662 IDirect3DCubeTexture9 **cube_texture)
1668 TRACE("(%p, %s, %u, %u, %#x, %#x, %#x, %#x, %#x, %#x, %p, %p, %p): relay\n",
1669 device, wine_dbgstr_w(src_filename), size, mip_levels, usage, format,
1670 pool, filter, mip_filter, color_key, image_info, palette, cube_texture);
1672 hr = map_view_of_file(src_filename, &data, &data_size);
1673 if (FAILED(hr)) return D3DXERR_INVALIDDATA;
1675 hr = D3DXCreateCubeTextureFromFileInMemoryEx(device, data, data_size, size, mip_levels,
1676 usage, format, pool, filter, mip_filter, color_key, image_info, palette, cube_texture);
1678 UnmapViewOfFile(data);
1692 static float get_cube_coord(enum cube_coord coord, unsigned int x, unsigned int y, unsigned int size)
1699 return size - x - 0.5f;
1703 return size - y - 0.5f;
1709 ERR("Unexpected coordinate value\n");
1714 HRESULT WINAPI D3DXFillCubeTexture(LPDIRECT3DCUBETEXTURE9 texture,
1715 LPD3DXFILL3D function,
1719 DWORD m, i, x, y, c, f, v;
1720 D3DSURFACE_DESC desc;
1721 D3DLOCKED_RECT lock_rect;
1723 D3DXVECTOR3 coord, size;
1724 const struct pixel_format_desc *format;
1728 static const enum cube_coord coordmap[6][3] =
1730 {ONE, YCOORDINV, XCOORDINV},
1731 {ZERO, YCOORDINV, XCOORD},
1732 {XCOORD, ONE, YCOORD},
1733 {XCOORD, ZERO, YCOORDINV},
1734 {XCOORD, YCOORDINV, ONE},
1735 {XCOORDINV, YCOORDINV, ZERO}
1738 if (texture == NULL || function == NULL)
1739 return D3DERR_INVALIDCALL;
1741 miplevels = IDirect3DBaseTexture9_GetLevelCount(texture);
1743 for (m = 0; m < miplevels; m++)
1745 if (FAILED(IDirect3DCubeTexture9_GetLevelDesc(texture, m, &desc)))
1746 return D3DERR_INVALIDCALL;
1748 format = get_format_info(desc.Format);
1749 if (format->format == D3DFMT_UNKNOWN)
1751 FIXME("Unsupported texture format %#x\n", desc.Format);
1752 return D3DERR_INVALIDCALL;
1755 for (f = 0; f < 6; f++)
1757 if (FAILED(IDirect3DCubeTexture9_LockRect(texture, f, m, &lock_rect, NULL, D3DLOCK_DISCARD)))
1758 return D3DERR_INVALIDCALL;
1760 size.x = (f == 0) || (f == 1) ? 0.0f : 2.0f / desc.Width;
1761 size.y = (f == 2) || (f == 3) ? 0.0f : 2.0f / desc.Width;
1762 size.z = (f == 4) || (f == 5) ? 0.0f : 2.0f / desc.Width;
1764 data = lock_rect.pBits;
1766 for (y = 0; y < desc.Height; y++)
1768 for (x = 0; x < desc.Width; x++)
1770 coord.x = get_cube_coord(coordmap[f][0], x, y, desc.Width) / desc.Width * 2.0f - 1.0f;
1771 coord.y = get_cube_coord(coordmap[f][1], x, y, desc.Width) / desc.Width * 2.0f - 1.0f;
1772 coord.z = get_cube_coord(coordmap[f][2], x, y, desc.Width) / desc.Width * 2.0f - 1.0f;
1774 function(&value, &coord, &size, funcdata);
1776 pos = data + y * lock_rect.Pitch + x * format->bytes_per_pixel;
1778 for (i = 0; i < format->bytes_per_pixel; i++)
1781 for (c = 0; c < 4; c++)
1786 comp_value = value.w;
1789 comp_value = value.x;
1792 comp_value = value.y;
1795 comp_value = value.z;
1799 v = comp_value * ((1 << format->bits[c]) - 1) + 0.5f;
1801 for (i = 0; i < format->bits[c] + format->shift[c]; i += 8)
1803 mask = ((1 << format->bits[c]) - 1) << format->shift[c] >> i;
1804 byte = (v << format->shift[c] >> i) & mask;
1810 IDirect3DCubeTexture9_UnlockRect(texture, f, m);
1817 HRESULT WINAPI D3DXFillVolumeTexture(LPDIRECT3DVOLUMETEXTURE9 texture,
1818 LPD3DXFILL3D function,
1822 DWORD m, i, x, y, z, c, v;
1823 D3DVOLUME_DESC desc;
1824 D3DLOCKED_BOX lock_box;
1826 D3DXVECTOR3 coord, size;
1827 const struct pixel_format_desc *format;
1832 if (texture == NULL || function == NULL)
1833 return D3DERR_INVALIDCALL;
1835 miplevels = IDirect3DBaseTexture9_GetLevelCount(texture);
1837 for (m = 0; m < miplevels; m++)
1839 if (FAILED(IDirect3DVolumeTexture9_GetLevelDesc(texture, m, &desc)))
1840 return D3DERR_INVALIDCALL;
1842 format = get_format_info(desc.Format);
1843 if (format->format == D3DFMT_UNKNOWN)
1845 FIXME("Unsupported texture format %#x\n", desc.Format);
1846 return D3DERR_INVALIDCALL;
1849 if (FAILED(IDirect3DVolumeTexture9_LockBox(texture, m, &lock_box, NULL, D3DLOCK_DISCARD)))
1850 return D3DERR_INVALIDCALL;
1852 size.x = 1.0f / desc.Width;
1853 size.y = 1.0f / desc.Height;
1854 size.z = 1.0f / desc.Depth;
1856 data = lock_box.pBits;
1858 for (z = 0; z < desc.Depth; z++)
1860 /* The callback function expects the coordinates of the center
1862 coord.z = (z + 0.5f) / desc.Depth;
1864 for (y = 0; y < desc.Height; y++)
1866 coord.y = (y + 0.5f) / desc.Height;
1868 for (x = 0; x < desc.Width; x++)
1870 coord.x = (x + 0.5f) / desc.Width;
1872 function(&value, &coord, &size, funcdata);
1874 pos = data + z * lock_box.SlicePitch + y * lock_box.RowPitch + x * format->bytes_per_pixel;
1876 for (i = 0; i < format->bytes_per_pixel; i++)
1879 for (c = 0; c < 4; c++)
1884 comp_value = value.w;
1887 comp_value = value.x;
1890 comp_value = value.y;
1893 comp_value = value.z;
1897 v = comp_value * ((1 << format->bits[c]) - 1) + 0.5f;
1899 for (i = 0; i < format->bits[c] + format->shift[c]; i += 8)
1901 mask = ((1 << format->bits[c]) - 1) << format->shift[c] >> i;
1902 byte = (v << format->shift[c] >> i) & mask;
1909 IDirect3DVolumeTexture9_UnlockBox(texture, m);
1915 HRESULT WINAPI D3DXSaveTextureToFileA(const char *dst_filename, D3DXIMAGE_FILEFORMAT file_format,
1916 IDirect3DBaseTexture9 *src_texture, const PALETTEENTRY *src_palette)
1921 ID3DXBuffer *buffer;
1923 TRACE("(%s, %#x, %p, %p): relay\n",
1924 wine_dbgstr_a(dst_filename), file_format, src_texture, src_palette);
1926 if (!dst_filename) return D3DERR_INVALIDCALL;
1928 len = MultiByteToWideChar(CP_ACP, 0, dst_filename, -1, NULL, 0);
1929 filename = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
1930 if (!filename) return E_OUTOFMEMORY;
1931 MultiByteToWideChar(CP_ACP, 0, dst_filename, -1, filename, len);
1933 hr = D3DXSaveTextureToFileInMemory(&buffer, file_format, src_texture, src_palette);
1936 hr = write_buffer_to_file(filename, buffer);
1937 ID3DXBuffer_Release(buffer);
1940 HeapFree(GetProcessHeap(), 0, filename);
1944 HRESULT WINAPI D3DXSaveTextureToFileW(const WCHAR *dst_filename, D3DXIMAGE_FILEFORMAT file_format,
1945 IDirect3DBaseTexture9 *src_texture, const PALETTEENTRY *src_palette)
1948 ID3DXBuffer *buffer;
1950 TRACE("(%s, %#x, %p, %p): relay\n",
1951 wine_dbgstr_w(dst_filename), file_format, src_texture, src_palette);
1953 if (!dst_filename) return D3DERR_INVALIDCALL;
1955 hr = D3DXSaveTextureToFileInMemory(&buffer, file_format, src_texture, src_palette);
1958 hr = write_buffer_to_file(dst_filename, buffer);
1959 ID3DXBuffer_Release(buffer);
1965 HRESULT WINAPI D3DXSaveTextureToFileInMemory(ID3DXBuffer **dst_buffer, D3DXIMAGE_FILEFORMAT file_format,
1966 IDirect3DBaseTexture9 *src_texture, const PALETTEENTRY *src_palette)
1969 D3DRESOURCETYPE type;
1970 IDirect3DSurface9 *surface;
1972 TRACE("(%p, %#x, %p, %p)\n",
1973 dst_buffer, file_format, src_texture, src_palette);
1975 if (!dst_buffer || !src_texture) return D3DERR_INVALIDCALL;
1977 if (file_format == D3DXIFF_DDS)
1979 FIXME("DDS file format isn't supported yet\n");
1983 type = IDirect3DBaseTexture9_GetType(src_texture);
1986 case D3DRTYPE_TEXTURE:
1987 case D3DRTYPE_CUBETEXTURE:
1988 hr = get_surface(type, src_texture, D3DCUBEMAP_FACE_POSITIVE_X, 0, &surface);
1990 case D3DRTYPE_VOLUMETEXTURE:
1991 FIXME("Volume textures aren't supported yet\n");
1994 return D3DERR_INVALIDCALL;
1999 hr = D3DXSaveSurfaceToFileInMemory(dst_buffer, file_format, surface, src_palette, NULL);
2000 IDirect3DSurface9_Release(surface);