wbemprox: Win32_NetworkAdapter.InterfaceIndex is unsigned.
[wine/multimedia.git] / dlls / d3dx9_36 / texture.c
blob1e87a00d05c317329309a41ce68f110bc99c6001
1 /*
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)
37 UINT result = 1;
39 /* In the unlikely event somebody passes a large value, make sure we don't enter an infinite loop */
40 if (num >= 0x80000000)
41 return 0x80000000;
43 while (result < num)
44 result <<= 1;
46 return result;
49 static HRESULT get_surface(D3DRESOURCETYPE type, LPDIRECT3DBASETEXTURE9 tex,
50 int face, UINT level, LPDIRECT3DSURFACE9 *surf)
52 switch (type)
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);
58 default:
59 ERR("Unexpected texture type\n");
60 return E_NOTIMPL;
64 HRESULT WINAPI D3DXFilterTexture(LPDIRECT3DBASETEXTURE9 texture,
65 CONST PALETTEENTRY *palette,
66 UINT srclevel,
67 DWORD filter)
69 UINT level;
70 HRESULT hr;
71 D3DRESOURCETYPE type;
73 TRACE("(%p, %p, %d, %d)\n", texture, palette, srclevel, filter);
75 if (!texture)
76 return D3DERR_INVALIDCALL;
78 if ((filter & 0xFFFF) > D3DX_FILTER_BOX && filter != D3DX_DEFAULT)
79 return D3DERR_INVALIDCALL;
81 if (srclevel >= IDirect3DBaseTexture9_GetLevelCount(texture))
82 return D3DERR_INVALIDCALL;
84 switch (type = IDirect3DBaseTexture9_GetType(texture))
86 case D3DRTYPE_TEXTURE:
87 case D3DRTYPE_CUBETEXTURE:
89 IDirect3DSurface9 *topsurf, *mipsurf;
90 D3DSURFACE_DESC desc;
91 int i, numfaces;
93 if (type == D3DRTYPE_TEXTURE)
95 numfaces = 1;
96 IDirect3DTexture9_GetLevelDesc((IDirect3DTexture9*) texture, srclevel, &desc);
98 else
100 numfaces = 6;
101 IDirect3DCubeTexture9_GetLevelDesc((IDirect3DTexture9*) texture, srclevel, &desc);
104 if (filter == D3DX_DEFAULT)
106 if (is_pow2(desc.Width) && is_pow2(desc.Height))
107 filter = D3DX_FILTER_BOX;
108 else
109 filter = D3DX_FILTER_BOX | D3DX_FILTER_DITHER;
112 for (i = 0; i < numfaces; i++)
114 level = srclevel + 1;
115 hr = get_surface(type, texture, i, srclevel, &topsurf);
117 if (FAILED(hr))
118 return D3DERR_INVALIDCALL;
120 while (get_surface(type, texture, i, level, &mipsurf) == D3D_OK)
122 hr = D3DXLoadSurfaceFromSurface(mipsurf, palette, NULL, topsurf, palette, NULL, filter, 0);
123 IDirect3DSurface9_Release(topsurf);
124 topsurf = mipsurf;
126 if (FAILED(hr))
127 break;
129 level++;
132 IDirect3DSurface9_Release(topsurf);
133 if (FAILED(hr))
134 return hr;
137 return D3D_OK;
140 default:
141 FIXME("Implement volume texture filtering\n");
142 return E_NOTIMPL;
146 HRESULT WINAPI D3DXCheckTextureRequirements(LPDIRECT3DDEVICE9 device,
147 UINT* width,
148 UINT* height,
149 UINT* miplevels,
150 DWORD usage,
151 D3DFORMAT* format,
152 D3DPOOL pool)
154 UINT w = (width && *width) ? *width : 1;
155 UINT h = (height && *height) ? *height : 1;
156 D3DCAPS9 caps;
157 D3DDEVICE_CREATION_PARAMETERS params;
158 IDirect3D9 *d3d = NULL;
159 D3DDISPLAYMODE mode;
160 HRESULT hr;
161 D3DFORMAT usedformat = D3DFMT_UNKNOWN;
163 TRACE("(%p, %p, %p, %p, %u, %p, %u)\n", device, width, height, miplevels, usage, format, pool);
165 if (!device)
166 return D3DERR_INVALIDCALL;
168 /* usage */
169 if (usage == D3DX_DEFAULT)
170 usage = 0;
171 if (usage & (D3DUSAGE_WRITEONLY | D3DUSAGE_DONOTCLIP | D3DUSAGE_POINTS | D3DUSAGE_RTPATCHES | D3DUSAGE_NPATCHES))
172 return D3DERR_INVALIDCALL;
174 /* pool */
175 if ((pool != D3DPOOL_DEFAULT) && (pool != D3DPOOL_MANAGED) && (pool != D3DPOOL_SYSTEMMEM) && (pool != D3DPOOL_SCRATCH))
176 return D3DERR_INVALIDCALL;
178 /* width and height */
179 if (FAILED(IDirect3DDevice9_GetDeviceCaps(device, &caps)))
180 return D3DERR_INVALIDCALL;
182 /* 256 x 256 default width/height */
183 if ((w == D3DX_DEFAULT) && (h == D3DX_DEFAULT))
184 w = h = 256;
185 else if (w == D3DX_DEFAULT)
186 w = (height ? h : 256);
187 else if (h == D3DX_DEFAULT)
188 h = (width ? w : 256);
190 /* ensure width/height is power of 2 */
191 if ((caps.TextureCaps & D3DPTEXTURECAPS_POW2) && (!is_pow2(w)))
192 w = make_pow2(w);
194 if (w > caps.MaxTextureWidth)
195 w = caps.MaxTextureWidth;
197 if ((caps.TextureCaps & D3DPTEXTURECAPS_POW2) && (!is_pow2(h)))
198 h = make_pow2(h);
200 if (h > caps.MaxTextureHeight)
201 h = caps.MaxTextureHeight;
203 /* texture must be square? */
204 if (caps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY)
206 if (w > h)
207 h = w;
208 else
209 w = h;
212 if (width)
213 *width = w;
215 if (height)
216 *height = h;
218 /* miplevels */
219 if (miplevels && (usage & D3DUSAGE_AUTOGENMIPMAP))
221 if (*miplevels > 1)
222 *miplevels = 0;
224 else if (miplevels)
226 UINT max_mipmaps = 1;
228 if (!width && !height)
229 max_mipmaps = 9; /* number of mipmaps in a 256x256 texture */
230 else
232 UINT max_dimen = max(w, h);
234 while (max_dimen > 1)
236 max_dimen >>= 1;
237 max_mipmaps++;
241 if (*miplevels == 0 || *miplevels > max_mipmaps)
242 *miplevels = max_mipmaps;
245 /* format */
246 if (format)
248 TRACE("Requested format %x\n", *format);
249 usedformat = *format;
252 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
254 if (FAILED(hr))
255 goto cleanup;
257 hr = IDirect3DDevice9_GetCreationParameters(device, &params);
259 if (FAILED(hr))
260 goto cleanup;
262 hr = IDirect3DDevice9_GetDisplayMode(device, 0, &mode);
264 if (FAILED(hr))
265 goto cleanup;
267 if ((usedformat == D3DFMT_UNKNOWN) || (usedformat == D3DX_DEFAULT))
268 usedformat = D3DFMT_A8R8G8B8;
270 hr = IDirect3D9_CheckDeviceFormat(d3d, params.AdapterOrdinal, params.DeviceType, mode.Format,
271 usage, D3DRTYPE_TEXTURE, usedformat);
273 if (FAILED(hr))
275 /* Heuristic to choose the fallback format */
276 const PixelFormatDesc *fmt = get_format_info(usedformat);
277 BOOL allow_24bits;
278 int bestscore = INT_MIN, i = 0, j;
279 unsigned int channels;
280 const PixelFormatDesc *curfmt;
282 if (!fmt)
284 FIXME("Pixel format %x not handled\n", usedformat);
285 goto cleanup;
288 allow_24bits = fmt->bytes_per_pixel == 3;
289 channels = (fmt->bits[0] ? 1 : 0) + (fmt->bits[1] ? 1 : 0)
290 + (fmt->bits[2] ? 1 : 0) + (fmt->bits[3] ? 1 : 0);
291 usedformat = D3DFMT_UNKNOWN;
293 while ((curfmt = get_format_info_idx(i)))
295 unsigned int curchannels = (curfmt->bits[0] ? 1 : 0) + (curfmt->bits[1] ? 1 : 0)
296 + (curfmt->bits[2] ? 1 : 0) + (curfmt->bits[3] ? 1 : 0);
297 int score;
299 i++;
301 if (curchannels < channels)
302 continue;
303 if (curfmt->bytes_per_pixel == 3 && !allow_24bits)
304 continue;
306 hr = IDirect3D9_CheckDeviceFormat(d3d, params.AdapterOrdinal, params.DeviceType,
307 mode.Format, usage, D3DRTYPE_TEXTURE, curfmt->format);
308 if (FAILED(hr))
309 continue;
311 /* This format can be used, let's evaluate it.
312 Weights chosen quite arbitrarily... */
313 score = 16 - 4 * (curchannels - channels);
315 for (j = 0; j < 4; j++)
317 int diff = curfmt->bits[j] - fmt->bits[j];
318 score += 16 - (diff < 0 ? -diff * 4 : diff);
321 if (score > bestscore)
323 bestscore = score;
324 usedformat = curfmt->format;
327 hr = D3D_OK;
330 cleanup:
332 if (d3d)
333 IDirect3D9_Release(d3d);
335 if (FAILED(hr))
336 return hr;
338 if (usedformat == D3DFMT_UNKNOWN)
340 WARN("Couldn't find a suitable pixel format\n");
341 return D3DERR_NOTAVAILABLE;
344 TRACE("Format chosen: %x\n", usedformat);
345 if (format)
346 *format = usedformat;
348 return D3D_OK;
351 HRESULT WINAPI D3DXCheckCubeTextureRequirements(LPDIRECT3DDEVICE9 device,
352 UINT *size,
353 UINT *miplevels,
354 DWORD usage,
355 D3DFORMAT *format,
356 D3DPOOL pool)
358 D3DCAPS9 caps;
359 UINT s = (size && *size) ? *size : 256;
360 HRESULT hr;
362 TRACE("(%p, %p, %p, %u, %p, %u)\n", device, size, miplevels, usage, format, pool);
364 if (s == D3DX_DEFAULT)
365 s = 256;
367 if (!device || FAILED(IDirect3DDevice9_GetDeviceCaps(device, &caps)))
368 return D3DERR_INVALIDCALL;
370 if (!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP))
371 return D3DERR_NOTAVAILABLE;
373 /* ensure width/height is power of 2 */
374 if ((caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2) && (!is_pow2(s)))
375 s = make_pow2(s);
377 hr = D3DXCheckTextureRequirements(device, &s, &s, miplevels, usage, format, pool);
379 if (!(caps.TextureCaps & D3DPTEXTURECAPS_MIPCUBEMAP))
381 if(miplevels)
382 *miplevels = 1;
385 if (size)
386 *size = s;
388 return hr;
391 HRESULT WINAPI D3DXCheckVolumeTextureRequirements(LPDIRECT3DDEVICE9 device,
392 UINT *width,
393 UINT *height,
394 UINT *depth,
395 UINT *miplevels,
396 DWORD usage,
397 D3DFORMAT *format,
398 D3DPOOL pool)
400 D3DCAPS9 caps;
401 UINT w = width ? *width : D3DX_DEFAULT;
402 UINT h = height ? *height : D3DX_DEFAULT;
403 UINT d = (depth && *depth) ? *depth : 1;
404 HRESULT hr;
406 TRACE("(%p, %p, %p, %p, %p, %u, %p, %u)\n", device, width, height, depth, miplevels,
407 usage, format, pool);
409 if (!device || FAILED(IDirect3DDevice9_GetDeviceCaps(device, &caps)))
410 return D3DERR_INVALIDCALL;
412 if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
413 return D3DERR_NOTAVAILABLE;
415 hr = D3DXCheckTextureRequirements(device, &w, &h, NULL, usage, format, pool);
416 if (d == D3DX_DEFAULT)
417 d = 1;
419 /* ensure width/height is power of 2 */
420 if ((caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP_POW2) &&
421 (!is_pow2(w) || !is_pow2(h) || !is_pow2(d)))
423 w = make_pow2(w);
424 h = make_pow2(h);
425 d = make_pow2(d);
428 if (w > caps.MaxVolumeExtent)
429 w = caps.MaxVolumeExtent;
430 if (h > caps.MaxVolumeExtent)
431 h = caps.MaxVolumeExtent;
432 if (d > caps.MaxVolumeExtent)
433 d = caps.MaxVolumeExtent;
435 if (miplevels)
437 if (!(caps.TextureCaps & D3DPTEXTURECAPS_MIPVOLUMEMAP))
438 *miplevels = 1;
439 else if ((usage & D3DUSAGE_AUTOGENMIPMAP))
441 if (*miplevels > 1)
442 *miplevels = 0;
444 else
446 UINT max_mipmaps = 1;
447 UINT max_dimen = max(max(w, h), d);
449 while (max_dimen > 1)
451 max_dimen >>= 1;
452 max_mipmaps++;
455 if (*miplevels == 0 || *miplevels > max_mipmaps)
456 *miplevels = max_mipmaps;
460 if (width)
461 *width = w;
462 if (height)
463 *height = h;
464 if (depth)
465 *depth = d;
467 return hr;
470 HRESULT WINAPI D3DXCreateTexture(LPDIRECT3DDEVICE9 pDevice,
471 UINT width,
472 UINT height,
473 UINT miplevels,
474 DWORD usage,
475 D3DFORMAT format,
476 D3DPOOL pool,
477 LPDIRECT3DTEXTURE9 *ppTexture)
479 HRESULT hr;
481 TRACE("(%p, %u, %u, %u, %x, %x, %x, %p)\n", pDevice, width, height, miplevels, usage, format,
482 pool, ppTexture);
484 if (!pDevice || !ppTexture)
485 return D3DERR_INVALIDCALL;
487 hr = D3DXCheckTextureRequirements(pDevice, &width, &height, &miplevels, usage, &format, pool);
489 if (FAILED(hr))
490 return hr;
492 return IDirect3DDevice9_CreateTexture(pDevice, width, height, miplevels, usage, format, pool, ppTexture, NULL);
495 HRESULT WINAPI D3DXCreateTextureFromFileInMemoryEx(LPDIRECT3DDEVICE9 device,
496 LPCVOID srcdata,
497 UINT srcdatasize,
498 UINT width,
499 UINT height,
500 UINT miplevels,
501 DWORD usage,
502 D3DFORMAT format,
503 D3DPOOL pool,
504 DWORD filter,
505 DWORD mipfilter,
506 D3DCOLOR colorkey,
507 D3DXIMAGE_INFO* srcinfo,
508 PALETTEENTRY* palette,
509 LPDIRECT3DTEXTURE9* texture)
511 IDirect3DTexture9 **texptr;
512 IDirect3DTexture9 *buftex;
513 IDirect3DSurface9 *surface;
514 BOOL file_width = FALSE, file_height = FALSE;
515 BOOL file_format = FALSE, file_miplevels = FALSE;
516 BOOL dynamic_texture;
517 D3DXIMAGE_INFO imginfo;
518 UINT loaded_miplevels;
519 D3DCAPS9 caps;
520 HRESULT hr;
522 TRACE("(%p, %p, %u, %u, %u, %u, %x, %x, %x, %u, %u, %x, %p, %p, %p)\n", device, srcdata, srcdatasize, width,
523 height, miplevels, usage, format, pool, filter, mipfilter, colorkey, srcinfo, palette, texture);
525 /* check for invalid parameters */
526 if (!device || !texture || !srcdata || !srcdatasize)
527 return D3DERR_INVALIDCALL;
529 hr = D3DXGetImageInfoFromFileInMemory(srcdata, srcdatasize, &imginfo);
531 if (FAILED(hr))
533 *texture = NULL;
534 return hr;
537 /* handle default values */
538 if (width == 0 || width == D3DX_DEFAULT_NONPOW2)
539 width = imginfo.Width;
541 if (height == 0 || height == D3DX_DEFAULT_NONPOW2)
542 height = imginfo.Height;
544 if (width == D3DX_DEFAULT)
545 width = make_pow2(imginfo.Width);
547 if (height == D3DX_DEFAULT)
548 height = make_pow2(imginfo.Height);
550 if (format == D3DFMT_UNKNOWN || format == D3DX_DEFAULT)
551 format = imginfo.Format;
553 if (width == D3DX_FROM_FILE)
555 file_width = TRUE;
556 width = imginfo.Width;
559 if (height == D3DX_FROM_FILE)
561 file_height = TRUE;
562 height = imginfo.Height;
565 if (format == D3DFMT_FROM_FILE)
567 file_format = TRUE;
568 format = imginfo.Format;
571 if (miplevels == D3DX_FROM_FILE)
573 file_miplevels = TRUE;
574 miplevels = imginfo.MipLevels;
577 /* fix texture creation parameters */
578 hr = D3DXCheckTextureRequirements(device, &width, &height, &miplevels, usage, &format, pool);
580 if (FAILED(hr))
582 *texture = NULL;
583 return hr;
586 if (imginfo.MipLevels < miplevels && (D3DFMT_DXT1 <= imginfo.Format && imginfo.Format <= D3DFMT_DXT5))
588 FIXME("Generation of mipmaps for compressed pixel formats is not implemented yet\n");
589 miplevels = imginfo.MipLevels;
592 if (((file_width) && (width != imginfo.Width)) ||
593 ((file_height) && (height != imginfo.Height)) ||
594 ((file_format) && (format != imginfo.Format)) ||
595 ((file_miplevels) && (miplevels != imginfo.MipLevels)))
597 return D3DERR_NOTAVAILABLE;
600 if (FAILED(IDirect3DDevice9_GetDeviceCaps(device, &caps)))
601 return D3DERR_INVALIDCALL;
603 /* Create the to-be-filled texture */
604 dynamic_texture = (caps.Caps2 & D3DCAPS2_DYNAMICTEXTURES) && (usage & D3DUSAGE_DYNAMIC);
605 if (pool == D3DPOOL_DEFAULT && !dynamic_texture)
607 hr = D3DXCreateTexture(device, width, height, miplevels, usage, format, D3DPOOL_SYSTEMMEM, &buftex);
608 texptr = &buftex;
610 else
612 hr = D3DXCreateTexture(device, width, height, miplevels, usage, format, pool, texture);
613 texptr = texture;
616 if (FAILED(hr))
618 *texture = NULL;
619 return hr;
622 /* Load the file */
623 if (imginfo.ImageFileFormat != D3DXIFF_DDS)
625 IDirect3DTexture9_GetSurfaceLevel(*texptr, 0, &surface);
626 hr = D3DXLoadSurfaceFromFileInMemory(surface, palette, NULL, srcdata, srcdatasize, NULL, filter, colorkey, NULL);
627 IDirect3DSurface9_Release(surface);
629 else
631 hr = load_texture_from_dds(*texptr, srcdata, palette, filter, colorkey, &imginfo);
634 if (FAILED(hr))
636 IDirect3DTexture9_Release(*texptr);
637 *texture = NULL;
638 return hr;
641 loaded_miplevels = min(IDirect3DTexture9_GetLevelCount(*texptr), imginfo.MipLevels);
642 hr = D3DXFilterTexture((IDirect3DBaseTexture9*) *texptr, palette, loaded_miplevels - 1, mipfilter);
644 if (FAILED(hr))
646 IDirect3DTexture9_Release(*texptr);
647 *texture = NULL;
648 return hr;
651 /* Move the data to the actual texture if necessary */
652 if (texptr == &buftex)
654 hr = D3DXCreateTexture(device, width, height, miplevels, usage, format, pool, texture);
656 if (FAILED(hr))
658 IDirect3DTexture9_Release(buftex);
659 *texture = NULL;
660 return hr;
663 IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9*)buftex, (IDirect3DBaseTexture9*)(*texture));
664 IDirect3DTexture9_Release(buftex);
667 if (srcinfo)
668 *srcinfo = imginfo;
670 return D3D_OK;
673 HRESULT WINAPI D3DXCreateTextureFromFileInMemory(LPDIRECT3DDEVICE9 device,
674 LPCVOID srcdata,
675 UINT srcdatasize,
676 LPDIRECT3DTEXTURE9 *texture)
678 TRACE("(%p, %p, %d, %p)\n", device, srcdata, srcdatasize, texture);
680 return D3DXCreateTextureFromFileInMemoryEx(device, srcdata, srcdatasize, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN,
681 D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, texture);
684 HRESULT WINAPI D3DXCreateTextureFromFileExW(LPDIRECT3DDEVICE9 device,
685 LPCWSTR srcfile,
686 UINT width,
687 UINT height,
688 UINT miplevels,
689 DWORD usage,
690 D3DFORMAT format,
691 D3DPOOL pool,
692 DWORD filter,
693 DWORD mipfilter,
694 D3DCOLOR colorkey,
695 D3DXIMAGE_INFO *srcinfo,
696 PALETTEENTRY *palette,
697 LPDIRECT3DTEXTURE9 *texture)
699 HRESULT hr;
700 DWORD size;
701 LPVOID buffer;
703 TRACE("(%p, %s, %u, %u, %u, %x, %x, %x, %u, %u, %x, %p, %p, %p): relay\n",
704 device, debugstr_w(srcfile), width, height, miplevels, usage, format, pool, filter,
705 mipfilter, colorkey, srcinfo, palette, texture);
707 if (!srcfile)
708 return D3DERR_INVALIDCALL;
710 hr = map_view_of_file(srcfile, &buffer, &size);
711 if (FAILED(hr))
712 return D3DXERR_INVALIDDATA;
714 hr = D3DXCreateTextureFromFileInMemoryEx(device, buffer, size, width, height, miplevels, usage, format, pool,
715 filter, mipfilter, colorkey, srcinfo, palette, texture);
717 UnmapViewOfFile(buffer);
719 return hr;
722 HRESULT WINAPI D3DXCreateTextureFromFileExA(LPDIRECT3DDEVICE9 device,
723 LPCSTR srcfile,
724 UINT width,
725 UINT height,
726 UINT miplevels,
727 DWORD usage,
728 D3DFORMAT format,
729 D3DPOOL pool,
730 DWORD filter,
731 DWORD mipfilter,
732 D3DCOLOR colorkey,
733 D3DXIMAGE_INFO *srcinfo,
734 PALETTEENTRY *palette,
735 LPDIRECT3DTEXTURE9 *texture)
737 LPWSTR widename;
738 HRESULT hr;
739 DWORD len;
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);
757 return hr;
760 HRESULT WINAPI D3DXCreateTextureFromFileA(LPDIRECT3DDEVICE9 device,
761 LPCSTR srcfile,
762 LPDIRECT3DTEXTURE9 *texture)
764 TRACE("(%p, %s, %p)\n", device, debugstr_a(srcfile), texture);
766 return D3DXCreateTextureFromFileExA(device, srcfile, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN,
767 D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, texture);
770 HRESULT WINAPI D3DXCreateTextureFromFileW(LPDIRECT3DDEVICE9 device,
771 LPCWSTR srcfile,
772 LPDIRECT3DTEXTURE9 *texture)
774 TRACE("(%p, %s, %p)\n", device, debugstr_w(srcfile), texture);
776 return D3DXCreateTextureFromFileExW(device, srcfile, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN,
777 D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, texture);
781 HRESULT WINAPI D3DXCreateTextureFromResourceA(LPDIRECT3DDEVICE9 device,
782 HMODULE srcmodule,
783 LPCSTR resource,
784 LPDIRECT3DTEXTURE9 *texture)
786 TRACE("(%p, %s): relay\n", srcmodule, debugstr_a(resource));
788 return D3DXCreateTextureFromResourceExA(device, srcmodule, resource, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN,
789 D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, texture);
792 HRESULT WINAPI D3DXCreateTextureFromResourceW(LPDIRECT3DDEVICE9 device,
793 HMODULE srcmodule,
794 LPCWSTR resource,
795 LPDIRECT3DTEXTURE9 *texture)
797 TRACE("(%p, %s): relay\n", srcmodule, debugstr_w(resource));
799 return D3DXCreateTextureFromResourceExW(device, srcmodule, resource, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN,
800 D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, texture);
803 HRESULT WINAPI D3DXCreateTextureFromResourceExA(LPDIRECT3DDEVICE9 device,
804 HMODULE srcmodule,
805 LPCSTR resource,
806 UINT width,
807 UINT height,
808 UINT miplevels,
809 DWORD usage,
810 D3DFORMAT format,
811 D3DPOOL pool,
812 DWORD filter,
813 DWORD mipfilter,
814 D3DCOLOR colorkey,
815 D3DXIMAGE_INFO *srcinfo,
816 PALETTEENTRY *palette,
817 LPDIRECT3DTEXTURE9 *texture)
819 HRSRC resinfo;
821 TRACE("(%p, %s): relay\n", srcmodule, debugstr_a(resource));
823 if (!device || !texture)
824 return D3DERR_INVALIDCALL;
826 resinfo = FindResourceA(srcmodule, resource, (LPCSTR) RT_RCDATA);
828 if (resinfo)
830 LPVOID buffer;
831 HRESULT hr;
832 DWORD size;
834 hr = load_resource_into_memory(srcmodule, resinfo, &buffer, &size);
836 if (FAILED(hr))
837 return D3DXERR_INVALIDDATA;
839 return D3DXCreateTextureFromFileInMemoryEx(device, buffer, size, width,
840 height, miplevels, usage, format,
841 pool, filter, mipfilter, colorkey,
842 srcinfo, palette, texture);
845 /* Try loading the resource as bitmap data */
846 resinfo = FindResourceA(srcmodule, resource, (LPCSTR) RT_BITMAP);
848 if (resinfo)
850 FIXME("Implement loading bitmaps from resource type RT_BITMAP\n");
851 return E_NOTIMPL;
854 return D3DXERR_INVALIDDATA;
857 HRESULT WINAPI D3DXCreateTextureFromResourceExW(LPDIRECT3DDEVICE9 device,
858 HMODULE srcmodule,
859 LPCWSTR resource,
860 UINT width,
861 UINT height,
862 UINT miplevels,
863 DWORD usage,
864 D3DFORMAT format,
865 D3DPOOL pool,
866 DWORD filter,
867 DWORD mipfilter,
868 D3DCOLOR colorkey,
869 D3DXIMAGE_INFO *srcinfo,
870 PALETTEENTRY *palette,
871 LPDIRECT3DTEXTURE9 *texture)
873 HRSRC resinfo;
875 TRACE("(%p, %s): relay\n", srcmodule, debugstr_w(resource));
877 if (!device || !texture)
878 return D3DERR_INVALIDCALL;
880 resinfo = FindResourceW(srcmodule, resource, (LPCWSTR) RT_RCDATA);
882 if (resinfo)
884 LPVOID buffer;
885 HRESULT hr;
886 DWORD size;
888 hr = load_resource_into_memory(srcmodule, resinfo, &buffer, &size);
890 if (FAILED(hr))
891 return D3DXERR_INVALIDDATA;
893 return D3DXCreateTextureFromFileInMemoryEx(device, buffer, size, width,
894 height, miplevels, usage, format,
895 pool, filter, mipfilter, colorkey,
896 srcinfo, palette, texture);
899 /* Try loading the resource as bitmap data */
900 resinfo = FindResourceW(srcmodule, resource, (LPCWSTR) RT_BITMAP);
902 if (resinfo)
904 FIXME("Implement loading bitmaps from resource type RT_BITMAP\n");
905 return E_NOTIMPL;
908 return D3DXERR_INVALIDDATA;
911 HRESULT WINAPI D3DXCreateCubeTexture(LPDIRECT3DDEVICE9 device,
912 UINT size,
913 UINT miplevels,
914 DWORD usage,
915 D3DFORMAT format,
916 D3DPOOL pool,
917 LPDIRECT3DCUBETEXTURE9 *texture)
919 HRESULT hr;
921 TRACE("(%p, %u, %u, %#x, %#x, %#x, %p)\n", device, size, miplevels, usage, format,
922 pool, texture);
924 if (!device || !texture)
925 return D3DERR_INVALIDCALL;
927 hr = D3DXCheckCubeTextureRequirements(device, &size, &miplevels, usage, &format, pool);
929 if (FAILED(hr))
931 TRACE("D3DXCheckCubeTextureRequirements failed\n");
932 return hr;
935 return IDirect3DDevice9_CreateCubeTexture(device, size, miplevels, usage, format, pool, texture, NULL);
938 HRESULT WINAPI D3DXCreateCubeTextureFromFileInMemory(LPDIRECT3DDEVICE9 device,
939 LPCVOID data,
940 UINT datasize,
941 LPDIRECT3DCUBETEXTURE9 *texture)
943 TRACE("(%p, %p, %u, %p)\n", device, data, datasize, texture);
945 return D3DXCreateCubeTextureFromFileInMemoryEx(device, data, datasize, D3DX_DEFAULT, D3DX_DEFAULT,
946 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, texture);
949 HRESULT WINAPI D3DXCreateVolumeTexture(LPDIRECT3DDEVICE9 device,
950 UINT width,
951 UINT height,
952 UINT depth,
953 UINT miplevels,
954 DWORD usage,
955 D3DFORMAT format,
956 D3DPOOL pool,
957 LPDIRECT3DVOLUMETEXTURE9 *texture)
959 HRESULT hr;
961 TRACE("(%p, %u, %u, %u, %u, %#x, %#x, %#x, %p)\n", device, width, height, depth,
962 miplevels, usage, format, pool, texture);
964 if (!device || !texture)
965 return D3DERR_INVALIDCALL;
967 hr = D3DXCheckVolumeTextureRequirements(device, &width, &height, &depth,
968 &miplevels, usage, &format, pool);
970 if (FAILED(hr))
972 TRACE("D3DXCheckVolumeTextureRequirements failed\n");
973 return hr;
976 return IDirect3DDevice9_CreateVolumeTexture(device, width, height, depth, miplevels,
977 usage, format, pool, texture, NULL);
980 HRESULT WINAPI D3DXCreateVolumeTextureFromFileInMemory(LPDIRECT3DDEVICE9 device,
981 LPCVOID data,
982 UINT datasize,
983 LPDIRECT3DVOLUMETEXTURE9 *texture)
985 TRACE("(%p, %p, %u, %p)\n", device, data, datasize, texture);
987 return D3DXCreateVolumeTextureFromFileInMemoryEx(device, data, datasize, D3DX_DEFAULT, D3DX_DEFAULT,
988 D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT,
989 0, NULL, NULL, texture);
992 HRESULT WINAPI D3DXCreateVolumeTextureFromFileInMemoryEx(LPDIRECT3DDEVICE9 device,
993 LPCVOID data,
994 UINT datasize,
995 UINT width,
996 UINT height,
997 UINT depth,
998 UINT miplevels,
999 DWORD usage,
1000 D3DFORMAT format,
1001 D3DPOOL pool,
1002 DWORD filter,
1003 DWORD mipfilter,
1004 D3DCOLOR colorkey,
1005 D3DXIMAGE_INFO *imageinfo,
1006 PALETTEENTRY *palette,
1007 LPDIRECT3DVOLUMETEXTURE9 *texture)
1009 FIXME("(%p, %p, %u, %u, %u, %u, %u, %#x, %#x, %#x, %#x, %#x, %#x, %p, %p, %p) : stub\n",
1010 device, data, datasize, width, height, depth, miplevels, usage, format, pool,
1011 filter, mipfilter, colorkey, imageinfo, palette, texture);
1013 return E_NOTIMPL;
1016 HRESULT WINAPI D3DXFillTexture(LPDIRECT3DTEXTURE9 texture,
1017 LPD3DXFILL2D function,
1018 LPVOID funcdata)
1020 DWORD miplevels;
1021 DWORD m, i, x, y, c, v;
1022 D3DSURFACE_DESC desc;
1023 D3DLOCKED_RECT lock_rect;
1024 D3DXVECTOR4 value;
1025 D3DXVECTOR2 coord, size;
1026 const PixelFormatDesc *format;
1027 BYTE *data, *pos;
1028 BYTE byte, mask;
1029 float comp_value;
1031 if (texture == NULL || function == NULL)
1032 return D3DERR_INVALIDCALL;
1034 miplevels = IDirect3DBaseTexture9_GetLevelCount(texture);
1036 for (m = 0; m < miplevels; m++)
1038 if (FAILED(IDirect3DTexture9_GetLevelDesc(texture, m, &desc)))
1039 return D3DERR_INVALIDCALL;
1041 format = get_format_info(desc.Format);
1042 if (format->format == D3DFMT_UNKNOWN)
1044 FIXME("Unsupported texture format %#x\n", desc.Format);
1045 return D3DERR_INVALIDCALL;
1048 if (FAILED(IDirect3DTexture9_LockRect(texture, m, &lock_rect, NULL, D3DLOCK_DISCARD)))
1049 return D3DERR_INVALIDCALL;
1051 size.x = 1.0f / desc.Width;
1052 size.y = 1.0f / desc.Height;
1054 data = lock_rect.pBits;
1056 for (y = 0; y < desc.Height; y++)
1058 /* The callback function expects the coordinates of the center
1059 of the texel */
1060 coord.y = (y + 0.5f) / desc.Height;
1062 for (x = 0; x < desc.Width; x++)
1064 coord.x = (x + 0.5f) / desc.Width;
1066 function(&value, &coord, &size, funcdata);
1068 pos = data + y * lock_rect.Pitch + x * format->bytes_per_pixel;
1070 for (i = 0; i < format->bytes_per_pixel; i++)
1071 pos[i] = 0;
1073 for (c = 0; c < 4; c++)
1075 switch (c)
1077 case 0: /* Alpha */
1078 comp_value = value.w;
1079 break;
1080 case 1: /* Red */
1081 comp_value = value.x;
1082 break;
1083 case 2: /* Green */
1084 comp_value = value.y;
1085 break;
1086 case 3: /* Blue */
1087 comp_value = value.z;
1088 break;
1091 v = comp_value * ((1 << format->bits[c]) - 1) + 0.5f;
1093 for (i = 0; i < format->bits[c] + format->shift[c]; i += 8)
1095 mask = ((1 << format->bits[c]) - 1) << format->shift[c] >> i;
1096 byte = (v << format->shift[c] >> i) & mask;
1097 pos[i / 8] |= byte;
1102 IDirect3DTexture9_UnlockRect(texture, m);
1105 return D3D_OK;
1108 HRESULT WINAPI D3DXCreateCubeTextureFromFileInMemoryEx(IDirect3DDevice9 *device,
1109 const void *src_data,
1110 UINT src_data_size,
1111 UINT size,
1112 UINT mip_levels,
1113 DWORD usage,
1114 D3DFORMAT format,
1115 D3DPOOL pool,
1116 DWORD filter,
1117 DWORD mip_filter,
1118 D3DCOLOR color_key,
1119 D3DXIMAGE_INFO *src_info,
1120 PALETTEENTRY *palette,
1121 IDirect3DCubeTexture9 **cube_texture)
1123 HRESULT hr;
1124 D3DCAPS9 caps;
1125 UINT loaded_miplevels;
1126 D3DXIMAGE_INFO img_info;
1127 BOOL dynamic_texture;
1128 BOOL file_size = FALSE;
1129 BOOL file_format = FALSE;
1130 BOOL file_mip_levels = FALSE;
1131 IDirect3DCubeTexture9 *tex, *buftex;
1133 TRACE("(%p, %p, %u, %u, %u, %#x, %#x, %#x, %#x, %#x, %#x, %p, %p, %p)\n", device,
1134 src_data, src_data_size, size, mip_levels, usage, format, pool, filter, mip_filter,
1135 color_key, src_info, palette, cube_texture);
1137 if (!device || !cube_texture || !src_data || !src_data_size)
1138 return D3DERR_INVALIDCALL;
1140 hr = D3DXGetImageInfoFromFileInMemory(src_data, src_data_size, &img_info);
1141 if (FAILED(hr))
1142 return hr;
1144 if (img_info.ImageFileFormat != D3DXIFF_DDS)
1145 return D3DXERR_INVALIDDATA;
1147 if (img_info.Width != img_info.Height)
1148 return D3DXERR_INVALIDDATA;
1150 if (size == 0 || size == D3DX_DEFAULT_NONPOW2)
1151 size = img_info.Width;
1152 if (size == D3DX_DEFAULT)
1153 size = make_pow2(img_info.Width);
1155 if (format == D3DFMT_UNKNOWN || format == D3DX_DEFAULT)
1156 format = img_info.Format;
1158 if (size == D3DX_FROM_FILE)
1160 file_size = TRUE;
1161 size = img_info.Width;
1164 if (format == D3DFMT_FROM_FILE)
1166 file_format = TRUE;
1167 format = img_info.Format;
1170 if (mip_levels == D3DX_FROM_FILE)
1172 file_mip_levels = TRUE;
1173 mip_levels = img_info.MipLevels;
1176 hr = D3DXCheckCubeTextureRequirements(device, &size, &mip_levels, usage, &format, pool);
1177 if (FAILED(hr))
1178 return hr;
1180 if ((file_size && size != img_info.Width)
1181 || (file_format && format != img_info.Format)
1182 || (file_mip_levels && mip_levels != img_info.MipLevels))
1183 return D3DERR_NOTAVAILABLE;
1185 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1186 if (FAILED(hr))
1187 return D3DERR_INVALIDCALL;
1189 if (mip_levels > img_info.MipLevels && (D3DFMT_DXT1 <= img_info.Format && img_info.Format <= D3DFMT_DXT5))
1191 FIXME("Generation of mipmaps for compressed pixel formats not supported yet\n");
1192 mip_levels = img_info.MipLevels;
1195 dynamic_texture = (caps.Caps2 & D3DCAPS2_DYNAMICTEXTURES) && (usage & D3DUSAGE_DYNAMIC);
1196 if (pool == D3DPOOL_DEFAULT && !dynamic_texture)
1198 hr = D3DXCreateCubeTexture(device, size, mip_levels, usage, format, D3DPOOL_SYSTEMMEM, &buftex);
1199 tex = buftex;
1201 else
1203 hr = D3DXCreateCubeTexture(device, size, mip_levels, usage, format, pool, &tex);
1204 buftex = NULL;
1206 if (FAILED(hr))
1207 return hr;
1209 hr = load_cube_texture_from_dds(tex, src_data, palette, filter, color_key, &img_info);
1210 if (FAILED(hr))
1212 IDirect3DCubeTexture9_Release(tex);
1213 return hr;
1216 loaded_miplevels = min(IDirect3DCubeTexture9_GetLevelCount(tex), img_info.MipLevels);
1217 hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, palette, loaded_miplevels - 1, mip_filter);
1218 if (FAILED(hr))
1220 IDirect3DCubeTexture9_Release(tex);
1221 return hr;
1224 if (buftex)
1226 hr = D3DXCreateCubeTexture(device, size, mip_levels, usage, format, pool, &tex);
1227 if (FAILED(hr))
1229 IDirect3DCubeTexture9_Release(buftex);
1230 return hr;
1233 IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)buftex, (IDirect3DBaseTexture9 *)tex);
1234 IDirect3DCubeTexture9_Release(buftex);
1237 if (src_info)
1238 *src_info = img_info;
1240 *cube_texture = tex;
1241 return D3D_OK;
1245 HRESULT WINAPI D3DXCreateCubeTextureFromFileA(IDirect3DDevice9 *device,
1246 const char *src_filename,
1247 IDirect3DCubeTexture9 **cube_texture)
1249 int len;
1250 HRESULT hr;
1251 WCHAR *filename;
1252 void *data;
1253 DWORD data_size;
1255 TRACE("(%p, %s, %p): relay\n", device, wine_dbgstr_a(src_filename), cube_texture);
1257 if (!src_filename) return D3DERR_INVALIDCALL;
1259 len = MultiByteToWideChar(CP_ACP, 0, src_filename, -1, NULL, 0);
1260 filename = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
1261 if (!filename) return E_OUTOFMEMORY;
1262 MultiByteToWideChar(CP_ACP, 0, src_filename, -1, filename, len);
1264 hr = map_view_of_file(filename, &data, &data_size);
1265 if (FAILED(hr))
1267 HeapFree(GetProcessHeap(), 0, filename);
1268 return D3DXERR_INVALIDDATA;
1271 hr = D3DXCreateCubeTextureFromFileInMemoryEx(device, data, data_size, D3DX_DEFAULT, D3DX_DEFAULT,
1272 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, cube_texture);
1274 UnmapViewOfFile(data);
1275 HeapFree(GetProcessHeap(), 0, filename);
1276 return hr;
1279 HRESULT WINAPI D3DXCreateCubeTextureFromFileW(IDirect3DDevice9 *device,
1280 const WCHAR *src_filename,
1281 IDirect3DCubeTexture9 **cube_texture)
1283 HRESULT hr;
1284 void *data;
1285 DWORD data_size;
1287 TRACE("(%p, %s, %p): relay\n", device, wine_dbgstr_w(src_filename), cube_texture);
1289 hr = map_view_of_file(src_filename, &data, &data_size);
1290 if (FAILED(hr)) return D3DXERR_INVALIDDATA;
1292 hr = D3DXCreateCubeTextureFromFileInMemoryEx(device, data, data_size, D3DX_DEFAULT, D3DX_DEFAULT,
1293 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, cube_texture);
1295 UnmapViewOfFile(data);
1296 return hr;
1299 HRESULT WINAPI D3DXCreateCubeTextureFromFileExA(IDirect3DDevice9 *device,
1300 const char *src_filename,
1301 UINT size,
1302 UINT mip_levels,
1303 DWORD usage,
1304 D3DFORMAT format,
1305 D3DPOOL pool,
1306 DWORD filter,
1307 DWORD mip_filter,
1308 D3DCOLOR color_key,
1309 D3DXIMAGE_INFO *image_info,
1310 PALETTEENTRY *palette,
1311 IDirect3DCubeTexture9 **cube_texture)
1313 int len;
1314 HRESULT hr;
1315 WCHAR *filename;
1316 void *data;
1317 DWORD data_size;
1319 TRACE("(%p, %s, %u, %u, %#x, %#x, %#x, %#x, %#x, %#x, %p, %p, %p): relay\n",
1320 device, wine_dbgstr_a(src_filename), size, mip_levels, usage, format,
1321 pool, filter, mip_filter, color_key, image_info, palette, cube_texture);
1323 if (!src_filename) return D3DERR_INVALIDCALL;
1325 len = MultiByteToWideChar(CP_ACP, 0, src_filename, -1, NULL, 0);
1326 filename = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
1327 if (!filename) return E_OUTOFMEMORY;
1328 MultiByteToWideChar(CP_ACP, 0, src_filename, -1, filename, len);
1330 hr = map_view_of_file(filename, &data, &data_size);
1331 if (FAILED(hr))
1333 HeapFree(GetProcessHeap(), 0, filename);
1334 return D3DXERR_INVALIDDATA;
1337 hr = D3DXCreateCubeTextureFromFileInMemoryEx(device, data, data_size, size, mip_levels,
1338 usage, format, pool, filter, mip_filter, color_key, image_info, palette, cube_texture);
1340 UnmapViewOfFile(data);
1341 HeapFree(GetProcessHeap(), 0, filename);
1342 return hr;
1345 HRESULT WINAPI D3DXCreateCubeTextureFromFileExW(IDirect3DDevice9 *device,
1346 const WCHAR *src_filename,
1347 UINT size,
1348 UINT mip_levels,
1349 DWORD usage,
1350 D3DFORMAT format,
1351 D3DPOOL pool,
1352 DWORD filter,
1353 DWORD mip_filter,
1354 D3DCOLOR color_key,
1355 D3DXIMAGE_INFO *image_info,
1356 PALETTEENTRY *palette,
1357 IDirect3DCubeTexture9 **cube_texture)
1359 HRESULT hr;
1360 void *data;
1361 DWORD data_size;
1363 TRACE("(%p, %s, %u, %u, %#x, %#x, %#x, %#x, %#x, %#x, %p, %p, %p): relay\n",
1364 device, wine_dbgstr_w(src_filename), size, mip_levels, usage, format,
1365 pool, filter, mip_filter, color_key, image_info, palette, cube_texture);
1367 hr = map_view_of_file(src_filename, &data, &data_size);
1368 if (FAILED(hr)) return D3DXERR_INVALIDDATA;
1370 hr = D3DXCreateCubeTextureFromFileInMemoryEx(device, data, data_size, size, mip_levels,
1371 usage, format, pool, filter, mip_filter, color_key, image_info, palette, cube_texture);
1373 UnmapViewOfFile(data);
1374 return hr;
1377 enum cube_coord
1379 XCOORD = 0,
1380 XCOORDINV = 1,
1381 YCOORD = 2,
1382 YCOORDINV = 3,
1383 ZERO = 4,
1384 ONE = 5
1387 static float get_cube_coord(enum cube_coord coord, unsigned int x, unsigned int y, unsigned int size)
1389 switch (coord)
1391 case XCOORD:
1392 return x + 0.5f;
1393 case XCOORDINV:
1394 return size - x - 0.5f;
1395 case YCOORD:
1396 return y + 0.5f;
1397 case YCOORDINV:
1398 return size - y - 0.5f;
1399 case ZERO:
1400 return 0.0f;
1401 case ONE:
1402 return size;
1403 default:
1404 ERR("Unexpected coordinate value\n");
1405 return 0.0f;
1409 HRESULT WINAPI D3DXFillCubeTexture(LPDIRECT3DCUBETEXTURE9 texture,
1410 LPD3DXFILL3D function,
1411 LPVOID funcdata)
1413 DWORD miplevels;
1414 DWORD m, i, x, y, c, f, v;
1415 D3DSURFACE_DESC desc;
1416 D3DLOCKED_RECT lock_rect;
1417 D3DXVECTOR4 value;
1418 D3DXVECTOR3 coord, size;
1419 const PixelFormatDesc *format;
1420 BYTE *data, *pos;
1421 BYTE byte, mask;
1422 float comp_value;
1423 static const enum cube_coord coordmap[6][3] =
1425 {ONE, YCOORDINV, XCOORDINV},
1426 {ZERO, YCOORDINV, XCOORD},
1427 {XCOORD, ONE, YCOORD},
1428 {XCOORD, ZERO, YCOORDINV},
1429 {XCOORD, YCOORDINV, ONE},
1430 {XCOORDINV, YCOORDINV, ZERO}
1433 if (texture == NULL || function == NULL)
1434 return D3DERR_INVALIDCALL;
1436 miplevels = IDirect3DBaseTexture9_GetLevelCount(texture);
1438 for (m = 0; m < miplevels; m++)
1440 if (FAILED(IDirect3DCubeTexture9_GetLevelDesc(texture, m, &desc)))
1441 return D3DERR_INVALIDCALL;
1443 format = get_format_info(desc.Format);
1444 if (format->format == D3DFMT_UNKNOWN)
1446 FIXME("Unsupported texture format %#x\n", desc.Format);
1447 return D3DERR_INVALIDCALL;
1450 for (f = 0; f < 6; f++)
1452 if (FAILED(IDirect3DCubeTexture9_LockRect(texture, f, m, &lock_rect, NULL, D3DLOCK_DISCARD)))
1453 return D3DERR_INVALIDCALL;
1455 size.x = (f == 0) || (f == 1) ? 0.0f : 2.0f / desc.Width;
1456 size.y = (f == 2) || (f == 3) ? 0.0f : 2.0f / desc.Width;
1457 size.z = (f == 4) || (f == 5) ? 0.0f : 2.0f / desc.Width;
1459 data = lock_rect.pBits;
1461 for (y = 0; y < desc.Height; y++)
1463 for (x = 0; x < desc.Width; x++)
1465 coord.x = get_cube_coord(coordmap[f][0], x, y, desc.Width) / desc.Width * 2.0f - 1.0f;
1466 coord.y = get_cube_coord(coordmap[f][1], x, y, desc.Width) / desc.Width * 2.0f - 1.0f;
1467 coord.z = get_cube_coord(coordmap[f][2], x, y, desc.Width) / desc.Width * 2.0f - 1.0f;
1469 function(&value, &coord, &size, funcdata);
1471 pos = data + y * lock_rect.Pitch + x * format->bytes_per_pixel;
1473 for (i = 0; i < format->bytes_per_pixel; i++)
1474 pos[i] = 0;
1476 for (c = 0; c < 4; c++)
1478 switch (c)
1480 case 0: /* Alpha */
1481 comp_value = value.w;
1482 break;
1483 case 1: /* Red */
1484 comp_value = value.x;
1485 break;
1486 case 2: /* Green */
1487 comp_value = value.y;
1488 break;
1489 case 3: /* Blue */
1490 comp_value = value.z;
1491 break;
1494 v = comp_value * ((1 << format->bits[c]) - 1) + 0.5f;
1496 for (i = 0; i < format->bits[c] + format->shift[c]; i += 8)
1498 mask = ((1 << format->bits[c]) - 1) << format->shift[c] >> i;
1499 byte = (v << format->shift[c] >> i) & mask;
1500 pos[i / 8] |= byte;
1505 IDirect3DCubeTexture9_UnlockRect(texture, f, m);
1509 return D3D_OK;
1512 HRESULT WINAPI D3DXFillVolumeTexture(LPDIRECT3DVOLUMETEXTURE9 texture,
1513 LPD3DXFILL3D function,
1514 LPVOID funcdata)
1516 DWORD miplevels;
1517 DWORD m, i, x, y, z, c, v;
1518 D3DVOLUME_DESC desc;
1519 D3DLOCKED_BOX lock_box;
1520 D3DXVECTOR4 value;
1521 D3DXVECTOR3 coord, size;
1522 const PixelFormatDesc *format;
1523 BYTE *data, *pos;
1524 BYTE byte, mask;
1525 float comp_value;
1527 if (texture == NULL || function == NULL)
1528 return D3DERR_INVALIDCALL;
1530 miplevels = IDirect3DBaseTexture9_GetLevelCount(texture);
1532 for (m = 0; m < miplevels; m++)
1534 if (FAILED(IDirect3DVolumeTexture9_GetLevelDesc(texture, m, &desc)))
1535 return D3DERR_INVALIDCALL;
1537 format = get_format_info(desc.Format);
1538 if (format->format == D3DFMT_UNKNOWN)
1540 FIXME("Unsupported texture format %#x\n", desc.Format);
1541 return D3DERR_INVALIDCALL;
1544 if (FAILED(IDirect3DVolumeTexture9_LockBox(texture, m, &lock_box, NULL, D3DLOCK_DISCARD)))
1545 return D3DERR_INVALIDCALL;
1547 size.x = 1.0f / desc.Width;
1548 size.y = 1.0f / desc.Height;
1549 size.z = 1.0f / desc.Depth;
1551 data = lock_box.pBits;
1553 for (z = 0; z < desc.Depth; z++)
1555 /* The callback function expects the coordinates of the center
1556 of the texel */
1557 coord.z = (z + 0.5f) / desc.Depth;
1559 for (y = 0; y < desc.Height; y++)
1561 coord.y = (y + 0.5f) / desc.Height;
1563 for (x = 0; x < desc.Width; x++)
1565 coord.x = (x + 0.5f) / desc.Width;
1567 function(&value, &coord, &size, funcdata);
1569 pos = data + z * lock_box.SlicePitch + y * lock_box.RowPitch + x * format->bytes_per_pixel;
1571 for (i = 0; i < format->bytes_per_pixel; i++)
1572 pos[i] = 0;
1574 for (c = 0; c < 4; c++)
1576 switch (c)
1578 case 0: /* Alpha */
1579 comp_value = value.w;
1580 break;
1581 case 1: /* Red */
1582 comp_value = value.x;
1583 break;
1584 case 2: /* Green */
1585 comp_value = value.y;
1586 break;
1587 case 3: /* Blue */
1588 comp_value = value.z;
1589 break;
1592 v = comp_value * ((1 << format->bits[c]) - 1) + 0.5f;
1594 for (i = 0; i < format->bits[c] + format->shift[c]; i += 8)
1596 mask = ((1 << format->bits[c]) - 1) << format->shift[c] >> i;
1597 byte = (v << format->shift[c] >> i) & mask;
1598 pos[i / 8] |= byte;
1604 IDirect3DVolumeTexture9_UnlockBox(texture, m);
1607 return D3D_OK;
1610 HRESULT WINAPI D3DXSaveTextureToFileA(const char *dst_filename, D3DXIMAGE_FILEFORMAT file_format,
1611 IDirect3DBaseTexture9 *src_texture, const PALETTEENTRY *src_palette)
1613 int len;
1614 WCHAR *filename;
1615 HRESULT hr;
1616 ID3DXBuffer *buffer;
1618 TRACE("(%s, %#x, %p, %p): relay\n",
1619 wine_dbgstr_a(dst_filename), file_format, src_texture, src_palette);
1621 if (!dst_filename) return D3DERR_INVALIDCALL;
1623 len = MultiByteToWideChar(CP_ACP, 0, dst_filename, -1, NULL, 0);
1624 filename = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
1625 if (!filename) return E_OUTOFMEMORY;
1626 MultiByteToWideChar(CP_ACP, 0, dst_filename, -1, filename, len);
1628 hr = D3DXSaveTextureToFileInMemory(&buffer, file_format, src_texture, src_palette);
1629 if (SUCCEEDED(hr))
1631 hr = write_buffer_to_file(filename, buffer);
1632 ID3DXBuffer_Release(buffer);
1635 HeapFree(GetProcessHeap(), 0, filename);
1636 return hr;
1639 HRESULT WINAPI D3DXSaveTextureToFileW(const WCHAR *dst_filename, D3DXIMAGE_FILEFORMAT file_format,
1640 IDirect3DBaseTexture9 *src_texture, const PALETTEENTRY *src_palette)
1642 HRESULT hr;
1643 ID3DXBuffer *buffer;
1645 TRACE("(%s, %#x, %p, %p): relay\n",
1646 wine_dbgstr_w(dst_filename), file_format, src_texture, src_palette);
1648 if (!dst_filename) return D3DERR_INVALIDCALL;
1650 hr = D3DXSaveTextureToFileInMemory(&buffer, file_format, src_texture, src_palette);
1651 if (SUCCEEDED(hr))
1653 hr = write_buffer_to_file(dst_filename, buffer);
1654 ID3DXBuffer_Release(buffer);
1657 return hr;
1660 HRESULT WINAPI D3DXSaveTextureToFileInMemory(ID3DXBuffer **dst_buffer, D3DXIMAGE_FILEFORMAT file_format,
1661 IDirect3DBaseTexture9 *src_texture, const PALETTEENTRY *src_palette)
1663 HRESULT hr;
1664 D3DRESOURCETYPE type;
1665 IDirect3DSurface9 *surface;
1667 TRACE("(%p, %#x, %p, %p)\n",
1668 dst_buffer, file_format, src_texture, src_palette);
1670 if (!dst_buffer || !src_texture) return D3DERR_INVALIDCALL;
1672 if (file_format == D3DXIFF_DDS)
1674 FIXME("DDS file format isn't supported yet\n");
1675 return E_NOTIMPL;
1678 type = IDirect3DBaseTexture9_GetType(src_texture);
1679 switch (type)
1681 case D3DRTYPE_TEXTURE:
1682 case D3DRTYPE_CUBETEXTURE:
1683 hr = get_surface(type, src_texture, D3DCUBEMAP_FACE_POSITIVE_X, 0, &surface);
1684 break;
1685 case D3DRTYPE_VOLUMETEXTURE:
1686 FIXME("Volume textures aren't supported yet\n");
1687 return E_NOTIMPL;
1688 default:
1689 return D3DERR_INVALIDCALL;
1692 if (SUCCEEDED(hr))
1694 hr = D3DXSaveSurfaceToFileInMemory(dst_buffer, file_format, surface, src_palette, NULL);
1695 IDirect3DSurface9_Release(surface);
1698 return hr;