/* Direct3D private include file
   (c) 1998 Lionel ULMER
   Copyright 2000-2001 TransGaming Technologies Inc.

   This files contains all the structure that are not exported
   through d3d.h and all common macros. */

#ifndef __GRAPHICS_WINE_D3D_PRIVATE_H
#define __GRAPHICS_WINE_D3D_PRIVATE_H

/* THIS FILE MUST NOT CONTAIN X11 or MESA DEFINES */

#ifdef DDRAW_SAVE_AND_RESTORE_FPU_HACK
#include "wine/d3d_fpuctl.h"
#endif

#include "d3d.h"
#include "ddraw_private.h"
#include "d3dhal.h"
#include "wine/d3dhalp.h"

typedef struct D3DStateBlock {
    DWORD state_block; /* driver's state block */
    DWORD dirty_tex;
    LPDIRECTDRAWSURFACE7 tex[8];
} D3DStateBlock;

/*****************************************************************************
 * IDirect3DDevice implementation structure
 */
struct IDirect3DDeviceImpl
{
    ICOM_VFIELD_MULTI(IDirect3DDevice7);
    ICOM_VFIELD_MULTI(IDirect3DDevice3);
    ICOM_VFIELD_MULTI(IDirect3DDevice2);
    ICOM_VFIELD_MULTI(IDirect3DDevice);

    DWORD ref;

    IDirect3DDeviceImpl* next_ddraw;
    IDirect3DDeviceImpl* prev_ddraw;

    IDirectDrawImpl* ddraw_owner;
    IDirectDrawSurfaceImpl* surface;
    IDirectDrawSurfaceImpl* zbuffer;

    void (*final_release)(IDirect3DDeviceImpl *This);

    HRESULT (*set_render_target)(IDirect3DDeviceImpl *This,
				 IDirectDrawSurfaceImpl *pDDS,
				 IDirectDrawSurfaceImpl *pDDSZ,
				 DWORD dwFlags);
    void (*setup_render_target)(IDirect3DDeviceImpl *This);

    HRESULT (*late_allocate_surface)(IDirect3DDeviceImpl *This, IDirectDrawSurfaceImpl *pDDS);

    HRESULT (*begin_scene)(IDirect3DDeviceImpl *This);
    HRESULT (*end_scene)(IDirect3DDeviceImpl *This);

    LPVOID ip_ctx;

    void WINAPI (*demolish_texture)(LPVOID ctx, DWORD dwTexture);

    HRESULT WINAPI (*alloc_state_block)(LPVOID ctx, LPDWORD lpdwBlock);
    HRESULT WINAPI (*free_state_block)(LPVOID ctx, DWORD dwBlock);

    HRESULT WINAPI (*start_dp2)(LPVOID ctx, DWORD dwFlags,
				DWORD dwVertexType, LPVOID lpVertices,
				DWORD dwVertexOffset, DWORD dwVertexLength,
				DWORD dwReqVertexBufSize, DWORD dwReqCommandBufSize);
    HRESULT WINAPI (*start_dp2_sd)(LPVOID ctx, DWORD dwFlags,
				   DWORD dwVertexType, LPVOID lpVertices,
				   DWORD dwVertexOffset, DWORD dwVertexLength,
				   DWORD dwReqVertexBufSize, DWORD dwReqCommandBufSize,
				   LPD3DDRAWPRIMITIVESTRIDEDDATA lpStridedData);
    HRESULT WINAPI (*emit_dp2)(LPVOID ctx, LPD3DHAL_DP2COMMAND cmd,
			       LPVOID data1, DWORD dwSize1, LPVOID data2, DWORD dwSize2);
    HRESULT WINAPI (*flush_dp2)(LPVOID ctx);

    HRESULT WINAPI (*validate_device)(LPVOID ctx, LPDWORD lpdwPasses);

    LPVOID private;

    D3D_P d3dp;

    D3DCLIPSTATUS clip_status;
    D3DStateBlock state, *current;

#ifdef DDRAW_SAVE_AND_RESTORE_FPU_HACK
    fpu_control_t fpucw; /* FPU control word - saved while in a scene */
#endif

    /* legacy stuff */
    IDirect3DViewportImpl* views;
    IDirect3DViewportImpl* view;
    IDirect3DMaterialImpl* material_handle;
};

extern D3D_Light Main_Direct3DDevice_default_light;

/* ddraw/d3d.c */
void Direct3D7_MakeDeviceDesc(LPD3DDEVICEDESC7 desc,
			      LPD3DDEVICEDESC_V1 desc1,
			      LPD3DHAL_D3DEXTENDEDCAPS desc2,
			      LPGUID lpGuid);
void Direct3D3_MakeDeviceDesc(LPD3DDEVICEDESC desc,
			      LPD3DDEVICEDESC_V1 desc1,
			      LPD3DHAL_D3DEXTENDEDCAPS desc2);

/*****************************************************************************
 * IDirect3DLight implementation structure
 */
struct IDirect3DLightImpl
{
    ICOM_VFIELD_MULTI(IDirect3DLight);

    DWORD ref;

    IDirect3DLightImpl* next_d3d;
    IDirect3DLightImpl* prev_d3d;
    IDirect3DLightImpl* next_view;
    IDirect3DLightImpl* prev_view;

    IDirectDrawImpl* d3d_owner;
    IDirect3DViewportImpl* view_owner;

    D3DLIGHT7 l;
    DWORD view_index;
};

/*****************************************************************************
 * IDirect3DMaterial implementation structure
 */
struct IDirect3DMaterialImpl
{
    ICOM_VFIELD_MULTI(IDirect3DMaterial3);
    ICOM_VFIELD_MULTI(IDirect3DMaterial2);
    ICOM_VFIELD_MULTI(IDirect3DMaterial);

    DWORD ref;

    IDirect3DMaterialImpl* next_d3d;
    IDirect3DMaterialImpl* prev_d3d;

    IDirectDrawImpl* d3d_owner;
    IDirect3DDeviceImpl* dev_owner;

    D3DMATERIAL7 m;
    IDirectDrawSurfaceImpl* tex;
};

/*****************************************************************************
 * IDirect3DViewport implementation structure
 */
struct IDirect3DViewportImpl
{
    ICOM_VFIELD_MULTI(IDirect3DViewport3);

    DWORD ref;

    IDirect3DViewportImpl* next_d3d;
    IDirect3DViewportImpl* prev_d3d;
    IDirect3DViewportImpl* next_dev;
    IDirect3DViewportImpl* prev_dev;

    IDirectDrawImpl* d3d_owner;
    IDirect3DDeviceImpl* dev_owner;

    D3DVIEWPORT7 v;
    D3DMATRIX clip_matrix;
    IDirect3DMaterialImpl* bm;
    IDirectDrawSurfaceImpl* bd;
    IDirect3DLightImpl* lights;

    BOOL bound;
    DWORD lmask;
};


#endif /* __GRAPHICS_WINE_D3D_PRIVATE_H */
