/*
 * Copyright 2009 Tony Wasserka
 * Copyright 2010 Christian Costa
 * Copyright 2010 Owen Rudge for CodeWeavers
 * Copyright 2010 Matteo Bruni for CodeWeavers
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "wine/unicode.h"
#include "wine/debug.h"
#include "d3dx9_36_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(d3dx);

/* Returns TRUE if num is a power of 2, FALSE if not, or if 0 */
static BOOL is_pow2(UINT num)
{
    return !(num & (num - 1));
}

/* Returns the smallest power of 2 which is greater than or equal to num */
static UINT make_pow2(UINT num)
{
    UINT result = 1;

    /* In the unlikely event somebody passes a large value, make sure we don't enter an infinite loop */
    if (num >= 0x80000000)
        return 0x80000000;

    while (result < num)
        result <<= 1;

    return result;
}

static HRESULT get_surface(D3DRESOURCETYPE type, LPDIRECT3DBASETEXTURE9 tex,
                           int face, UINT level, LPDIRECT3DSURFACE9 *surf)
{
    switch (type)
    {
        case D3DRTYPE_TEXTURE:
            return IDirect3DTexture9_GetSurfaceLevel((IDirect3DTexture9*) tex, level, surf);
        case D3DRTYPE_CUBETEXTURE:
            return IDirect3DCubeTexture9_GetCubeMapSurface((IDirect3DCubeTexture9*) tex, face, level, surf);
        default:
            ERR("Unexpected texture type\n");
            return E_NOTIMPL;
    }
}

HRESULT WINAPI D3DXFilterTexture(LPDIRECT3DBASETEXTURE9 texture,
                                 CONST PALETTEENTRY *palette,
                                 UINT srclevel,
                                 DWORD filter)
{
    UINT level;
    HRESULT hr;
    D3DRESOURCETYPE type;

    TRACE("(%p, %p, %d, %d)\n", texture, palette, srclevel, filter);

    if (!texture)
        return D3DERR_INVALIDCALL;

    if ((filter & 0xFFFF) > D3DX_FILTER_BOX && filter != D3DX_DEFAULT)
        return D3DERR_INVALIDCALL;

    if (srclevel >= IDirect3DBaseTexture9_GetLevelCount(texture))
        return D3DERR_INVALIDCALL;

    switch (type = IDirect3DBaseTexture9_GetType(texture))
    {
        case D3DRTYPE_TEXTURE:
        case D3DRTYPE_CUBETEXTURE:
        {
            IDirect3DSurface9 *topsurf, *mipsurf;
            D3DSURFACE_DESC desc;
            int i, numfaces;

            if (type == D3DRTYPE_TEXTURE)
            {
                numfaces = 1;
                IDirect3DTexture9_GetLevelDesc((IDirect3DTexture9*) texture, srclevel, &desc);
            }
            else
            {
                numfaces = 6;
                IDirect3DCubeTexture9_GetLevelDesc((IDirect3DTexture9*) texture, srclevel, &desc);
            }

            if (filter == D3DX_DEFAULT)
            {
                if (is_pow2(desc.Width) && is_pow2(desc.Height))
                    filter = D3DX_FILTER_BOX;
                else
                    filter = D3DX_FILTER_BOX | D3DX_FILTER_DITHER;
            }

            for (i = 0; i < numfaces; i++)
            {
                level = srclevel + 1;
                hr = get_surface(type, texture, i, srclevel, &topsurf);

                if (FAILED(hr))
                    return D3DERR_INVALIDCALL;

                while (get_surface(type, texture, i, level, &mipsurf) == D3D_OK)
                {
                    hr = D3DXLoadSurfaceFromSurface(mipsurf, palette, NULL, topsurf, palette, NULL, filter, 0);
                    IDirect3DSurface9_Release(topsurf);
                    topsurf = mipsurf;

                    if (FAILED(hr))
                        break;

                    level++;
                }

                IDirect3DSurface9_Release(topsurf);
                if (FAILED(hr))
                    return hr;
            }

            return D3D_OK;
        }

        default:
            FIXME("Implement volume texture filtering\n");
            return E_NOTIMPL;
    }
}

HRESULT WINAPI D3DXCheckTextureRequirements(LPDIRECT3DDEVICE9 device,
                                            UINT* width,
                                            UINT* height,
                                            UINT* miplevels,
                                            DWORD usage,
                                            D3DFORMAT* format,
                                            D3DPOOL pool)
{
    UINT w = (width && *width) ? *width : 1;
    UINT h = (height && *height) ? *height : 1;
    D3DCAPS9 caps;
    D3DDEVICE_CREATION_PARAMETERS params;
    IDirect3D9 *d3d = NULL;
    D3DDISPLAYMODE mode;
    HRESULT hr;
    D3DFORMAT usedformat = D3DFMT_UNKNOWN;

    TRACE("(%p, %p, %p, %p, %u, %p, %u)\n", device, width, height, miplevels, usage, format, pool);

    if (!device)
        return D3DERR_INVALIDCALL;

    /* usage */
    if (usage == D3DX_DEFAULT)
        usage = 0;
    if (usage & (D3DUSAGE_WRITEONLY | D3DUSAGE_DONOTCLIP | D3DUSAGE_POINTS | D3DUSAGE_RTPATCHES | D3DUSAGE_NPATCHES))
        return D3DERR_INVALIDCALL;

    /* pool */
    if ((pool != D3DPOOL_DEFAULT) && (pool != D3DPOOL_MANAGED) && (pool != D3DPOOL_SYSTEMMEM) && (pool != D3DPOOL_SCRATCH))
        return D3DERR_INVALIDCALL;

    /* width and height */
    if (FAILED(IDirect3DDevice9_GetDeviceCaps(device, &caps)))
        return D3DERR_INVALIDCALL;

    /* 256 x 256 default width/height */
    if ((w == D3DX_DEFAULT) && (h == D3DX_DEFAULT))
        w = h = 256;
    else if (w == D3DX_DEFAULT)
        w = (height ? h : 256);
    else if (h == D3DX_DEFAULT)
        h = (width ? w : 256);

    /* ensure width/height is power of 2 */
    if ((caps.TextureCaps & D3DPTEXTURECAPS_POW2) && (!is_pow2(w)))
        w = make_pow2(w);

    if (w > caps.MaxTextureWidth)
        w = caps.MaxTextureWidth;

    if ((caps.TextureCaps & D3DPTEXTURECAPS_POW2) && (!is_pow2(h)))
        h = make_pow2(h);

    if (h > caps.MaxTextureHeight)
        h = caps.MaxTextureHeight;

    /* texture must be square? */
    if (caps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY)
    {
        if (w > h)
            h = w;
        else
            w = h;
    }

    if (width)
        *width = w;

    if (height)
        *height = h;

    /* miplevels */
    if (miplevels && (usage & D3DUSAGE_AUTOGENMIPMAP))
    {
        if (*miplevels > 1)
            *miplevels = 0;
    }
    else if (miplevels)
    {
        UINT max_mipmaps = 1;

        if (!width && !height)
            max_mipmaps = 9;    /* number of mipmaps in a 256x256 texture */
        else
        {
            UINT max_dimen = max(w, h);

            while (max_dimen > 1)
            {
                max_dimen >>= 1;
                max_mipmaps++;
            }
        }

        if (*miplevels == 0 || *miplevels > max_mipmaps)
            *miplevels = max_mipmaps;
    }

    /* format */
    if (format)
    {
        TRACE("Requested format %x\n", *format);
        usedformat = *format;
    }

    hr = IDirect3DDevice9_GetDirect3D(device, &d3d);

    if (FAILED(hr))
        goto cleanup;

    hr = IDirect3DDevice9_GetCreationParameters(device, &params);

    if (FAILED(hr))
        goto cleanup;

    hr = IDirect3DDevice9_GetDisplayMode(device, 0, &mode);

    if (FAILED(hr))
        goto cleanup;

    if ((usedformat == D3DFMT_UNKNOWN) || (usedformat == D3DX_DEFAULT))
        usedformat = D3DFMT_A8R8G8B8;

    hr = IDirect3D9_CheckDeviceFormat(d3d, params.AdapterOrdinal, params.DeviceType, mode.Format,
        usage, D3DRTYPE_TEXTURE, usedformat);

    if (FAILED(hr))
    {
        /* Heuristic to choose the fallback format */
        const PixelFormatDesc *fmt = get_format_info(usedformat);
        BOOL allow_24bits;
        int bestscore = INT_MIN, i = 0, j;
        unsigned int channels;
        const PixelFormatDesc *curfmt;

        if (!fmt)
        {
            FIXME("Pixel format %x not handled\n", usedformat);
            goto cleanup;
        }

        allow_24bits = fmt->bytes_per_pixel == 3;
        channels = (fmt->bits[0] ? 1 : 0) + (fmt->bits[1] ? 1 : 0)
            + (fmt->bits[2] ? 1 : 0) + (fmt->bits[3] ? 1 : 0);
        usedformat = D3DFMT_UNKNOWN;

        while ((curfmt = get_format_info_idx(i)))
        {
            unsigned int curchannels = (curfmt->bits[0] ? 1 : 0) + (curfmt->bits[1] ? 1 : 0)
                + (curfmt->bits[2] ? 1 : 0) + (curfmt->bits[3] ? 1 : 0);
            int score;

            i++;

            if (curchannels < channels)
                continue;
            if (curfmt->bytes_per_pixel == 3 && !allow_24bits)
                continue;

            hr = IDirect3D9_CheckDeviceFormat(d3d, params.AdapterOrdinal, params.DeviceType,
                mode.Format, usage, D3DRTYPE_TEXTURE, curfmt->format);
            if (FAILED(hr))
                continue;

            /* This format can be used, let's evaluate it.
               Weights chosen quite arbitrarily... */
            score = 16 - 4 * (curchannels - channels);

            for (j = 0; j < 4; j++)
            {
                int diff = curfmt->bits[j] - fmt->bits[j];
                score += 16 - (diff < 0 ? -diff * 4 : diff);
            }

            if (score > bestscore)
            {
                bestscore = score;
                usedformat = curfmt->format;
            }
        }
        hr = D3D_OK;
    }

cleanup:

    if (d3d)
        IDirect3D9_Release(d3d);

    if (FAILED(hr))
        return hr;

    if (usedformat == D3DFMT_UNKNOWN)
    {
        WARN("Couldn't find a suitable pixel format\n");
        return D3DERR_NOTAVAILABLE;
    }

    TRACE("Format chosen: %x\n", usedformat);
    if (format)
        *format = usedformat;

    return D3D_OK;
}

HRESULT WINAPI D3DXCheckCubeTextureRequirements(LPDIRECT3DDEVICE9 device,
                                                UINT *size,
                                                UINT *miplevels,
                                                DWORD usage,
                                                D3DFORMAT *format,
                                                D3DPOOL pool)
{
    D3DCAPS9 caps;
    UINT s = (size && *size) ? *size : 256;
    HRESULT hr;

    TRACE("(%p, %p, %p, %u, %p, %u)\n", device, size, miplevels, usage, format, pool);

    if (s == D3DX_DEFAULT)
        s = 256;

    if (!device || FAILED(IDirect3DDevice9_GetDeviceCaps(device, &caps)))
        return D3DERR_INVALIDCALL;

    if (!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP))
        return D3DERR_NOTAVAILABLE;

    /* ensure width/height is power of 2 */
    if ((caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2) && (!is_pow2(s)))
        s = make_pow2(s);

    hr = D3DXCheckTextureRequirements(device, &s, &s, miplevels, usage, format, pool);

    if (!(caps.TextureCaps & D3DPTEXTURECAPS_MIPCUBEMAP))
    {
        if(miplevels)
            *miplevels = 1;
    }

    if (size)
        *size = s;

    return hr;
}

HRESULT WINAPI D3DXCheckVolumeTextureRequirements(LPDIRECT3DDEVICE9 device,
                                                  UINT *width,
                                                  UINT *height,
                                                  UINT *depth,
                                                  UINT *miplevels,
                                                  DWORD usage,
                                                  D3DFORMAT *format,
                                                  D3DPOOL pool)
{
    D3DCAPS9 caps;
    UINT w = width ? *width : D3DX_DEFAULT;
    UINT h = height ? *height : D3DX_DEFAULT;
    UINT d = (depth && *depth) ? *depth : 1;
    HRESULT hr;

    TRACE("(%p, %p, %p, %p, %p, %u, %p, %u)\n", device, width, height, depth, miplevels,
          usage, format, pool);

    if (!device || FAILED(IDirect3DDevice9_GetDeviceCaps(device, &caps)))
        return D3DERR_INVALIDCALL;

    if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
        return D3DERR_NOTAVAILABLE;

    hr = D3DXCheckTextureRequirements(device, &w, &h, NULL, usage, format, pool);
    if (d == D3DX_DEFAULT)
        d = 1;

    /* ensure width/height is power of 2 */
    if ((caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP_POW2) &&
        (!is_pow2(w) || !is_pow2(h) || !is_pow2(d)))
    {
        w = make_pow2(w);
        h = make_pow2(h);
        d = make_pow2(d);
    }

    if (w > caps.MaxVolumeExtent)
        w = caps.MaxVolumeExtent;
    if (h > caps.MaxVolumeExtent)
        h = caps.MaxVolumeExtent;
    if (d > caps.MaxVolumeExtent)
        d = caps.MaxVolumeExtent;

    if (miplevels)
    {
        if (!(caps.TextureCaps & D3DPTEXTURECAPS_MIPVOLUMEMAP))
            *miplevels = 1;
        else if ((usage & D3DUSAGE_AUTOGENMIPMAP))
        {
            if (*miplevels > 1)
                *miplevels = 0;
        }
        else
        {
            UINT max_mipmaps = 1;
            UINT max_dimen = max(max(w, h), d);

            while (max_dimen > 1)
            {
                max_dimen >>= 1;
                max_mipmaps++;
            }

            if (*miplevels == 0 || *miplevels > max_mipmaps)
                *miplevels = max_mipmaps;
        }
    }

    if (width)
        *width = w;
    if (height)
        *height = h;
    if (depth)
        *depth = d;

    return hr;
}

HRESULT WINAPI D3DXCreateTexture(LPDIRECT3DDEVICE9 pDevice,
                                 UINT width,
                                 UINT height,
                                 UINT miplevels,
                                 DWORD usage,
                                 D3DFORMAT format,
                                 D3DPOOL pool,
                                 LPDIRECT3DTEXTURE9 *ppTexture)
{
    HRESULT hr;

    TRACE("(%p, %u, %u, %u, %x, %x, %x, %p)\n", pDevice, width, height, miplevels, usage, format,
        pool, ppTexture);

    if (!pDevice || !ppTexture)
        return D3DERR_INVALIDCALL;

    hr = D3DXCheckTextureRequirements(pDevice, &width, &height, &miplevels, usage, &format, pool);

    if (FAILED(hr))
        return hr;

    return IDirect3DDevice9_CreateTexture(pDevice, width, height, miplevels, usage, format, pool, ppTexture, NULL);
}

HRESULT WINAPI D3DXCreateTextureFromFileInMemoryEx(LPDIRECT3DDEVICE9 device,
                                                   LPCVOID srcdata,
                                                   UINT srcdatasize,
                                                   UINT width,
                                                   UINT height,
                                                   UINT miplevels,
                                                   DWORD usage,
                                                   D3DFORMAT format,
                                                   D3DPOOL pool,
                                                   DWORD filter,
                                                   DWORD mipfilter,
                                                   D3DCOLOR colorkey,
                                                   D3DXIMAGE_INFO* srcinfo,
                                                   PALETTEENTRY* palette,
                                                   LPDIRECT3DTEXTURE9* texture)
{
    IDirect3DTexture9 **texptr;
    IDirect3DTexture9 *buftex;
    IDirect3DSurface9 *surface;
    BOOL file_width = FALSE, file_height = FALSE;
    BOOL file_format = FALSE, file_miplevels = FALSE;
    BOOL dynamic_texture;
    D3DXIMAGE_INFO imginfo;
    UINT loaded_miplevels;
    D3DCAPS9 caps;
    HRESULT hr;

    TRACE("(%p, %p, %u, %u, %u, %u, %x, %x, %x, %u, %u, %x, %p, %p, %p)\n", device, srcdata, srcdatasize, width,
        height, miplevels, usage, format, pool, filter, mipfilter, colorkey, srcinfo, palette, texture);

    /* check for invalid parameters */
    if (!device || !texture || !srcdata || !srcdatasize)
        return D3DERR_INVALIDCALL;

    hr = D3DXGetImageInfoFromFileInMemory(srcdata, srcdatasize, &imginfo);

    if (FAILED(hr))
    {
        *texture = NULL;
        return hr;
    }

    /* handle default values */
    if (width == 0 || width == D3DX_DEFAULT_NONPOW2)
        width = imginfo.Width;

    if (height == 0 || height == D3DX_DEFAULT_NONPOW2)
        height = imginfo.Height;

    if (width == D3DX_DEFAULT)
        width = make_pow2(imginfo.Width);

    if (height == D3DX_DEFAULT)
        height = make_pow2(imginfo.Height);

    if (format == D3DFMT_UNKNOWN || format == D3DX_DEFAULT)
        format = imginfo.Format;

    if (width == D3DX_FROM_FILE)
    {
        file_width = TRUE;
        width = imginfo.Width;
    }

    if (height == D3DX_FROM_FILE)
    {
        file_height = TRUE;
        height = imginfo.Height;
    }

    if (format == D3DFMT_FROM_FILE)
    {
        file_format = TRUE;
        format = imginfo.Format;
    }

    if (miplevels == D3DX_FROM_FILE)
    {
        file_miplevels = TRUE;
        miplevels = imginfo.MipLevels;
    }

    /* fix texture creation parameters */
    hr = D3DXCheckTextureRequirements(device, &width, &height, &miplevels, usage, &format, pool);

    if (FAILED(hr))
    {
        *texture = NULL;
        return hr;
    }

    if (imginfo.MipLevels < miplevels && (D3DFMT_DXT1 <= imginfo.Format && imginfo.Format <= D3DFMT_DXT5))
    {
        FIXME("Generation of mipmaps for compressed pixel formats is not implemented yet\n");
        miplevels = imginfo.MipLevels;
    }

    if (((file_width) && (width != imginfo.Width))    ||
        ((file_height) && (height != imginfo.Height)) ||
        ((file_format) && (format != imginfo.Format)) ||
        ((file_miplevels) && (miplevels != imginfo.MipLevels)))
    {
        return D3DERR_NOTAVAILABLE;
    }

    if (FAILED(IDirect3DDevice9_GetDeviceCaps(device, &caps)))
        return D3DERR_INVALIDCALL;

    /* Create the to-be-filled texture */
    dynamic_texture = (caps.Caps2 & D3DCAPS2_DYNAMICTEXTURES) && (usage & D3DUSAGE_DYNAMIC);
    if (pool == D3DPOOL_DEFAULT && !dynamic_texture)
    {
        hr = D3DXCreateTexture(device, width, height, miplevels, usage, format, D3DPOOL_SYSTEMMEM, &buftex);
        texptr = &buftex;
    }
    else
    {
        hr = D3DXCreateTexture(device, width, height, miplevels, usage, format, pool, texture);
        texptr = texture;
    }

    if (FAILED(hr))
    {
        *texture = NULL;
        return hr;
    }

    /* Load the file */
    if (imginfo.ImageFileFormat != D3DXIFF_DDS)
    {
        IDirect3DTexture9_GetSurfaceLevel(*texptr, 0, &surface);
        hr = D3DXLoadSurfaceFromFileInMemory(surface, palette, NULL, srcdata, srcdatasize, NULL, filter, colorkey, NULL);
        IDirect3DSurface9_Release(surface);
    }
    else
    {
        hr = load_texture_from_dds(*texptr, srcdata, palette, filter, colorkey, &imginfo);
    }

    if (FAILED(hr))
    {
        IDirect3DTexture9_Release(*texptr);
        *texture = NULL;
        return hr;
    }

    loaded_miplevels = min(IDirect3DTexture9_GetLevelCount(*texptr), imginfo.MipLevels);
    hr = D3DXFilterTexture((IDirect3DBaseTexture9*) *texptr, palette, loaded_miplevels - 1, mipfilter);

    if (FAILED(hr))
    {
        IDirect3DTexture9_Release(*texptr);
        *texture = NULL;
        return hr;
    }

    /* Move the data to the actual texture if necessary */
    if (texptr == &buftex)
    {
        hr = D3DXCreateTexture(device, width, height, miplevels, usage, format, pool, texture);

        if (FAILED(hr))
        {
            IDirect3DTexture9_Release(buftex);
            *texture = NULL;
            return hr;
        }

        IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9*)buftex, (IDirect3DBaseTexture9*)(*texture));
        IDirect3DTexture9_Release(buftex);
    }

    if (srcinfo)
        *srcinfo = imginfo;

    return D3D_OK;
}

HRESULT WINAPI D3DXCreateTextureFromFileInMemory(LPDIRECT3DDEVICE9 device,
                                                 LPCVOID srcdata,
                                                 UINT srcdatasize,
                                                 LPDIRECT3DTEXTURE9 *texture)
{
    TRACE("(%p, %p, %d, %p)\n", device, srcdata, srcdatasize, texture);

    return D3DXCreateTextureFromFileInMemoryEx(device, srcdata, srcdatasize, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN,
                                               D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, texture);
}

HRESULT WINAPI D3DXCreateTextureFromFileExW(LPDIRECT3DDEVICE9 device,
                                            LPCWSTR srcfile,
                                            UINT width,
                                            UINT height,
                                            UINT miplevels,
                                            DWORD usage,
                                            D3DFORMAT format,
                                            D3DPOOL pool,
                                            DWORD filter,
                                            DWORD mipfilter,
                                            D3DCOLOR colorkey,
                                            D3DXIMAGE_INFO *srcinfo,
                                            PALETTEENTRY *palette,
                                            LPDIRECT3DTEXTURE9 *texture)
{
    HRESULT hr;
    DWORD size;
    LPVOID buffer;

    TRACE("(%p, %s, %u, %u, %u, %x, %x, %x, %u, %u, %x, %p, %p, %p): relay\n",
            device, debugstr_w(srcfile), width, height, miplevels, usage, format, pool, filter,
            mipfilter, colorkey, srcinfo, palette, texture);

    if (!srcfile)
        return D3DERR_INVALIDCALL;

    hr = map_view_of_file(srcfile, &buffer, &size);
    if (FAILED(hr))
        return D3DXERR_INVALIDDATA;

    hr = D3DXCreateTextureFromFileInMemoryEx(device, buffer, size, width, height, miplevels, usage, format, pool,
        filter, mipfilter, colorkey, srcinfo, palette, texture);

    UnmapViewOfFile(buffer);

    return hr;
}

HRESULT WINAPI D3DXCreateTextureFromFileExA(LPDIRECT3DDEVICE9 device,
                                            LPCSTR srcfile,
                                            UINT width,
                                            UINT height,
                                            UINT miplevels,
                                            DWORD usage,
                                            D3DFORMAT format,
                                            D3DPOOL pool,
                                            DWORD filter,
                                            DWORD mipfilter,
                                            D3DCOLOR colorkey,
                                            D3DXIMAGE_INFO *srcinfo,
                                            PALETTEENTRY *palette,
                                            LPDIRECT3DTEXTURE9 *texture)
{
    LPWSTR widename;
    HRESULT hr;
    DWORD len;

    TRACE("(%p, %s, %u, %u, %u, %x, %x, %x, %u, %u, %x, %p, %p, %p): relay\n",
            device, debugstr_a(srcfile), width, height, miplevels, usage, format, pool, filter,
            mipfilter, colorkey, srcinfo, palette, texture);

    if (!device || !srcfile || !texture)
        return D3DERR_INVALIDCALL;

    len = MultiByteToWideChar(CP_ACP, 0, srcfile, -1, NULL, 0);
    widename = HeapAlloc(GetProcessHeap(), 0, len * sizeof(*widename));
    MultiByteToWideChar(CP_ACP, 0, srcfile, -1, widename, len);

    hr = D3DXCreateTextureFromFileExW(device, widename, width, height, miplevels,
                                      usage, format, pool, filter, mipfilter,
                                      colorkey, srcinfo, palette, texture);

    HeapFree(GetProcessHeap(), 0, widename);
    return hr;
}

HRESULT WINAPI D3DXCreateTextureFromFileA(LPDIRECT3DDEVICE9 device,
                                          LPCSTR srcfile,
                                          LPDIRECT3DTEXTURE9 *texture)
{
    TRACE("(%p, %s, %p)\n", device, debugstr_a(srcfile), texture);

    return D3DXCreateTextureFromFileExA(device, srcfile, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN,
                                        D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, texture);
}

HRESULT WINAPI D3DXCreateTextureFromFileW(LPDIRECT3DDEVICE9 device,
                                          LPCWSTR srcfile,
                                          LPDIRECT3DTEXTURE9 *texture)
{
    TRACE("(%p, %s, %p)\n", device, debugstr_w(srcfile), texture);

    return D3DXCreateTextureFromFileExW(device, srcfile, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN,
                                        D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, texture);
}


HRESULT WINAPI D3DXCreateTextureFromResourceA(LPDIRECT3DDEVICE9 device,
                                              HMODULE srcmodule,
                                              LPCSTR resource,
                                              LPDIRECT3DTEXTURE9 *texture)
{
    TRACE("(%p, %s): relay\n", srcmodule, debugstr_a(resource));

    return D3DXCreateTextureFromResourceExA(device, srcmodule, resource, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN,
                                            D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, texture);
}

HRESULT WINAPI D3DXCreateTextureFromResourceW(LPDIRECT3DDEVICE9 device,
                                              HMODULE srcmodule,
                                              LPCWSTR resource,
                                              LPDIRECT3DTEXTURE9 *texture)
{
    TRACE("(%p, %s): relay\n", srcmodule, debugstr_w(resource));

    return D3DXCreateTextureFromResourceExW(device, srcmodule, resource, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN,
                                            D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, texture);
}

HRESULT WINAPI D3DXCreateTextureFromResourceExA(LPDIRECT3DDEVICE9 device,
                                                HMODULE srcmodule,
                                                LPCSTR resource,
                                                UINT width,
                                                UINT height,
                                                UINT miplevels,
                                                DWORD usage,
                                                D3DFORMAT format,
                                                D3DPOOL pool,
                                                DWORD filter,
                                                DWORD mipfilter,
                                                D3DCOLOR colorkey,
                                                D3DXIMAGE_INFO *srcinfo,
                                                PALETTEENTRY *palette,
                                                LPDIRECT3DTEXTURE9 *texture)
{
    HRSRC resinfo;

    TRACE("(%p, %s): relay\n", srcmodule, debugstr_a(resource));

    if (!device || !texture)
        return D3DERR_INVALIDCALL;

    resinfo = FindResourceA(srcmodule, resource, (LPCSTR) RT_RCDATA);

    if (resinfo)
    {
        LPVOID buffer;
        HRESULT hr;
        DWORD size;

        hr = load_resource_into_memory(srcmodule, resinfo, &buffer, &size);

        if (FAILED(hr))
            return D3DXERR_INVALIDDATA;

        return D3DXCreateTextureFromFileInMemoryEx(device, buffer, size, width,
                                                   height, miplevels, usage, format,
                                                   pool, filter, mipfilter, colorkey,
                                                   srcinfo, palette, texture);
    }

    /* Try loading the resource as bitmap data */
    resinfo = FindResourceA(srcmodule, resource, (LPCSTR) RT_BITMAP);

    if (resinfo)
    {
        FIXME("Implement loading bitmaps from resource type RT_BITMAP\n");
        return E_NOTIMPL;
    }

    return D3DXERR_INVALIDDATA;
}

HRESULT WINAPI D3DXCreateTextureFromResourceExW(LPDIRECT3DDEVICE9 device,
                                                HMODULE srcmodule,
                                                LPCWSTR resource,
                                                UINT width,
                                                UINT height,
                                                UINT miplevels,
                                                DWORD usage,
                                                D3DFORMAT format,
                                                D3DPOOL pool,
                                                DWORD filter,
                                                DWORD mipfilter,
                                                D3DCOLOR colorkey,
                                                D3DXIMAGE_INFO *srcinfo,
                                                PALETTEENTRY *palette,
                                                LPDIRECT3DTEXTURE9 *texture)
{
    HRSRC resinfo;

    TRACE("(%p, %s): relay\n", srcmodule, debugstr_w(resource));

    if (!device || !texture)
        return D3DERR_INVALIDCALL;

    resinfo = FindResourceW(srcmodule, resource, (LPCWSTR) RT_RCDATA);

    if (resinfo)
    {
        LPVOID buffer;
        HRESULT hr;
        DWORD size;

        hr = load_resource_into_memory(srcmodule, resinfo, &buffer, &size);

        if (FAILED(hr))
            return D3DXERR_INVALIDDATA;

        return D3DXCreateTextureFromFileInMemoryEx(device, buffer, size, width,
                                                   height, miplevels, usage, format,
                                                   pool, filter, mipfilter, colorkey,
                                                   srcinfo, palette, texture);
    }

    /* Try loading the resource as bitmap data */
    resinfo = FindResourceW(srcmodule, resource, (LPCWSTR) RT_BITMAP);

    if (resinfo)
    {
        FIXME("Implement loading bitmaps from resource type RT_BITMAP\n");
        return E_NOTIMPL;
    }

    return D3DXERR_INVALIDDATA;
}

HRESULT WINAPI D3DXCreateCubeTexture(LPDIRECT3DDEVICE9 device,
                                     UINT size,
                                     UINT miplevels,
                                     DWORD usage,
                                     D3DFORMAT format,
                                     D3DPOOL pool,
                                     LPDIRECT3DCUBETEXTURE9 *texture)
{
    HRESULT hr;

    TRACE("(%p, %u, %u, %#x, %#x, %#x, %p)\n", device, size, miplevels, usage, format,
        pool, texture);

    if (!device || !texture)
        return D3DERR_INVALIDCALL;

    hr = D3DXCheckCubeTextureRequirements(device, &size, &miplevels, usage, &format, pool);

    if (FAILED(hr))
    {
        TRACE("D3DXCheckCubeTextureRequirements failed\n");
        return hr;
    }

    return IDirect3DDevice9_CreateCubeTexture(device, size, miplevels, usage, format, pool, texture, NULL);
}

HRESULT WINAPI D3DXCreateCubeTextureFromFileInMemory(LPDIRECT3DDEVICE9 device,
                                                     LPCVOID data,
                                                     UINT datasize,
                                                     LPDIRECT3DCUBETEXTURE9 *texture)
{
    TRACE("(%p, %p, %u, %p)\n", device, data, datasize, texture);

    return D3DXCreateCubeTextureFromFileInMemoryEx(device, data, datasize, D3DX_DEFAULT, D3DX_DEFAULT,
        0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, texture);
}

HRESULT WINAPI D3DXCreateVolumeTexture(LPDIRECT3DDEVICE9 device,
                                       UINT width,
                                       UINT height,
                                       UINT depth,
                                       UINT miplevels,
                                       DWORD usage,
                                       D3DFORMAT format,
                                       D3DPOOL pool,
                                       LPDIRECT3DVOLUMETEXTURE9 *texture)
{
    HRESULT hr;

    TRACE("(%p, %u, %u, %u, %u, %#x, %#x, %#x, %p)\n", device, width, height, depth,
          miplevels, usage, format, pool, texture);

    if (!device || !texture)
        return D3DERR_INVALIDCALL;

    hr = D3DXCheckVolumeTextureRequirements(device, &width, &height, &depth,
                                            &miplevels, usage, &format, pool);

    if (FAILED(hr))
    {
        TRACE("D3DXCheckVolumeTextureRequirements failed\n");
        return hr;
    }

    return IDirect3DDevice9_CreateVolumeTexture(device, width, height, depth, miplevels,
                                                usage, format, pool, texture, NULL);
}

HRESULT WINAPI D3DXCreateVolumeTextureFromFileInMemory(LPDIRECT3DDEVICE9 device,
                                                      LPCVOID data,
                                                      UINT datasize,
                                                      LPDIRECT3DVOLUMETEXTURE9 *texture)
{
    TRACE("(%p, %p, %u, %p)\n", device, data, datasize, texture);

    return D3DXCreateVolumeTextureFromFileInMemoryEx(device, data, datasize, D3DX_DEFAULT, D3DX_DEFAULT,
        D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT,
        0, NULL, NULL, texture);
}

HRESULT WINAPI D3DXCreateVolumeTextureFromFileInMemoryEx(LPDIRECT3DDEVICE9 device,
                                                         LPCVOID data,
                                                         UINT datasize,
                                                         UINT width,
                                                         UINT height,
                                                         UINT depth,
                                                         UINT miplevels,
                                                         DWORD usage,
                                                         D3DFORMAT format,
                                                         D3DPOOL pool,
                                                         DWORD filter,
                                                         DWORD mipfilter,
                                                         D3DCOLOR colorkey,
                                                         D3DXIMAGE_INFO *imageinfo,
                                                         PALETTEENTRY *palette,
                                                         LPDIRECT3DVOLUMETEXTURE9 *texture)
{
    FIXME("(%p, %p, %u, %u, %u, %u, %u, %#x, %#x, %#x, %#x, %#x, %#x, %p, %p, %p) : stub\n",
        device, data, datasize, width, height, depth, miplevels, usage, format, pool,
        filter, mipfilter, colorkey, imageinfo, palette, texture);

    return E_NOTIMPL;
}

HRESULT WINAPI D3DXFillTexture(LPDIRECT3DTEXTURE9 texture,
                               LPD3DXFILL2D function,
                               LPVOID funcdata)
{
    DWORD miplevels;
    DWORD m, i, x, y, c, v;
    D3DSURFACE_DESC desc;
    D3DLOCKED_RECT lock_rect;
    D3DXVECTOR4 value;
    D3DXVECTOR2 coord, size;
    const PixelFormatDesc *format;
    BYTE *data, *pos;
    BYTE byte, mask;
    float comp_value;

    if (texture == NULL || function == NULL)
        return D3DERR_INVALIDCALL;

    miplevels = IDirect3DBaseTexture9_GetLevelCount(texture);

    for (m = 0; m < miplevels; m++)
    {
        if (FAILED(IDirect3DTexture9_GetLevelDesc(texture, m, &desc)))
            return D3DERR_INVALIDCALL;

        format = get_format_info(desc.Format);
        if (format->format == D3DFMT_UNKNOWN)
        {
            FIXME("Unsupported texture format %#x\n", desc.Format);
            return D3DERR_INVALIDCALL;
        }

        if (FAILED(IDirect3DTexture9_LockRect(texture, m, &lock_rect, NULL, D3DLOCK_DISCARD)))
            return D3DERR_INVALIDCALL;

        size.x = 1.0f / desc.Width;
        size.y = 1.0f / desc.Height;

        data = lock_rect.pBits;

        for (y = 0; y < desc.Height; y++)
        {
            /* The callback function expects the coordinates of the center
               of the texel */
            coord.y = (y + 0.5f) / desc.Height;

            for (x = 0; x < desc.Width; x++)
            {
                coord.x = (x + 0.5f) / desc.Width;

                function(&value, &coord, &size, funcdata);

                pos = data + y * lock_rect.Pitch + x * format->bytes_per_pixel;

                for (i = 0; i < format->bytes_per_pixel; i++)
                    pos[i] = 0;

                for (c = 0; c < 4; c++)
                {
                    switch (c)
                    {
                        case 0: /* Alpha */
                            comp_value = value.w;
                            break;
                        case 1: /* Red */
                            comp_value = value.x;
                            break;
                        case 2: /* Green */
                            comp_value = value.y;
                            break;
                        case 3: /* Blue */
                            comp_value = value.z;
                            break;
                    }

                    v = comp_value * ((1 << format->bits[c]) - 1) + 0.5f;

                    for (i = 0; i < format->bits[c] + format->shift[c]; i += 8)
                    {
                        mask = ((1 << format->bits[c]) - 1) << format->shift[c] >> i;
                        byte = (v << format->shift[c] >> i) & mask;
                        pos[i / 8] |= byte;
                    }
                }
            }
        }
        IDirect3DTexture9_UnlockRect(texture, m);
    }

    return D3D_OK;
}

HRESULT WINAPI D3DXCreateCubeTextureFromFileInMemoryEx(IDirect3DDevice9 *device,
                                                       const void *src_data,
                                                       UINT src_data_size,
                                                       UINT size,
                                                       UINT mip_levels,
                                                       DWORD usage,
                                                       D3DFORMAT format,
                                                       D3DPOOL pool,
                                                       DWORD filter,
                                                       DWORD mip_filter,
                                                       D3DCOLOR color_key,
                                                       D3DXIMAGE_INFO *src_info,
                                                       PALETTEENTRY *palette,
                                                       IDirect3DCubeTexture9 **cube_texture)
{
    HRESULT hr;
    D3DCAPS9 caps;
    UINT loaded_miplevels;
    D3DXIMAGE_INFO img_info;
    BOOL dynamic_texture;
    BOOL file_size = FALSE;
    BOOL file_format = FALSE;
    BOOL file_mip_levels = FALSE;
    IDirect3DCubeTexture9 *tex, *buftex;

    TRACE("(%p, %p, %u, %u, %u, %#x, %#x, %#x, %#x, %#x, %#x, %p, %p, %p)\n", device,
        src_data, src_data_size, size, mip_levels, usage, format, pool, filter, mip_filter,
        color_key, src_info, palette, cube_texture);

    if (!device || !cube_texture || !src_data || !src_data_size)
        return D3DERR_INVALIDCALL;

    hr = D3DXGetImageInfoFromFileInMemory(src_data, src_data_size, &img_info);
    if (FAILED(hr))
        return hr;

    if (img_info.ImageFileFormat != D3DXIFF_DDS)
        return D3DXERR_INVALIDDATA;

    if (img_info.Width != img_info.Height)
        return D3DXERR_INVALIDDATA;

    if (size == 0 || size == D3DX_DEFAULT_NONPOW2)
        size = img_info.Width;
    if (size == D3DX_DEFAULT)
        size = make_pow2(img_info.Width);

    if (format == D3DFMT_UNKNOWN || format == D3DX_DEFAULT)
        format = img_info.Format;

    if (size == D3DX_FROM_FILE)
    {
        file_size = TRUE;
        size = img_info.Width;
    }

    if (format == D3DFMT_FROM_FILE)
    {
        file_format = TRUE;
        format = img_info.Format;
    }

    if (mip_levels == D3DX_FROM_FILE)
    {
        file_mip_levels = TRUE;
        mip_levels = img_info.MipLevels;
    }

    hr = D3DXCheckCubeTextureRequirements(device, &size, &mip_levels, usage, &format, pool);
    if (FAILED(hr))
        return hr;

    if ((file_size && size != img_info.Width)
            || (file_format && format != img_info.Format)
            || (file_mip_levels && mip_levels != img_info.MipLevels))
        return D3DERR_NOTAVAILABLE;

    hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
    if (FAILED(hr))
        return D3DERR_INVALIDCALL;

    if (mip_levels > img_info.MipLevels && (D3DFMT_DXT1 <= img_info.Format && img_info.Format <= D3DFMT_DXT5))
    {
        FIXME("Generation of mipmaps for compressed pixel formats not supported yet\n");
        mip_levels = img_info.MipLevels;
    }

    dynamic_texture = (caps.Caps2 & D3DCAPS2_DYNAMICTEXTURES) && (usage & D3DUSAGE_DYNAMIC);
    if (pool == D3DPOOL_DEFAULT && !dynamic_texture)
    {
        hr = D3DXCreateCubeTexture(device, size, mip_levels, usage, format, D3DPOOL_SYSTEMMEM, &buftex);
        tex = buftex;
    }
    else
    {
        hr = D3DXCreateCubeTexture(device, size, mip_levels, usage, format, pool, &tex);
        buftex = NULL;
    }
    if (FAILED(hr))
        return hr;

    hr = load_cube_texture_from_dds(tex, src_data, palette, filter, color_key, &img_info);
    if (FAILED(hr))
    {
        IDirect3DCubeTexture9_Release(tex);
        return hr;
    }

    loaded_miplevels = min(IDirect3DCubeTexture9_GetLevelCount(tex), img_info.MipLevels);
    hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, palette, loaded_miplevels - 1, mip_filter);
    if (FAILED(hr))
    {
        IDirect3DCubeTexture9_Release(tex);
        return hr;
    }

    if (buftex)
    {
        hr = D3DXCreateCubeTexture(device, size, mip_levels, usage, format, pool, &tex);
        if (FAILED(hr))
        {
            IDirect3DCubeTexture9_Release(buftex);
            return hr;
        }

        IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)buftex, (IDirect3DBaseTexture9 *)tex);
        IDirect3DCubeTexture9_Release(buftex);
    }

    if (src_info)
        *src_info = img_info;

    *cube_texture = tex;
    return D3D_OK;
}


HRESULT WINAPI D3DXCreateCubeTextureFromFileA(IDirect3DDevice9 *device,
                                              const char *src_filename,
                                              IDirect3DCubeTexture9 **cube_texture)
{
    int len;
    HRESULT hr;
    WCHAR *filename;
    void *data;
    DWORD data_size;

    TRACE("(%p, %s, %p): relay\n", device, wine_dbgstr_a(src_filename), cube_texture);

    if (!src_filename) return D3DERR_INVALIDCALL;

    len = MultiByteToWideChar(CP_ACP, 0, src_filename, -1, NULL, 0);
    filename = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
    if (!filename) return E_OUTOFMEMORY;
    MultiByteToWideChar(CP_ACP, 0, src_filename, -1, filename, len);

    hr = map_view_of_file(filename, &data, &data_size);
    if (FAILED(hr))
    {
        HeapFree(GetProcessHeap(), 0, filename);
        return D3DXERR_INVALIDDATA;
    }

    hr = D3DXCreateCubeTextureFromFileInMemoryEx(device, data, data_size, D3DX_DEFAULT, D3DX_DEFAULT,
        0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, cube_texture);

    UnmapViewOfFile(data);
    HeapFree(GetProcessHeap(), 0, filename);
    return hr;
}

HRESULT WINAPI D3DXCreateCubeTextureFromFileW(IDirect3DDevice9 *device,
                                              const WCHAR *src_filename,
                                              IDirect3DCubeTexture9 **cube_texture)
{
    HRESULT hr;
    void *data;
    DWORD data_size;

    TRACE("(%p, %s, %p): relay\n", device, wine_dbgstr_w(src_filename), cube_texture);

    hr = map_view_of_file(src_filename, &data, &data_size);
    if (FAILED(hr)) return D3DXERR_INVALIDDATA;

    hr = D3DXCreateCubeTextureFromFileInMemoryEx(device, data, data_size, D3DX_DEFAULT, D3DX_DEFAULT,
        0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, cube_texture);

    UnmapViewOfFile(data);
    return hr;
}

HRESULT WINAPI D3DXCreateCubeTextureFromFileExA(IDirect3DDevice9 *device,
                                                const char *src_filename,
                                                UINT size,
                                                UINT mip_levels,
                                                DWORD usage,
                                                D3DFORMAT format,
                                                D3DPOOL pool,
                                                DWORD filter,
                                                DWORD mip_filter,
                                                D3DCOLOR color_key,
                                                D3DXIMAGE_INFO *image_info,
                                                PALETTEENTRY *palette,
                                                IDirect3DCubeTexture9 **cube_texture)
{
    int len;
    HRESULT hr;
    WCHAR *filename;
    void *data;
    DWORD data_size;

    TRACE("(%p, %s, %u, %u, %#x, %#x, %#x, %#x, %#x, %#x, %p, %p, %p): relay\n",
            device, wine_dbgstr_a(src_filename), size, mip_levels, usage, format,
            pool, filter, mip_filter, color_key, image_info, palette, cube_texture);

    if (!src_filename) return D3DERR_INVALIDCALL;

    len = MultiByteToWideChar(CP_ACP, 0, src_filename, -1, NULL, 0);
    filename = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
    if (!filename) return E_OUTOFMEMORY;
    MultiByteToWideChar(CP_ACP, 0, src_filename, -1, filename, len);

    hr = map_view_of_file(filename, &data, &data_size);
    if (FAILED(hr))
    {
        HeapFree(GetProcessHeap(), 0, filename);
        return D3DXERR_INVALIDDATA;
    }

    hr = D3DXCreateCubeTextureFromFileInMemoryEx(device, data, data_size, size, mip_levels,
        usage, format, pool, filter, mip_filter, color_key, image_info, palette, cube_texture);

    UnmapViewOfFile(data);
    HeapFree(GetProcessHeap(), 0, filename);
    return hr;
}

HRESULT WINAPI D3DXCreateCubeTextureFromFileExW(IDirect3DDevice9 *device,
                                                const WCHAR *src_filename,
                                                UINT size,
                                                UINT mip_levels,
                                                DWORD usage,
                                                D3DFORMAT format,
                                                D3DPOOL pool,
                                                DWORD filter,
                                                DWORD mip_filter,
                                                D3DCOLOR color_key,
                                                D3DXIMAGE_INFO *image_info,
                                                PALETTEENTRY *palette,
                                                IDirect3DCubeTexture9 **cube_texture)
{
    HRESULT hr;
    void *data;
    DWORD data_size;

    TRACE("(%p, %s, %u, %u, %#x, %#x, %#x, %#x, %#x, %#x, %p, %p, %p): relay\n",
            device, wine_dbgstr_w(src_filename), size, mip_levels, usage, format,
            pool, filter, mip_filter, color_key, image_info, palette, cube_texture);

    hr = map_view_of_file(src_filename, &data, &data_size);
    if (FAILED(hr)) return D3DXERR_INVALIDDATA;

    hr = D3DXCreateCubeTextureFromFileInMemoryEx(device, data, data_size, size, mip_levels,
        usage, format, pool, filter, mip_filter, color_key, image_info, palette, cube_texture);

    UnmapViewOfFile(data);
    return hr;
}

enum cube_coord
{
    XCOORD = 0,
    XCOORDINV = 1,
    YCOORD = 2,
    YCOORDINV = 3,
    ZERO = 4,
    ONE = 5
};

static float get_cube_coord(enum cube_coord coord, unsigned int x, unsigned int y, unsigned int size)
{
    switch (coord)
    {
        case XCOORD:
            return x + 0.5f;
        case XCOORDINV:
            return size - x - 0.5f;
        case YCOORD:
            return y + 0.5f;
        case YCOORDINV:
            return size - y - 0.5f;
        case ZERO:
            return 0.0f;
        case ONE:
            return size;
       default:
           ERR("Unexpected coordinate value\n");
           return 0.0f;
    }
}

HRESULT WINAPI D3DXFillCubeTexture(LPDIRECT3DCUBETEXTURE9 texture,
                                   LPD3DXFILL3D function,
                                   LPVOID funcdata)
{
    DWORD miplevels;
    DWORD m, i, x, y, c, f, v;
    D3DSURFACE_DESC desc;
    D3DLOCKED_RECT lock_rect;
    D3DXVECTOR4 value;
    D3DXVECTOR3 coord, size;
    const PixelFormatDesc *format;
    BYTE *data, *pos;
    BYTE byte, mask;
    float comp_value;
    static const enum cube_coord coordmap[6][3] =
        {
            {ONE, YCOORDINV, XCOORDINV},
            {ZERO, YCOORDINV, XCOORD},
            {XCOORD, ONE, YCOORD},
            {XCOORD, ZERO, YCOORDINV},
            {XCOORD, YCOORDINV, ONE},
            {XCOORDINV, YCOORDINV, ZERO}
        };

    if (texture == NULL || function == NULL)
        return D3DERR_INVALIDCALL;

    miplevels = IDirect3DBaseTexture9_GetLevelCount(texture);

    for (m = 0; m < miplevels; m++)
    {
        if (FAILED(IDirect3DCubeTexture9_GetLevelDesc(texture, m, &desc)))
            return D3DERR_INVALIDCALL;

        format = get_format_info(desc.Format);
        if (format->format == D3DFMT_UNKNOWN)
        {
            FIXME("Unsupported texture format %#x\n", desc.Format);
            return D3DERR_INVALIDCALL;
        }

        for (f = 0; f < 6; f++)
        {
            if (FAILED(IDirect3DCubeTexture9_LockRect(texture, f, m, &lock_rect, NULL, D3DLOCK_DISCARD)))
                return D3DERR_INVALIDCALL;

            size.x = (f == 0) || (f == 1) ? 0.0f : 2.0f / desc.Width;
            size.y = (f == 2) || (f == 3) ? 0.0f : 2.0f / desc.Width;
            size.z = (f == 4) || (f == 5) ? 0.0f : 2.0f / desc.Width;

            data = lock_rect.pBits;

            for (y = 0; y < desc.Height; y++)
            {
                for (x = 0; x < desc.Width; x++)
                {
                    coord.x = get_cube_coord(coordmap[f][0], x, y, desc.Width) / desc.Width * 2.0f - 1.0f;
                    coord.y = get_cube_coord(coordmap[f][1], x, y, desc.Width) / desc.Width * 2.0f - 1.0f;
                    coord.z = get_cube_coord(coordmap[f][2], x, y, desc.Width) / desc.Width * 2.0f - 1.0f;

                    function(&value, &coord, &size, funcdata);

                    pos = data + y * lock_rect.Pitch + x * format->bytes_per_pixel;

                    for (i = 0; i < format->bytes_per_pixel; i++)
                        pos[i] = 0;

                    for (c = 0; c < 4; c++)
                    {
                        switch (c)
                        {
                            case 0: /* Alpha */
                                comp_value = value.w;
                                break;
                            case 1: /* Red */
                                comp_value = value.x;
                                break;
                            case 2: /* Green */
                                comp_value = value.y;
                                break;
                            case 3: /* Blue */
                                comp_value = value.z;
                                break;
                        }

                        v = comp_value * ((1 << format->bits[c]) - 1) + 0.5f;

                        for (i = 0; i < format->bits[c] + format->shift[c]; i += 8)
                        {
                            mask = ((1 << format->bits[c]) - 1) << format->shift[c] >> i;
                            byte = (v << format->shift[c] >> i) & mask;
                            pos[i / 8] |= byte;
                        }
                    }
                }
            }
            IDirect3DCubeTexture9_UnlockRect(texture, f, m);
        }
    }

    return D3D_OK;
}

HRESULT WINAPI D3DXFillVolumeTexture(LPDIRECT3DVOLUMETEXTURE9 texture,
                                     LPD3DXFILL3D function,
                                     LPVOID funcdata)
{
    DWORD miplevels;
    DWORD m, i, x, y, z, c, v;
    D3DVOLUME_DESC desc;
    D3DLOCKED_BOX lock_box;
    D3DXVECTOR4 value;
    D3DXVECTOR3 coord, size;
    const PixelFormatDesc *format;
    BYTE *data, *pos;
    BYTE byte, mask;
    float comp_value;

    if (texture == NULL || function == NULL)
        return D3DERR_INVALIDCALL;

    miplevels = IDirect3DBaseTexture9_GetLevelCount(texture);

    for (m = 0; m < miplevels; m++)
    {
        if (FAILED(IDirect3DVolumeTexture9_GetLevelDesc(texture, m, &desc)))
            return D3DERR_INVALIDCALL;

        format = get_format_info(desc.Format);
        if (format->format == D3DFMT_UNKNOWN)
        {
            FIXME("Unsupported texture format %#x\n", desc.Format);
            return D3DERR_INVALIDCALL;
        }

        if (FAILED(IDirect3DVolumeTexture9_LockBox(texture, m, &lock_box, NULL, D3DLOCK_DISCARD)))
            return D3DERR_INVALIDCALL;

        size.x = 1.0f / desc.Width;
        size.y = 1.0f / desc.Height;
        size.z = 1.0f / desc.Depth;

        data = lock_box.pBits;

        for (z = 0; z < desc.Depth; z++)
        {
            /* The callback function expects the coordinates of the center
               of the texel */
            coord.z = (z + 0.5f) / desc.Depth;

            for (y = 0; y < desc.Height; y++)
            {
                coord.y = (y + 0.5f) / desc.Height;

                for (x = 0; x < desc.Width; x++)
                {
                    coord.x = (x + 0.5f) / desc.Width;

                    function(&value, &coord, &size, funcdata);

                    pos = data + z * lock_box.SlicePitch + y * lock_box.RowPitch + x * format->bytes_per_pixel;

                    for (i = 0; i < format->bytes_per_pixel; i++)
                        pos[i] = 0;

                    for (c = 0; c < 4; c++)
                    {
                        switch (c)
                        {
                            case 0: /* Alpha */
                                comp_value = value.w;
                                break;
                            case 1: /* Red */
                                comp_value = value.x;
                                break;
                            case 2: /* Green */
                                comp_value = value.y;
                                break;
                            case 3: /* Blue */
                                comp_value = value.z;
                                break;
                        }

                        v = comp_value * ((1 << format->bits[c]) - 1) + 0.5f;

                        for (i = 0; i < format->bits[c] + format->shift[c]; i += 8)
                        {
                            mask = ((1 << format->bits[c]) - 1) << format->shift[c] >> i;
                            byte = (v << format->shift[c] >> i) & mask;
                            pos[i / 8] |= byte;
                        }
                    }
                }
            }
        }
        IDirect3DVolumeTexture9_UnlockBox(texture, m);
    }

    return D3D_OK;
}

HRESULT WINAPI D3DXSaveTextureToFileA(const char *dst_filename, D3DXIMAGE_FILEFORMAT file_format,
        IDirect3DBaseTexture9 *src_texture, const PALETTEENTRY *src_palette)
{
    int len;
    WCHAR *filename;
    HRESULT hr;
    ID3DXBuffer *buffer;

    TRACE("(%s, %#x, %p, %p): relay\n",
            wine_dbgstr_a(dst_filename), file_format, src_texture, src_palette);

    if (!dst_filename) return D3DERR_INVALIDCALL;

    len = MultiByteToWideChar(CP_ACP, 0, dst_filename, -1, NULL, 0);
    filename = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
    if (!filename) return E_OUTOFMEMORY;
    MultiByteToWideChar(CP_ACP, 0, dst_filename, -1, filename, len);

    hr = D3DXSaveTextureToFileInMemory(&buffer, file_format, src_texture, src_palette);
    if (SUCCEEDED(hr))
    {
        hr = write_buffer_to_file(filename, buffer);
        ID3DXBuffer_Release(buffer);
    }

    HeapFree(GetProcessHeap(), 0, filename);
    return hr;
}

HRESULT WINAPI D3DXSaveTextureToFileW(const WCHAR *dst_filename, D3DXIMAGE_FILEFORMAT file_format,
        IDirect3DBaseTexture9 *src_texture, const PALETTEENTRY *src_palette)
{
    HRESULT hr;
    ID3DXBuffer *buffer;

    TRACE("(%s, %#x, %p, %p): relay\n",
        wine_dbgstr_w(dst_filename), file_format, src_texture, src_palette);

    if (!dst_filename) return D3DERR_INVALIDCALL;

    hr = D3DXSaveTextureToFileInMemory(&buffer, file_format, src_texture, src_palette);
    if (SUCCEEDED(hr))
    {
        hr = write_buffer_to_file(dst_filename, buffer);
        ID3DXBuffer_Release(buffer);
    }

    return hr;
}

HRESULT WINAPI D3DXSaveTextureToFileInMemory(ID3DXBuffer **dst_buffer, D3DXIMAGE_FILEFORMAT file_format,
        IDirect3DBaseTexture9 *src_texture, const PALETTEENTRY *src_palette)
{
    HRESULT hr;
    D3DRESOURCETYPE type;
    IDirect3DSurface9 *surface;

    TRACE("(%p, %#x, %p, %p)\n",
        dst_buffer, file_format, src_texture, src_palette);

    if (!dst_buffer || !src_texture) return D3DERR_INVALIDCALL;

    if (file_format == D3DXIFF_DDS)
    {
        FIXME("DDS file format isn't supported yet\n");
        return E_NOTIMPL;
    }

    type = IDirect3DBaseTexture9_GetType(src_texture);
    switch (type)
    {
        case D3DRTYPE_TEXTURE:
        case D3DRTYPE_CUBETEXTURE:
            hr = get_surface(type, src_texture, D3DCUBEMAP_FACE_POSITIVE_X, 0, &surface);
            break;
        case D3DRTYPE_VOLUMETEXTURE:
            FIXME("Volume textures aren't supported yet\n");
            return E_NOTIMPL;
        default:
            return D3DERR_INVALIDCALL;
    }

    if (SUCCEEDED(hr))
    {
        hr = D3DXSaveSurfaceToFileInMemory(dst_buffer, file_format, surface, src_palette, NULL);
        IDirect3DSurface9_Release(surface);
    }

    return hr;
}
