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, struct IDirect3DBaseTexture9 *tex,
50 int face, UINT level, struct IDirect3DSurface9 **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(struct IDirect3DDevice9 *device, UINT width, UINT height,
512 UINT miplevels, DWORD usage, D3DFORMAT format, D3DPOOL pool, struct IDirect3DTexture9 **texture)
516 TRACE("device %p, width %u, height %u, miplevels %u, usage %#x, format %#x, pool %#x, texture %p.\n",
517 device, width, height, miplevels, usage, format, pool, texture);
519 if (!device || !texture)
520 return D3DERR_INVALIDCALL;
522 if (FAILED(hr = D3DXCheckTextureRequirements(device, &width, &height, &miplevels, usage, &format, pool)))
525 return IDirect3DDevice9_CreateTexture(device, width, height, miplevels, usage, format, pool, texture, NULL);
528 HRESULT WINAPI D3DXCreateTextureFromFileInMemoryEx(struct IDirect3DDevice9 *device, const void *srcdata,
529 UINT srcdatasize, UINT width, UINT height, UINT miplevels, DWORD usage, D3DFORMAT format,
530 D3DPOOL pool, DWORD filter, DWORD mipfilter, D3DCOLOR colorkey, D3DXIMAGE_INFO *srcinfo,
531 PALETTEENTRY *palette, struct IDirect3DTexture9 **texture)
533 IDirect3DTexture9 **texptr;
534 IDirect3DTexture9 *buftex;
535 IDirect3DSurface9 *surface;
536 BOOL file_width = FALSE, file_height = FALSE;
537 BOOL file_format = FALSE, file_miplevels = FALSE;
538 BOOL dynamic_texture;
539 D3DXIMAGE_INFO imginfo;
540 UINT loaded_miplevels;
544 TRACE("(%p, %p, %u, %u, %u, %u, %x, %x, %x, %u, %u, %x, %p, %p, %p)\n", device, srcdata, srcdatasize, width,
545 height, miplevels, usage, format, pool, filter, mipfilter, colorkey, srcinfo, palette, texture);
547 /* check for invalid parameters */
548 if (!device || !texture || !srcdata || !srcdatasize)
549 return D3DERR_INVALIDCALL;
551 hr = D3DXGetImageInfoFromFileInMemory(srcdata, srcdatasize, &imginfo);
559 /* handle default values */
560 if (width == 0 || width == D3DX_DEFAULT_NONPOW2)
561 width = imginfo.Width;
563 if (height == 0 || height == D3DX_DEFAULT_NONPOW2)
564 height = imginfo.Height;
566 if (width == D3DX_DEFAULT)
567 width = make_pow2(imginfo.Width);
569 if (height == D3DX_DEFAULT)
570 height = make_pow2(imginfo.Height);
572 if (format == D3DFMT_UNKNOWN || format == D3DX_DEFAULT)
573 format = imginfo.Format;
575 if (width == D3DX_FROM_FILE)
578 width = imginfo.Width;
581 if (height == D3DX_FROM_FILE)
584 height = imginfo.Height;
587 if (format == D3DFMT_FROM_FILE)
590 format = imginfo.Format;
593 if (miplevels == D3DX_FROM_FILE)
595 file_miplevels = TRUE;
596 miplevels = imginfo.MipLevels;
599 /* fix texture creation parameters */
600 hr = D3DXCheckTextureRequirements(device, &width, &height, &miplevels, usage, &format, pool);
608 if (imginfo.MipLevels < miplevels && (D3DFMT_DXT1 <= imginfo.Format && imginfo.Format <= D3DFMT_DXT5))
610 FIXME("Generation of mipmaps for compressed pixel formats is not implemented yet\n");
611 miplevels = imginfo.MipLevels;
614 if (((file_width) && (width != imginfo.Width)) ||
615 ((file_height) && (height != imginfo.Height)) ||
616 ((file_format) && (format != imginfo.Format)) ||
617 ((file_miplevels) && (miplevels != imginfo.MipLevels)))
619 return D3DERR_NOTAVAILABLE;
622 if (FAILED(IDirect3DDevice9_GetDeviceCaps(device, &caps)))
623 return D3DERR_INVALIDCALL;
625 /* Create the to-be-filled texture */
626 dynamic_texture = (caps.Caps2 & D3DCAPS2_DYNAMICTEXTURES) && (usage & D3DUSAGE_DYNAMIC);
627 if (pool == D3DPOOL_DEFAULT && !dynamic_texture)
629 hr = D3DXCreateTexture(device, width, height, miplevels, usage, format, D3DPOOL_SYSTEMMEM, &buftex);
634 hr = D3DXCreateTexture(device, width, height, miplevels, usage, format, pool, texture);
645 if (imginfo.ImageFileFormat != D3DXIFF_DDS)
647 IDirect3DTexture9_GetSurfaceLevel(*texptr, 0, &surface);
648 hr = D3DXLoadSurfaceFromFileInMemory(surface, palette, NULL, srcdata, srcdatasize, NULL, filter, colorkey, NULL);
649 IDirect3DSurface9_Release(surface);
653 hr = load_texture_from_dds(*texptr, srcdata, palette, filter, colorkey, &imginfo);
658 IDirect3DTexture9_Release(*texptr);
663 loaded_miplevels = min(IDirect3DTexture9_GetLevelCount(*texptr), imginfo.MipLevels);
664 hr = D3DXFilterTexture((IDirect3DBaseTexture9*) *texptr, palette, loaded_miplevels - 1, mipfilter);
668 IDirect3DTexture9_Release(*texptr);
673 /* Move the data to the actual texture if necessary */
674 if (texptr == &buftex)
676 hr = D3DXCreateTexture(device, width, height, miplevels, usage, format, pool, texture);
680 IDirect3DTexture9_Release(buftex);
685 IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9*)buftex, (IDirect3DBaseTexture9*)(*texture));
686 IDirect3DTexture9_Release(buftex);
695 HRESULT WINAPI D3DXCreateTextureFromFileInMemory(struct IDirect3DDevice9 *device,
696 const void *srcdata, UINT srcdatasize, struct IDirect3DTexture9 **texture)
698 TRACE("(%p, %p, %d, %p)\n", device, srcdata, srcdatasize, texture);
700 return D3DXCreateTextureFromFileInMemoryEx(device, srcdata, srcdatasize, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN,
701 D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, texture);
704 HRESULT WINAPI D3DXCreateTextureFromFileExW(struct IDirect3DDevice9 *device, const WCHAR *srcfile,
705 UINT width, UINT height, UINT miplevels, DWORD usage, D3DFORMAT format,
706 D3DPOOL pool, DWORD filter, DWORD mipfilter, D3DCOLOR colorkey, D3DXIMAGE_INFO *srcinfo,
707 PALETTEENTRY *palette, struct IDirect3DTexture9 **texture)
713 TRACE("(%p, %s, %u, %u, %u, %x, %x, %x, %u, %u, %x, %p, %p, %p): relay\n",
714 device, debugstr_w(srcfile), width, height, miplevels, usage, format, pool, filter,
715 mipfilter, colorkey, srcinfo, palette, texture);
718 return D3DERR_INVALIDCALL;
720 hr = map_view_of_file(srcfile, &buffer, &size);
722 return D3DXERR_INVALIDDATA;
724 hr = D3DXCreateTextureFromFileInMemoryEx(device, buffer, size, width, height, miplevels, usage, format, pool,
725 filter, mipfilter, colorkey, srcinfo, palette, texture);
727 UnmapViewOfFile(buffer);
732 HRESULT WINAPI D3DXCreateTextureFromFileExA(struct IDirect3DDevice9 *device, const char *srcfile,
733 UINT width, UINT height, UINT miplevels, DWORD usage, D3DFORMAT format,
734 D3DPOOL pool, DWORD filter, DWORD mipfilter, D3DCOLOR colorkey, D3DXIMAGE_INFO *srcinfo,
735 PALETTEENTRY *palette, struct IDirect3DTexture9 **texture)
741 TRACE("(%p, %s, %u, %u, %u, %x, %x, %x, %u, %u, %x, %p, %p, %p): relay\n",
742 device, debugstr_a(srcfile), width, height, miplevels, usage, format, pool, filter,
743 mipfilter, colorkey, srcinfo, palette, texture);
745 if (!device || !srcfile || !texture)
746 return D3DERR_INVALIDCALL;
748 len = MultiByteToWideChar(CP_ACP, 0, srcfile, -1, NULL, 0);
749 widename = HeapAlloc(GetProcessHeap(), 0, len * sizeof(*widename));
750 MultiByteToWideChar(CP_ACP, 0, srcfile, -1, widename, len);
752 hr = D3DXCreateTextureFromFileExW(device, widename, width, height, miplevels,
753 usage, format, pool, filter, mipfilter,
754 colorkey, srcinfo, palette, texture);
756 HeapFree(GetProcessHeap(), 0, widename);
760 HRESULT WINAPI D3DXCreateTextureFromFileA(struct IDirect3DDevice9 *device,
761 const char *srcfile, struct IDirect3DTexture9 **texture)
763 TRACE("(%p, %s, %p)\n", device, debugstr_a(srcfile), texture);
765 return D3DXCreateTextureFromFileExA(device, srcfile, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN,
766 D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, texture);
769 HRESULT WINAPI D3DXCreateTextureFromFileW(struct IDirect3DDevice9 *device,
770 const WCHAR *srcfile, struct IDirect3DTexture9 **texture)
772 TRACE("(%p, %s, %p)\n", device, debugstr_w(srcfile), texture);
774 return D3DXCreateTextureFromFileExW(device, srcfile, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN,
775 D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, texture);
779 HRESULT WINAPI D3DXCreateTextureFromResourceA(struct IDirect3DDevice9 *device,
780 HMODULE srcmodule, const char *resource, struct IDirect3DTexture9 **texture)
782 TRACE("(%p, %s): relay\n", srcmodule, debugstr_a(resource));
784 return D3DXCreateTextureFromResourceExA(device, srcmodule, resource, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN,
785 D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, texture);
788 HRESULT WINAPI D3DXCreateTextureFromResourceW(struct IDirect3DDevice9 *device,
789 HMODULE srcmodule, const WCHAR *resource, struct IDirect3DTexture9 **texture)
791 TRACE("(%p, %s): relay\n", srcmodule, debugstr_w(resource));
793 return D3DXCreateTextureFromResourceExW(device, srcmodule, resource, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN,
794 D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, texture);
797 HRESULT WINAPI D3DXCreateTextureFromResourceExA(struct IDirect3DDevice9 *device, HMODULE srcmodule,
798 const char *resource, UINT width, UINT height, UINT miplevels, DWORD usage, D3DFORMAT format,
799 D3DPOOL pool, DWORD filter, DWORD mipfilter, D3DCOLOR colorkey, D3DXIMAGE_INFO *srcinfo,
800 PALETTEENTRY *palette, struct IDirect3DTexture9 **texture)
804 TRACE("(%p, %s): relay\n", srcmodule, debugstr_a(resource));
806 if (!device || !texture)
807 return D3DERR_INVALIDCALL;
809 resinfo = FindResourceA(srcmodule, resource, (LPCSTR) RT_RCDATA);
817 hr = load_resource_into_memory(srcmodule, resinfo, &buffer, &size);
820 return D3DXERR_INVALIDDATA;
822 return D3DXCreateTextureFromFileInMemoryEx(device, buffer, size, width,
823 height, miplevels, usage, format,
824 pool, filter, mipfilter, colorkey,
825 srcinfo, palette, texture);
828 /* Try loading the resource as bitmap data */
829 resinfo = FindResourceA(srcmodule, resource, (LPCSTR) RT_BITMAP);
833 FIXME("Implement loading bitmaps from resource type RT_BITMAP\n");
837 return D3DXERR_INVALIDDATA;
840 HRESULT WINAPI D3DXCreateTextureFromResourceExW(struct IDirect3DDevice9 *device, HMODULE srcmodule,
841 const WCHAR *resource, UINT width, UINT height, UINT miplevels, DWORD usage, D3DFORMAT format,
842 D3DPOOL pool, DWORD filter, DWORD mipfilter, D3DCOLOR colorkey, D3DXIMAGE_INFO *srcinfo,
843 PALETTEENTRY *palette, struct IDirect3DTexture9 **texture)
847 TRACE("(%p, %s): relay\n", srcmodule, debugstr_w(resource));
849 if (!device || !texture)
850 return D3DERR_INVALIDCALL;
852 resinfo = FindResourceW(srcmodule, resource, (LPCWSTR) RT_RCDATA);
860 hr = load_resource_into_memory(srcmodule, resinfo, &buffer, &size);
863 return D3DXERR_INVALIDDATA;
865 return D3DXCreateTextureFromFileInMemoryEx(device, buffer, size, width,
866 height, miplevels, usage, format,
867 pool, filter, mipfilter, colorkey,
868 srcinfo, palette, texture);
871 /* Try loading the resource as bitmap data */
872 resinfo = FindResourceW(srcmodule, resource, (LPCWSTR) RT_BITMAP);
876 FIXME("Implement loading bitmaps from resource type RT_BITMAP\n");
880 return D3DXERR_INVALIDDATA;
883 HRESULT WINAPI D3DXCreateCubeTexture(struct IDirect3DDevice9 *device, UINT size, UINT miplevels,
884 DWORD usage, D3DFORMAT format, D3DPOOL pool, struct IDirect3DCubeTexture9 **texture)
888 TRACE("(%p, %u, %u, %#x, %#x, %#x, %p)\n", device, size, miplevels, usage, format,
891 if (!device || !texture)
892 return D3DERR_INVALIDCALL;
894 hr = D3DXCheckCubeTextureRequirements(device, &size, &miplevels, usage, &format, pool);
898 TRACE("D3DXCheckCubeTextureRequirements failed\n");
902 return IDirect3DDevice9_CreateCubeTexture(device, size, miplevels, usage, format, pool, texture, NULL);
905 HRESULT WINAPI D3DXCreateCubeTextureFromFileInMemory(struct IDirect3DDevice9 *device,
906 const void *data, UINT datasize, struct IDirect3DCubeTexture9 **texture)
908 TRACE("(%p, %p, %u, %p)\n", device, data, datasize, texture);
910 return D3DXCreateCubeTextureFromFileInMemoryEx(device, data, datasize, D3DX_DEFAULT, D3DX_DEFAULT,
911 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, texture);
914 HRESULT WINAPI D3DXCreateVolumeTexture(struct IDirect3DDevice9 *device, UINT width, UINT height, UINT depth,
915 UINT miplevels, DWORD usage, D3DFORMAT format, D3DPOOL pool, struct IDirect3DVolumeTexture9 **texture)
919 TRACE("(%p, %u, %u, %u, %u, %#x, %#x, %#x, %p)\n", device, width, height, depth,
920 miplevels, usage, format, pool, texture);
922 if (!device || !texture)
923 return D3DERR_INVALIDCALL;
925 hr = D3DXCheckVolumeTextureRequirements(device, &width, &height, &depth,
926 &miplevels, usage, &format, pool);
930 TRACE("D3DXCheckVolumeTextureRequirements failed\n");
934 return IDirect3DDevice9_CreateVolumeTexture(device, width, height, depth, miplevels,
935 usage, format, pool, texture, NULL);
938 HRESULT WINAPI D3DXCreateVolumeTextureFromFileA(IDirect3DDevice9 *device,
939 const char *filename,
940 IDirect3DVolumeTexture9 **volume_texture)
948 TRACE("(%p, %s, %p): relay\n",
949 device, debugstr_a(filename), volume_texture);
951 if (!filename) return D3DERR_INVALIDCALL;
953 len = MultiByteToWideChar(CP_ACP, 0, filename, -1, NULL, 0);
954 filenameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
955 if (!filenameW) return E_OUTOFMEMORY;
956 MultiByteToWideChar(CP_ACP, 0, filename, -1, filenameW, len);
958 hr = map_view_of_file(filenameW, &data, &data_size);
959 HeapFree(GetProcessHeap(), 0, filenameW);
960 if (FAILED(hr)) return D3DXERR_INVALIDDATA;
962 hr = D3DXCreateVolumeTextureFromFileInMemoryEx(device, data, data_size, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT,
963 D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, volume_texture);
965 UnmapViewOfFile(data);
969 HRESULT WINAPI D3DXCreateVolumeTextureFromFileW(IDirect3DDevice9 *device,
970 const WCHAR *filename,
971 IDirect3DVolumeTexture9 **volume_texture)
977 TRACE("(%p, %s, %p): relay\n",
978 device, debugstr_w(filename), volume_texture);
980 if (!filename) return D3DERR_INVALIDCALL;
982 hr = map_view_of_file(filename, &data, &data_size);
983 if (FAILED(hr)) return D3DXERR_INVALIDDATA;
985 hr = D3DXCreateVolumeTextureFromFileInMemoryEx(device, data, data_size, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT,
986 D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, volume_texture);
988 UnmapViewOfFile(data);
992 HRESULT WINAPI D3DXCreateVolumeTextureFromFileExA(IDirect3DDevice9 *device,
993 const char *filename,
1004 D3DXIMAGE_INFO *src_info,
1005 PALETTEENTRY *palette,
1006 IDirect3DVolumeTexture9 **volume_texture)
1014 TRACE("(%p, %s, %u, %u, %u, %u, %#x, %#x, %#x, %#x, %#x, %#x, %p, %p, %p): relay\n",
1015 device, debugstr_a(filename), width, height, depth, mip_levels,
1016 usage, format, pool, filter, mip_filter, color_key, src_info,
1017 palette, volume_texture);
1019 if (!filename) return D3DERR_INVALIDCALL;
1021 len = MultiByteToWideChar(CP_ACP, 0, filename, -1, NULL, 0);
1022 filenameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
1023 if (!filenameW) return E_OUTOFMEMORY;
1024 MultiByteToWideChar(CP_ACP, 0, filename, -1, filenameW, len);
1026 hr = map_view_of_file(filenameW, &data, &data_size);
1027 HeapFree(GetProcessHeap(), 0, filenameW);
1028 if (FAILED(hr)) return D3DXERR_INVALIDDATA;
1030 hr = D3DXCreateVolumeTextureFromFileInMemoryEx(device, data, data_size, width, height, depth,
1031 mip_levels, usage, format, pool, filter, mip_filter, color_key, src_info, palette,
1034 UnmapViewOfFile(data);
1038 HRESULT WINAPI D3DXCreateVolumeTextureFromFileExW(IDirect3DDevice9 *device,
1039 const WCHAR *filename,
1050 D3DXIMAGE_INFO *src_info,
1051 PALETTEENTRY *palette,
1052 IDirect3DVolumeTexture9 **volume_texture)
1058 TRACE("(%p, %s, %u, %u, %u, %u, %#x, %#x, %#x, %#x, %#x, %#x, %p, %p, %p): relay\n",
1059 device, debugstr_w(filename), width, height, depth, mip_levels,
1060 usage, format, pool, filter, mip_filter, color_key, src_info,
1061 palette, 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, width, height, depth,
1069 mip_levels, usage, format, pool, filter, mip_filter, color_key, src_info, palette,
1072 UnmapViewOfFile(data);
1076 HRESULT WINAPI D3DXCreateVolumeTextureFromFileInMemory(IDirect3DDevice9 *device,
1079 IDirect3DVolumeTexture9 **volume_texture)
1081 TRACE("(%p, %p, %u, %p): relay\n", device, data, data_size, volume_texture);
1083 return D3DXCreateVolumeTextureFromFileInMemoryEx(device, data, data_size, D3DX_DEFAULT, D3DX_DEFAULT,
1084 D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT,
1085 0, NULL, NULL, volume_texture);
1088 HRESULT WINAPI D3DXCreateVolumeTextureFromFileInMemoryEx(IDirect3DDevice9 *device,
1101 D3DXIMAGE_INFO *info,
1102 PALETTEENTRY *palette,
1103 IDirect3DVolumeTexture9 **volume_texture)
1107 D3DXIMAGE_INFO image_info;
1108 BOOL dynamic_texture;
1109 BOOL file_width = FALSE;
1110 BOOL file_height = FALSE;
1111 BOOL file_depth = FALSE;
1112 BOOL file_format = FALSE;
1113 BOOL file_mip_levels = FALSE;
1114 IDirect3DVolumeTexture9 *tex, *buftex;
1116 TRACE("(%p, %p, %u, %u, %u, %u, %u, %#x, %#x, %#x, %#x, %#x, %#x, %p, %p, %p)\n",
1117 device, data, data_size, width, height, depth, mip_levels, usage, format, pool,
1118 filter, mip_filter, color_key, info, palette, volume_texture);
1120 if (!device || !data || !data_size || !volume_texture)
1121 return D3DERR_INVALIDCALL;
1123 hr = D3DXGetImageInfoFromFileInMemory(data, data_size, &image_info);
1124 if (FAILED(hr)) return hr;
1126 if (image_info.ImageFileFormat != D3DXIFF_DDS)
1127 return D3DXERR_INVALIDDATA;
1129 if (width == 0 || width == D3DX_DEFAULT_NONPOW2)
1130 width = image_info.Width;
1131 if (width == D3DX_DEFAULT)
1132 width = make_pow2(image_info.Width);
1134 if (height == 0 || height == D3DX_DEFAULT_NONPOW2)
1135 height = image_info.Height;
1136 if (height == D3DX_DEFAULT)
1137 height = make_pow2(image_info.Height);
1139 if (depth == 0 || depth == D3DX_DEFAULT_NONPOW2)
1140 depth = image_info.Depth;
1141 if (depth == D3DX_DEFAULT)
1142 depth = make_pow2(image_info.Depth);
1144 if (format == D3DFMT_UNKNOWN || format == D3DX_DEFAULT)
1145 format = image_info.Format;
1147 if (width == D3DX_FROM_FILE)
1150 width = image_info.Width;
1153 if (height == D3DX_FROM_FILE)
1156 height = image_info.Height;
1159 if (depth == D3DX_FROM_FILE)
1162 depth = image_info.Depth;
1165 if (format == D3DFMT_FROM_FILE)
1168 format = image_info.Format;
1171 if (mip_levels == D3DX_FROM_FILE)
1173 file_mip_levels = TRUE;
1174 mip_levels = image_info.MipLevels;
1177 hr = D3DXCheckVolumeTextureRequirements(device, &width, &height, &depth, &mip_levels, usage, &format, pool);
1178 if (FAILED(hr)) return hr;
1180 if ((file_width && width != image_info.Width)
1181 || (file_height && height != image_info.Height)
1182 || (file_depth && depth != image_info.Depth)
1183 || (file_format && format != image_info.Format)
1184 || (file_mip_levels && mip_levels != image_info.MipLevels))
1185 return D3DERR_NOTAVAILABLE;
1187 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1189 return D3DERR_INVALIDCALL;
1191 if (mip_levels > image_info.MipLevels)
1193 FIXME("Generation of mipmaps for volume textures is not implemented yet\n");
1194 mip_levels = image_info.MipLevels;
1197 dynamic_texture = (caps.Caps2 & D3DCAPS2_DYNAMICTEXTURES) && (usage & D3DUSAGE_DYNAMIC);
1198 if (pool == D3DPOOL_DEFAULT && !dynamic_texture)
1200 hr = D3DXCreateVolumeTexture(device, width, height, depth, mip_levels, usage, format, D3DPOOL_SYSTEMMEM, &buftex);
1205 hr = D3DXCreateVolumeTexture(device, width, height, depth, mip_levels, usage, format, pool, &tex);
1209 if (FAILED(hr)) return hr;
1211 hr = load_volume_texture_from_dds(tex, data, palette, filter, color_key, &image_info);
1214 IDirect3DVolumeTexture9_Release(tex);
1220 hr = D3DXCreateVolumeTexture(device, width, height, depth, mip_levels, usage, format, pool, &tex);
1223 IDirect3DVolumeTexture9_Release(buftex);
1227 IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)buftex, (IDirect3DBaseTexture9 *)tex);
1228 IDirect3DVolumeTexture9_Release(buftex);
1234 *volume_texture = tex;
1238 HRESULT WINAPI D3DXFillTexture(struct IDirect3DTexture9 *texture, LPD3DXFILL2D function, void *funcdata)
1241 DWORD m, i, x, y, c, v;
1242 D3DSURFACE_DESC desc;
1243 D3DLOCKED_RECT lock_rect;
1245 D3DXVECTOR2 coord, size;
1246 const struct pixel_format_desc *format;
1251 if (texture == NULL || function == NULL)
1252 return D3DERR_INVALIDCALL;
1254 miplevels = IDirect3DBaseTexture9_GetLevelCount(texture);
1256 for (m = 0; m < miplevels; m++)
1258 if (FAILED(IDirect3DTexture9_GetLevelDesc(texture, m, &desc)))
1259 return D3DERR_INVALIDCALL;
1261 format = get_format_info(desc.Format);
1262 if (format->type != FORMAT_ARGB)
1264 FIXME("Unsupported texture format %#x\n", desc.Format);
1265 return D3DERR_INVALIDCALL;
1268 if (FAILED(IDirect3DTexture9_LockRect(texture, m, &lock_rect, NULL, D3DLOCK_DISCARD)))
1269 return D3DERR_INVALIDCALL;
1271 size.x = 1.0f / desc.Width;
1272 size.y = 1.0f / desc.Height;
1274 data = lock_rect.pBits;
1276 for (y = 0; y < desc.Height; y++)
1278 /* The callback function expects the coordinates of the center
1280 coord.y = (y + 0.5f) / desc.Height;
1282 for (x = 0; x < desc.Width; x++)
1284 coord.x = (x + 0.5f) / desc.Width;
1286 function(&value, &coord, &size, funcdata);
1288 pos = data + y * lock_rect.Pitch + x * format->bytes_per_pixel;
1290 for (i = 0; i < format->bytes_per_pixel; i++)
1293 for (c = 0; c < 4; c++)
1298 comp_value = value.w;
1301 comp_value = value.x;
1304 comp_value = value.y;
1307 comp_value = value.z;
1311 v = comp_value * ((1 << format->bits[c]) - 1) + 0.5f;
1313 for (i = 0; i < format->bits[c] + format->shift[c]; i += 8)
1315 mask = ((1 << format->bits[c]) - 1) << format->shift[c] >> i;
1316 byte = (v << format->shift[c] >> i) & mask;
1322 IDirect3DTexture9_UnlockRect(texture, m);
1328 HRESULT WINAPI D3DXCreateCubeTextureFromFileInMemoryEx(IDirect3DDevice9 *device,
1329 const void *src_data,
1339 D3DXIMAGE_INFO *src_info,
1340 PALETTEENTRY *palette,
1341 IDirect3DCubeTexture9 **cube_texture)
1345 UINT loaded_miplevels;
1346 D3DXIMAGE_INFO img_info;
1347 BOOL dynamic_texture;
1348 BOOL file_size = FALSE;
1349 BOOL file_format = FALSE;
1350 BOOL file_mip_levels = FALSE;
1351 IDirect3DCubeTexture9 *tex, *buftex;
1353 TRACE("(%p, %p, %u, %u, %u, %#x, %#x, %#x, %#x, %#x, %#x, %p, %p, %p)\n", device,
1354 src_data, src_data_size, size, mip_levels, usage, format, pool, filter, mip_filter,
1355 color_key, src_info, palette, cube_texture);
1357 if (!device || !cube_texture || !src_data || !src_data_size)
1358 return D3DERR_INVALIDCALL;
1360 hr = D3DXGetImageInfoFromFileInMemory(src_data, src_data_size, &img_info);
1364 if (img_info.ImageFileFormat != D3DXIFF_DDS)
1365 return D3DXERR_INVALIDDATA;
1367 if (img_info.Width != img_info.Height)
1368 return D3DXERR_INVALIDDATA;
1370 if (size == 0 || size == D3DX_DEFAULT_NONPOW2)
1371 size = img_info.Width;
1372 if (size == D3DX_DEFAULT)
1373 size = make_pow2(img_info.Width);
1375 if (format == D3DFMT_UNKNOWN || format == D3DX_DEFAULT)
1376 format = img_info.Format;
1378 if (size == D3DX_FROM_FILE)
1381 size = img_info.Width;
1384 if (format == D3DFMT_FROM_FILE)
1387 format = img_info.Format;
1390 if (mip_levels == D3DX_FROM_FILE)
1392 file_mip_levels = TRUE;
1393 mip_levels = img_info.MipLevels;
1396 hr = D3DXCheckCubeTextureRequirements(device, &size, &mip_levels, usage, &format, pool);
1400 if ((file_size && size != img_info.Width)
1401 || (file_format && format != img_info.Format)
1402 || (file_mip_levels && mip_levels != img_info.MipLevels))
1403 return D3DERR_NOTAVAILABLE;
1405 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1407 return D3DERR_INVALIDCALL;
1409 if (mip_levels > img_info.MipLevels && (D3DFMT_DXT1 <= img_info.Format && img_info.Format <= D3DFMT_DXT5))
1411 FIXME("Generation of mipmaps for compressed pixel formats not supported yet\n");
1412 mip_levels = img_info.MipLevels;
1415 dynamic_texture = (caps.Caps2 & D3DCAPS2_DYNAMICTEXTURES) && (usage & D3DUSAGE_DYNAMIC);
1416 if (pool == D3DPOOL_DEFAULT && !dynamic_texture)
1418 hr = D3DXCreateCubeTexture(device, size, mip_levels, usage, format, D3DPOOL_SYSTEMMEM, &buftex);
1423 hr = D3DXCreateCubeTexture(device, size, mip_levels, usage, format, pool, &tex);
1429 hr = load_cube_texture_from_dds(tex, src_data, palette, filter, color_key, &img_info);
1432 IDirect3DCubeTexture9_Release(tex);
1436 loaded_miplevels = min(IDirect3DCubeTexture9_GetLevelCount(tex), img_info.MipLevels);
1437 hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, palette, loaded_miplevels - 1, mip_filter);
1440 IDirect3DCubeTexture9_Release(tex);
1446 hr = D3DXCreateCubeTexture(device, size, mip_levels, usage, format, pool, &tex);
1449 IDirect3DCubeTexture9_Release(buftex);
1453 IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)buftex, (IDirect3DBaseTexture9 *)tex);
1454 IDirect3DCubeTexture9_Release(buftex);
1458 *src_info = img_info;
1460 *cube_texture = tex;
1465 HRESULT WINAPI D3DXCreateCubeTextureFromFileA(IDirect3DDevice9 *device,
1466 const char *src_filename,
1467 IDirect3DCubeTexture9 **cube_texture)
1475 TRACE("(%p, %s, %p): relay\n", device, wine_dbgstr_a(src_filename), cube_texture);
1477 if (!src_filename) return D3DERR_INVALIDCALL;
1479 len = MultiByteToWideChar(CP_ACP, 0, src_filename, -1, NULL, 0);
1480 filename = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
1481 if (!filename) return E_OUTOFMEMORY;
1482 MultiByteToWideChar(CP_ACP, 0, src_filename, -1, filename, len);
1484 hr = map_view_of_file(filename, &data, &data_size);
1487 HeapFree(GetProcessHeap(), 0, filename);
1488 return D3DXERR_INVALIDDATA;
1491 hr = D3DXCreateCubeTextureFromFileInMemoryEx(device, data, data_size, D3DX_DEFAULT, D3DX_DEFAULT,
1492 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, cube_texture);
1494 UnmapViewOfFile(data);
1495 HeapFree(GetProcessHeap(), 0, filename);
1499 HRESULT WINAPI D3DXCreateCubeTextureFromFileW(IDirect3DDevice9 *device,
1500 const WCHAR *src_filename,
1501 IDirect3DCubeTexture9 **cube_texture)
1507 TRACE("(%p, %s, %p): relay\n", device, wine_dbgstr_w(src_filename), cube_texture);
1509 hr = map_view_of_file(src_filename, &data, &data_size);
1510 if (FAILED(hr)) return D3DXERR_INVALIDDATA;
1512 hr = D3DXCreateCubeTextureFromFileInMemoryEx(device, data, data_size, D3DX_DEFAULT, D3DX_DEFAULT,
1513 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, cube_texture);
1515 UnmapViewOfFile(data);
1519 HRESULT WINAPI D3DXCreateCubeTextureFromFileExA(IDirect3DDevice9 *device,
1520 const char *src_filename,
1529 D3DXIMAGE_INFO *image_info,
1530 PALETTEENTRY *palette,
1531 IDirect3DCubeTexture9 **cube_texture)
1539 TRACE("(%p, %s, %u, %u, %#x, %#x, %#x, %#x, %#x, %#x, %p, %p, %p): relay\n",
1540 device, wine_dbgstr_a(src_filename), size, mip_levels, usage, format,
1541 pool, filter, mip_filter, color_key, image_info, palette, cube_texture);
1543 if (!src_filename) return D3DERR_INVALIDCALL;
1545 len = MultiByteToWideChar(CP_ACP, 0, src_filename, -1, NULL, 0);
1546 filename = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
1547 if (!filename) return E_OUTOFMEMORY;
1548 MultiByteToWideChar(CP_ACP, 0, src_filename, -1, filename, len);
1550 hr = map_view_of_file(filename, &data, &data_size);
1553 HeapFree(GetProcessHeap(), 0, filename);
1554 return D3DXERR_INVALIDDATA;
1557 hr = D3DXCreateCubeTextureFromFileInMemoryEx(device, data, data_size, size, mip_levels,
1558 usage, format, pool, filter, mip_filter, color_key, image_info, palette, cube_texture);
1560 UnmapViewOfFile(data);
1561 HeapFree(GetProcessHeap(), 0, filename);
1565 HRESULT WINAPI D3DXCreateCubeTextureFromFileExW(IDirect3DDevice9 *device,
1566 const WCHAR *src_filename,
1575 D3DXIMAGE_INFO *image_info,
1576 PALETTEENTRY *palette,
1577 IDirect3DCubeTexture9 **cube_texture)
1583 TRACE("(%p, %s, %u, %u, %#x, %#x, %#x, %#x, %#x, %#x, %p, %p, %p): relay\n",
1584 device, wine_dbgstr_w(src_filename), size, mip_levels, usage, format,
1585 pool, filter, mip_filter, color_key, image_info, palette, cube_texture);
1587 hr = map_view_of_file(src_filename, &data, &data_size);
1588 if (FAILED(hr)) return D3DXERR_INVALIDDATA;
1590 hr = D3DXCreateCubeTextureFromFileInMemoryEx(device, data, data_size, size, mip_levels,
1591 usage, format, pool, filter, mip_filter, color_key, image_info, palette, cube_texture);
1593 UnmapViewOfFile(data);
1607 static float get_cube_coord(enum cube_coord coord, unsigned int x, unsigned int y, unsigned int size)
1614 return size - x - 0.5f;
1618 return size - y - 0.5f;
1624 ERR("Unexpected coordinate value\n");
1629 HRESULT WINAPI D3DXFillCubeTexture(struct IDirect3DCubeTexture9 *texture, LPD3DXFILL3D function, void *funcdata)
1632 DWORD m, i, x, y, c, f, v;
1633 D3DSURFACE_DESC desc;
1634 D3DLOCKED_RECT lock_rect;
1636 D3DXVECTOR3 coord, size;
1637 const struct pixel_format_desc *format;
1641 static const enum cube_coord coordmap[6][3] =
1643 {ONE, YCOORDINV, XCOORDINV},
1644 {ZERO, YCOORDINV, XCOORD},
1645 {XCOORD, ONE, YCOORD},
1646 {XCOORD, ZERO, YCOORDINV},
1647 {XCOORD, YCOORDINV, ONE},
1648 {XCOORDINV, YCOORDINV, ZERO}
1651 if (texture == NULL || function == NULL)
1652 return D3DERR_INVALIDCALL;
1654 miplevels = IDirect3DBaseTexture9_GetLevelCount(texture);
1656 for (m = 0; m < miplevels; m++)
1658 if (FAILED(IDirect3DCubeTexture9_GetLevelDesc(texture, m, &desc)))
1659 return D3DERR_INVALIDCALL;
1661 format = get_format_info(desc.Format);
1662 if (format->type != FORMAT_ARGB)
1664 FIXME("Unsupported texture format %#x\n", desc.Format);
1665 return D3DERR_INVALIDCALL;
1668 for (f = 0; f < 6; f++)
1670 if (FAILED(IDirect3DCubeTexture9_LockRect(texture, f, m, &lock_rect, NULL, D3DLOCK_DISCARD)))
1671 return D3DERR_INVALIDCALL;
1673 size.x = (f == 0) || (f == 1) ? 0.0f : 2.0f / desc.Width;
1674 size.y = (f == 2) || (f == 3) ? 0.0f : 2.0f / desc.Width;
1675 size.z = (f == 4) || (f == 5) ? 0.0f : 2.0f / desc.Width;
1677 data = lock_rect.pBits;
1679 for (y = 0; y < desc.Height; y++)
1681 for (x = 0; x < desc.Width; x++)
1683 coord.x = get_cube_coord(coordmap[f][0], x, y, desc.Width) / desc.Width * 2.0f - 1.0f;
1684 coord.y = get_cube_coord(coordmap[f][1], x, y, desc.Width) / desc.Width * 2.0f - 1.0f;
1685 coord.z = get_cube_coord(coordmap[f][2], x, y, desc.Width) / desc.Width * 2.0f - 1.0f;
1687 function(&value, &coord, &size, funcdata);
1689 pos = data + y * lock_rect.Pitch + x * format->bytes_per_pixel;
1691 for (i = 0; i < format->bytes_per_pixel; i++)
1694 for (c = 0; c < 4; c++)
1699 comp_value = value.w;
1702 comp_value = value.x;
1705 comp_value = value.y;
1708 comp_value = value.z;
1712 v = comp_value * ((1 << format->bits[c]) - 1) + 0.5f;
1714 for (i = 0; i < format->bits[c] + format->shift[c]; i += 8)
1716 mask = ((1 << format->bits[c]) - 1) << format->shift[c] >> i;
1717 byte = (v << format->shift[c] >> i) & mask;
1723 IDirect3DCubeTexture9_UnlockRect(texture, f, m);
1730 HRESULT WINAPI D3DXFillVolumeTexture(struct IDirect3DVolumeTexture9 *texture, LPD3DXFILL3D function, void *funcdata)
1733 DWORD m, i, x, y, z, c, v;
1734 D3DVOLUME_DESC desc;
1735 D3DLOCKED_BOX lock_box;
1737 D3DXVECTOR3 coord, size;
1738 const struct pixel_format_desc *format;
1743 if (texture == NULL || function == NULL)
1744 return D3DERR_INVALIDCALL;
1746 miplevels = IDirect3DBaseTexture9_GetLevelCount(texture);
1748 for (m = 0; m < miplevels; m++)
1750 if (FAILED(IDirect3DVolumeTexture9_GetLevelDesc(texture, m, &desc)))
1751 return D3DERR_INVALIDCALL;
1753 format = get_format_info(desc.Format);
1754 if (format->type != FORMAT_ARGB)
1756 FIXME("Unsupported texture format %#x\n", desc.Format);
1757 return D3DERR_INVALIDCALL;
1760 if (FAILED(IDirect3DVolumeTexture9_LockBox(texture, m, &lock_box, NULL, D3DLOCK_DISCARD)))
1761 return D3DERR_INVALIDCALL;
1763 size.x = 1.0f / desc.Width;
1764 size.y = 1.0f / desc.Height;
1765 size.z = 1.0f / desc.Depth;
1767 data = lock_box.pBits;
1769 for (z = 0; z < desc.Depth; z++)
1771 /* The callback function expects the coordinates of the center
1773 coord.z = (z + 0.5f) / desc.Depth;
1775 for (y = 0; y < desc.Height; y++)
1777 coord.y = (y + 0.5f) / desc.Height;
1779 for (x = 0; x < desc.Width; x++)
1781 coord.x = (x + 0.5f) / desc.Width;
1783 function(&value, &coord, &size, funcdata);
1785 pos = data + z * lock_box.SlicePitch + y * lock_box.RowPitch + x * format->bytes_per_pixel;
1787 for (i = 0; i < format->bytes_per_pixel; i++)
1790 for (c = 0; c < 4; c++)
1795 comp_value = value.w;
1798 comp_value = value.x;
1801 comp_value = value.y;
1804 comp_value = value.z;
1808 v = comp_value * ((1 << format->bits[c]) - 1) + 0.5f;
1810 for (i = 0; i < format->bits[c] + format->shift[c]; i += 8)
1812 mask = ((1 << format->bits[c]) - 1) << format->shift[c] >> i;
1813 byte = (v << format->shift[c] >> i) & mask;
1820 IDirect3DVolumeTexture9_UnlockBox(texture, m);
1826 HRESULT WINAPI D3DXSaveTextureToFileA(const char *dst_filename, D3DXIMAGE_FILEFORMAT file_format,
1827 IDirect3DBaseTexture9 *src_texture, const PALETTEENTRY *src_palette)
1832 ID3DXBuffer *buffer;
1834 TRACE("(%s, %#x, %p, %p): relay\n",
1835 wine_dbgstr_a(dst_filename), file_format, src_texture, src_palette);
1837 if (!dst_filename) return D3DERR_INVALIDCALL;
1839 len = MultiByteToWideChar(CP_ACP, 0, dst_filename, -1, NULL, 0);
1840 filename = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
1841 if (!filename) return E_OUTOFMEMORY;
1842 MultiByteToWideChar(CP_ACP, 0, dst_filename, -1, filename, len);
1844 hr = D3DXSaveTextureToFileInMemory(&buffer, file_format, src_texture, src_palette);
1847 hr = write_buffer_to_file(filename, buffer);
1848 ID3DXBuffer_Release(buffer);
1851 HeapFree(GetProcessHeap(), 0, filename);
1855 HRESULT WINAPI D3DXSaveTextureToFileW(const WCHAR *dst_filename, D3DXIMAGE_FILEFORMAT file_format,
1856 IDirect3DBaseTexture9 *src_texture, const PALETTEENTRY *src_palette)
1859 ID3DXBuffer *buffer;
1861 TRACE("(%s, %#x, %p, %p): relay\n",
1862 wine_dbgstr_w(dst_filename), file_format, src_texture, src_palette);
1864 if (!dst_filename) return D3DERR_INVALIDCALL;
1866 hr = D3DXSaveTextureToFileInMemory(&buffer, file_format, src_texture, src_palette);
1869 hr = write_buffer_to_file(dst_filename, buffer);
1870 ID3DXBuffer_Release(buffer);
1876 HRESULT WINAPI D3DXSaveTextureToFileInMemory(ID3DXBuffer **dst_buffer, D3DXIMAGE_FILEFORMAT file_format,
1877 IDirect3DBaseTexture9 *src_texture, const PALETTEENTRY *src_palette)
1880 D3DRESOURCETYPE type;
1881 IDirect3DSurface9 *surface;
1883 TRACE("(%p, %#x, %p, %p)\n",
1884 dst_buffer, file_format, src_texture, src_palette);
1886 if (!dst_buffer || !src_texture) return D3DERR_INVALIDCALL;
1888 if (file_format == D3DXIFF_DDS)
1890 FIXME("DDS file format isn't supported yet\n");
1894 type = IDirect3DBaseTexture9_GetType(src_texture);
1897 case D3DRTYPE_TEXTURE:
1898 case D3DRTYPE_CUBETEXTURE:
1899 hr = get_surface(type, src_texture, D3DCUBEMAP_FACE_POSITIVE_X, 0, &surface);
1901 case D3DRTYPE_VOLUMETEXTURE:
1902 FIXME("Volume textures aren't supported yet\n");
1905 return D3DERR_INVALIDCALL;
1910 hr = D3DXSaveSurfaceToFileInMemory(dst_buffer, file_format, surface, src_palette, NULL);
1911 IDirect3DSurface9_Release(surface);