/*
 * IDirect3DDevice8 implementation
 *
 * Copyright 2002-2004 Jason Edmeades
 * Copyright 2004 Christian Costa
 *
 * 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 "config.h"

#include <math.h>
#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "wingdi.h"
#include "wine/debug.h"

#include "d3d8_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(d3d8);

static void STDMETHODCALLTYPE d3d8_null_wined3d_object_destroyed(void *parent) {}

static const struct wined3d_parent_ops d3d8_null_wined3d_parent_ops =
{
    d3d8_null_wined3d_object_destroyed,
};

D3DFORMAT d3dformat_from_wined3dformat(enum wined3d_format_id format)
{
    BYTE *c = (BYTE *)&format;

    /* Don't translate FOURCC formats */
    if (isprint(c[0]) && isprint(c[1]) && isprint(c[2]) && isprint(c[3])) return format;

    switch(format)
    {
        case WINED3DFMT_UNKNOWN: return D3DFMT_UNKNOWN;
        case WINED3DFMT_B8G8R8_UNORM: return D3DFMT_R8G8B8;
        case WINED3DFMT_B8G8R8A8_UNORM: return D3DFMT_A8R8G8B8;
        case WINED3DFMT_B8G8R8X8_UNORM: return D3DFMT_X8R8G8B8;
        case WINED3DFMT_B5G6R5_UNORM: return D3DFMT_R5G6B5;
        case WINED3DFMT_B5G5R5X1_UNORM: return D3DFMT_X1R5G5B5;
        case WINED3DFMT_B5G5R5A1_UNORM: return D3DFMT_A1R5G5B5;
        case WINED3DFMT_B4G4R4A4_UNORM: return D3DFMT_A4R4G4B4;
        case WINED3DFMT_B2G3R3_UNORM: return D3DFMT_R3G3B2;
        case WINED3DFMT_A8_UNORM: return D3DFMT_A8;
        case WINED3DFMT_B2G3R3A8_UNORM: return D3DFMT_A8R3G3B2;
        case WINED3DFMT_B4G4R4X4_UNORM: return D3DFMT_X4R4G4B4;
        case WINED3DFMT_R10G10B10A2_UNORM: return D3DFMT_A2B10G10R10;
        case WINED3DFMT_R16G16_UNORM: return D3DFMT_G16R16;
        case WINED3DFMT_P8_UINT_A8_UNORM: return D3DFMT_A8P8;
        case WINED3DFMT_P8_UINT: return D3DFMT_P8;
        case WINED3DFMT_L8_UNORM: return D3DFMT_L8;
        case WINED3DFMT_L8A8_UNORM: return D3DFMT_A8L8;
        case WINED3DFMT_L4A4_UNORM: return D3DFMT_A4L4;
        case WINED3DFMT_R8G8_SNORM: return D3DFMT_V8U8;
        case WINED3DFMT_R5G5_SNORM_L6_UNORM: return D3DFMT_L6V5U5;
        case WINED3DFMT_R8G8_SNORM_L8X8_UNORM: return D3DFMT_X8L8V8U8;
        case WINED3DFMT_R8G8B8A8_SNORM: return D3DFMT_Q8W8V8U8;
        case WINED3DFMT_R16G16_SNORM: return D3DFMT_V16U16;
        case WINED3DFMT_R10G11B11_SNORM: return D3DFMT_W11V11U10;
        case WINED3DFMT_R10G10B10_SNORM_A2_UNORM: return D3DFMT_A2W10V10U10;
        case WINED3DFMT_D16_LOCKABLE: return D3DFMT_D16_LOCKABLE;
        case WINED3DFMT_D32_UNORM: return D3DFMT_D32;
        case WINED3DFMT_S1_UINT_D15_UNORM: return D3DFMT_D15S1;
        case WINED3DFMT_D24_UNORM_S8_UINT: return D3DFMT_D24S8;
        case WINED3DFMT_X8D24_UNORM: return D3DFMT_D24X8;
        case WINED3DFMT_S4X4_UINT_D24_UNORM: return D3DFMT_D24X4S4;
        case WINED3DFMT_D16_UNORM: return D3DFMT_D16;
        case WINED3DFMT_VERTEXDATA: return D3DFMT_VERTEXDATA;
        case WINED3DFMT_R16_UINT: return D3DFMT_INDEX16;
        case WINED3DFMT_R32_UINT: return D3DFMT_INDEX32;
        default:
            FIXME("Unhandled wined3d format %#x.\n", format);
            return D3DFMT_UNKNOWN;
    }
}

enum wined3d_format_id wined3dformat_from_d3dformat(D3DFORMAT format)
{
    BYTE *c = (BYTE *)&format;

    /* Don't translate FOURCC formats */
    if (isprint(c[0]) && isprint(c[1]) && isprint(c[2]) && isprint(c[3])) return format;

    switch(format)
    {
        case D3DFMT_UNKNOWN: return WINED3DFMT_UNKNOWN;
        case D3DFMT_R8G8B8: return WINED3DFMT_B8G8R8_UNORM;
        case D3DFMT_A8R8G8B8: return WINED3DFMT_B8G8R8A8_UNORM;
        case D3DFMT_X8R8G8B8: return WINED3DFMT_B8G8R8X8_UNORM;
        case D3DFMT_R5G6B5: return WINED3DFMT_B5G6R5_UNORM;
        case D3DFMT_X1R5G5B5: return WINED3DFMT_B5G5R5X1_UNORM;
        case D3DFMT_A1R5G5B5: return WINED3DFMT_B5G5R5A1_UNORM;
        case D3DFMT_A4R4G4B4: return WINED3DFMT_B4G4R4A4_UNORM;
        case D3DFMT_R3G3B2: return WINED3DFMT_B2G3R3_UNORM;
        case D3DFMT_A8: return WINED3DFMT_A8_UNORM;
        case D3DFMT_A8R3G3B2: return WINED3DFMT_B2G3R3A8_UNORM;
        case D3DFMT_X4R4G4B4: return WINED3DFMT_B4G4R4X4_UNORM;
        case D3DFMT_A2B10G10R10: return WINED3DFMT_R10G10B10A2_UNORM;
        case D3DFMT_G16R16: return WINED3DFMT_R16G16_UNORM;
        case D3DFMT_A8P8: return WINED3DFMT_P8_UINT_A8_UNORM;
        case D3DFMT_P8: return WINED3DFMT_P8_UINT;
        case D3DFMT_L8: return WINED3DFMT_L8_UNORM;
        case D3DFMT_A8L8: return WINED3DFMT_L8A8_UNORM;
        case D3DFMT_A4L4: return WINED3DFMT_L4A4_UNORM;
        case D3DFMT_V8U8: return WINED3DFMT_R8G8_SNORM;
        case D3DFMT_L6V5U5: return WINED3DFMT_R5G5_SNORM_L6_UNORM;
        case D3DFMT_X8L8V8U8: return WINED3DFMT_R8G8_SNORM_L8X8_UNORM;
        case D3DFMT_Q8W8V8U8: return WINED3DFMT_R8G8B8A8_SNORM;
        case D3DFMT_V16U16: return WINED3DFMT_R16G16_SNORM;
        case D3DFMT_W11V11U10: return WINED3DFMT_R10G11B11_SNORM;
        case D3DFMT_A2W10V10U10: return WINED3DFMT_R10G10B10_SNORM_A2_UNORM;
        case D3DFMT_D16_LOCKABLE: return WINED3DFMT_D16_LOCKABLE;
        case D3DFMT_D32: return WINED3DFMT_D32_UNORM;
        case D3DFMT_D15S1: return WINED3DFMT_S1_UINT_D15_UNORM;
        case D3DFMT_D24S8: return WINED3DFMT_D24_UNORM_S8_UINT;
        case D3DFMT_D24X8: return WINED3DFMT_X8D24_UNORM;
        case D3DFMT_D24X4S4: return WINED3DFMT_S4X4_UINT_D24_UNORM;
        case D3DFMT_D16: return WINED3DFMT_D16_UNORM;
        case D3DFMT_VERTEXDATA: return WINED3DFMT_VERTEXDATA;
        case D3DFMT_INDEX16: return WINED3DFMT_R16_UINT;
        case D3DFMT_INDEX32: return WINED3DFMT_R32_UINT;
        default:
            FIXME("Unhandled D3DFORMAT %#x\n", format);
            return WINED3DFMT_UNKNOWN;
    }
}

static UINT vertex_count_from_primitive_count(D3DPRIMITIVETYPE primitive_type, UINT primitive_count)
{
    switch(primitive_type)
    {
        case D3DPT_POINTLIST:
            return primitive_count;

        case D3DPT_LINELIST:
            return primitive_count * 2;

        case D3DPT_LINESTRIP:
            return primitive_count + 1;

        case D3DPT_TRIANGLELIST:
            return primitive_count * 3;

        case D3DPT_TRIANGLESTRIP:
        case D3DPT_TRIANGLEFAN:
            return primitive_count + 2;

        default:
            FIXME("Unhandled primitive type %#x\n", primitive_type);
            return 0;
    }
}

static void present_parameters_from_wined3d_swapchain_desc(D3DPRESENT_PARAMETERS *present_parameters,
        const struct wined3d_swapchain_desc *swapchain_desc)
{
    present_parameters->BackBufferWidth = swapchain_desc->backbuffer_width;
    present_parameters->BackBufferHeight = swapchain_desc->backbuffer_height;
    present_parameters->BackBufferFormat = d3dformat_from_wined3dformat(swapchain_desc->backbuffer_format);
    present_parameters->BackBufferCount = swapchain_desc->backbuffer_count;
    present_parameters->MultiSampleType = swapchain_desc->multisample_type;
    present_parameters->SwapEffect = swapchain_desc->swap_effect;
    present_parameters->hDeviceWindow = swapchain_desc->device_window;
    present_parameters->Windowed = swapchain_desc->windowed;
    present_parameters->EnableAutoDepthStencil = swapchain_desc->enable_auto_depth_stencil;
    present_parameters->AutoDepthStencilFormat
            = d3dformat_from_wined3dformat(swapchain_desc->auto_depth_stencil_format);
    present_parameters->Flags = swapchain_desc->flags;
    present_parameters->FullScreen_RefreshRateInHz = swapchain_desc->refresh_rate;
    present_parameters->FullScreen_PresentationInterval = swapchain_desc->swap_interval;
}

static BOOL wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapchain_desc *swapchain_desc,
        const D3DPRESENT_PARAMETERS *present_parameters)
{
    if (!present_parameters->SwapEffect || present_parameters->SwapEffect > D3DSWAPEFFECT_COPY_VSYNC)
    {
        WARN("Invalid swap effect %u passed.\n", present_parameters->SwapEffect);
        return FALSE;
    }
    if (present_parameters->BackBufferCount > 3
            || ((present_parameters->SwapEffect == D3DSWAPEFFECT_COPY
            || present_parameters->SwapEffect == D3DSWAPEFFECT_COPY_VSYNC)
            && present_parameters->BackBufferCount > 1))
    {
        WARN("Invalid backbuffer count %u.\n", present_parameters->BackBufferCount);
        return FALSE;
    }

    swapchain_desc->backbuffer_width = present_parameters->BackBufferWidth;
    swapchain_desc->backbuffer_height = present_parameters->BackBufferHeight;
    swapchain_desc->backbuffer_format = wined3dformat_from_d3dformat(present_parameters->BackBufferFormat);
    swapchain_desc->backbuffer_count = max(1, present_parameters->BackBufferCount);
    swapchain_desc->multisample_type = present_parameters->MultiSampleType;
    swapchain_desc->multisample_quality = 0; /* d3d9 only */
    swapchain_desc->swap_effect = present_parameters->SwapEffect;
    swapchain_desc->device_window = present_parameters->hDeviceWindow;
    swapchain_desc->windowed = present_parameters->Windowed;
    swapchain_desc->enable_auto_depth_stencil = present_parameters->EnableAutoDepthStencil;
    swapchain_desc->auto_depth_stencil_format
            = wined3dformat_from_d3dformat(present_parameters->AutoDepthStencilFormat);
    swapchain_desc->flags = present_parameters->Flags;
    swapchain_desc->refresh_rate = present_parameters->FullScreen_RefreshRateInHz;
    swapchain_desc->swap_interval = present_parameters->FullScreen_PresentationInterval;
    swapchain_desc->auto_restore_display_mode = TRUE;

    return TRUE;
}

/* Handle table functions */
static DWORD d3d8_allocate_handle(struct d3d8_handle_table *t, void *object, enum d3d8_handle_type type)
{
    struct d3d8_handle_entry *entry;

    if (t->free_entries)
    {
        DWORD index = t->free_entries - t->entries;
        /* Use a free handle */
        entry = t->free_entries;
        if (entry->type != D3D8_HANDLE_FREE)
        {
            ERR("Handle %u(%p) is in the free list, but has type %#x.\n", index, entry, entry->type);
            return D3D8_INVALID_HANDLE;
        }
        t->free_entries = entry->object;
        entry->object = object;
        entry->type = type;

        return index;
    }

    if (!(t->entry_count < t->table_size))
    {
        /* Grow the table */
        UINT new_size = t->table_size + (t->table_size >> 1);
        struct d3d8_handle_entry *new_entries = HeapReAlloc(GetProcessHeap(),
                0, t->entries, new_size * sizeof(*t->entries));
        if (!new_entries)
        {
            ERR("Failed to grow the handle table.\n");
            return D3D8_INVALID_HANDLE;
        }
        t->entries = new_entries;
        t->table_size = new_size;
    }

    entry = &t->entries[t->entry_count];
    entry->object = object;
    entry->type = type;

    return t->entry_count++;
}

static void *d3d8_free_handle(struct d3d8_handle_table *t, DWORD handle, enum d3d8_handle_type type)
{
    struct d3d8_handle_entry *entry;
    void *object;

    if (handle == D3D8_INVALID_HANDLE || handle >= t->entry_count)
    {
        WARN("Invalid handle %u passed.\n", handle);
        return NULL;
    }

    entry = &t->entries[handle];
    if (entry->type != type)
    {
        WARN("Handle %u(%p) is not of type %#x.\n", handle, entry, type);
        return NULL;
    }

    object = entry->object;
    entry->object = t->free_entries;
    entry->type = D3D8_HANDLE_FREE;
    t->free_entries = entry;

    return object;
}

static void *d3d8_get_object(struct d3d8_handle_table *t, DWORD handle, enum d3d8_handle_type type)
{
    struct d3d8_handle_entry *entry;

    if (handle == D3D8_INVALID_HANDLE || handle >= t->entry_count)
    {
        WARN("Invalid handle %u passed.\n", handle);
        return NULL;
    }

    entry = &t->entries[handle];
    if (entry->type != type)
    {
        WARN("Handle %u(%p) is not of type %#x.\n", handle, entry, type);
        return NULL;
    }

    return entry->object;
}

static HRESULT WINAPI d3d8_device_QueryInterface(IDirect3DDevice8 *iface, REFIID riid, void **out)
{
    TRACE("iface %p, riid %s, out %p.\n",
            iface, debugstr_guid(riid), out);

    if (IsEqualGUID(riid, &IID_IDirect3DDevice8)
            || IsEqualGUID(riid, &IID_IUnknown))
    {
        IDirect3DDevice8_AddRef(iface);
        *out = iface;
        return S_OK;
    }

    WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));

    *out = NULL;
    return E_NOINTERFACE;
}

static ULONG WINAPI d3d8_device_AddRef(IDirect3DDevice8 *iface)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    ULONG ref = InterlockedIncrement(&device->ref);

    TRACE("%p increasing refcount to %u.\n", iface, ref);

    return ref;
}

static ULONG WINAPI d3d8_device_Release(IDirect3DDevice8 *iface)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    ULONG ref;

    if (device->inDestruction)
        return 0;

    ref = InterlockedDecrement(&device->ref);

    TRACE("%p decreasing refcount to %u.\n", iface, ref);

    if (!ref)
    {
        IDirect3D8 *parent = device->d3d_parent;
        unsigned i;

        TRACE("Releasing wined3d device %p.\n", device->wined3d_device);

        wined3d_mutex_lock();

        device->inDestruction = TRUE;

        for (i = 0; i < device->numConvertedDecls; ++i)
        {
            d3d8_vertex_declaration_destroy(device->decls[i].declaration);
        }
        HeapFree(GetProcessHeap(), 0, device->decls);

        if (device->vertex_buffer)
            wined3d_buffer_decref(device->vertex_buffer);
        if (device->index_buffer)
            wined3d_buffer_decref(device->index_buffer);

        wined3d_device_uninit_3d(device->wined3d_device);
        wined3d_device_release_focus_window(device->wined3d_device);
        wined3d_device_decref(device->wined3d_device);
        HeapFree(GetProcessHeap(), 0, device->handle_table.entries);
        HeapFree(GetProcessHeap(), 0, device);

        wined3d_mutex_unlock();

        IDirect3D8_Release(parent);
    }
    return ref;
}

static HRESULT WINAPI d3d8_device_TestCooperativeLevel(IDirect3DDevice8 *iface)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);

    TRACE("iface %p.\n", iface);

    TRACE("device state: %#x.\n", device->device_state);

    switch (device->device_state)
    {
        default:
        case D3D8_DEVICE_STATE_OK:
            return D3D_OK;
        case D3D8_DEVICE_STATE_LOST:
            return D3DERR_DEVICELOST;
        case D3D8_DEVICE_STATE_NOT_RESET:
            return D3DERR_DEVICENOTRESET;
    }
}

static UINT WINAPI d3d8_device_GetAvailableTextureMem(IDirect3DDevice8 *iface)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    UINT ret;

    TRACE("iface %p.\n", iface);

    wined3d_mutex_lock();
    ret = wined3d_device_get_available_texture_mem(device->wined3d_device);
    wined3d_mutex_unlock();

    return ret;
}

static HRESULT WINAPI d3d8_device_ResourceManagerDiscardBytes(IDirect3DDevice8 *iface, DWORD byte_count)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);

    TRACE("iface %p, byte_count %u.\n", iface, byte_count);

    if (byte_count)
        FIXME("Byte count ignored.\n");

    wined3d_mutex_lock();
    wined3d_device_evict_managed_resources(device->wined3d_device);
    wined3d_mutex_unlock();

    return D3D_OK;
}

static HRESULT WINAPI d3d8_device_GetDirect3D(IDirect3DDevice8 *iface, IDirect3D8 **d3d8)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);

    TRACE("iface %p, d3d8 %p.\n", iface, d3d8);

    if (!d3d8)
        return D3DERR_INVALIDCALL;

    return IDirect3D8_QueryInterface(device->d3d_parent, &IID_IDirect3D8, (void **)d3d8);
}

static HRESULT WINAPI d3d8_device_GetDeviceCaps(IDirect3DDevice8 *iface, D3DCAPS8 *caps)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    WINED3DCAPS *wined3d_caps;
    HRESULT hr;

    TRACE("iface %p, caps %p.\n", iface, caps);

    if (!caps)
        return D3DERR_INVALIDCALL;

    if (!(wined3d_caps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*wined3d_caps))))
        return D3DERR_INVALIDCALL; /* well this is what MSDN says to return */

    wined3d_mutex_lock();
    hr = wined3d_device_get_device_caps(device->wined3d_device, wined3d_caps);
    wined3d_mutex_unlock();

    fixup_caps(wined3d_caps);
    WINECAPSTOD3D8CAPS(caps, wined3d_caps)
    HeapFree(GetProcessHeap(), 0, wined3d_caps);

    return hr;
}

static HRESULT WINAPI d3d8_device_GetDisplayMode(IDirect3DDevice8 *iface, D3DDISPLAYMODE *mode)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    struct wined3d_display_mode wined3d_mode;
    HRESULT hr;

    TRACE("iface %p, mode %p.\n", iface, mode);

    wined3d_mutex_lock();
    hr = wined3d_device_get_display_mode(device->wined3d_device, 0, &wined3d_mode, NULL);
    wined3d_mutex_unlock();

    if (SUCCEEDED(hr))
    {
        mode->Width = wined3d_mode.width;
        mode->Height = wined3d_mode.height;
        mode->RefreshRate = wined3d_mode.refresh_rate;
        mode->Format = d3dformat_from_wined3dformat(wined3d_mode.format_id);
    }

    return hr;
}

static HRESULT WINAPI d3d8_device_GetCreationParameters(IDirect3DDevice8 *iface,
        D3DDEVICE_CREATION_PARAMETERS *parameters)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);

    TRACE("iface %p, parameters %p.\n", iface, parameters);

    wined3d_mutex_lock();
    wined3d_device_get_creation_parameters(device->wined3d_device,
            (struct wined3d_device_creation_parameters *)parameters);
    wined3d_mutex_unlock();

    return D3D_OK;
}

static HRESULT WINAPI d3d8_device_SetCursorProperties(IDirect3DDevice8 *iface,
        UINT hotspot_x, UINT hotspot_y, IDirect3DSurface8 *bitmap)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    struct d3d8_surface *bitmap_impl = unsafe_impl_from_IDirect3DSurface8(bitmap);
    HRESULT hr;

    TRACE("iface %p, hotspot_x %u, hotspot_y %u, bitmap %p.\n",
            iface, hotspot_x, hotspot_y, bitmap);

    if (!bitmap)
    {
        WARN("No cursor bitmap, returning D3DERR_INVALIDCALL.\n");
        return D3DERR_INVALIDCALL;
    }

    wined3d_mutex_lock();
    hr = wined3d_device_set_cursor_properties(device->wined3d_device,
            hotspot_x, hotspot_y, bitmap_impl->wined3d_texture, bitmap_impl->sub_resource_idx);
    wined3d_mutex_unlock();

    return hr;
}

static void WINAPI d3d8_device_SetCursorPosition(IDirect3DDevice8 *iface, UINT x, UINT y, DWORD flags)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);

    TRACE("iface %p, x %u, y %u, flags %#x.\n", iface, x, y, flags);

    wined3d_mutex_lock();
    wined3d_device_set_cursor_position(device->wined3d_device, x, y, flags);
    wined3d_mutex_unlock();
}

static BOOL WINAPI d3d8_device_ShowCursor(IDirect3DDevice8 *iface, BOOL show)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    BOOL ret;

    TRACE("iface %p, show %#x.\n", iface, show);

    wined3d_mutex_lock();
    ret = wined3d_device_show_cursor(device->wined3d_device, show);
    wined3d_mutex_unlock();

    return ret;
}

static HRESULT WINAPI d3d8_device_CreateAdditionalSwapChain(IDirect3DDevice8 *iface,
        D3DPRESENT_PARAMETERS *present_parameters, IDirect3DSwapChain8 **swapchain)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    struct wined3d_swapchain_desc desc;
    struct d3d8_swapchain *object;
    UINT i, count;
    HRESULT hr;

    TRACE("iface %p, present_parameters %p, swapchain %p.\n",
            iface, present_parameters, swapchain);

    if (!present_parameters->Windowed)
    {
        WARN("Trying to create an additional fullscreen swapchain, returning D3DERR_INVALIDCALL.\n");
        return D3DERR_INVALIDCALL;
    }

    wined3d_mutex_lock();
    count = wined3d_device_get_swapchain_count(device->wined3d_device);
    for (i = 0; i < count; ++i)
    {
        struct wined3d_swapchain *wined3d_swapchain;

        wined3d_swapchain = wined3d_device_get_swapchain(device->wined3d_device, i);
        wined3d_swapchain_get_desc(wined3d_swapchain, &desc);

        if (!desc.windowed)
        {
            wined3d_mutex_unlock();
            WARN("Trying to create an additional swapchain in fullscreen mode, returning D3DERR_INVALIDCALL.\n");
            return D3DERR_INVALIDCALL;
        }
    }
    wined3d_mutex_unlock();

    if (!wined3d_swapchain_desc_from_present_parameters(&desc, present_parameters))
        return D3DERR_INVALIDCALL;
    if (SUCCEEDED(hr = d3d8_swapchain_create(device, &desc, &object)))
        *swapchain = &object->IDirect3DSwapChain8_iface;
    present_parameters_from_wined3d_swapchain_desc(present_parameters, &desc);

    return hr;
}

static HRESULT CDECL reset_enum_callback(struct wined3d_resource *resource)
{
    struct wined3d_resource_desc desc;

    wined3d_resource_get_desc(resource, &desc);
    if (desc.pool == WINED3D_POOL_DEFAULT)
    {
        struct d3d8_surface *surface;

        if (desc.resource_type == WINED3D_RTYPE_TEXTURE_2D)
        {
            IUnknown *parent = wined3d_resource_get_parent(resource);
            IDirect3DBaseTexture8 *texture;

            if (SUCCEEDED(IUnknown_QueryInterface(parent, &IID_IDirect3DBaseTexture8, (void **)&texture)))
            {
                IDirect3DBaseTexture8_Release(texture);
                WARN("Texture %p (resource %p) in pool D3DPOOL_DEFAULT blocks the Reset call.\n", texture, resource);
                return D3DERR_DEVICELOST;
            }

            return D3D_OK;
        }

        if (desc.resource_type != WINED3D_RTYPE_SURFACE)
        {
            WARN("Resource %p in pool D3DPOOL_DEFAULT blocks the Reset call.\n", resource);
            return D3DERR_DEVICELOST;
        }

        surface = wined3d_resource_get_parent(resource);
        if (surface->resource.refcount)
        {
            WARN("Surface %p (resource %p) in pool D3DPOOL_DEFAULT blocks the Reset call.\n", surface, resource);
            return D3DERR_DEVICELOST;
        }

        WARN("Surface %p (resource %p) is an implicit resource with ref 0.\n", surface, resource);
    }

    return D3D_OK;
}

static HRESULT WINAPI d3d8_device_Reset(IDirect3DDevice8 *iface,
        D3DPRESENT_PARAMETERS *present_parameters)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    struct wined3d_swapchain_desc swapchain_desc;
    HRESULT hr;

    TRACE("iface %p, present_parameters %p.\n", iface, present_parameters);

    if (device->device_state == D3D8_DEVICE_STATE_LOST)
    {
        WARN("App not active, returning D3DERR_DEVICELOST.\n");
        return D3DERR_DEVICELOST;
    }
    if (!wined3d_swapchain_desc_from_present_parameters(&swapchain_desc, present_parameters))
        return D3DERR_INVALIDCALL;

    wined3d_mutex_lock();

    if (device->vertex_buffer)
    {
        wined3d_buffer_decref(device->vertex_buffer);
        device->vertex_buffer = NULL;
        device->vertex_buffer_size = 0;
    }
    if (device->index_buffer)
    {
        wined3d_buffer_decref(device->index_buffer);
        device->index_buffer = NULL;
        device->index_buffer_size = 0;
    }

    if (SUCCEEDED(hr = wined3d_device_reset(device->wined3d_device, &swapchain_desc,
            NULL, reset_enum_callback, TRUE)))
    {
        present_parameters->BackBufferCount = swapchain_desc.backbuffer_count;
        wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_POINTSIZE_MIN, 0);
        device->device_state = D3D8_DEVICE_STATE_OK;
    }
    else
    {
        device->device_state = D3D8_DEVICE_STATE_NOT_RESET;
    }
    wined3d_mutex_unlock();

    return hr;
}

static HRESULT WINAPI d3d8_device_Present(IDirect3DDevice8 *iface, const RECT *src_rect,
        const RECT *dst_rect, HWND dst_window_override, const RGNDATA *dirty_region)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);

    TRACE("iface %p, src_rect %s, dst_rect %s, dst_window_override %p, dirty_region %p.\n",
            iface, wine_dbgstr_rect(src_rect), wine_dbgstr_rect(dst_rect), dst_window_override, dirty_region);

    /* Fraps does not hook IDirect3DDevice8::Present regardless of the hotpatch
     * attribute. It only hooks IDirect3DSwapChain8::Present. Yet it properly
     * shows a framerate on Windows in applications that only call the device
     * method, like e.g. the dx8 sdk samples. The conclusion is that native
     * calls the swapchain's public method from the device. */
    return IDirect3DSwapChain8_Present(&device->implicit_swapchain->IDirect3DSwapChain8_iface,
            src_rect, dst_rect, dst_window_override, dirty_region);
}

static HRESULT WINAPI d3d8_device_GetBackBuffer(IDirect3DDevice8 *iface,
        UINT backbuffer_idx, D3DBACKBUFFER_TYPE backbuffer_type, IDirect3DSurface8 **backbuffer)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    struct wined3d_swapchain *wined3d_swapchain;
    struct wined3d_texture *wined3d_texture;
    struct d3d8_surface *surface_impl;

    TRACE("iface %p, backbuffer_idx %u, backbuffer_type %#x, backbuffer %p.\n",
            iface, backbuffer_idx, backbuffer_type, backbuffer);

    /* backbuffer_type is ignored by native. */

    /* No need to check for backbuffer == NULL, Windows crashes in that case. */
    wined3d_mutex_lock();

    wined3d_swapchain = device->implicit_swapchain->wined3d_swapchain;
    if (!(wined3d_texture = wined3d_swapchain_get_back_buffer(wined3d_swapchain, backbuffer_idx)))
    {
        wined3d_mutex_unlock();
        *backbuffer = NULL;
        return D3DERR_INVALIDCALL;
    }

    surface_impl = wined3d_texture_get_sub_resource_parent(wined3d_texture, 0);
    *backbuffer = &surface_impl->IDirect3DSurface8_iface;
    IDirect3DSurface8_AddRef(*backbuffer);

    wined3d_mutex_unlock();
    return D3D_OK;
}

static HRESULT WINAPI d3d8_device_GetRasterStatus(IDirect3DDevice8 *iface, D3DRASTER_STATUS *raster_status)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    HRESULT hr;

    TRACE("iface %p, raster_status %p.\n", iface, raster_status);

    wined3d_mutex_lock();
    hr = wined3d_device_get_raster_status(device->wined3d_device, 0, (struct wined3d_raster_status *)raster_status);
    wined3d_mutex_unlock();

    return hr;
}

static void WINAPI d3d8_device_SetGammaRamp(IDirect3DDevice8 *iface, DWORD flags, const D3DGAMMARAMP *ramp)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);

    TRACE("iface %p, flags %#x, ramp %p.\n", iface, flags, ramp);

    /* Note: D3DGAMMARAMP is compatible with struct wined3d_gamma_ramp. */
    wined3d_mutex_lock();
    wined3d_device_set_gamma_ramp(device->wined3d_device, 0, flags, (const struct wined3d_gamma_ramp *)ramp);
    wined3d_mutex_unlock();
}

static void WINAPI d3d8_device_GetGammaRamp(IDirect3DDevice8 *iface, D3DGAMMARAMP *ramp)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);

    TRACE("iface %p, ramp %p.\n", iface, ramp);

    /* Note: D3DGAMMARAMP is compatible with struct wined3d_gamma_ramp. */
    wined3d_mutex_lock();
    wined3d_device_get_gamma_ramp(device->wined3d_device, 0, (struct wined3d_gamma_ramp *)ramp);
    wined3d_mutex_unlock();
}

static HRESULT WINAPI d3d8_device_CreateTexture(IDirect3DDevice8 *iface,
        UINT width, UINT height, UINT levels, DWORD usage, D3DFORMAT format,
        D3DPOOL pool, IDirect3DTexture8 **texture)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    struct d3d8_texture *object;
    HRESULT hr;

    TRACE("iface %p, width %u, height %u, levels %u, usage %#x, format %#x, pool %#x, texture %p.\n",
            iface, width, height, levels, usage, format, pool, texture);

    *texture = NULL;
    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
    if (!object)
        return D3DERR_OUTOFVIDEOMEMORY;

    hr = texture_init(object, device, width, height, levels, usage, format, pool);
    if (FAILED(hr))
    {
        WARN("Failed to initialize texture, hr %#x.\n", hr);
        HeapFree(GetProcessHeap(), 0, object);
        return hr;
    }

    TRACE("Created texture %p.\n", object);
    *texture = (IDirect3DTexture8 *)&object->IDirect3DBaseTexture8_iface;

    return D3D_OK;
}

static HRESULT WINAPI d3d8_device_CreateVolumeTexture(IDirect3DDevice8 *iface,
        UINT width, UINT height, UINT depth, UINT levels, DWORD usage, D3DFORMAT format,
        D3DPOOL pool, IDirect3DVolumeTexture8 **texture)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    struct d3d8_texture *object;
    HRESULT hr;

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

    *texture = NULL;
    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
    if (!object)
        return D3DERR_OUTOFVIDEOMEMORY;

    hr = volumetexture_init(object, device, width, height, depth, levels, usage, format, pool);
    if (FAILED(hr))
    {
        WARN("Failed to initialize volume texture, hr %#x.\n", hr);
        HeapFree(GetProcessHeap(), 0, object);
        return hr;
    }

    TRACE("Created volume texture %p.\n", object);
    *texture = (IDirect3DVolumeTexture8 *)&object->IDirect3DBaseTexture8_iface;

    return D3D_OK;
}

static HRESULT WINAPI d3d8_device_CreateCubeTexture(IDirect3DDevice8 *iface, UINT edge_length,
        UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool, IDirect3DCubeTexture8 **texture)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    struct d3d8_texture *object;
    HRESULT hr;

    TRACE("iface %p, edge_length %u, levels %u, usage %#x, format %#x, pool %#x, texture %p.\n",
            iface, edge_length, levels, usage, format, pool, texture);

    *texture = NULL;
    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
    if (!object)
        return D3DERR_OUTOFVIDEOMEMORY;

    hr = cubetexture_init(object, device, edge_length, levels, usage, format, pool);
    if (FAILED(hr))
    {
        WARN("Failed to initialize cube texture, hr %#x.\n", hr);
        HeapFree(GetProcessHeap(), 0, object);
        return hr;
    }

    TRACE("Created cube texture %p.\n", object);
    *texture = (IDirect3DCubeTexture8 *)&object->IDirect3DBaseTexture8_iface;

    return hr;
}

static HRESULT WINAPI d3d8_device_CreateVertexBuffer(IDirect3DDevice8 *iface, UINT size,
        DWORD usage, DWORD fvf, D3DPOOL pool, IDirect3DVertexBuffer8 **buffer)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    struct d3d8_vertexbuffer *object;
    HRESULT hr;

    TRACE("iface %p, size %u, usage %#x, fvf %#x, pool %#x, buffer %p.\n",
            iface, size, usage, fvf, pool, buffer);

    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
    if (!object)
        return D3DERR_OUTOFVIDEOMEMORY;

    hr = vertexbuffer_init(object, device, size, usage, fvf, pool);
    if (FAILED(hr))
    {
        WARN("Failed to initialize vertex buffer, hr %#x.\n", hr);
        HeapFree(GetProcessHeap(), 0, object);
        return hr;
    }

    TRACE("Created vertex buffer %p.\n", object);
    *buffer = &object->IDirect3DVertexBuffer8_iface;

    return D3D_OK;
}

static HRESULT WINAPI d3d8_device_CreateIndexBuffer(IDirect3DDevice8 *iface, UINT size,
        DWORD usage, D3DFORMAT format, D3DPOOL pool, IDirect3DIndexBuffer8 **buffer)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    struct d3d8_indexbuffer *object;
    HRESULT hr;

    TRACE("iface %p, size %u, usage %#x, format %#x, pool %#x, buffer %p.\n",
            iface, size, usage, format, pool, buffer);

    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
    if (!object)
        return D3DERR_OUTOFVIDEOMEMORY;

    hr = indexbuffer_init(object, device, size, usage, format, pool);
    if (FAILED(hr))
    {
        WARN("Failed to initialize index buffer, hr %#x.\n", hr);
        HeapFree(GetProcessHeap(), 0, object);
        return hr;
    }

    TRACE("Created index buffer %p.\n", object);
    *buffer = &object->IDirect3DIndexBuffer8_iface;

    return D3D_OK;
}

static HRESULT d3d8_device_create_surface(struct d3d8_device *device, UINT width, UINT height,
        D3DFORMAT format, DWORD flags, IDirect3DSurface8 **surface, UINT usage, D3DPOOL pool,
        D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality)
{
    struct wined3d_resource_desc desc;
    struct d3d8_surface *surface_impl;
    struct wined3d_texture *texture;
    HRESULT hr;

    TRACE("device %p, width %u, height %u, format %#x, flags %#x, surface %p, "
            "usage %#x, pool %#x, multisample_type %#x, multisample_quality %u.\n",
            device, width, height, format, flags, surface,
            usage, pool, multisample_type, multisample_quality);

    desc.resource_type = WINED3D_RTYPE_TEXTURE_2D;
    desc.format = wined3dformat_from_d3dformat(format);
    desc.multisample_type = multisample_type;
    desc.multisample_quality = multisample_quality;
    desc.usage = usage & WINED3DUSAGE_MASK;
    desc.pool = pool;
    desc.width = width;
    desc.height = height;
    desc.depth = 1;
    desc.size = 0;

    wined3d_mutex_lock();

    if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &desc,
            1, flags, NULL, NULL, &d3d8_null_wined3d_parent_ops, &texture)))
    {
        wined3d_mutex_unlock();
        WARN("Failed to create texture, hr %#x.\n", hr);
        return hr;
    }

    surface_impl = wined3d_texture_get_sub_resource_parent(texture, 0);
    surface_impl->parent_device = &device->IDirect3DDevice8_iface;
    *surface = &surface_impl->IDirect3DSurface8_iface;
    IDirect3DSurface8_AddRef(*surface);
    wined3d_texture_decref(texture);

    wined3d_mutex_unlock();

    return D3D_OK;
}

static HRESULT WINAPI d3d8_device_CreateRenderTarget(IDirect3DDevice8 *iface, UINT width,
        UINT height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multisample_type, BOOL lockable,
        IDirect3DSurface8 **surface)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    DWORD flags = 0;

    TRACE("iface %p, width %u, height %u, format %#x, multisample_type %#x, lockable %#x, surface %p.\n",
            iface, width, height, format, multisample_type, lockable, surface);

    *surface = NULL;
    if (lockable)
        flags |= WINED3D_TEXTURE_CREATE_MAPPABLE;

    return d3d8_device_create_surface(device, width, height, format, flags, surface,
            D3DUSAGE_RENDERTARGET, D3DPOOL_DEFAULT, multisample_type, 0);
}

static HRESULT WINAPI d3d8_device_CreateDepthStencilSurface(IDirect3DDevice8 *iface,
        UINT width, UINT height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multisample_type,
        IDirect3DSurface8 **surface)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);

    TRACE("iface %p, width %u, height %u, format %#x, multisample_type %#x, surface %p.\n",
            iface, width, height, format, multisample_type, surface);

    *surface = NULL;

    /* TODO: Verify that Discard is false */
    return d3d8_device_create_surface(device, width, height, format, WINED3D_TEXTURE_CREATE_MAPPABLE,
            surface, D3DUSAGE_DEPTHSTENCIL, D3DPOOL_DEFAULT, multisample_type, 0);
}

/*  IDirect3DDevice8Impl::CreateImageSurface returns surface with pool type SYSTEMMEM */
static HRESULT WINAPI d3d8_device_CreateImageSurface(IDirect3DDevice8 *iface, UINT width,
        UINT height, D3DFORMAT format, IDirect3DSurface8 **surface)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);

    TRACE("iface %p, width %u, height %u, format %#x, surface %p.\n",
            iface, width, height, format, surface);

    *surface = NULL;

    return d3d8_device_create_surface(device, width, height, format, WINED3D_TEXTURE_CREATE_MAPPABLE,
            surface, 0, D3DPOOL_SYSTEMMEM, D3DMULTISAMPLE_NONE, 0);
}

static HRESULT WINAPI d3d8_device_CopyRects(IDirect3DDevice8 *iface,
        IDirect3DSurface8 *src_surface, const RECT *src_rects, UINT rect_count,
        IDirect3DSurface8 *dst_surface, const POINT *dst_points)
{
    struct d3d8_surface *src = unsafe_impl_from_IDirect3DSurface8(src_surface);
    struct d3d8_surface *dst = unsafe_impl_from_IDirect3DSurface8(dst_surface);
    enum wined3d_format_id src_format, dst_format;
    struct wined3d_sub_resource_desc wined3d_desc;
    UINT src_w, src_h;

    TRACE("iface %p, src_surface %p, src_rects %p, rect_count %u, dst_surface %p, dst_points %p.\n",
            iface, src_surface, src_rects, rect_count, dst_surface, dst_points);

    /* Check that the source texture is in WINED3D_POOL_SYSTEM_MEM and the
     * destination texture is in WINED3D_POOL_DEFAULT. */

    wined3d_mutex_lock();
    wined3d_texture_get_sub_resource_desc(src->wined3d_texture, src->sub_resource_idx, &wined3d_desc);
    if (wined3d_desc.usage & WINED3DUSAGE_DEPTHSTENCIL)
    {
        WARN("Source %p is a depth stencil surface, returning D3DERR_INVALIDCALL.\n", src_surface);
        wined3d_mutex_unlock();
        return D3DERR_INVALIDCALL;
    }
    src_format = wined3d_desc.format;
    src_w = wined3d_desc.width;
    src_h = wined3d_desc.height;

    wined3d_texture_get_sub_resource_desc(dst->wined3d_texture, dst->sub_resource_idx, &wined3d_desc);
    if (wined3d_desc.usage & WINED3DUSAGE_DEPTHSTENCIL)
    {
        WARN("Destination %p is a depth stencil surface, returning D3DERR_INVALIDCALL.\n", dst_surface);
        wined3d_mutex_unlock();
        return D3DERR_INVALIDCALL;
    }
    dst_format = wined3d_desc.format;

    /* Check that the source and destination formats match */
    if (src_format != dst_format)
    {
        WARN("Source %p format must match the destination %p format, returning D3DERR_INVALIDCALL.\n",
                src_surface, dst_surface);
        wined3d_mutex_unlock();
        return D3DERR_INVALIDCALL;
    }

    /* Quick if complete copy ... */
    if (!rect_count && !src_rects && !dst_points)
    {
        RECT rect = {0, 0, src_w, src_h};
        wined3d_texture_blt(dst->wined3d_texture, dst->sub_resource_idx, &rect,
                src->wined3d_texture, src->sub_resource_idx, &rect, 0, NULL, WINED3D_TEXF_POINT);
    }
    else
    {
        unsigned int i;
        /* Copy rect by rect */
        if (src_rects && dst_points)
        {
            for (i = 0; i < rect_count; ++i)
            {
                UINT w = src_rects[i].right - src_rects[i].left;
                UINT h = src_rects[i].bottom - src_rects[i].top;
                RECT dst_rect = {dst_points[i].x, dst_points[i].y,
                        dst_points[i].x + w, dst_points[i].y + h};

                wined3d_texture_blt(dst->wined3d_texture, dst->sub_resource_idx, &dst_rect,
                        src->wined3d_texture, src->sub_resource_idx, &src_rects[i], 0, NULL, WINED3D_TEXF_POINT);
            }
        }
        else
        {
            for (i = 0; i < rect_count; ++i)
            {
                UINT w = src_rects[i].right - src_rects[i].left;
                UINT h = src_rects[i].bottom - src_rects[i].top;
                RECT dst_rect = {0, 0, w, h};

                wined3d_texture_blt(dst->wined3d_texture, dst->sub_resource_idx, &dst_rect,
                        src->wined3d_texture, src->sub_resource_idx, &src_rects[i], 0, NULL, WINED3D_TEXF_POINT);
            }
        }
    }
    wined3d_mutex_unlock();

    return WINED3D_OK;
}

static HRESULT WINAPI d3d8_device_UpdateTexture(IDirect3DDevice8 *iface,
        IDirect3DBaseTexture8 *src_texture, IDirect3DBaseTexture8 *dst_texture)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    struct d3d8_texture *src_impl, *dst_impl;
    HRESULT hr;

    TRACE("iface %p, src_texture %p, dst_texture %p.\n", iface, src_texture, dst_texture);

    src_impl = unsafe_impl_from_IDirect3DBaseTexture8(src_texture);
    dst_impl = unsafe_impl_from_IDirect3DBaseTexture8(dst_texture);

    wined3d_mutex_lock();
    hr = wined3d_device_update_texture(device->wined3d_device,
            src_impl->wined3d_texture, dst_impl->wined3d_texture);
    wined3d_mutex_unlock();

    return hr;
}

static HRESULT WINAPI d3d8_device_GetFrontBuffer(IDirect3DDevice8 *iface, IDirect3DSurface8 *dst_surface)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    struct d3d8_surface *dst_impl = unsafe_impl_from_IDirect3DSurface8(dst_surface);
    HRESULT hr;

    TRACE("iface %p, dst_surface %p.\n", iface, dst_surface);

    if (!dst_surface)
    {
        WARN("Invalid destination surface passed.\n");
        return D3DERR_INVALIDCALL;
    }

    wined3d_mutex_lock();
    hr = wined3d_swapchain_get_front_buffer_data(device->implicit_swapchain->wined3d_swapchain,
            dst_impl->wined3d_texture, dst_impl->sub_resource_idx);
    wined3d_mutex_unlock();

    return hr;
}

static HRESULT WINAPI d3d8_device_SetRenderTarget(IDirect3DDevice8 *iface,
        IDirect3DSurface8 *render_target, IDirect3DSurface8 *depth_stencil)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    struct d3d8_surface *rt_impl = unsafe_impl_from_IDirect3DSurface8(render_target);
    struct d3d8_surface *ds_impl = unsafe_impl_from_IDirect3DSurface8(depth_stencil);
    struct wined3d_rendertarget_view *original_dsv;
    HRESULT hr = D3D_OK;

    TRACE("iface %p, render_target %p, depth_stencil %p.\n", iface, render_target, depth_stencil);

    wined3d_mutex_lock();

    if (ds_impl)
    {
        struct wined3d_sub_resource_desc ds_desc, rt_desc;
        struct wined3d_rendertarget_view *original_rtv;
        struct d3d8_surface *original_surface;

        /* If no render target is passed in check the size against the current RT */
        if (!render_target)
        {

            if (!(original_rtv = wined3d_device_get_rendertarget_view(device->wined3d_device, 0)))
            {
                wined3d_mutex_unlock();
                return D3DERR_NOTFOUND;
            }
            original_surface = wined3d_rendertarget_view_get_sub_resource_parent(original_rtv);
            wined3d_texture_get_sub_resource_desc(original_surface->wined3d_texture,
                    original_surface->sub_resource_idx, &rt_desc);
        }
        else
            wined3d_texture_get_sub_resource_desc(rt_impl->wined3d_texture,
                    rt_impl->sub_resource_idx, &rt_desc);

        wined3d_texture_get_sub_resource_desc(ds_impl->wined3d_texture, ds_impl->sub_resource_idx, &ds_desc);

        if (ds_desc.width < rt_desc.width || ds_desc.height < rt_desc.height)
        {
            WARN("Depth stencil is smaller than the render target, returning D3DERR_INVALIDCALL\n");
            wined3d_mutex_unlock();
            return D3DERR_INVALIDCALL;
        }
        if (ds_desc.multisample_type != rt_desc.multisample_type
                || ds_desc.multisample_quality != rt_desc.multisample_quality)
        {
            WARN("Multisample settings do not match, returning D3DERR_INVALIDCALL\n");
            wined3d_mutex_unlock();
            return D3DERR_INVALIDCALL;

        }
    }

    original_dsv = wined3d_device_get_depth_stencil_view(device->wined3d_device);
    wined3d_device_set_depth_stencil_view(device->wined3d_device,
            ds_impl ? d3d8_surface_get_rendertarget_view(ds_impl) : NULL);
    if (render_target && FAILED(hr = wined3d_device_set_rendertarget_view(device->wined3d_device, 0,
            d3d8_surface_get_rendertarget_view(rt_impl), TRUE)))
        wined3d_device_set_depth_stencil_view(device->wined3d_device, original_dsv);

    wined3d_mutex_unlock();

    return hr;
}

static HRESULT WINAPI d3d8_device_GetRenderTarget(IDirect3DDevice8 *iface, IDirect3DSurface8 **render_target)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    struct wined3d_rendertarget_view *wined3d_rtv;
    struct d3d8_surface *surface_impl;
    HRESULT hr;

    TRACE("iface %p, render_target %p.\n", iface, render_target);

    if (!render_target)
        return D3DERR_INVALIDCALL;

    wined3d_mutex_lock();
    if ((wined3d_rtv = wined3d_device_get_rendertarget_view(device->wined3d_device, 0)))
    {
        /* We want the sub resource parent here, since the view itself may be
         * internal to wined3d and may not have a parent. */
        surface_impl = wined3d_rendertarget_view_get_sub_resource_parent(wined3d_rtv);
        *render_target = &surface_impl->IDirect3DSurface8_iface;
        IDirect3DSurface8_AddRef(*render_target);
        hr = D3D_OK;
    }
    else
    {
        ERR("Failed to get wined3d render target.\n");
        *render_target = NULL;
        hr = D3DERR_NOTFOUND;
    }
    wined3d_mutex_unlock();

    return hr;
}

static HRESULT WINAPI d3d8_device_GetDepthStencilSurface(IDirect3DDevice8 *iface, IDirect3DSurface8 **depth_stencil)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    struct wined3d_rendertarget_view *wined3d_dsv;
    struct d3d8_surface *surface_impl;
    HRESULT hr = D3D_OK;

    TRACE("iface %p, depth_stencil %p.\n", iface, depth_stencil);

    if (!depth_stencil)
        return D3DERR_INVALIDCALL;

    wined3d_mutex_lock();
    if ((wined3d_dsv = wined3d_device_get_depth_stencil_view(device->wined3d_device)))
    {
        /* We want the sub resource parent here, since the view itself may be
         * internal to wined3d and may not have a parent. */
        surface_impl = wined3d_rendertarget_view_get_sub_resource_parent(wined3d_dsv);
        *depth_stencil = &surface_impl->IDirect3DSurface8_iface;
        IDirect3DSurface8_AddRef(*depth_stencil);
    }
    else
    {
        hr = D3DERR_NOTFOUND;
        *depth_stencil = NULL;
    }
    wined3d_mutex_unlock();

    return hr;
}

static HRESULT WINAPI d3d8_device_BeginScene(IDirect3DDevice8 *iface)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    HRESULT hr;

    TRACE("iface %p.\n", iface);

    wined3d_mutex_lock();
    hr = wined3d_device_begin_scene(device->wined3d_device);
    wined3d_mutex_unlock();

    return hr;
}

static HRESULT WINAPI DECLSPEC_HOTPATCH d3d8_device_EndScene(IDirect3DDevice8 *iface)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    HRESULT hr;

    TRACE("iface %p.\n", iface);

    wined3d_mutex_lock();
    hr = wined3d_device_end_scene(device->wined3d_device);
    wined3d_mutex_unlock();

    return hr;
}

static HRESULT WINAPI d3d8_device_Clear(IDirect3DDevice8 *iface, DWORD rect_count,
        const D3DRECT *rects, DWORD flags, D3DCOLOR color, float z, DWORD stencil)
{
    const struct wined3d_color c =
    {
        ((color >> 16) & 0xff) / 255.0f,
        ((color >>  8) & 0xff) / 255.0f,
        (color & 0xff) / 255.0f,
        ((color >> 24) & 0xff) / 255.0f,
    };
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    HRESULT hr;

    TRACE("iface %p, rect_count %u, rects %p, flags %#x, color 0x%08x, z %.8e, stencil %u.\n",
            iface, rect_count, rects, flags, color, z, stencil);

    if (rect_count && !rects)
    {
        WARN("count %u with NULL rects.\n", rect_count);
        rect_count = 0;
    }

    wined3d_mutex_lock();
    hr = wined3d_device_clear(device->wined3d_device, rect_count, (const RECT *)rects, flags, &c, z, stencil);
    wined3d_mutex_unlock();

    return hr;
}

static HRESULT WINAPI d3d8_device_SetTransform(IDirect3DDevice8 *iface,
        D3DTRANSFORMSTATETYPE state, const D3DMATRIX *matrix)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);

    TRACE("iface %p, state %#x, matrix %p.\n", iface, state, matrix);

    /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */
    wined3d_mutex_lock();
    wined3d_device_set_transform(device->wined3d_device, state, (const struct wined3d_matrix *)matrix);
    wined3d_mutex_unlock();

    return D3D_OK;
}

static HRESULT WINAPI d3d8_device_GetTransform(IDirect3DDevice8 *iface,
        D3DTRANSFORMSTATETYPE state, D3DMATRIX *matrix)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);

    TRACE("iface %p, state %#x, matrix %p.\n", iface, state, matrix);

    /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */
    wined3d_mutex_lock();
    wined3d_device_get_transform(device->wined3d_device, state, (struct wined3d_matrix *)matrix);
    wined3d_mutex_unlock();

    return D3D_OK;
}

static HRESULT WINAPI d3d8_device_MultiplyTransform(IDirect3DDevice8 *iface,
        D3DTRANSFORMSTATETYPE state, const D3DMATRIX *matrix)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);

    TRACE("iface %p, state %#x, matrix %p.\n", iface, state, matrix);

    /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */
    wined3d_mutex_lock();
    wined3d_device_multiply_transform(device->wined3d_device, state, (const struct wined3d_matrix *)matrix);
    wined3d_mutex_unlock();

    return D3D_OK;
}

static HRESULT WINAPI d3d8_device_SetViewport(IDirect3DDevice8 *iface, const D3DVIEWPORT8 *viewport)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);

    TRACE("iface %p, viewport %p.\n", iface, viewport);

    /* Note: D3DVIEWPORT8 is compatible with struct wined3d_viewport. */
    wined3d_mutex_lock();
    wined3d_device_set_viewport(device->wined3d_device, (const struct wined3d_viewport *)viewport);
    wined3d_mutex_unlock();

    return D3D_OK;
}

static HRESULT WINAPI d3d8_device_GetViewport(IDirect3DDevice8 *iface, D3DVIEWPORT8 *viewport)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);

    TRACE("iface %p, viewport %p.\n", iface, viewport);

    /* Note: D3DVIEWPORT8 is compatible with struct wined3d_viewport. */
    wined3d_mutex_lock();
    wined3d_device_get_viewport(device->wined3d_device, (struct wined3d_viewport *)viewport);
    wined3d_mutex_unlock();

    return D3D_OK;
}

static HRESULT WINAPI d3d8_device_SetMaterial(IDirect3DDevice8 *iface, const D3DMATERIAL8 *material)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);

    TRACE("iface %p, material %p.\n", iface, material);

    /* Note: D3DMATERIAL8 is compatible with struct wined3d_material. */
    wined3d_mutex_lock();
    wined3d_device_set_material(device->wined3d_device, (const struct wined3d_material *)material);
    wined3d_mutex_unlock();

    return D3D_OK;
}

static HRESULT WINAPI d3d8_device_GetMaterial(IDirect3DDevice8 *iface, D3DMATERIAL8 *material)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);

    TRACE("iface %p, material %p.\n", iface, material);

    /* Note: D3DMATERIAL8 is compatible with struct wined3d_material. */
    wined3d_mutex_lock();
    wined3d_device_get_material(device->wined3d_device, (struct wined3d_material *)material);
    wined3d_mutex_unlock();

    return D3D_OK;
}

static HRESULT WINAPI d3d8_device_SetLight(IDirect3DDevice8 *iface, DWORD index, const D3DLIGHT8 *light)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    HRESULT hr;

    TRACE("iface %p, index %u, light %p.\n", iface, index, light);

    /* Note: D3DLIGHT8 is compatible with struct wined3d_light. */
    wined3d_mutex_lock();
    hr = wined3d_device_set_light(device->wined3d_device, index, (const struct wined3d_light *)light);
    wined3d_mutex_unlock();

    return hr;
}

static HRESULT WINAPI d3d8_device_GetLight(IDirect3DDevice8 *iface, DWORD index, D3DLIGHT8 *light)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    HRESULT hr;

    TRACE("iface %p, index %u, light %p.\n", iface, index, light);

    /* Note: D3DLIGHT8 is compatible with struct wined3d_light. */
    wined3d_mutex_lock();
    hr = wined3d_device_get_light(device->wined3d_device, index, (struct wined3d_light *)light);
    wined3d_mutex_unlock();

    return hr;
}

static HRESULT WINAPI d3d8_device_LightEnable(IDirect3DDevice8 *iface, DWORD index, BOOL enable)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    HRESULT hr;

    TRACE("iface %p, index %u, enable %#x.\n", iface, index, enable);

    wined3d_mutex_lock();
    hr = wined3d_device_set_light_enable(device->wined3d_device, index, enable);
    wined3d_mutex_unlock();

    return hr;
}

static HRESULT WINAPI d3d8_device_GetLightEnable(IDirect3DDevice8 *iface, DWORD index, BOOL *enable)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    HRESULT hr;

    TRACE("iface %p, index %u, enable %p.\n", iface, index, enable);

    wined3d_mutex_lock();
    hr = wined3d_device_get_light_enable(device->wined3d_device, index, enable);
    wined3d_mutex_unlock();

    return hr;
}

static HRESULT WINAPI d3d8_device_SetClipPlane(IDirect3DDevice8 *iface, DWORD index, const float *plane)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    HRESULT hr;

    TRACE("iface %p, index %u, plane %p.\n", iface, index, plane);

    wined3d_mutex_lock();
    hr = wined3d_device_set_clip_plane(device->wined3d_device, index, (const struct wined3d_vec4 *)plane);
    wined3d_mutex_unlock();

    return hr;
}

static HRESULT WINAPI d3d8_device_GetClipPlane(IDirect3DDevice8 *iface, DWORD index, float *plane)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    HRESULT hr;

    TRACE("iface %p, index %u, plane %p.\n", iface, index, plane);

    wined3d_mutex_lock();
    hr = wined3d_device_get_clip_plane(device->wined3d_device, index, (struct wined3d_vec4 *)plane);
    wined3d_mutex_unlock();

    return hr;
}

static HRESULT WINAPI d3d8_device_SetRenderState(IDirect3DDevice8 *iface,
        D3DRENDERSTATETYPE state, DWORD value)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);

    TRACE("iface %p, state %#x, value %#x.\n", iface, state, value);

    wined3d_mutex_lock();
    switch (state)
    {
        case D3DRS_ZBIAS:
            wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_DEPTHBIAS, value);
            break;

        default:
            wined3d_device_set_render_state(device->wined3d_device, state, value);
    }
    wined3d_mutex_unlock();

    return D3D_OK;
}

static HRESULT WINAPI d3d8_device_GetRenderState(IDirect3DDevice8 *iface,
        D3DRENDERSTATETYPE state, DWORD *value)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);

    TRACE("iface %p, state %#x, value %p.\n", iface, state, value);

    wined3d_mutex_lock();
    switch (state)
    {
        case D3DRS_ZBIAS:
            *value = wined3d_device_get_render_state(device->wined3d_device, WINED3D_RS_DEPTHBIAS);
            break;

        default:
            *value = wined3d_device_get_render_state(device->wined3d_device, state);
    }
    wined3d_mutex_unlock();

    return D3D_OK;
}

static HRESULT WINAPI d3d8_device_BeginStateBlock(IDirect3DDevice8 *iface)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    HRESULT hr;

    TRACE("iface %p.\n", iface);

    wined3d_mutex_lock();
    hr = wined3d_device_begin_stateblock(device->wined3d_device);
    wined3d_mutex_unlock();

    return hr;
}

static HRESULT WINAPI d3d8_device_EndStateBlock(IDirect3DDevice8 *iface, DWORD *token)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    struct wined3d_stateblock *stateblock;
    HRESULT hr;

    TRACE("iface %p, token %p.\n", iface, token);

    /* Tell wineD3D to endstateblock before anything else (in case we run out
     * of memory later and cause locking problems)
     */
    wined3d_mutex_lock();
    hr = wined3d_device_end_stateblock(device->wined3d_device, &stateblock);
    if (FAILED(hr))
    {
        WARN("IWineD3DDevice_EndStateBlock returned an error\n");
        wined3d_mutex_unlock();
        return hr;
    }

    *token = d3d8_allocate_handle(&device->handle_table, stateblock, D3D8_HANDLE_SB);
    wined3d_mutex_unlock();

    if (*token == D3D8_INVALID_HANDLE)
    {
        ERR("Failed to create a handle\n");
        wined3d_mutex_lock();
        wined3d_stateblock_decref(stateblock);
        wined3d_mutex_unlock();
        return E_FAIL;
    }
    ++*token;

    TRACE("Returning %#x (%p).\n", *token, stateblock);

    return hr;
}

static HRESULT WINAPI d3d8_device_ApplyStateBlock(IDirect3DDevice8 *iface, DWORD token)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    struct wined3d_stateblock *stateblock;

    TRACE("iface %p, token %#x.\n", iface, token);

    if (!token)
        return D3D_OK;

    wined3d_mutex_lock();
    stateblock = d3d8_get_object(&device->handle_table, token - 1, D3D8_HANDLE_SB);
    if (!stateblock)
    {
        WARN("Invalid handle (%#x) passed.\n", token);
        wined3d_mutex_unlock();
        return D3DERR_INVALIDCALL;
    }
    wined3d_stateblock_apply(stateblock);
    wined3d_mutex_unlock();

    return D3D_OK;
}

static HRESULT WINAPI d3d8_device_CaptureStateBlock(IDirect3DDevice8 *iface, DWORD token)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    struct wined3d_stateblock *stateblock;

    TRACE("iface %p, token %#x.\n", iface, token);

    wined3d_mutex_lock();
    stateblock = d3d8_get_object(&device->handle_table, token - 1, D3D8_HANDLE_SB);
    if (!stateblock)
    {
        WARN("Invalid handle (%#x) passed.\n", token);
        wined3d_mutex_unlock();
        return D3DERR_INVALIDCALL;
    }
    wined3d_stateblock_capture(stateblock);
    wined3d_mutex_unlock();

    return D3D_OK;
}

static HRESULT WINAPI d3d8_device_DeleteStateBlock(IDirect3DDevice8 *iface, DWORD token)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    struct wined3d_stateblock *stateblock;

    TRACE("iface %p, token %#x.\n", iface, token);

    wined3d_mutex_lock();
    stateblock = d3d8_free_handle(&device->handle_table, token - 1, D3D8_HANDLE_SB);

    if (!stateblock)
    {
        WARN("Invalid handle (%#x) passed.\n", token);
        wined3d_mutex_unlock();
        return D3DERR_INVALIDCALL;
    }

    if (wined3d_stateblock_decref(stateblock))
    {
        ERR("Stateblock %p has references left, this shouldn't happen.\n", stateblock);
    }
    wined3d_mutex_unlock();

    return D3D_OK;
}

static HRESULT WINAPI d3d8_device_CreateStateBlock(IDirect3DDevice8 *iface,
        D3DSTATEBLOCKTYPE type, DWORD *handle)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    struct wined3d_stateblock *stateblock;
    HRESULT hr;

    TRACE("iface %p, type %#x, handle %p.\n", iface, type, handle);

    if (type != D3DSBT_ALL
            && type != D3DSBT_PIXELSTATE
            && type != D3DSBT_VERTEXSTATE)
    {
        WARN("Unexpected stateblock type, returning D3DERR_INVALIDCALL\n");
        return D3DERR_INVALIDCALL;
    }

    wined3d_mutex_lock();
    hr = wined3d_stateblock_create(device->wined3d_device, (enum wined3d_stateblock_type)type, &stateblock);
    if (FAILED(hr))
    {
        wined3d_mutex_unlock();
        ERR("IWineD3DDevice_CreateStateBlock failed, hr %#x\n", hr);
        return hr;
    }

    *handle = d3d8_allocate_handle(&device->handle_table, stateblock, D3D8_HANDLE_SB);
    wined3d_mutex_unlock();

    if (*handle == D3D8_INVALID_HANDLE)
    {
        ERR("Failed to allocate a handle.\n");
        wined3d_mutex_lock();
        wined3d_stateblock_decref(stateblock);
        wined3d_mutex_unlock();
        return E_FAIL;
    }
    ++*handle;

    TRACE("Returning %#x (%p).\n", *handle, stateblock);

    return hr;
}

static HRESULT WINAPI d3d8_device_SetClipStatus(IDirect3DDevice8 *iface, const D3DCLIPSTATUS8 *clip_status)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    HRESULT hr;

    TRACE("iface %p, clip_status %p.\n", iface, clip_status);
    /* FIXME: Verify that D3DCLIPSTATUS8 ~= struct wined3d_clip_status. */

    wined3d_mutex_lock();
    hr = wined3d_device_set_clip_status(device->wined3d_device, (const struct wined3d_clip_status *)clip_status);
    wined3d_mutex_unlock();

    return hr;
}

static HRESULT WINAPI d3d8_device_GetClipStatus(IDirect3DDevice8 *iface, D3DCLIPSTATUS8 *clip_status)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    HRESULT hr;

    TRACE("iface %p, clip_status %p.\n", iface, clip_status);

    wined3d_mutex_lock();
    hr = wined3d_device_get_clip_status(device->wined3d_device, (struct wined3d_clip_status *)clip_status);
    wined3d_mutex_unlock();

    return hr;
}

static HRESULT WINAPI d3d8_device_GetTexture(IDirect3DDevice8 *iface, DWORD stage, IDirect3DBaseTexture8 **texture)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    struct wined3d_texture *wined3d_texture;
    struct d3d8_texture *texture_impl;

    TRACE("iface %p, stage %u, texture %p.\n", iface, stage, texture);

    if (!texture)
        return D3DERR_INVALIDCALL;

    wined3d_mutex_lock();
    if ((wined3d_texture = wined3d_device_get_texture(device->wined3d_device, stage)))
    {
        texture_impl = wined3d_texture_get_parent(wined3d_texture);
        *texture = &texture_impl->IDirect3DBaseTexture8_iface;
        IDirect3DBaseTexture8_AddRef(*texture);
    }
    else
    {
        *texture = NULL;
    }
    wined3d_mutex_unlock();

    return D3D_OK;
}

static HRESULT WINAPI d3d8_device_SetTexture(IDirect3DDevice8 *iface, DWORD stage, IDirect3DBaseTexture8 *texture)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    struct d3d8_texture *texture_impl;
    HRESULT hr;

    TRACE("iface %p, stage %u, texture %p.\n", iface, stage, texture);

    texture_impl = unsafe_impl_from_IDirect3DBaseTexture8(texture);

    wined3d_mutex_lock();
    hr = wined3d_device_set_texture(device->wined3d_device, stage,
            texture_impl ? texture_impl->wined3d_texture : NULL);
    wined3d_mutex_unlock();

    return hr;
}

static const struct tss_lookup
{
    BOOL sampler_state;
    enum wined3d_texture_stage_state state;
}
tss_lookup[] =
{
    {FALSE, WINED3D_TSS_INVALID},                   /*  0, unused */
    {FALSE, WINED3D_TSS_COLOR_OP},                  /*  1, D3DTSS_COLOROP */
    {FALSE, WINED3D_TSS_COLOR_ARG1},                /*  2, D3DTSS_COLORARG1 */
    {FALSE, WINED3D_TSS_COLOR_ARG2},                /*  3, D3DTSS_COLORARG2 */
    {FALSE, WINED3D_TSS_ALPHA_OP},                  /*  4, D3DTSS_ALPHAOP */
    {FALSE, WINED3D_TSS_ALPHA_ARG1},                /*  5, D3DTSS_ALPHAARG1 */
    {FALSE, WINED3D_TSS_ALPHA_ARG2},                /*  6, D3DTSS_ALPHAARG2 */
    {FALSE, WINED3D_TSS_BUMPENV_MAT00},             /*  7, D3DTSS_BUMPENVMAT00 */
    {FALSE, WINED3D_TSS_BUMPENV_MAT01},             /*  8, D3DTSS_BUMPENVMAT01 */
    {FALSE, WINED3D_TSS_BUMPENV_MAT10},             /*  9, D3DTSS_BUMPENVMAT10 */
    {FALSE, WINED3D_TSS_BUMPENV_MAT11},             /* 10, D3DTSS_BUMPENVMAT11 */
    {FALSE, WINED3D_TSS_TEXCOORD_INDEX},            /* 11, D3DTSS_TEXCOORDINDEX */
    {FALSE, WINED3D_TSS_INVALID},                   /* 12, unused */
    {TRUE,  WINED3D_SAMP_ADDRESS_U},                /* 13, D3DTSS_ADDRESSU */
    {TRUE,  WINED3D_SAMP_ADDRESS_V},                /* 14, D3DTSS_ADDRESSV */
    {TRUE,  WINED3D_SAMP_BORDER_COLOR},             /* 15, D3DTSS_BORDERCOLOR */
    {TRUE,  WINED3D_SAMP_MAG_FILTER},               /* 16, D3DTSS_MAGFILTER */
    {TRUE,  WINED3D_SAMP_MIN_FILTER},               /* 17, D3DTSS_MINFILTER */
    {TRUE,  WINED3D_SAMP_MIP_FILTER},               /* 18, D3DTSS_MIPFILTER */
    {TRUE,  WINED3D_SAMP_MIPMAP_LOD_BIAS},          /* 19, D3DTSS_MIPMAPLODBIAS */
    {TRUE,  WINED3D_SAMP_MAX_MIP_LEVEL},            /* 20, D3DTSS_MAXMIPLEVEL */
    {TRUE,  WINED3D_SAMP_MAX_ANISOTROPY},           /* 21, D3DTSS_MAXANISOTROPY */
    {FALSE, WINED3D_TSS_BUMPENV_LSCALE},            /* 22, D3DTSS_BUMPENVLSCALE */
    {FALSE, WINED3D_TSS_BUMPENV_LOFFSET},           /* 23, D3DTSS_BUMPENVLOFFSET */
    {FALSE, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS},   /* 24, D3DTSS_TEXTURETRANSFORMFLAGS */
    {TRUE,  WINED3D_SAMP_ADDRESS_W},                /* 25, D3DTSS_ADDRESSW */
    {FALSE, WINED3D_TSS_COLOR_ARG0},                /* 26, D3DTSS_COLORARG0 */
    {FALSE, WINED3D_TSS_ALPHA_ARG0},                /* 27, D3DTSS_ALPHAARG0 */
    {FALSE, WINED3D_TSS_RESULT_ARG},                /* 28, D3DTSS_RESULTARG */
};

static HRESULT WINAPI d3d8_device_GetTextureStageState(IDirect3DDevice8 *iface,
        DWORD stage, D3DTEXTURESTAGESTATETYPE Type, DWORD *value)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    const struct tss_lookup *l;

    TRACE("iface %p, stage %u, state %#x, value %p.\n", iface, stage, Type, value);

    if (Type >= sizeof(tss_lookup) / sizeof(*tss_lookup))
    {
        WARN("Invalid Type %#x passed.\n", Type);
        return D3D_OK;
    }

    l = &tss_lookup[Type];

    wined3d_mutex_lock();
    if (l->sampler_state)
        *value = wined3d_device_get_sampler_state(device->wined3d_device, stage, l->state);
    else
        *value = wined3d_device_get_texture_stage_state(device->wined3d_device, stage, l->state);
    wined3d_mutex_unlock();

    return D3D_OK;
}

static HRESULT WINAPI d3d8_device_SetTextureStageState(IDirect3DDevice8 *iface,
        DWORD stage, D3DTEXTURESTAGESTATETYPE type, DWORD value)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    const struct tss_lookup *l;

    TRACE("iface %p, stage %u, state %#x, value %#x.\n", iface, stage, type, value);

    if (type >= sizeof(tss_lookup) / sizeof(*tss_lookup))
    {
        WARN("Invalid type %#x passed.\n", type);
        return D3D_OK;
    }

    l = &tss_lookup[type];

    wined3d_mutex_lock();
    if (l->sampler_state)
        wined3d_device_set_sampler_state(device->wined3d_device, stage, l->state, value);
    else
        wined3d_device_set_texture_stage_state(device->wined3d_device, stage, l->state, value);
    wined3d_mutex_unlock();

    return D3D_OK;
}

static HRESULT WINAPI d3d8_device_ValidateDevice(IDirect3DDevice8 *iface, DWORD *pass_count)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    HRESULT hr;

    TRACE("iface %p, pass_count %p.\n", iface, pass_count);

    wined3d_mutex_lock();
    hr = wined3d_device_validate_device(device->wined3d_device, pass_count);
    wined3d_mutex_unlock();

    return hr;
}

static HRESULT WINAPI d3d8_device_GetInfo(IDirect3DDevice8 *iface,
        DWORD info_id, void *info, DWORD info_size)
{
    FIXME("iface %p, info_id %#x, info %p, info_size %u stub!\n", iface, info_id, info, info_size);

    return D3D_OK;
}

static HRESULT WINAPI d3d8_device_SetPaletteEntries(IDirect3DDevice8 *iface,
        UINT palette_idx, const PALETTEENTRY *entries)
{
    WARN("iface %p, palette_idx %u, entries %p unimplemented\n", iface, palette_idx, entries);

    /* GPUs stopped supporting palettized textures with the Shader Model 1 generation. Wined3d
     * does not have a d3d8/9-style palette API */

    return D3D_OK;
}

static HRESULT WINAPI d3d8_device_GetPaletteEntries(IDirect3DDevice8 *iface,
        UINT palette_idx, PALETTEENTRY *entries)
{
    FIXME("iface %p, palette_idx %u, entries %p unimplemented.\n", iface, palette_idx, entries);

    return D3DERR_INVALIDCALL;
}

static HRESULT WINAPI d3d8_device_SetCurrentTexturePalette(IDirect3DDevice8 *iface, UINT palette_idx)
{
    WARN("iface %p, palette_idx %u unimplemented.\n", iface, palette_idx);

    return D3D_OK;
}

static HRESULT WINAPI d3d8_device_GetCurrentTexturePalette(IDirect3DDevice8 *iface, UINT *palette_idx)
{
    FIXME("iface %p, palette_idx %p unimplemented.\n", iface, palette_idx);

    return D3DERR_INVALIDCALL;
}

static HRESULT WINAPI d3d8_device_DrawPrimitive(IDirect3DDevice8 *iface,
        D3DPRIMITIVETYPE primitive_type, UINT start_vertex, UINT primitive_count)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    HRESULT hr;

    TRACE("iface %p, primitive_type %#x, start_vertex %u, primitive_count %u.\n",
            iface, primitive_type, start_vertex, primitive_count);

    wined3d_mutex_lock();
    wined3d_device_set_primitive_type(device->wined3d_device, primitive_type);
    hr = wined3d_device_draw_primitive(device->wined3d_device, start_vertex,
            vertex_count_from_primitive_count(primitive_type, primitive_count));
    wined3d_mutex_unlock();

    return hr;
}

static HRESULT WINAPI d3d8_device_DrawIndexedPrimitive(IDirect3DDevice8 *iface,
        D3DPRIMITIVETYPE primitive_type, UINT min_vertex_idx, UINT vertex_count,
        UINT start_idx, UINT primitive_count)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    HRESULT hr;

    TRACE("iface %p, primitive_type %#x, min_vertex_idx %u, vertex_count %u, start_idx %u, primitive_count %u.\n",
            iface, primitive_type, min_vertex_idx, vertex_count, start_idx, primitive_count);

    wined3d_mutex_lock();
    wined3d_device_set_primitive_type(device->wined3d_device, primitive_type);
    hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, start_idx,
            vertex_count_from_primitive_count(primitive_type, primitive_count));
    wined3d_mutex_unlock();

    return hr;
}

/* The caller is responsible for wined3d locking */
static HRESULT d3d8_device_prepare_vertex_buffer(struct d3d8_device *device, UINT min_size)
{
    HRESULT hr;

    if (device->vertex_buffer_size < min_size || !device->vertex_buffer)
    {
        UINT size = max(device->vertex_buffer_size * 2, min_size);
        struct wined3d_buffer *buffer;

        TRACE("Growing vertex buffer to %u bytes\n", size);

        hr = wined3d_buffer_create_vb(device->wined3d_device, size, WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY,
                WINED3D_POOL_DEFAULT, NULL, &d3d8_null_wined3d_parent_ops, &buffer);
        if (FAILED(hr))
        {
            ERR("(%p) wined3d_buffer_create_vb failed with hr = %08x\n", device, hr);
            return hr;
        }

        if (device->vertex_buffer)
            wined3d_buffer_decref(device->vertex_buffer);

        device->vertex_buffer = buffer;
        device->vertex_buffer_size = size;
        device->vertex_buffer_pos = 0;
    }
    return D3D_OK;
}

static HRESULT WINAPI d3d8_device_DrawPrimitiveUP(IDirect3DDevice8 *iface,
        D3DPRIMITIVETYPE primitive_type, UINT primitive_count, const void *data,
        UINT stride)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    HRESULT hr;
    UINT vtx_count = vertex_count_from_primitive_count(primitive_type, primitive_count);
    UINT size = vtx_count * stride;
    UINT vb_pos, align;
    BYTE *buffer_data;

    TRACE("iface %p, primitive_type %#x, primitive_count %u, data %p, stride %u.\n",
            iface, primitive_type, primitive_count, data, stride);

    if (!primitive_count)
    {
        WARN("primitive_count is 0, returning D3D_OK\n");
        return D3D_OK;
    }

    wined3d_mutex_lock();
    hr = d3d8_device_prepare_vertex_buffer(device, size);
    if (FAILED(hr))
        goto done;

    vb_pos = device->vertex_buffer_pos;
    align = vb_pos % stride;
    if (align) align = stride - align;
    if (vb_pos + size + align > device->vertex_buffer_size)
        vb_pos = 0;
    else
        vb_pos += align;

    hr = wined3d_buffer_map(device->vertex_buffer, vb_pos, size, &buffer_data,
            vb_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD);
    if (FAILED(hr))
        goto done;
    memcpy(buffer_data, data, size);
    wined3d_buffer_unmap(device->vertex_buffer);
    device->vertex_buffer_pos = vb_pos + size;

    hr = wined3d_device_set_stream_source(device->wined3d_device, 0, device->vertex_buffer, 0, stride);
    if (FAILED(hr))
        goto done;

    wined3d_device_set_primitive_type(device->wined3d_device, primitive_type);
    hr = wined3d_device_draw_primitive(device->wined3d_device, vb_pos / stride, vtx_count);
    wined3d_device_set_stream_source(device->wined3d_device, 0, NULL, 0, 0);

done:
    wined3d_mutex_unlock();
    return hr;
}

/* The caller is responsible for wined3d locking */
static HRESULT d3d8_device_prepare_index_buffer(struct d3d8_device *device, UINT min_size)
{
    HRESULT hr;

    if (device->index_buffer_size < min_size || !device->index_buffer)
    {
        UINT size = max(device->index_buffer_size * 2, min_size);
        struct wined3d_buffer *buffer;

        TRACE("Growing index buffer to %u bytes\n", size);

        hr = wined3d_buffer_create_ib(device->wined3d_device, size, WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY,
                WINED3D_POOL_DEFAULT, NULL, &d3d8_null_wined3d_parent_ops, &buffer);
        if (FAILED(hr))
        {
            ERR("(%p) wined3d_buffer_create_ib failed with hr = %08x\n", device, hr);
            return hr;
        }

        if (device->index_buffer)
            wined3d_buffer_decref(device->index_buffer);

        device->index_buffer = buffer;
        device->index_buffer_size = size;
        device->index_buffer_pos = 0;
    }
    return D3D_OK;
}

static HRESULT WINAPI d3d8_device_DrawIndexedPrimitiveUP(IDirect3DDevice8 *iface,
        D3DPRIMITIVETYPE primitive_type, UINT min_vertex_idx, UINT vertex_count,
        UINT primitive_count, const void *index_data, D3DFORMAT index_format,
        const void *vertex_data, UINT vertex_stride)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    HRESULT hr;
    BYTE *buffer_data;

    UINT idx_count = vertex_count_from_primitive_count(primitive_type, primitive_count);
    UINT idx_fmt_size = index_format == D3DFMT_INDEX16 ? 2 : 4;
    UINT idx_size = idx_count * idx_fmt_size;
    UINT ib_pos;

    UINT vtx_size = vertex_count * vertex_stride;
    UINT vb_pos, align;

    TRACE("iface %p, primitive_type %#x, min_vertex_idx %u, vertex_count %u, primitive_count %u, "
            "index_data %p, index_format %#x, vertex_data %p, vertex_stride %u.\n",
            iface, primitive_type, min_vertex_idx, vertex_count, primitive_count,
            index_data, index_format, vertex_data, vertex_stride);

    if (!primitive_count)
    {
        WARN("primitive_count is 0, returning D3D_OK\n");
        return D3D_OK;
    }

    wined3d_mutex_lock();

    hr = d3d8_device_prepare_vertex_buffer(device, vtx_size);
    if (FAILED(hr))
        goto done;

    vb_pos = device->vertex_buffer_pos;
    align = vb_pos % vertex_stride;
    if (align) align = vertex_stride - align;
    if (vb_pos + vtx_size + align > device->vertex_buffer_size)
        vb_pos = 0;
    else
        vb_pos += align;

    hr = wined3d_buffer_map(device->vertex_buffer, vb_pos, vtx_size, &buffer_data,
            vb_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD);
    if (FAILED(hr))
        goto done;
    memcpy(buffer_data, vertex_data, vtx_size);
    wined3d_buffer_unmap(device->vertex_buffer);
    device->vertex_buffer_pos = vb_pos + vtx_size;

    hr = d3d8_device_prepare_index_buffer(device, idx_size);
    if (FAILED(hr))
        goto done;

    ib_pos = device->index_buffer_pos;
    align = ib_pos % idx_fmt_size;
    if (align) align = idx_fmt_size - align;
    if (ib_pos + idx_size + align > device->index_buffer_size)
        ib_pos = 0;
    else
        ib_pos += align;

    hr = wined3d_buffer_map(device->index_buffer, ib_pos, idx_size, &buffer_data,
            ib_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD);
    if (FAILED(hr))
        goto done;
    memcpy(buffer_data, index_data, idx_size);
    wined3d_buffer_unmap(device->index_buffer);
    device->index_buffer_pos = ib_pos + idx_size;

    hr = wined3d_device_set_stream_source(device->wined3d_device, 0, device->vertex_buffer, 0, vertex_stride);
    if (FAILED(hr))
        goto done;

    wined3d_device_set_index_buffer(device->wined3d_device, device->index_buffer,
            wined3dformat_from_d3dformat(index_format));
    wined3d_device_set_base_vertex_index(device->wined3d_device, vb_pos / vertex_stride);

    wined3d_device_set_primitive_type(device->wined3d_device, primitive_type);
    hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, ib_pos / idx_fmt_size, idx_count);

    wined3d_device_set_stream_source(device->wined3d_device, 0, NULL, 0, 0);
    wined3d_device_set_index_buffer(device->wined3d_device, NULL, WINED3DFMT_UNKNOWN);
    wined3d_device_set_base_vertex_index(device->wined3d_device, 0);

done:
    wined3d_mutex_unlock();
    return hr;
}

static HRESULT WINAPI d3d8_device_ProcessVertices(IDirect3DDevice8 *iface, UINT src_start_idx,
        UINT dst_idx, UINT vertex_count, IDirect3DVertexBuffer8 *dst_buffer, DWORD flags)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    struct d3d8_vertexbuffer *dst = unsafe_impl_from_IDirect3DVertexBuffer8(dst_buffer);
    HRESULT hr;

    TRACE("iface %p, src_start_idx %u, dst_idx %u, vertex_count %u, dst_buffer %p, flags %#x.\n",
            iface, src_start_idx, dst_idx, vertex_count, dst_buffer, flags);

    wined3d_mutex_lock();
    hr = wined3d_device_process_vertices(device->wined3d_device, src_start_idx, dst_idx,
            vertex_count, dst->wined3d_buffer, NULL, flags, dst->fvf);
    wined3d_mutex_unlock();

    return hr;
}

static HRESULT WINAPI d3d8_device_CreateVertexShader(IDirect3DDevice8 *iface,
        const DWORD *declaration, const DWORD *byte_code, DWORD *shader, DWORD usage)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    struct d3d8_vertex_shader *object;
    DWORD shader_handle;
    DWORD handle;
    HRESULT hr;

    TRACE("iface %p, declaration %p, byte_code %p, shader %p, usage %#x.\n",
            iface, declaration, byte_code, shader, usage);

    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
    if (!object)
    {
        *shader = 0;
        return E_OUTOFMEMORY;
    }

    wined3d_mutex_lock();
    handle = d3d8_allocate_handle(&device->handle_table, object, D3D8_HANDLE_VS);
    wined3d_mutex_unlock();
    if (handle == D3D8_INVALID_HANDLE)
    {
        ERR("Failed to allocate vertex shader handle.\n");
        HeapFree(GetProcessHeap(), 0, object);
        *shader = 0;
        return E_OUTOFMEMORY;
    }

    shader_handle = handle + VS_HIGHESTFIXEDFXF + 1;

    hr = d3d8_vertex_shader_init(object, device, declaration, byte_code, shader_handle, usage);
    if (FAILED(hr))
    {
        WARN("Failed to initialize vertex shader, hr %#x.\n", hr);
        wined3d_mutex_lock();
        d3d8_free_handle(&device->handle_table, handle, D3D8_HANDLE_VS);
        wined3d_mutex_unlock();
        HeapFree(GetProcessHeap(), 0, object);
        *shader = 0;
        return hr;
    }

    TRACE("Created vertex shader %p (handle %#x).\n", object, shader_handle);
    *shader = shader_handle;

    return D3D_OK;
}

static struct d3d8_vertex_declaration *d3d8_device_get_fvf_declaration(struct d3d8_device *device, DWORD fvf)
{
    struct d3d8_vertex_declaration *d3d8_declaration;
    struct FvfToDecl *convertedDecls = device->decls;
    int p, low, high; /* deliberately signed */
    HRESULT hr;

    TRACE("Searching for declaration for fvf %08x... ", fvf);

    low = 0;
    high = device->numConvertedDecls - 1;
    while (low <= high)
    {
        p = (low + high) >> 1;
        TRACE("%d ", p);

        if (convertedDecls[p].fvf == fvf)
        {
            TRACE("found %p\n", convertedDecls[p].declaration);
            return convertedDecls[p].declaration;
        }

        if (convertedDecls[p].fvf < fvf)
            low = p + 1;
        else
            high = p - 1;
    }
    TRACE("not found. Creating and inserting at position %d.\n", low);

    if (!(d3d8_declaration = HeapAlloc(GetProcessHeap(), 0, sizeof(*d3d8_declaration))))
        return NULL;

    if (FAILED(hr = d3d8_vertex_declaration_init_fvf(d3d8_declaration, device, fvf)))
    {
        WARN("Failed to initialize vertex declaration, hr %#x.\n", hr);
        HeapFree(GetProcessHeap(), 0, d3d8_declaration);
        return NULL;
    }

    if (device->declArraySize == device->numConvertedDecls)
    {
        UINT grow = device->declArraySize / 2;

        convertedDecls = HeapReAlloc(GetProcessHeap(), 0, convertedDecls,
                sizeof(*convertedDecls) * (device->numConvertedDecls + grow));
        if (!convertedDecls)
        {
            d3d8_vertex_declaration_destroy(d3d8_declaration);
            return NULL;
        }
        device->decls = convertedDecls;
        device->declArraySize += grow;
    }

    memmove(convertedDecls + low + 1, convertedDecls + low,
            sizeof(*convertedDecls) * (device->numConvertedDecls - low));
    convertedDecls[low].declaration = d3d8_declaration;
    convertedDecls[low].fvf = fvf;
    ++device->numConvertedDecls;

    TRACE("Returning %p. %u decls in array.\n", d3d8_declaration, device->numConvertedDecls);

    return d3d8_declaration;
}

static HRESULT WINAPI d3d8_device_SetVertexShader(IDirect3DDevice8 *iface, DWORD shader)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    struct d3d8_vertex_shader *shader_impl;

    TRACE("iface %p, shader %#x.\n", iface, shader);

    if (VS_HIGHESTFIXEDFXF >= shader)
    {
        TRACE("Setting FVF, %#x\n", shader);

        wined3d_mutex_lock();
        wined3d_device_set_vertex_declaration(device->wined3d_device,
                d3d8_device_get_fvf_declaration(device, shader)->wined3d_vertex_declaration);
        wined3d_device_set_vertex_shader(device->wined3d_device, NULL);
        wined3d_mutex_unlock();

        return D3D_OK;
    }

    TRACE("Setting shader\n");

    wined3d_mutex_lock();
    if (!(shader_impl = d3d8_get_object(&device->handle_table, shader - (VS_HIGHESTFIXEDFXF + 1), D3D8_HANDLE_VS)))
    {
        WARN("Invalid handle (%#x) passed.\n", shader);
        wined3d_mutex_unlock();

        return D3DERR_INVALIDCALL;
    }

    wined3d_device_set_vertex_declaration(device->wined3d_device,
            shader_impl->vertex_declaration->wined3d_vertex_declaration);
    wined3d_device_set_vertex_shader(device->wined3d_device, shader_impl->wined3d_shader);
    wined3d_mutex_unlock();

    return D3D_OK;
}

static HRESULT WINAPI d3d8_device_GetVertexShader(IDirect3DDevice8 *iface, DWORD *shader)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    struct wined3d_vertex_declaration *wined3d_declaration;
    struct d3d8_vertex_declaration *d3d8_declaration;

    TRACE("iface %p, shader %p.\n", iface, shader);

    wined3d_mutex_lock();
    if ((wined3d_declaration = wined3d_device_get_vertex_declaration(device->wined3d_device)))
    {
        d3d8_declaration = wined3d_vertex_declaration_get_parent(wined3d_declaration);
        *shader = d3d8_declaration->shader_handle;
    }
    else
    {
        *shader = 0;
    }
    wined3d_mutex_unlock();

    TRACE("Returning %#x.\n", *shader);

    return D3D_OK;
}

static HRESULT WINAPI d3d8_device_DeleteVertexShader(IDirect3DDevice8 *iface, DWORD shader)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    struct d3d8_vertex_shader *shader_impl;

    TRACE("iface %p, shader %#x.\n", iface, shader);

    wined3d_mutex_lock();
    if (!(shader_impl = d3d8_free_handle(&device->handle_table, shader - (VS_HIGHESTFIXEDFXF + 1), D3D8_HANDLE_VS)))
    {
        WARN("Invalid handle (%#x) passed.\n", shader);
        wined3d_mutex_unlock();

        return D3DERR_INVALIDCALL;
    }

    if (shader_impl->wined3d_shader
            && wined3d_device_get_vertex_shader(device->wined3d_device) == shader_impl->wined3d_shader)
        IDirect3DDevice8_SetVertexShader(iface, 0);

    wined3d_mutex_unlock();

    d3d8_vertex_shader_destroy(shader_impl);

    return D3D_OK;
}

static HRESULT WINAPI d3d8_device_SetVertexShaderConstant(IDirect3DDevice8 *iface,
        DWORD start_register, const void *data, DWORD count)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    HRESULT hr;

    TRACE("iface %p, start_register %u, data %p, count %u.\n",
            iface, start_register, data, count);

    if (start_register + count > D3D8_MAX_VERTEX_SHADER_CONSTANTF)
    {
        WARN("Trying to access %u constants, but d3d8 only supports %u\n",
             start_register + count, D3D8_MAX_VERTEX_SHADER_CONSTANTF);
        return D3DERR_INVALIDCALL;
    }

    wined3d_mutex_lock();
    hr = wined3d_device_set_vs_consts_f(device->wined3d_device, start_register, data, count);
    wined3d_mutex_unlock();

    return hr;
}

static HRESULT WINAPI d3d8_device_GetVertexShaderConstant(IDirect3DDevice8 *iface,
        DWORD start_register, void *data, DWORD count)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    HRESULT hr;

    TRACE("iface %p, start_register %u, data %p, count %u.\n",
            iface, start_register, data, count);

    if (start_register + count > D3D8_MAX_VERTEX_SHADER_CONSTANTF)
    {
        WARN("Trying to access %u constants, but d3d8 only supports %u\n",
             start_register + count, D3D8_MAX_VERTEX_SHADER_CONSTANTF);
        return D3DERR_INVALIDCALL;
    }

    wined3d_mutex_lock();
    hr = wined3d_device_get_vs_consts_f(device->wined3d_device, start_register, data, count);
    wined3d_mutex_unlock();

    return hr;
}

static HRESULT WINAPI d3d8_device_GetVertexShaderDeclaration(IDirect3DDevice8 *iface,
        DWORD shader, void *data, DWORD *data_size)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    struct d3d8_vertex_declaration *declaration;
    struct d3d8_vertex_shader *shader_impl;

    TRACE("iface %p, shader %#x, data %p, data_size %p.\n",
            iface, shader, data, data_size);

    wined3d_mutex_lock();
    shader_impl = d3d8_get_object(&device->handle_table, shader - (VS_HIGHESTFIXEDFXF + 1), D3D8_HANDLE_VS);
    wined3d_mutex_unlock();

    if (!shader_impl)
    {
        WARN("Invalid handle (%#x) passed.\n", shader);
        return D3DERR_INVALIDCALL;
    }
    declaration = shader_impl->vertex_declaration;

    if (!data)
    {
        *data_size = declaration->elements_size;
        return D3D_OK;
    }

    /* MSDN claims that if *data_size is smaller than the required size
     * we should write the required size and return D3DERR_MOREDATA.
     * That's not actually true. */
    if (*data_size < declaration->elements_size)
        return D3DERR_INVALIDCALL;

    memcpy(data, declaration->elements, declaration->elements_size);

    return D3D_OK;
}

static HRESULT WINAPI d3d8_device_GetVertexShaderFunction(IDirect3DDevice8 *iface,
        DWORD shader, void *data, DWORD *data_size)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    struct d3d8_vertex_shader *shader_impl = NULL;
    HRESULT hr;

    TRACE("iface %p, shader %#x, data %p, data_size %p.\n",
            iface, shader, data, data_size);

    wined3d_mutex_lock();
    if (!(shader_impl = d3d8_get_object(&device->handle_table, shader - (VS_HIGHESTFIXEDFXF + 1), D3D8_HANDLE_VS)))
    {
        WARN("Invalid handle (%#x) passed.\n", shader);
        wined3d_mutex_unlock();

        return D3DERR_INVALIDCALL;
    }

    if (!shader_impl->wined3d_shader)
    {
        wined3d_mutex_unlock();
        *data_size = 0;
        return D3D_OK;
    }

    hr = wined3d_shader_get_byte_code(shader_impl->wined3d_shader, data, data_size);
    wined3d_mutex_unlock();

    return hr;
}

static HRESULT WINAPI d3d8_device_SetIndices(IDirect3DDevice8 *iface,
        IDirect3DIndexBuffer8 *buffer, UINT base_vertex_idx)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    struct d3d8_indexbuffer *ib = unsafe_impl_from_IDirect3DIndexBuffer8(buffer);

    TRACE("iface %p, buffer %p, base_vertex_idx %u.\n", iface, buffer, base_vertex_idx);

    /* WineD3D takes an INT(due to d3d9), but d3d8 uses UINTs. Do I have to add a check here that
     * the UINT doesn't cause an overflow in the INT? It seems rather unlikely because such large
     * vertex buffers can't be created to address them with an index that requires the 32nd bit
     * (4 Byte minimum vertex size * 2^31-1 -> 8 gb buffer. The index sign would be the least
     * problem)
     */
    wined3d_mutex_lock();
    wined3d_device_set_base_vertex_index(device->wined3d_device, base_vertex_idx);
    wined3d_device_set_index_buffer(device->wined3d_device,
            ib ? ib->wined3d_buffer : NULL,
            ib ? ib->format : WINED3DFMT_UNKNOWN);
    wined3d_mutex_unlock();

    return D3D_OK;
}

static HRESULT WINAPI d3d8_device_GetIndices(IDirect3DDevice8 *iface,
        IDirect3DIndexBuffer8 **buffer, UINT *base_vertex_index)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    enum wined3d_format_id wined3d_format;
    struct wined3d_buffer *wined3d_buffer;
    struct d3d8_indexbuffer *buffer_impl;

    TRACE("iface %p, buffer %p, base_vertex_index %p.\n", iface, buffer, base_vertex_index);

    if (!buffer)
        return D3DERR_INVALIDCALL;

    /* The case from UINT to INT is safe because d3d8 will never set negative values */
    wined3d_mutex_lock();
    *base_vertex_index = wined3d_device_get_base_vertex_index(device->wined3d_device);
    if ((wined3d_buffer = wined3d_device_get_index_buffer(device->wined3d_device, &wined3d_format)))
    {
        buffer_impl = wined3d_buffer_get_parent(wined3d_buffer);
        *buffer = &buffer_impl->IDirect3DIndexBuffer8_iface;
        IDirect3DIndexBuffer8_AddRef(*buffer);
    }
    else
    {
        *buffer = NULL;
    }
    wined3d_mutex_unlock();

    return D3D_OK;
}

static HRESULT WINAPI d3d8_device_CreatePixelShader(IDirect3DDevice8 *iface,
        const DWORD *byte_code, DWORD *shader)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    struct d3d8_pixel_shader *object;
    DWORD shader_handle;
    DWORD handle;
    HRESULT hr;

    TRACE("iface %p, byte_code %p, shader %p.\n", iface, byte_code, shader);

    if (!shader)
        return D3DERR_INVALIDCALL;

    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
    if (!object)
        return E_OUTOFMEMORY;

    wined3d_mutex_lock();
    handle = d3d8_allocate_handle(&device->handle_table, object, D3D8_HANDLE_PS);
    wined3d_mutex_unlock();
    if (handle == D3D8_INVALID_HANDLE)
    {
        ERR("Failed to allocate pixel shader handle.\n");
        HeapFree(GetProcessHeap(), 0, object);
        return E_OUTOFMEMORY;
    }

    shader_handle = handle + VS_HIGHESTFIXEDFXF + 1;

    hr = d3d8_pixel_shader_init(object, device, byte_code, shader_handle);
    if (FAILED(hr))
    {
        WARN("Failed to initialize pixel shader, hr %#x.\n", hr);
        wined3d_mutex_lock();
        d3d8_free_handle(&device->handle_table, handle, D3D8_HANDLE_PS);
        wined3d_mutex_unlock();
        HeapFree(GetProcessHeap(), 0, object);
        *shader = 0;
        return hr;
    }

    TRACE("Created pixel shader %p (handle %#x).\n", object, shader_handle);
    *shader = shader_handle;

    return D3D_OK;
}

static HRESULT WINAPI d3d8_device_SetPixelShader(IDirect3DDevice8 *iface, DWORD shader)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    struct d3d8_pixel_shader *shader_impl;

    TRACE("iface %p, shader %#x.\n", iface, shader);

    wined3d_mutex_lock();

    if (!shader)
    {
        wined3d_device_set_pixel_shader(device->wined3d_device, NULL);
        wined3d_mutex_unlock();
        return D3D_OK;
    }

    if (!(shader_impl = d3d8_get_object(&device->handle_table, shader - (VS_HIGHESTFIXEDFXF + 1), D3D8_HANDLE_PS)))
    {
        WARN("Invalid handle (%#x) passed.\n", shader);
        wined3d_mutex_unlock();
        return D3DERR_INVALIDCALL;
    }

    TRACE("Setting shader %p.\n", shader_impl);
    wined3d_device_set_pixel_shader(device->wined3d_device, shader_impl->wined3d_shader);
    wined3d_mutex_unlock();

    return D3D_OK;
}

static HRESULT WINAPI d3d8_device_GetPixelShader(IDirect3DDevice8 *iface, DWORD *shader)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    struct wined3d_shader *object;

    TRACE("iface %p, shader %p.\n", iface, shader);

    if (!shader)
        return D3DERR_INVALIDCALL;

    wined3d_mutex_lock();
    if ((object = wined3d_device_get_pixel_shader(device->wined3d_device)))
    {
        struct d3d8_pixel_shader *d3d8_shader;
        d3d8_shader = wined3d_shader_get_parent(object);
        *shader = d3d8_shader->handle;
    }
    else
    {
        *shader = 0;
    }
    wined3d_mutex_unlock();

    TRACE("Returning %#x.\n", *shader);

    return D3D_OK;
}

static HRESULT WINAPI d3d8_device_DeletePixelShader(IDirect3DDevice8 *iface, DWORD shader)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    struct d3d8_pixel_shader *shader_impl;

    TRACE("iface %p, shader %#x.\n", iface, shader);

    wined3d_mutex_lock();

    if (!(shader_impl = d3d8_free_handle(&device->handle_table, shader - (VS_HIGHESTFIXEDFXF + 1), D3D8_HANDLE_PS)))
    {
        WARN("Invalid handle (%#x) passed.\n", shader);
        wined3d_mutex_unlock();
        return D3DERR_INVALIDCALL;
    }

    if (wined3d_device_get_pixel_shader(device->wined3d_device) == shader_impl->wined3d_shader)
        IDirect3DDevice8_SetPixelShader(iface, 0);

    wined3d_mutex_unlock();

    d3d8_pixel_shader_destroy(shader_impl);

    return D3D_OK;
}

static HRESULT WINAPI d3d8_device_SetPixelShaderConstant(IDirect3DDevice8 *iface,
        DWORD start_register, const void *data, DWORD count)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    HRESULT hr;

    TRACE("iface %p, start_register %u, data %p, count %u.\n",
            iface, start_register, data, count);

    wined3d_mutex_lock();
    hr = wined3d_device_set_ps_consts_f(device->wined3d_device, start_register, data, count);
    wined3d_mutex_unlock();

    return hr;
}

static HRESULT WINAPI d3d8_device_GetPixelShaderConstant(IDirect3DDevice8 *iface,
        DWORD start_register, void *data, DWORD count)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    HRESULT hr;

    TRACE("iface %p, start_register %u, data %p, count %u.\n",
            iface, start_register, data, count);

    wined3d_mutex_lock();
    hr = wined3d_device_get_ps_consts_f(device->wined3d_device, start_register, data, count);
    wined3d_mutex_unlock();

    return hr;
}

static HRESULT WINAPI d3d8_device_GetPixelShaderFunction(IDirect3DDevice8 *iface,
        DWORD shader, void *data, DWORD *data_size)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    struct d3d8_pixel_shader *shader_impl = NULL;
    HRESULT hr;

    TRACE("iface %p, shader %#x, data %p, data_size %p.\n",
            iface, shader, data, data_size);

    wined3d_mutex_lock();
    if (!(shader_impl = d3d8_get_object(&device->handle_table, shader - (VS_HIGHESTFIXEDFXF + 1), D3D8_HANDLE_PS)))
    {
        WARN("Invalid handle (%#x) passed.\n", shader);
        wined3d_mutex_unlock();

        return D3DERR_INVALIDCALL;
    }

    hr = wined3d_shader_get_byte_code(shader_impl->wined3d_shader, data, data_size);
    wined3d_mutex_unlock();

    return hr;
}

static HRESULT WINAPI d3d8_device_DrawRectPatch(IDirect3DDevice8 *iface, UINT handle,
        const float *segment_count, const D3DRECTPATCH_INFO *patch_info)
{
    FIXME("iface %p, handle %#x, segment_count %p, patch_info %p unimplemented.\n",
            iface, handle, segment_count, patch_info);
    return D3D_OK;
}

static HRESULT WINAPI d3d8_device_DrawTriPatch(IDirect3DDevice8 *iface, UINT handle,
        const float *segment_count, const D3DTRIPATCH_INFO *patch_info)
{
    FIXME("iface %p, handle %#x, segment_count %p, patch_info %p unimplemented.\n",
            iface, handle, segment_count, patch_info);
    return D3D_OK;
}

static HRESULT WINAPI d3d8_device_DeletePatch(IDirect3DDevice8 *iface, UINT handle)
{
    FIXME("iface %p, handle %#x unimplemented.\n", iface, handle);
    return D3DERR_INVALIDCALL;
}

static HRESULT WINAPI d3d8_device_SetStreamSource(IDirect3DDevice8 *iface,
        UINT stream_idx, IDirect3DVertexBuffer8 *buffer, UINT stride)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    struct d3d8_vertexbuffer *buffer_impl = unsafe_impl_from_IDirect3DVertexBuffer8(buffer);
    HRESULT hr;

    TRACE("iface %p, stream_idx %u, buffer %p, stride %u.\n",
            iface, stream_idx, buffer, stride);

    wined3d_mutex_lock();
    hr = wined3d_device_set_stream_source(device->wined3d_device, stream_idx,
            buffer_impl ? buffer_impl->wined3d_buffer : NULL, 0, stride);
    wined3d_mutex_unlock();

    return hr;
}

static HRESULT WINAPI d3d8_device_GetStreamSource(IDirect3DDevice8 *iface,
        UINT stream_idx, IDirect3DVertexBuffer8 **buffer, UINT *stride)
{
    struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
    struct d3d8_vertexbuffer *buffer_impl;
    struct wined3d_buffer *wined3d_buffer = NULL;
    HRESULT hr;

    TRACE("iface %p, stream_idx %u, buffer %p, stride %p.\n",
            iface, stream_idx, buffer, stride);

    if (!buffer)
        return D3DERR_INVALIDCALL;

    wined3d_mutex_lock();
    hr = wined3d_device_get_stream_source(device->wined3d_device, stream_idx, &wined3d_buffer, 0, stride);
    if (SUCCEEDED(hr) && wined3d_buffer)
    {
        buffer_impl = wined3d_buffer_get_parent(wined3d_buffer);
        *buffer = &buffer_impl->IDirect3DVertexBuffer8_iface;
        IDirect3DVertexBuffer8_AddRef(*buffer);
    }
    else
    {
        if (FAILED(hr))
            ERR("Failed to get wined3d stream source, hr %#x.\n", hr);
        *buffer = NULL;
    }
    wined3d_mutex_unlock();

    return hr;
}

static const struct IDirect3DDevice8Vtbl d3d8_device_vtbl =
{
    d3d8_device_QueryInterface,
    d3d8_device_AddRef,
    d3d8_device_Release,
    d3d8_device_TestCooperativeLevel,
    d3d8_device_GetAvailableTextureMem,
    d3d8_device_ResourceManagerDiscardBytes,
    d3d8_device_GetDirect3D,
    d3d8_device_GetDeviceCaps,
    d3d8_device_GetDisplayMode,
    d3d8_device_GetCreationParameters,
    d3d8_device_SetCursorProperties,
    d3d8_device_SetCursorPosition,
    d3d8_device_ShowCursor,
    d3d8_device_CreateAdditionalSwapChain,
    d3d8_device_Reset,
    d3d8_device_Present,
    d3d8_device_GetBackBuffer,
    d3d8_device_GetRasterStatus,
    d3d8_device_SetGammaRamp,
    d3d8_device_GetGammaRamp,
    d3d8_device_CreateTexture,
    d3d8_device_CreateVolumeTexture,
    d3d8_device_CreateCubeTexture,
    d3d8_device_CreateVertexBuffer,
    d3d8_device_CreateIndexBuffer,
    d3d8_device_CreateRenderTarget,
    d3d8_device_CreateDepthStencilSurface,
    d3d8_device_CreateImageSurface,
    d3d8_device_CopyRects,
    d3d8_device_UpdateTexture,
    d3d8_device_GetFrontBuffer,
    d3d8_device_SetRenderTarget,
    d3d8_device_GetRenderTarget,
    d3d8_device_GetDepthStencilSurface,
    d3d8_device_BeginScene,
    d3d8_device_EndScene,
    d3d8_device_Clear,
    d3d8_device_SetTransform,
    d3d8_device_GetTransform,
    d3d8_device_MultiplyTransform,
    d3d8_device_SetViewport,
    d3d8_device_GetViewport,
    d3d8_device_SetMaterial,
    d3d8_device_GetMaterial,
    d3d8_device_SetLight,
    d3d8_device_GetLight,
    d3d8_device_LightEnable,
    d3d8_device_GetLightEnable,
    d3d8_device_SetClipPlane,
    d3d8_device_GetClipPlane,
    d3d8_device_SetRenderState,
    d3d8_device_GetRenderState,
    d3d8_device_BeginStateBlock,
    d3d8_device_EndStateBlock,
    d3d8_device_ApplyStateBlock,
    d3d8_device_CaptureStateBlock,
    d3d8_device_DeleteStateBlock,
    d3d8_device_CreateStateBlock,
    d3d8_device_SetClipStatus,
    d3d8_device_GetClipStatus,
    d3d8_device_GetTexture,
    d3d8_device_SetTexture,
    d3d8_device_GetTextureStageState,
    d3d8_device_SetTextureStageState,
    d3d8_device_ValidateDevice,
    d3d8_device_GetInfo,
    d3d8_device_SetPaletteEntries,
    d3d8_device_GetPaletteEntries,
    d3d8_device_SetCurrentTexturePalette,
    d3d8_device_GetCurrentTexturePalette,
    d3d8_device_DrawPrimitive,
    d3d8_device_DrawIndexedPrimitive,
    d3d8_device_DrawPrimitiveUP,
    d3d8_device_DrawIndexedPrimitiveUP,
    d3d8_device_ProcessVertices,
    d3d8_device_CreateVertexShader,
    d3d8_device_SetVertexShader,
    d3d8_device_GetVertexShader,
    d3d8_device_DeleteVertexShader,
    d3d8_device_SetVertexShaderConstant,
    d3d8_device_GetVertexShaderConstant,
    d3d8_device_GetVertexShaderDeclaration,
    d3d8_device_GetVertexShaderFunction,
    d3d8_device_SetStreamSource,
    d3d8_device_GetStreamSource,
    d3d8_device_SetIndices,
    d3d8_device_GetIndices,
    d3d8_device_CreatePixelShader,
    d3d8_device_SetPixelShader,
    d3d8_device_GetPixelShader,
    d3d8_device_DeletePixelShader,
    d3d8_device_SetPixelShaderConstant,
    d3d8_device_GetPixelShaderConstant,
    d3d8_device_GetPixelShaderFunction,
    d3d8_device_DrawRectPatch,
    d3d8_device_DrawTriPatch,
    d3d8_device_DeletePatch,
};

static inline struct d3d8_device *device_from_device_parent(struct wined3d_device_parent *device_parent)
{
    return CONTAINING_RECORD(device_parent, struct d3d8_device, device_parent);
}

static void CDECL device_parent_wined3d_device_created(struct wined3d_device_parent *device_parent,
        struct wined3d_device *device)
{
    TRACE("device_parent %p, device %p\n", device_parent, device);
}

static void CDECL device_parent_mode_changed(struct wined3d_device_parent *device_parent)
{
    TRACE("device_parent %p.\n", device_parent);
}

static void CDECL device_parent_activate(struct wined3d_device_parent *device_parent, BOOL activate)
{
    struct d3d8_device *device = device_from_device_parent(device_parent);

    TRACE("device_parent %p, activate %#x.\n", device_parent, activate);

    if (!activate)
        InterlockedCompareExchange(&device->device_state, D3D8_DEVICE_STATE_LOST, D3D8_DEVICE_STATE_OK);
    else
        InterlockedCompareExchange(&device->device_state, D3D8_DEVICE_STATE_NOT_RESET, D3D8_DEVICE_STATE_LOST);
}

static HRESULT CDECL device_parent_surface_created(struct wined3d_device_parent *device_parent,
        struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx,
        void **parent, const struct wined3d_parent_ops **parent_ops)
{
    struct d3d8_surface *d3d_surface;

    TRACE("device_parent %p, wined3d_texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n",
            device_parent, wined3d_texture, sub_resource_idx, parent, parent_ops);

    if (!(d3d_surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*d3d_surface))))
        return E_OUTOFMEMORY;

    surface_init(d3d_surface, wined3d_texture, sub_resource_idx, parent_ops);
    *parent = d3d_surface;
    TRACE("Created surface %p.\n", d3d_surface);

    return D3D_OK;
}

static HRESULT CDECL device_parent_volume_created(struct wined3d_device_parent *device_parent,
        struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx,
        void **parent, const struct wined3d_parent_ops **parent_ops)
{
    struct d3d8_volume *d3d_volume;

    TRACE("device_parent %p, texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n",
            device_parent, wined3d_texture, sub_resource_idx, parent, parent_ops);

    if (!(d3d_volume = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*d3d_volume))))
        return E_OUTOFMEMORY;

    volume_init(d3d_volume, wined3d_texture, sub_resource_idx, parent_ops);
    *parent = d3d_volume;
    TRACE("Created volume %p.\n", d3d_volume);

    return D3D_OK;
}

static HRESULT CDECL device_parent_create_swapchain_texture(struct wined3d_device_parent *device_parent,
        void *container_parent, const struct wined3d_resource_desc *desc, struct wined3d_texture **texture)
{
    struct d3d8_device *device = device_from_device_parent(device_parent);
    struct d3d8_surface *d3d_surface;
    HRESULT hr;

    TRACE("device_parent %p, container_parent %p, desc %p, texture %p.\n",
            device_parent, container_parent, desc, texture);

    if (FAILED(hr = wined3d_texture_create(device->wined3d_device, desc, 1, WINED3D_TEXTURE_CREATE_MAPPABLE,
            NULL, &device->IDirect3DDevice8_iface, &d3d8_null_wined3d_parent_ops, texture)))
    {
        WARN("Failed to create texture, hr %#x.\n", hr);
        return hr;
    }

    d3d_surface = wined3d_texture_get_sub_resource_parent(*texture, 0);
    d3d_surface->parent_device = &device->IDirect3DDevice8_iface;

    return hr;
}

static HRESULT CDECL device_parent_create_swapchain(struct wined3d_device_parent *device_parent,
        struct wined3d_swapchain_desc *desc, struct wined3d_swapchain **swapchain)
{
    struct d3d8_device *device = device_from_device_parent(device_parent);
    struct d3d8_swapchain *d3d_swapchain;
    HRESULT hr;

    TRACE("device_parent %p, desc %p, swapchain %p.\n", device_parent, desc, swapchain);

    if (FAILED(hr = d3d8_swapchain_create(device, desc, &d3d_swapchain)))
    {
        WARN("Failed to create swapchain, hr %#x.\n", hr);
        *swapchain = NULL;
        return hr;
    }

    *swapchain = d3d_swapchain->wined3d_swapchain;
    wined3d_swapchain_incref(*swapchain);
    IDirect3DSwapChain8_Release(&d3d_swapchain->IDirect3DSwapChain8_iface);

    return hr;
}

static const struct wined3d_device_parent_ops d3d8_wined3d_device_parent_ops =
{
    device_parent_wined3d_device_created,
    device_parent_mode_changed,
    device_parent_activate,
    device_parent_surface_created,
    device_parent_volume_created,
    device_parent_create_swapchain_texture,
    device_parent_create_swapchain,
};

static void setup_fpu(void)
{
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
    WORD cw;
    __asm__ volatile ("fnstcw %0" : "=m" (cw));
    cw = (cw & ~0xf3f) | 0x3f;
    __asm__ volatile ("fldcw %0" : : "m" (cw));
#elif defined(__i386__) && defined(_MSC_VER)
    WORD cw;
    __asm fnstcw cw;
    cw = (cw & ~0xf3f) | 0x3f;
    __asm fldcw cw;
#else
    FIXME("FPU setup not implemented for this platform.\n");
#endif
}

HRESULT device_init(struct d3d8_device *device, struct d3d8 *parent, struct wined3d *wined3d, UINT adapter,
        D3DDEVTYPE device_type, HWND focus_window, DWORD flags, D3DPRESENT_PARAMETERS *parameters)
{
    struct wined3d_swapchain_desc swapchain_desc;
    struct wined3d_swapchain *wined3d_swapchain;
    HRESULT hr;

    device->IDirect3DDevice8_iface.lpVtbl = &d3d8_device_vtbl;
    device->device_parent.ops = &d3d8_wined3d_device_parent_ops;
    device->ref = 1;
    device->handle_table.entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
            D3D8_INITIAL_HANDLE_TABLE_SIZE * sizeof(*device->handle_table.entries));
    if (!device->handle_table.entries)
    {
        ERR("Failed to allocate handle table memory.\n");
        return E_OUTOFMEMORY;
    }
    device->handle_table.table_size = D3D8_INITIAL_HANDLE_TABLE_SIZE;

    if (!(flags & D3DCREATE_FPU_PRESERVE)) setup_fpu();

    wined3d_mutex_lock();
    hr = wined3d_device_create(wined3d, adapter, device_type, focus_window, flags, 4,
            &device->device_parent, &device->wined3d_device);
    if (FAILED(hr))
    {
        WARN("Failed to create wined3d device, hr %#x.\n", hr);
        wined3d_mutex_unlock();
        HeapFree(GetProcessHeap(), 0, device->handle_table.entries);
        return hr;
    }

    if (!parameters->Windowed)
    {
        HWND device_window = parameters->hDeviceWindow;

        if (!focus_window)
            focus_window = device_window;
        if (FAILED(hr = wined3d_device_acquire_focus_window(device->wined3d_device, focus_window)))
        {
            ERR("Failed to acquire focus window, hr %#x.\n", hr);
            wined3d_device_decref(device->wined3d_device);
            wined3d_mutex_unlock();
            HeapFree(GetProcessHeap(), 0, device->handle_table.entries);
            return hr;
        }

        if (!device_window)
            device_window = focus_window;
        wined3d_device_setup_fullscreen_window(device->wined3d_device, device_window,
                parameters->BackBufferWidth,
                parameters->BackBufferHeight);
    }

    if (flags & D3DCREATE_MULTITHREADED)
        wined3d_device_set_multithreaded(device->wined3d_device);

    if (!wined3d_swapchain_desc_from_present_parameters(&swapchain_desc, parameters))
    {
        wined3d_device_release_focus_window(device->wined3d_device);
        wined3d_device_decref(device->wined3d_device);
        wined3d_mutex_unlock();
        HeapFree(GetProcessHeap(), 0, device->handle_table.entries);
        return D3DERR_INVALIDCALL;
    }

    hr = wined3d_device_init_3d(device->wined3d_device, &swapchain_desc);
    if (FAILED(hr))
    {
        WARN("Failed to initialize 3D, hr %#x.\n", hr);
        wined3d_device_release_focus_window(device->wined3d_device);
        wined3d_device_decref(device->wined3d_device);
        wined3d_mutex_unlock();
        HeapFree(GetProcessHeap(), 0, device->handle_table.entries);
        return hr;
    }

    wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_POINTSIZE_MIN, 0);
    wined3d_mutex_unlock();

    present_parameters_from_wined3d_swapchain_desc(parameters, &swapchain_desc);

    device->declArraySize = 16;
    device->decls = HeapAlloc(GetProcessHeap(), 0, device->declArraySize * sizeof(*device->decls));
    if (!device->decls)
    {
        ERR("Failed to allocate FVF vertex declaration map memory.\n");
        hr = E_OUTOFMEMORY;
        goto err;
    }

    wined3d_swapchain = wined3d_device_get_swapchain(device->wined3d_device, 0);
    device->implicit_swapchain = wined3d_swapchain_get_parent(wined3d_swapchain);

    device->d3d_parent = &parent->IDirect3D8_iface;
    IDirect3D8_AddRef(device->d3d_parent);

    return D3D_OK;

err:
    wined3d_mutex_lock();
    wined3d_device_uninit_3d(device->wined3d_device);
    wined3d_device_release_focus_window(device->wined3d_device);
    wined3d_device_decref(device->wined3d_device);
    wined3d_mutex_unlock();
    HeapFree(GetProcessHeap(), 0, device->handle_table.entries);
    return hr;
}
