From d13469c1d889e2ebe2003a2db6d70a69feb2c1ee Mon Sep 17 00:00:00 2001 From: Roderick Colenbrander Date: Sat, 25 Feb 2006 13:15:08 +0100 Subject: [PATCH] d3d8: Moved the remaining code over to WineD3D (based on patches by Oliver Stieber). --- dlls/d3d8/Makefile.in | 8 +- dlls/d3d8/basetexture.c | 14 - dlls/d3d8/d3d8_main.c | 117 +- dlls/d3d8/d3d8_private.h | 459 +-- dlls/d3d8/device.c | 4885 ++++++-------------------------- dlls/d3d8/directx.c | 421 +-- dlls/d3d8/drawprim.c | 1663 ----------- dlls/d3d8/indexbuffer.c | 128 +- dlls/d3d8/pixelshader.c | 94 + dlls/d3d8/resource.c | 84 +- dlls/d3d8/shader.c | 2386 ---------------- dlls/d3d8/stateblock.c | 886 +----- dlls/d3d8/swapchain.c | 48 +- dlls/d3d8/texture.c | 50 +- dlls/d3d8/utils.c | 1845 ------------ dlls/d3d8/vertexbuffer.c | 150 +- dlls/d3d8/vertexshader.c | 98 + dlls/d3d8/vshaderdeclaration.c | 723 ----- dlls/wined3d/device.c | 2 +- dlls/wined3d/directx.c | 16 +- 20 files changed, 1676 insertions(+), 12401 deletions(-) delete mode 100644 dlls/d3d8/drawprim.c create mode 100644 dlls/d3d8/pixelshader.c delete mode 100644 dlls/d3d8/shader.c delete mode 100644 dlls/d3d8/utils.c create mode 100644 dlls/d3d8/vertexshader.c delete mode 100644 dlls/d3d8/vshaderdeclaration.c diff --git a/dlls/d3d8/Makefile.in b/dlls/d3d8/Makefile.in index 4f49fb17ffc..026cb8a9d45 100644 --- a/dlls/d3d8/Makefile.in +++ b/dlls/d3d8/Makefile.in @@ -14,19 +14,17 @@ C_SRCS = \ d3d8_main.c \ device.c \ directx.c \ - drawprim.c \ indexbuffer.c \ + pixelshader.c \ resource.c \ - shader.c \ stateblock.c \ surface.c \ swapchain.c \ texture.c \ - utils.c \ vertexbuffer.c \ + vertexshader.c \ volume.c \ - volumetexture.c \ - vshaderdeclaration.c + volumetexture.c RC_SRCS = version.rc diff --git a/dlls/d3d8/basetexture.c b/dlls/d3d8/basetexture.c index 0e2240519bc..c371e434128 100644 --- a/dlls/d3d8/basetexture.c +++ b/dlls/d3d8/basetexture.c @@ -161,17 +161,3 @@ const IDirect3DBaseTexture8Vtbl Direct3DBaseTexture8_Vtbl = IDirect3DBaseTexture8Impl_GetLOD, IDirect3DBaseTexture8Impl_GetLevelCount }; - -BOOL WINAPI IDirect3DBaseTexture8Impl_IsDirty(LPDIRECT3DBASETEXTURE8 iface) { - IDirect3DBaseTexture8Impl *This = (IDirect3DBaseTexture8Impl *)iface; - return ((IWineD3DBaseTextureImpl*)This->wineD3DBaseTexture)->baseTexture.dirty; -} - -BOOL WINAPI IDirect3DBaseTexture8Impl_SetDirty(LPDIRECT3DBASETEXTURE8 iface, BOOL dirty) { - BOOL old; - IDirect3DBaseTexture8Impl *This = (IDirect3DBaseTexture8Impl *)iface; - - old = ((IWineD3DBaseTextureImpl*)This->wineD3DBaseTexture)->baseTexture.dirty; - ((IWineD3DBaseTextureImpl*)This->wineD3DBaseTexture)->baseTexture.dirty = dirty; - return old; -} diff --git a/dlls/d3d8/d3d8_main.c b/dlls/d3d8/d3d8_main.c index fd65426ae74..be37d41b2c7 100644 --- a/dlls/d3d8/d3d8_main.c +++ b/dlls/d3d8/d3d8_main.c @@ -1,4 +1,7 @@ -/* Direct3D 8 +/* + * Direct3D 8 + * + * Copyright 2005 Oliver Stieber * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,100 +21,74 @@ #include "config.h" #include "initguid.h" - -#include - -#include "windef.h" -#include "winbase.h" -#include "winreg.h" -#include "wingdi.h" -#include "winuser.h" +#include "d3d8_private.h" #include "wine/debug.h" -#include "d3d8.h" -#include "d3d8_private.h" +WINE_DEFAULT_DEBUG_CHANNEL(d3d8); -WINE_DEFAULT_DEBUG_CHANNEL(d3d); - -int num_lock = 0; void (*wine_tsx11_lock_ptr)(void) = NULL; void (*wine_tsx11_unlock_ptr)(void) = NULL; -int vs_mode = VS_HW; /* Hardware by default */ -int ps_mode = PS_NONE; /* Disabled by default */ -HRESULT WINAPI D3D8GetSWInfo(void) -{ + +HRESULT WINAPI D3D8GetSWInfo(void) { FIXME("(void): stub\n"); return 0; } -void WINAPI DebugSetMute(void) -{ +void WINAPI DebugSetMute(void) { /* nothing to do */ } -IDirect3D8* WINAPI Direct3DCreate8(UINT SDKVersion) -{ - IDirect3D8Impl *object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3D8Impl)); +IDirect3D8* WINAPI Direct3DCreate8(UINT SDKVersion) { + IDirect3D8Impl* object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3D8Impl)); object->lpVtbl = &Direct3D8_Vtbl; - object->direct3d8 = object; object->ref = 1; object->WineD3D = WineDirect3DCreate(SDKVersion, 8, (IUnknown *)object); TRACE("SDKVersion = %x, Created Direct3D object @ %p, WineObj @ %p\n", SDKVersion, object, object->WineD3D); - return (IDirect3D8 *)object; + return (IDirect3D8*) object; } /* At process attach */ -BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) -{ - TRACE("D3D8 DLLMain Reason=%ld\n", fdwReason); - if (fdwReason == DLL_PROCESS_ATTACH) - { - HMODULE mod; - char buffer[32]; - DWORD size = sizeof(buffer); - HKEY hkey = 0; +BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) { + TRACE("fdwReason=%ld\n", fdwReason); + if (fdwReason == DLL_PROCESS_ATTACH) { + HMODULE mod; - DisableThreadLibraryCalls(hInstDLL); + DisableThreadLibraryCalls(hInstDLL); - mod = GetModuleHandleA( "winex11.drv" ); - if (mod) - { - wine_tsx11_lock_ptr = (void *)GetProcAddress( mod, "wine_tsx11_lock" ); - wine_tsx11_unlock_ptr = (void *)GetProcAddress( mod, "wine_tsx11_unlock" ); - } - /* @@ Wine registry key: HKCU\Software\Wine\Direct3D */ - if ( !RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\Direct3D", &hkey) ) - { - if ( !RegQueryValueExA( hkey, "VertexShaderMode", 0, NULL, (LPBYTE) buffer, &size) ) - { - if (!strcmp(buffer,"none")) - { - TRACE("Disable vertex shaders\n"); - vs_mode = VS_NONE; - } - else if (!strcmp(buffer,"emulation")) - { - TRACE("Force SW vertex shaders\n"); - vs_mode = VS_SW; - } - } - if ( !RegQueryValueExA( hkey, "PixelShaderMode", 0, NULL, (LPBYTE) buffer, &size) ) - { - if (!strcmp(buffer,"enabled")) - { - TRACE("Allow pixel shaders\n"); - ps_mode = PS_HW; - } - } - } - if (vs_mode == VS_HW) - TRACE("Allow HW vertex shaders\n"); - if (ps_mode == PS_NONE) - TRACE("Disable pixel shaders\n"); + mod = GetModuleHandleA( "winex11.drv" ); + if (mod) + { + wine_tsx11_lock_ptr = (void*) GetProcAddress(mod, "wine_tsx11_lock"); + wine_tsx11_unlock_ptr = (void*) GetProcAddress(mod, "wine_tsx11_unlock"); + } } return TRUE; } + +/*********************************************************************** + * ValidateVertexShader (D3D8.@) + * + * PARAMS + * toto result? + */ +BOOL WINAPI ValidateVertexShader(LPVOID pFunction, int foo, int bar, void *fee, int rab) +{ + FIXME("(void): stub: %p %d %d %p %d\n", pFunction, foo, bar, fee, rab); + return TRUE; +} + +/*********************************************************************** + * ValidatePixelShader (D3D8.@) + * + * PARAMS + * toto result? + */ +BOOL WINAPI ValidatePixelShader(LPVOID pFunction, int foo, int bar, void *fee, int rab) +{ + FIXME("(void): stub: %p %d %d %p %d\n", pFunction, foo, bar, fee, rab); + return TRUE; +} diff --git a/dlls/d3d8/d3d8_private.h b/dlls/d3d8/d3d8_private.h index f9aab7fc2b8..27f86f8cd0e 100644 --- a/dlls/d3d8/d3d8_private.h +++ b/dlls/d3d8/d3d8_private.h @@ -88,6 +88,7 @@ extern int ps_mode; #define MAX_STREAMS 16 #define MAX_CLIPPLANES D3DMAXUSERCLIPPLANES #define MAX_LEVELS 256 +#define MAX_SHADERS 64 /* Other useful values */ #define HIGHEST_RENDER_STATE 174 @@ -189,6 +190,7 @@ typedef struct IDirect3DVertexShaderDeclarationImpl IDirect3DVertexShaderDeclara /* Advance declaration of structures to satisfy compiler */ typedef struct IWineD3DStateBlockImpl IWineD3DStateBlockImpl; +typedef struct IDirect3DVertexShader8Impl IDirect3DVertexShader8Impl; typedef struct D3DSHADERVECTOR { float x; @@ -541,76 +543,11 @@ struct IDirect3DDevice8Impl /* IUnknown fields */ const IDirect3DDevice8Vtbl *lpVtbl; LONG ref; - - /* IDirect3DDevice8 fields */ - IDirect3D8Impl *direct3d8; +/* But what about baseVertexIndex in state blocks? hmm... it may be a better idea to pass this to wined3d */ IWineD3DDevice *WineD3DDevice; - - IDirect3DSurface8Impl *frontBuffer; - IDirect3DSurface8Impl *backBuffer; - IDirect3DSurface8Impl *depthStencilBuffer; - - IDirect3DSurface8Impl *renderTarget; - IDirect3DSurface8Impl *stencilBufferTarget; - - D3DPRESENT_PARAMETERS PresentParms; - D3DDEVICE_CREATION_PARAMETERS CreateParms; - - UINT adapterNo; - D3DDEVTYPE devType; - - UINT srcBlend; - UINT dstBlend; - UINT alphafunc; - UINT stencilfunc; - - /* State block related */ - BOOL isRecordingState; - IDirect3DStateBlockImpl *StateBlock; - IDirect3DStateBlockImpl *UpdateStateBlock; - - /* palettes texture management */ - PALETTEENTRY palettes[MAX_PALETTES][256]; - UINT currentPalette; - - BOOL texture_shader_active; - - /* Optimization */ - BOOL modelview_valid; - BOOL proj_valid; - BOOL view_ident; /* true iff view matrix is identity */ - BOOL last_was_rhw; /* true iff last draw_primitive was in xyzrhw mode */ - GLenum tracking_parm; /* Which source is tracking current colour */ - LONG tracking_color; /* used iff GL_COLOR_MATERIAL was enabled */ -#define DISABLED_TRACKING 0 /* Disabled */ -#define IS_TRACKING 1 /* tracking_parm is tracking diffuse color */ -#define NEEDS_TRACKING 2 /* Tracking needs to be enabled when needed */ -#define NEEDS_DISABLE 3 /* Tracking needs to be disabled when needed*/ - - /* OpenGL related */ - GLXContext glCtx; - XVisualInfo *visInfo; - Display *display; - HWND win_handle; - Window win; - GLXContext render_ctx; - Drawable drawable; - GLint maxConcurrentLights; - - /* OpenGL Extension related */ - - /* Cursor management */ - BOOL bCursorVisible; - UINT xHotSpot; - UINT yHotSpot; - UINT xScreenSpace; - UINT yScreenSpace; - GLint cursor; - - UINT dummyTextureName[8]; - - /* For rendering to a texture using glCopyTexImage */ - BOOL renderUpsideDown; + IDirect3DVertexShader8Impl *vShaders[MAX_SHADERS]; +/* FIXME: Move *baseVertexIndex somewhere sensible like wined3d */ + UINT baseVertexIndex; }; /* IUnknown: */ @@ -948,11 +885,10 @@ struct IDirect3DResource8Impl { /* IUnknown fields */ const IDirect3DResource8Vtbl *lpVtbl; - LONG ref; + LONG ref; /* IDirect3DResource8 fields */ - IDirect3DDevice8Impl *Device; - D3DRESOURCETYPE ResourceType; + IWineD3DResource *wineD3DResource; }; /* IUnknown: */ @@ -987,16 +923,10 @@ struct IDirect3DVertexBuffer8Impl { /* IUnknown fields */ const IDirect3DVertexBuffer8Vtbl *lpVtbl; - LONG ref; - LONG refInt; + LONG ref; /* IDirect3DResource8 fields */ - IDirect3DDevice8Impl *Device; - D3DRESOURCETYPE ResourceType; - - /* IDirect3DVertexBuffer8 fields */ - BYTE *allocatedMemory; - D3DVERTEXBUFFER_DESC currentDesc; + IWineD3DVertexBuffer *wineD3DVertexBuffer; }; /* IUnknown: */ @@ -1040,16 +970,10 @@ struct IDirect3DIndexBuffer8Impl { /* IUnknown fields */ const IDirect3DIndexBuffer8Vtbl *lpVtbl; - LONG ref; - LONG refInt; + LONG ref; /* IDirect3DResource8 fields */ - IDirect3DDevice8Impl *Device; - D3DRESOURCETYPE ResourceType; - - /* IDirect3DIndexBuffer8 fields */ - void *allocatedMemory; - D3DINDEXBUFFER_DESC currentDesc; + IWineD3DIndexBuffer *wineD3DIndexBuffer; }; /* IUnknown: */ @@ -1427,221 +1351,159 @@ struct IWineD3DStateBlockImpl }; +/* ============================================================================== + Private interfaces: beginning of cleaning/splitting for HAL and d3d9 support + ============================================================================== */ + /* ----------------------- */ /* IDirect3DStateBlockImpl */ /* ----------------------- */ +/* TODO: Generate a valid GUIDs */ +/* {83B073CE-6F30-11d9-C687-00046142C14F} */ +DEFINE_GUID(IID_IDirect3DStateBlock8, +0x83b073ce, 0x6f30, 0x11d9, 0xc6, 0x87, 0x0, 0x4, 0x61, 0x42, 0xc1, 0x4f); + +DEFINE_GUID(IID_IDirect3DVertexShader8, +0xefc5557e, 0x6265, 0x4613, 0x8a, 0x94, 0x43, 0x85, 0x78, 0x89, 0xeb, 0x36); + +DEFINE_GUID(IID_IDirect3DPixelShader8, +0x6d3bdbdc, 0x5b02, 0x4415, 0xb8, 0x52, 0xce, 0x5e, 0x8b, 0xcc, 0xb2, 0x89); + + +/***************************************************************************** + * IDirect3DStateBlock8 interface + */ +#define INTERFACE IDirect3DStateBlock8 +DECLARE_INTERFACE_(IDirect3DStateBlock8, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + /*** IDirect3DStateBlock9 methods ***/ + STDMETHOD(GetDevice)(THIS_ struct IDirect3DDevice8** ppDevice) PURE; + STDMETHOD(Capture)(THIS) PURE; + STDMETHOD(Apply)(THIS) PURE; +}; +#undef INTERFACE + +/*** IUnknown methods ***/ +#define IDirect3DStateBlock8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DStateBlock8_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DStateBlock8_Release(p) (p)->lpVtbl->Release(p) +/*** IDirect3DStateBlock9 methods ***/ +#define IDirect3DStateBlock8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DStateBlock8_Capture(p) (p)->lpVtbl->Capture(p) +#define IDirect3DStateBlock8_Apply(p) (p)->lpVtbl->Apply(p) + /***************************************************************************** * Predeclare the interface implementation structures */ -/*extern const IDirect3DStateBlock9Vtbl Direct3DStateBlock9_Vtbl;*/ +extern const IDirect3DStateBlock8Vtbl Direct3DStateBlock8_Vtbl; /***************************************************************************** * IDirect3DStateBlock implementation structure */ -struct IDirect3DStateBlockImpl { - /* IUnknown fields */ - /*const IDirect3DStateBlock9Vtbl *lpVtbl;*/ - LONG ref; +typedef struct IDirect3DStateBlock8Impl { + /* IUnknown fields */ + const IDirect3DStateBlock8Vtbl *lpVtbl; + LONG ref; - /* The device, to be replaced by an IDirect3DDeviceImpl */ - IDirect3DDevice8Impl* device; + /* IDirect3DResource8 fields */ + IWineD3DStateBlock *wineD3DStateBlock; +} IDirect3DStateBlock8Impl; - D3DSTATEBLOCKTYPE blockType; - - SAVEDSTATES Changed; - SAVEDSTATES Set; - - /* Clipping */ - double clipplane[MAX_CLIPPLANES][4]; - D3DCLIPSTATUS8 clip_status; - - /* Stream Source */ - UINT stream_stride[MAX_STREAMS]; - IDirect3DVertexBuffer8 *stream_source[MAX_STREAMS]; - BOOL streamIsUP; - - /* Indices */ - IDirect3DIndexBuffer8* pIndexData; - UINT baseVertexIndex; - - /* Texture */ - IDirect3DBaseTexture8 *textures[8]; - int textureDimensions[8]; - /* Texture State Stage */ - DWORD texture_state[8][HIGHEST_TEXTURE_STATE]; - - /* Lights */ - PLIGHTINFOEL *lights; /* NOTE: active GL lights must be front of the chain */ - - /* Material */ - D3DMATERIAL8 material; - - /* RenderState */ - DWORD renderstate[HIGHEST_RENDER_STATE]; - - /* Transform */ - D3DMATRIX transforms[HIGHEST_TRANSFORMSTATE]; - - /* ViewPort */ - D3DVIEWPORT8 viewport; - - /* Vertex Shader */ - DWORD VertexShader; - - /* Vertex Shader Declaration */ - IDirect3DVertexShaderDeclarationImpl* vertexShaderDecl; - - /* Pixel Shader */ - DWORD PixelShader; - - /* Indexed Vertex Blending */ - D3DVERTEXBLENDFLAGS vertex_blend; - FLOAT tween_factor; - - /* Vertex Shader Constant */ - D3DSHADERVECTOR vertexShaderConstant[D3D8_VSHADER_MAX_CONSTANTS]; - /* Pixel Shader Constant */ - D3DSHADERVECTOR pixelShaderConstant[D3D8_PSHADER_MAX_CONSTANTS]; +/***************************************************************************** + * IDirect3DVertexShader9 interface + */ +#define INTERFACE IDirect3DVertexShader8 +DECLARE_INTERFACE_(IDirect3DVertexShader8, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + /*** IDirect3DVertexShader9 methods ***/ + STDMETHOD(GetDevice)(THIS_ struct IDirect3DDevice8** ppDevice) PURE; + STDMETHOD(GetFunction)(THIS_ void*, UINT* pSizeOfData) PURE; }; +#undef INTERFACE -/* exported Interfaces */ -/* internal Interfaces */ -/* temporary internal Interfaces */ -extern HRESULT WINAPI IDirect3DDeviceImpl_InitStartupStateBlock(IDirect3DDevice8Impl* This); -extern HRESULT WINAPI IDirect3DDeviceImpl_CreateStateBlock(IDirect3DDevice8Impl* This, D3DSTATEBLOCKTYPE Type, IDirect3DStateBlockImpl** ppStateBlock); -extern HRESULT WINAPI IDirect3DDeviceImpl_DeleteStateBlock(IDirect3DDevice8Impl* This, IDirect3DStateBlockImpl* pSB); -extern HRESULT WINAPI IDirect3DDeviceImpl_BeginStateBlock(IDirect3DDevice8Impl* This); -extern HRESULT WINAPI IDirect3DDeviceImpl_EndStateBlock(IDirect3DDevice8Impl* This, IDirect3DStateBlockImpl** ppStateBlock); -extern HRESULT WINAPI IDirect3DDeviceImpl_ApplyStateBlock(IDirect3DDevice8Impl* iface, IDirect3DStateBlockImpl* pSB); -extern HRESULT WINAPI IDirect3DDeviceImpl_CaptureStateBlock(IDirect3DDevice8Impl* This, IDirect3DStateBlockImpl* pSB); +/*** IUnknown methods ***/ +#define IDirect3DVertexShader8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DVertexShader8_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DVertexShader8_Release(p) (p)->lpVtbl->Release(p) +/*** IDirect3DVertexShader8 methods ***/ +#define IDirect3DVertexShader8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DVertexShader8_GetFunction(p,a,b) (p)->lpVtbl->GetFunction(p,a,b) + +/* ------------------------- */ +/* IDirect3DVertexShader8Impl */ +/* ------------------------- */ + +/***************************************************************************** + * IDirect3DPixelShader9 interface + */ +#define INTERFACE IDirect3DPixelShader8 +DECLARE_INTERFACE_(IDirect3DPixelShader8,IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + /*** IDirect3DPixelShader8 methods ***/ + STDMETHOD(GetDevice)(THIS_ struct IDirect3DDevice8** ppDevice) PURE; + STDMETHOD(GetFunction)(THIS_ void*, UINT* pSizeOfData) PURE; +}; +#undef INTERFACE + +/*** IUnknown methods ***/ +#define IDirect3DPixelShader8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DPixelShader8_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DPixelShader8_Release(p) (p)->lpVtbl->Release(p) +/*** IDirect3DPixelShader8 methods ***/ +#define IDirect3DPixelShader8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DPixelShader8_GetFunction(p,a,b) (p)->lpVtbl->GetFunction(p,a,b) -/* ------------------------------------ */ -/* IDirect3DVertexShaderDeclarationImpl */ -/* ------------------------------------ */ /***************************************************************************** * Predeclare the interface implementation structures */ -/*extern const IDirect3DVertexShaderDeclaration9Vtbl Direct3DVertexShaderDeclaration9_Vtbl;*/ - -/***************************************************************************** - * IDirect3DVertexShaderDeclaration implementation structure - */ -struct IDirect3DVertexShaderDeclarationImpl { - /* IUnknown fields */ - /*const IDirect3DVertexShaderDeclaration9Vtbl *lpVtbl;*/ - LONG ref; - - /* The device, to be replaced by an IDirect3DDeviceImpl */ - IDirect3DDevice8Impl* device; - - /** precomputed fvf if simple declaration */ - DWORD fvf[MAX_STREAMS]; - DWORD allFVF; - - /** dx8 compatible Declaration fields */ - DWORD* pDeclaration8; - DWORD declaration8Length; -}; - -/* exported Interfaces */ -extern HRESULT WINAPI IDirect3DVertexShaderDeclarationImpl_GetDeclaration8(IDirect3DVertexShaderDeclarationImpl* This, DWORD* pData, UINT* pSizeOfData); -/*extern HRESULT IDirect3DVertexShaderDeclarationImpl_GetDeclaration9(IDirect3DVertexShaderDeclarationImpl* This, D3DVERTEXELEMENT9* pData, UINT* pNumElements);*/ -/* internal Interfaces */ -/* temporary internal Interfaces */ -extern HRESULT WINAPI IDirect3DDeviceImpl_CreateVertexShaderDeclaration8(IDirect3DDevice8Impl* This, CONST DWORD* pDeclaration8, IDirect3DVertexShaderDeclarationImpl** ppVertexShaderDecl); - - -/* ------------------------- */ -/* IDirect3DVertexShaderImpl */ -/* ------------------------- */ - -/***************************************************************************** - * Predeclare the interface implementation structures - */ -/*extern const IDirect3DVertexShader9Vtbl Direct3DVertexShader9_Vtbl;*/ +extern const IDirect3DVertexShader8Vtbl Direct3DVertexShader8_Vtbl; /***************************************************************************** * IDirect3DVertexShader implementation structure */ -struct IDirect3DVertexShaderImpl { - /*const IDirect3DVertexShader9Vtbl *lpVtbl;*/ + +struct IDirect3DVertexShader8Impl { + const IDirect3DVertexShader8Vtbl *lpVtbl; LONG ref; - /* The device, to be replaced by an IDirect3DDeviceImpl */ - IDirect3DDevice8Impl* device; - - DWORD* function; - UINT functionLength; - DWORD usage; /* 0 || D3DUSAGE_SOFTWAREPROCESSING */ - DWORD version; - - /** fields for hw vertex shader use */ - GLuint prgId; - - /* run time datas */ - VSHADERDATA8* data; - VSHADERINPUTDATA8 input; - VSHADEROUTPUTDATA8 output; + IWineD3DVertexShader *wineD3DVertexShader; }; -/* exported Interfaces */ -extern HRESULT WINAPI IDirect3DVertexShaderImpl_GetFunction(IDirect3DVertexShaderImpl* This, VOID* pData, UINT* pSizeOfData); -/*extern HRESULT WINAPI IDirect3DVertexShaderImpl_SetConstantB(IDirect3DVertexShaderImpl* This, UINT StartRegister, CONST BOOL* pConstantData, UINT BoolCount);*/ -/*extern HRESULT WINAPI IDirect3DVertexShaderImpl_SetConstantI(IDirect3DVertexShaderImpl* This, UINT StartRegister, CONST INT* pConstantData, UINT Vector4iCount);*/ -extern HRESULT WINAPI IDirect3DVertexShaderImpl_SetConstantF(IDirect3DVertexShaderImpl* This, UINT StartRegister, CONST FLOAT* pConstantData, UINT Vector4fCount); -/*extern HRESULT WINAPI IDirect3DVertexShaderImpl_GetConstantB(IDirect3DVertexShaderImpl* This, UINT StartRegister, BOOL* pConstantData, UINT BoolCount);*/ -/*extern HRESULT WINAPI IDirect3DVertexShaderImpl_GetConstantI(IDirect3DVertexShaderImpl* This, UINT StartRegister, INT* pConstantData, UINT Vector4iCount);*/ -extern HRESULT WINAPI IDirect3DVertexShaderImpl_GetConstantF(IDirect3DVertexShaderImpl* This, UINT StartRegister, FLOAT* pConstantData, UINT Vector4fCount); -/* internal Interfaces */ -extern DWORD WINAPI IDirect3DVertexShaderImpl_GetVersion(IDirect3DVertexShaderImpl* This); -extern HRESULT WINAPI IDirect3DVertexShaderImpl_ExecuteSW(IDirect3DVertexShaderImpl* This, VSHADERINPUTDATA8* input, VSHADEROUTPUTDATA8* output); -/* temporary internal Interfaces */ -extern HRESULT WINAPI IDirect3DDeviceImpl_CreateVertexShader(IDirect3DDevice8Impl* This, CONST DWORD* pFunction, DWORD Usage, IDirect3DVertexShaderImpl** ppVertexShader); -extern HRESULT WINAPI IDirect3DDeviceImpl_FillVertexShaderInputSW(IDirect3DDevice8Impl* This, IDirect3DVertexShaderImpl* vshader, DWORD SkipnStrides); -extern HRESULT WINAPI IDirect3DDeviceImpl_FillVertexShaderInputArbHW(IDirect3DDevice8Impl* This, IDirect3DVertexShaderImpl* vshader, DWORD SkipnStrides); /* ------------------------ */ /* IDirect3DPixelShaderImpl */ /* ------------------------ */ + /***************************************************************************** * Predeclare the interface implementation structures */ -/*extern const IDirect3DPixelShader9Vtbl Direct3DPixelShader9_Vtbl;*/ +extern const IDirect3DPixelShader8Vtbl Direct3DPixelShader8_Vtbl; /***************************************************************************** * IDirect3DPixelShader implementation structure */ -struct IDirect3DPixelShaderImpl { - /*const IDirect3DPixelShader9Vtbl *lpVtbl;*/ - LONG ref; - - /* The device, to be replaced by an IDirect3DDeviceImpl */ - IDirect3DDevice8Impl* device; - - DWORD* function; - UINT functionLength; - DWORD version; - - /** fields for hw pixel shader use */ - GLuint prgId; - - /* run time datas */ - PSHADERDATA8* data; - PSHADERINPUTDATA8 input; - PSHADEROUTPUTDATA8 output; -}; - -/* exported Interfaces */ -extern HRESULT WINAPI IDirect3DPixelShaderImpl_GetFunction(IDirect3DPixelShaderImpl* This, VOID* pData, UINT* pSizeOfData); -extern HRESULT WINAPI IDirect3DPixelShaderImpl_SetConstantF(IDirect3DPixelShaderImpl* This, UINT StartRegister, CONST FLOAT* pConstantData, UINT Vector4fCount); -/* internal Interfaces */ -extern DWORD WINAPI IDirect3DPixelShaderImpl_GetVersion(IDirect3DPixelShaderImpl* This); -/* temporary internal Interfaces */ -extern HRESULT WINAPI IDirect3DDeviceImpl_CreatePixelShader(IDirect3DDevice8Impl* This, CONST DWORD* pFunction, IDirect3DPixelShaderImpl** ppPixelShader); +typedef struct IDirect3DPixelShader8Impl { + const IDirect3DPixelShader8Vtbl *lpVtbl; + LONG ref; + /* The device, to be replaced by an IDirect3DDeviceImpl */ + IWineD3DPixelShader *wineD3DPixelShader; +} IDirect3DPixelShader8Impl; /** * Internals functions @@ -1680,65 +1542,24 @@ int SOURCEx_ALPHA_EXT(DWORD arg); int OPERANDx_ALPHA_EXT(DWORD arg); GLenum StencilOp(DWORD op); -/** - * Internals debug functions - */ -const char* debug_d3ddevicetype(D3DDEVTYPE devtype); -const char* debug_d3dusage(DWORD usage); -const char* debug_d3dformat(D3DFORMAT fmt); -const char* debug_d3dressourcetype(D3DRESOURCETYPE res); -const char* debug_d3dprimitivetype(D3DPRIMITIVETYPE PrimitiveType); -const char* debug_d3dpool(D3DPOOL Pool); -const char *debug_d3drenderstate(DWORD State); -const char *debug_d3dtexturestate(DWORD State); +/* Callbacks */ +extern HRESULT WINAPI D3D8CB_CreateSurface(IUnknown *device, UINT Width, UINT Height, + WINED3DFORMAT Format, DWORD Usage, D3DPOOL Pool, UINT Level, + IWineD3DSurface** ppSurface, HANDLE* pSharedHandle); -/* Some #defines for additional diagnostics */ -#if 0 /* NOTE: Must be 0 in cvs */ - /* To avoid having to get gigabytes of trace, the following can be compiled in, and at the start - of each frame, a check is made for the existence of C:\D3DTRACE, and if if exists d3d trace - is enabled, and if it doesn't exists it is disabled. */ -# define FRAME_DEBUGGING - /* Adding in the SINGLE_FRAME_DEBUGGING gives a trace of just what makes up a single frame, before - the file is deleted */ -# if 1 /* NOTE: Must be 1 in cvs, as this is mostly more useful than a trace from program start */ -# define SINGLE_FRAME_DEBUGGING -# endif - /* The following, when enabled, lets you see the makeup of the frame, by drawprimitive calls. - It can only be enabled when FRAME_DEBUGGING is also enabled - The contents of the back buffer are written into /tmp/backbuffer_* after each primitive - array is drawn. */ -# if 0 /* NOTE: Must be 0 in cvs, as this give a lot of ppm files when compiled in */ -# define SHOW_FRAME_MAKEUP 1 -# endif - /* The following, when enabled, lets you see the makeup of the all the textures used during each - of the drawprimitive calls. It can only be enabled when SHOW_FRAME_MAKEUP is also enabled. - The contents of the textures assigned to each stage are written into - /tmp/texture_*_.ppm after each primitive array is drawn. */ -# if 0 /* NOTE: Must be 0 in cvs, as this give a lot of ppm files when compiled in */ -# define SHOW_TEXTURE_MAKEUP 0 -# endif -extern BOOL isOn; -extern BOOL isDumpingFrames; -extern LONG primCounter; -#endif +extern HRESULT WINAPI D3D8CB_CreateVolume(IUnknown *pDevice, UINT Width, UINT Height, UINT Depth, + WINED3DFORMAT Format, D3DPOOL Pool, DWORD Usage, + IWineD3DVolume **ppVolume, + HANDLE * pSharedHandle); -/* Per-vertex trace: */ -#if 0 /* NOTE: Must be 0 in cvs */ -# define VTRACE(A) TRACE A -#else -# define VTRACE(A) -#endif +extern HRESULT WINAPI D3D8CB_CreateDepthStencilSurface(IUnknown *device, UINT Width, UINT Height, + WINED3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, + DWORD MultisampleQuality, BOOL Discard, + IWineD3DSurface** ppSurface, HANDLE* pSharedHandle); -#define TRACE_VECTOR(name) TRACE( #name "=(%f, %f, %f, %f)\n", name.x, name.y, name.z, name.w); -#define TRACE_STRIDED(sd,name) TRACE( #name "=(data:%p, stride:%ld, type:%ld)\n", sd->u.s.name.lpData, sd->u.s.name.dwStride, sd->u.s.name.dwType); - -#define DUMP_LIGHT_CHAIN() \ -{ \ - PLIGHTINFOEL *el = This->StateBlock->lights;\ - while (el) { \ - TRACE("Light %p (glIndex %ld, d3dIndex %ld, enabled %d)\n", el, el->glIndex, el->OriginalIndex, el->lightEnabled);\ - el = el->next; \ - } \ -} +extern HRESULT WINAPI D3D8CB_CreateRenderTarget(IUnknown *device, UINT Width, UINT Height, + WINED3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, + DWORD MultisampleQuality, BOOL Lockable, + IWineD3DSurface** ppSurface, HANDLE* pSharedHandle); #endif /* __WINE_D3DX8_PRIVATE_H */ diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c index 5db038b472b..ac3b39e8a9e 100644 --- a/dlls/d3d8/device.c +++ b/dlls/d3d8/device.c @@ -32,252 +32,9 @@ #include "wingdi.h" #include "wine/debug.h" -/** define GL_GLEXT_PROTOTYPES for having extensions prototypes defined */ -/*#define GL_GLEXT_PROTOTYPES*/ -/*#undef GLX_GLXEXT_LEGACY*/ #include "d3d8_private.h" -/** currently desactiving 1_4 support as mesa doesn't implement all 1_4 support while defining it */ -#undef GL_VERSION_1_4 - -/* Uncomment the next line to get extra traces, important but impact speed */ -/* #define EXTRA_TRACES */ - WINE_DEFAULT_DEBUG_CHANNEL(d3d); -WINE_DECLARE_DEBUG_CHANNEL(d3d_shader); -WINE_DECLARE_DEBUG_CHANNEL(d3d_fps); - -IDirect3DVertexShaderImpl* VertexShaders[64]; -IDirect3DVertexShaderDeclarationImpl* VertexShaderDeclarations[64]; -IDirect3DPixelShaderImpl* PixelShaders[64]; - -/* Debugging aids: */ -#ifdef FRAME_DEBUGGING -BOOL isOn = FALSE; -BOOL isDumpingFrames = FALSE; -LONG primCounter = 0; -#endif - -/* - * Utility functions or macros - */ -#define conv_mat(mat,gl_mat) \ -do { \ - TRACE("%f %f %f %f\n", (mat)->u.s._11, (mat)->u.s._12, (mat)->u.s._13, (mat)->u.s._14); \ - TRACE("%f %f %f %f\n", (mat)->u.s._21, (mat)->u.s._22, (mat)->u.s._23, (mat)->u.s._24); \ - TRACE("%f %f %f %f\n", (mat)->u.s._31, (mat)->u.s._32, (mat)->u.s._33, (mat)->u.s._34); \ - TRACE("%f %f %f %f\n", (mat)->u.s._41, (mat)->u.s._42, (mat)->u.s._43, (mat)->u.s._44); \ - memcpy(gl_mat, (mat), 16 * sizeof(float)); \ -} while (0) - -/* Apply the current values to the specified texture stage */ -void setupTextureStates(LPDIRECT3DDEVICE8 iface, DWORD Stage, DWORD Flags) { - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - int i = 0; - float col[4]; - BOOL changeTexture = TRUE; - - TRACE("-----------------------> Updating the texture at stage %ld to have new texture state information\n", Stage); - for (i = 1; i < HIGHEST_TEXTURE_STATE; i++) { - - BOOL skip = FALSE; - - switch (i) { - /* Performance: For texture states where multiples effect the outcome, only bother - applying the last one as it will pick up all the other values */ - case D3DTSS_COLORARG0: /* Will be picked up when setting color op */ - case D3DTSS_COLORARG1: /* Will be picked up when setting color op */ - case D3DTSS_COLORARG2: /* Will be picked up when setting color op */ - case D3DTSS_ALPHAARG0: /* Will be picked up when setting alpha op */ - case D3DTSS_ALPHAARG1: /* Will be picked up when setting alpha op */ - case D3DTSS_ALPHAARG2: /* Will be picked up when setting alpha op */ - skip = TRUE; - break; - - /* Performance: If the texture states only impact settings for the texture unit - (compared to the texture object) then there is no need to reapply them. The - only time they need applying is the first time, since we cheat and put the - values into the stateblock without applying. - Per-texture unit: texture function (eg. combine), ops and args - texture env color - texture generation settings - Note: Due to some special conditions there may be a need to do particular ones - of these, which is what the Flags allows */ - case D3DTSS_COLOROP: - case D3DTSS_TEXCOORDINDEX: - if (!(Flags == REAPPLY_ALL)) skip=TRUE; - break; - - case D3DTSS_ALPHAOP: - if (!(Flags & REAPPLY_ALPHAOP)) skip=TRUE; - break; - - default: - skip = FALSE; - } - - if (skip == FALSE) { - /* Performance: Only change to this texture if we have to */ - if (changeTexture) { - /* Make appropriate texture active */ - if (GL_SUPPORT(ARB_MULTITEXTURE)) { -#if defined(GL_VERSION_1_3) - glActiveTexture(GL_TEXTURE0 + Stage); - checkGLcall("glActiveTexture"); -#else - glActiveTextureARB(GL_TEXTURE0_ARB + Stage); - checkGLcall("glActiveTextureARB"); -#endif - } else if (Stage > 0) { - FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n"); - } - changeTexture = FALSE; - } - - /* Now apply the change */ - IDirect3DDevice8Impl_SetTextureStageState(iface, Stage, i, This->StateBlock->texture_state[Stage][i]); - } - } - - /* Note the D3DRS value applies to all textures, but GL has one - * per texture, so apply it now ready to be used! - */ - D3DCOLORTOGLFLOAT4(This->StateBlock->renderstate[D3DRS_TEXTUREFACTOR], col); - glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]); - checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);"); - - TRACE("-----------------------> Updated the texture at stage %ld to have new texture state information\n", Stage); -} - -/* Convert the D3DLIGHT8 properties into equivalent gl lights */ -static void setup_light(LPDIRECT3DDEVICE8 iface, LONG Index, PLIGHTINFOEL *lightInfo) { - - float quad_att; - float colRGBA[] = {0.0, 0.0, 0.0, 0.0}; - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - - /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/ - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0]); - - /* Diffuse: */ - colRGBA[0] = lightInfo->OriginalParms.Diffuse.r; - colRGBA[1] = lightInfo->OriginalParms.Diffuse.g; - colRGBA[2] = lightInfo->OriginalParms.Diffuse.b; - colRGBA[3] = lightInfo->OriginalParms.Diffuse.a; - glLightfv(GL_LIGHT0+Index, GL_DIFFUSE, colRGBA); - checkGLcall("glLightfv"); - - /* Specular */ - colRGBA[0] = lightInfo->OriginalParms.Specular.r; - colRGBA[1] = lightInfo->OriginalParms.Specular.g; - colRGBA[2] = lightInfo->OriginalParms.Specular.b; - colRGBA[3] = lightInfo->OriginalParms.Specular.a; - glLightfv(GL_LIGHT0+Index, GL_SPECULAR, colRGBA); - checkGLcall("glLightfv"); - - /* Ambient */ - colRGBA[0] = lightInfo->OriginalParms.Ambient.r; - colRGBA[1] = lightInfo->OriginalParms.Ambient.g; - colRGBA[2] = lightInfo->OriginalParms.Ambient.b; - colRGBA[3] = lightInfo->OriginalParms.Ambient.a; - glLightfv(GL_LIGHT0+Index, GL_AMBIENT, colRGBA); - checkGLcall("glLightfv"); - - /* Attenuation - Are these right? guessing... */ - glLightf(GL_LIGHT0+Index, GL_CONSTANT_ATTENUATION, lightInfo->OriginalParms.Attenuation0); - checkGLcall("glLightf"); - glLightf(GL_LIGHT0+Index, GL_LINEAR_ATTENUATION, lightInfo->OriginalParms.Attenuation1); - checkGLcall("glLightf"); - - quad_att = 1.4/(lightInfo->OriginalParms.Range*lightInfo->OriginalParms.Range); - if (quad_att < lightInfo->OriginalParms.Attenuation2) quad_att = lightInfo->OriginalParms.Attenuation2; - glLightf(GL_LIGHT0+Index, GL_QUADRATIC_ATTENUATION, quad_att); - checkGLcall("glLightf"); - - switch (lightInfo->OriginalParms.Type) { - case D3DLIGHT_POINT: - /* Position */ - glLightfv(GL_LIGHT0+Index, GL_POSITION, &lightInfo->lightPosn[0]); - checkGLcall("glLightfv"); - glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff); - checkGLcall("glLightf"); - /* FIXME: Range */ - break; - - case D3DLIGHT_SPOT: - /* Position */ - glLightfv(GL_LIGHT0+Index, GL_POSITION, &lightInfo->lightPosn[0]); - checkGLcall("glLightfv"); - /* Direction */ - glLightfv(GL_LIGHT0+Index, GL_SPOT_DIRECTION, &lightInfo->lightDirn[0]); - checkGLcall("glLightfv"); - glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, lightInfo->exponent); - checkGLcall("glLightf"); - glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff); - checkGLcall("glLightf"); - /* FIXME: Range */ - break; - - case D3DLIGHT_DIRECTIONAL: - /* Direction */ - glLightfv(GL_LIGHT0+Index, GL_POSITION, &lightInfo->lightPosn[0]); /* Note gl uses w position of 0 for direction! */ - checkGLcall("glLightfv"); - glLightf(GL_LIGHT0+Index, GL_SPOT_CUTOFF, lightInfo->cutoff); - checkGLcall("glLightf"); - glLightf(GL_LIGHT0+Index, GL_SPOT_EXPONENT, 0.0f); - checkGLcall("glLightf"); - break; - - default: - FIXME("Unrecognized light type %d\n", lightInfo->OriginalParms.Type); - } - - /* Restore the modelview matrix */ - glPopMatrix(); -} - -/* Setup this textures matrix */ -static void set_texture_matrix(const float *smat, DWORD flags) -{ - float mat[16]; - - glMatrixMode(GL_TEXTURE); - - if (flags == D3DTTFF_DISABLE) { - glLoadIdentity(); - checkGLcall("glLoadIdentity()"); - return; - } - - if (flags == (D3DTTFF_COUNT1|D3DTTFF_PROJECTED)) { - ERR("Invalid texture transform flags: D3DTTFF_COUNT1|D3DTTFF_PROJECTED\n"); - checkGLcall("glLoadIdentity()"); - return; - } - - memcpy(mat, smat, 16*sizeof(float)); - - switch (flags & ~D3DTTFF_PROJECTED) { - case D3DTTFF_COUNT1: mat[1] = mat[5] = mat[9] = mat[13] = 0; - case D3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0; - default: mat[3] = mat[7] = mat[11] = 0, mat[15] = 1; - } - - if (flags & D3DTTFF_PROJECTED) switch (flags & ~D3DTTFF_PROJECTED) { - case D3DTTFF_COUNT2: - mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13]; - mat[1] = mat[5] = mat[9] = mat[13] = 0; - break; - case D3DTTFF_COUNT3: - mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14]; - mat[2] = mat[6] = mat[10] = mat[14] = 0; - break; - } - glLoadMatrixf(mat); - checkGLcall("glLoadMatrixf(mat)"); -} /* IDirect3D IUnknown parts follow: */ HRESULT WINAPI IDirect3DDevice8Impl_QueryInterface(LPDIRECT3DDEVICE8 iface,REFIID riid,LPVOID *ppobj) @@ -286,12 +43,12 @@ HRESULT WINAPI IDirect3DDevice8Impl_QueryInterface(LPDIRECT3DDEVICE8 iface,REFII if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IDirect3DDevice8)) { - IDirect3DDevice8Impl_AddRef(iface); + IUnknown_AddRef(iface); *ppobj = This; return D3D_OK; } - WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj); + WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj); return E_NOINTERFACE; } @@ -304,45 +61,6 @@ ULONG WINAPI IDirect3DDevice8Impl_AddRef(LPDIRECT3DDEVICE8 iface) { return ref; } -/* The function below is needed during the D3D8->WineD3D transition - in order to release various surfaces like the front- and backBuffer. - When the transition is complete code similar to this will be executed - by IWineD3DDevice_Release. -*/ -void IDirect3DDevice8_CleanUp(IDirect3DDevice8Impl *This) -{ - LPDIRECT3DSURFACE8 stencilBufferParent; - /* Release the buffers (with sanity checks)*/ - if(This->stencilBufferTarget != NULL && (IDirect3DSurface8Impl_Release((LPDIRECT3DSURFACE8)This->stencilBufferTarget) >0)){ - if(This->depthStencilBuffer != This->stencilBufferTarget) - TRACE("(%p) Something's still holding the depthStencilBuffer\n",This); - } - This->stencilBufferTarget = NULL; - - if(This->renderTarget != NULL) { - IDirect3DSurface8Impl_Release((LPDIRECT3DSURFACE8)This->renderTarget); - This->renderTarget = NULL; - } - - if(This->depthStencilBuffer != NULL) { - stencilBufferParent = (LPDIRECT3DSURFACE8)D3D8_SURFACE(This->depthStencilBuffer)->resource.parent; - if(stencilBufferParent != NULL) { - IDirect3DSurface8_Release(stencilBufferParent); - This->depthStencilBuffer = NULL; - } - } - - if(This->backBuffer != NULL) { - IDirect3DSurface8Impl_Release((LPDIRECT3DSURFACE8)This->backBuffer); - This->backBuffer = NULL; - } - - if(This->frontBuffer != NULL) { - IDirect3DSurface8Impl_Release((LPDIRECT3DSURFACE8)This->frontBuffer); - This->frontBuffer = NULL; - } -} - ULONG WINAPI IDirect3DDevice8Impl_Release(LPDIRECT3DDEVICE8 iface) { IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; ULONG ref = InterlockedDecrement(&This->ref); @@ -350,310 +68,222 @@ ULONG WINAPI IDirect3DDevice8Impl_Release(LPDIRECT3DDEVICE8 iface) { TRACE("(%p) : ReleaseRef to %ld\n", This, ref); if (ref == 0) { - IDirect3DDevice8Impl_CleanRender(iface); - IDirect3D8_Release((LPDIRECT3D8) This->direct3d8); - IDirect3DDevice8_CleanUp(This); + TRACE("Releasing wined3d device %p\n", This->WineD3DDevice); IWineD3DDevice_Release(This->WineD3DDevice); - if (glXGetCurrentContext() == This->glCtx) { - glXMakeCurrent(This->display, None, NULL); - } - glXDestroyContext(This->display, This->glCtx); - HeapFree(GetProcessHeap(), 0, This); } return ref; } /* IDirect3DDevice Interface follow: */ -HRESULT WINAPI IDirect3DDevice8Impl_TestCooperativeLevel(LPDIRECT3DDEVICE8 iface) { +HRESULT WINAPI IDirect3DDevice8Impl_TestCooperativeLevel(LPDIRECT3DDEVICE8 iface) { IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - TRACE("(%p) : stub\n", This); /* No way of notifying yet! */ - return D3D_OK; + + TRACE("(%p) : Relay\n", This); + return IWineD3DDevice_TestCooperativeLevel(This->WineD3DDevice); } -UINT WINAPI IDirect3DDevice8Impl_GetAvailableTextureMem(LPDIRECT3DDEVICE8 iface) { +UINT WINAPI IDirect3DDevice8Impl_GetAvailableTextureMem(LPDIRECT3DDEVICE8 iface) { IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - TRACE("(%p) : stub, emulating 32Mb for now\n", This); - /* - * pretend we have 32MB of any type of memory queried. - */ - return (1024*1024*32); + + TRACE("(%p) Relay\n", This); + return IWineD3DDevice_GetAvailableTextureMem(This->WineD3DDevice); } -HRESULT WINAPI IDirect3DDevice8Impl_ResourceManagerDiscardBytes(LPDIRECT3DDEVICE8 iface, DWORD Bytes) { +HRESULT WINAPI IDirect3DDevice8Impl_ResourceManagerDiscardBytes(LPDIRECT3DDEVICE8 iface, DWORD Bytes) { IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - FIXME("(%p) : stub\n", This); - return D3D_OK; + + TRACE("(%p) : Relay bytes(%ld)\n", This, Bytes); + return IWineD3DDevice_EvictManagedResources(This->WineD3DDevice); } -HRESULT WINAPI IDirect3DDevice8Impl_GetDirect3D(LPDIRECT3DDEVICE8 iface, IDirect3D8** ppD3D8) { + +HRESULT WINAPI IDirect3DDevice8Impl_GetDirect3D(LPDIRECT3DDEVICE8 iface, IDirect3D8** ppD3D8) { IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - TRACE("(%p) : returning %p\n", This, This->direct3d8); + HRESULT hr = D3D_OK; + IWineD3D* pWineD3D; - /* Inc ref count */ - IDirect3D8_AddRef((LPDIRECT3D8) This->direct3d8); + TRACE("(%p) Relay\n", This); - *ppD3D8 = (IDirect3D8 *)This->direct3d8; - return D3D_OK; -} -HRESULT WINAPI IDirect3DDevice8Impl_GetDeviceCaps(LPDIRECT3DDEVICE8 iface, D3DCAPS8* pCaps) { - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - FIXME("(%p) : stub, calling idirect3d for now\n", This); - IDirect3D8Impl_GetDeviceCaps((LPDIRECT3D8) This->direct3d8, This->adapterNo, This->devType, pCaps); - return D3D_OK; -} -HRESULT WINAPI IDirect3DDevice8Impl_GetDisplayMode(LPDIRECT3DDEVICE8 iface, D3DDISPLAYMODE* pMode) { - - HDC hdc; - int bpp = 0; - - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - pMode->Width = GetSystemMetrics(SM_CXSCREEN); - pMode->Height = GetSystemMetrics(SM_CYSCREEN); - pMode->RefreshRate = 85; /*FIXME: How to identify? */ - - hdc = CreateDCA("DISPLAY", NULL, NULL, NULL); - bpp = GetDeviceCaps(hdc, BITSPIXEL); - DeleteDC(hdc); - - switch (bpp) { - case 8: pMode->Format = D3DFMT_R8G8B8; break; - case 16: pMode->Format = D3DFMT_R5G6B5; break; - case 24: /*pMode->Format = D3DFMT_R8G8B8; break; */ - case 32: pMode->Format = D3DFMT_A8R8G8B8; break; - default: - FIXME("Unrecognized display mode format\n"); - pMode->Format = D3DFMT_UNKNOWN; - } - - FIXME("(%p) : returning w(%d) h(%d) rr(%d) fmt(%u,%s)\n", This, pMode->Width, pMode->Height, pMode->RefreshRate, - pMode->Format, debug_d3dformat(pMode->Format)); - return D3D_OK; -} -HRESULT WINAPI IDirect3DDevice8Impl_GetCreationParameters(LPDIRECT3DDEVICE8 iface, D3DDEVICE_CREATION_PARAMETERS *pParameters) { - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - TRACE("(%p) copying to %p\n", This, pParameters); - memcpy(pParameters, &This->CreateParms, sizeof(D3DDEVICE_CREATION_PARAMETERS)); - return D3D_OK; -} -HRESULT WINAPI IDirect3DDevice8Impl_SetCursorProperties(LPDIRECT3DDEVICE8 iface, UINT XHotSpot, UINT YHotSpot, IDirect3DSurface8* pCursorBitmap) { - IDirect3DSurface8Impl* pSur = (IDirect3DSurface8Impl*) pCursorBitmap; - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - TRACE("(%p) : Spot Pos(%u,%u)\n", This, XHotSpot, YHotSpot); - - if (D3DFMT_A8R8G8B8 != D3D8_SURFACE(pSur)->resource.format) { - ERR("(%p) : surface(%p) has an invalid format\n", This, pCursorBitmap); - return D3DERR_INVALIDCALL; - } - if (32 != D3D8_SURFACE(pSur)->currentDesc.Height || 32 != D3D8_SURFACE(pSur)->currentDesc.Width) { - ERR("(%p) : surface(%p) has an invalid size\n", This, pCursorBitmap); - return D3DERR_INVALIDCALL; - } - - This->xHotSpot = XHotSpot; - This->yHotSpot = YHotSpot; - return D3D_OK; -} -void WINAPI IDirect3DDevice8Impl_SetCursorPosition(LPDIRECT3DDEVICE8 iface, UINT XScreenSpace, UINT YScreenSpace, DWORD Flags) { - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - TRACE("(%p) : SetPos to (%u,%u)\n", This, XScreenSpace, YScreenSpace); - This->xScreenSpace = XScreenSpace; - This->yScreenSpace = YScreenSpace; - return; -} -BOOL WINAPI IDirect3DDevice8Impl_ShowCursor(LPDIRECT3DDEVICE8 iface, BOOL bShow) { - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - TRACE("(%p) : visible(%d)\n", This, bShow); - This->bCursorVisible = bShow; - return D3D_OK; -} -HRESULT WINAPI IDirect3DDevice8Impl_CreateAdditionalSwapChain(LPDIRECT3DDEVICE8 iface, D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DSwapChain8** pSwapChain) { - IDirect3DSwapChain8Impl* object; - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - FIXME("(%p) : stub\n", This); - - object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DDevice8Impl)); - if (NULL == object) { - return D3DERR_OUTOFVIDEOMEMORY; - } - object->lpVtbl = &Direct3DSwapChain8_Vtbl; - object->ref = 1; - - TRACE("(%p)->(DepthStencil:(%u,%s), BackBufferFormat:(%u,%s))\n", This, - pPresentationParameters->AutoDepthStencilFormat, debug_d3dformat(pPresentationParameters->AutoDepthStencilFormat), - pPresentationParameters->BackBufferFormat, debug_d3dformat(pPresentationParameters->BackBufferFormat)); - - if (pPresentationParameters->Windowed && ((pPresentationParameters->BackBufferWidth == 0) || - (pPresentationParameters->BackBufferHeight == 0))) { - RECT Rect; - - GetClientRect(This->win_handle, &Rect); - - if (pPresentationParameters->BackBufferWidth == 0) { - pPresentationParameters->BackBufferWidth = Rect.right; - TRACE("Updating width to %d\n", pPresentationParameters->BackBufferWidth); - } - if (pPresentationParameters->BackBufferHeight == 0) { - pPresentationParameters->BackBufferHeight = Rect.bottom; - TRACE("Updating height to %d\n", pPresentationParameters->BackBufferHeight); - } - } - - /* Save the presentation parms now filled in correctly */ - memcpy(&object->PresentParms, pPresentationParameters, sizeof(D3DPRESENT_PARAMETERS)); - - IDirect3DDevice8Impl_CreateRenderTarget((LPDIRECT3DDEVICE8) object, - pPresentationParameters->BackBufferWidth, - pPresentationParameters->BackBufferHeight, - pPresentationParameters->BackBufferFormat, - pPresentationParameters->MultiSampleType, - TRUE, - (LPDIRECT3DSURFACE8*) &object->frontBuffer); - - IDirect3DDevice8Impl_CreateRenderTarget((LPDIRECT3DDEVICE8) object, - pPresentationParameters->BackBufferWidth, - pPresentationParameters->BackBufferHeight, - pPresentationParameters->BackBufferFormat, - pPresentationParameters->MultiSampleType, - TRUE, - (LPDIRECT3DSURFACE8*) &object->backBuffer); - - if (pPresentationParameters->EnableAutoDepthStencil) { - IDirect3DDevice8Impl_CreateDepthStencilSurface((LPDIRECT3DDEVICE8) object, - pPresentationParameters->BackBufferWidth, - pPresentationParameters->BackBufferHeight, - pPresentationParameters->AutoDepthStencilFormat, - D3DMULTISAMPLE_NONE, - (LPDIRECT3DSURFACE8*) &object->depthStencilBuffer); - } else { - object->depthStencilBuffer = NULL; - } - - *pSwapChain = (IDirect3DSwapChain8*) object; - return D3D_OK; -} -HRESULT WINAPI IDirect3DDevice8Impl_Reset(LPDIRECT3DDEVICE8 iface, D3DPRESENT_PARAMETERS* pPresentationParameters) { - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - FIXME("(%p) : stub\n", This); - return D3D_OK; -} -HRESULT WINAPI IDirect3DDevice8Impl_Present(LPDIRECT3DDEVICE8 iface, - CONST RECT* pSourceRect, CONST RECT* pDestRect, - HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion) { - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - TRACE("(%p) : complete stub!\n", This); - - ENTER_GL(); - - if (pSourceRect || pDestRect) FIXME("Unhandled present options %p/%p\n", pSourceRect, pDestRect); - - - glXSwapBuffers(This->display, This->drawable); - /* Don't call checkGLcall, as glGetError is not applicable here */ - TRACE("glXSwapBuffers called, Starting new frame\n"); - - /* FPS support */ - if (TRACE_ON(d3d_fps)) - { - static long prev_time, frames; - - DWORD time = GetTickCount(); - frames++; - /* every 1.5 seconds */ - if (time - prev_time > 1500) { - TRACE_(d3d_fps)("@ approx %.2ffps\n", 1000.0*frames/(time - prev_time)); - prev_time = time; - frames = 0; - } - } - -#if defined(FRAME_DEBUGGING) -{ - if (GetFileAttributesA("C:\\D3DTRACE") != INVALID_FILE_ATTRIBUTES) { - if (!isOn) { - isOn = TRUE; - FIXME("Enabling D3D Trace\n"); - __WINE_SET_DEBUGGING(__WINE_DBCL_TRACE, __wine_dbch_d3d, 1); -#if defined(SHOW_FRAME_MAKEUP) - FIXME("Singe Frame snapshots Starting\n"); - isDumpingFrames = TRUE; - glClear(GL_COLOR_BUFFER_BIT); -#endif - -#if defined(SINGLE_FRAME_DEBUGGING) - } else { -#if defined(SHOW_FRAME_MAKEUP) - FIXME("Singe Frame snapshots Finishing\n"); - isDumpingFrames = FALSE; -#endif - FIXME("Singe Frame trace complete\n"); - DeleteFileA("C:\\D3DTRACE"); - __WINE_SET_DEBUGGING(__WINE_DBCL_TRACE, __wine_dbch_d3d, 0); -#endif - } - } else { - if (isOn) { - isOn = FALSE; -#if defined(SHOW_FRAME_MAKEUP) - FIXME("Singe Frame snapshots Finishing\n"); - isDumpingFrames = FALSE; -#endif - FIXME("Disabling D3D Trace\n"); - __WINE_SET_DEBUGGING(__WINE_DBCL_TRACE, __wine_dbch_d3d, 0); - } - } -} -#endif - - LEAVE_GL(); - /* Although this is not strictly required, a simple demo showed this does occur - on (at least non-debug) d3d */ - if (This->PresentParms.SwapEffect == D3DSWAPEFFECT_DISCARD) { - IDirect3DDevice8Impl_Clear(iface, 0, NULL, D3DCLEAR_STENCIL|D3DCLEAR_ZBUFFER|D3DCLEAR_TARGET, 0x00, 1.0, 0); - } - - return D3D_OK; -} -HRESULT WINAPI IDirect3DDevice8Impl_GetBackBuffer(LPDIRECT3DDEVICE8 iface, UINT BackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface8** ppBackBuffer) { - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - *ppBackBuffer = (LPDIRECT3DSURFACE8) This->backBuffer; - TRACE("(%p) : BackBuf %d Type %d returning %p\n", This, BackBuffer, Type, *ppBackBuffer); - - if (BackBuffer > This->PresentParms.BackBufferCount - 1) { - FIXME("Only one backBuffer currently supported\n"); + if (NULL == ppD3D8) { return D3DERR_INVALIDCALL; } - - /* Note inc ref on returned surface */ - IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppBackBuffer); - - return D3D_OK; + hr = IWineD3DDevice_GetDirect3D(This->WineD3DDevice, &pWineD3D); + if (hr == D3D_OK && pWineD3D != NULL) + { + IWineD3DResource_GetParent((IWineD3DResource *)pWineD3D,(IUnknown **)ppD3D8); + IWineD3DResource_Release((IWineD3DResource *)pWineD3D); + } else { + FIXME("Call to IWineD3DDevice_GetDirect3D failed\n"); + *ppD3D8 = NULL; + } + TRACE("(%p) returning %p\b",This , *ppD3D8); + return hr; } -HRESULT WINAPI IDirect3DDevice8Impl_GetRasterStatus(LPDIRECT3DDEVICE8 iface, D3DRASTER_STATUS* pRasterStatus) { - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - FIXME("(%p) : stub\n", This); - return D3D_OK; -} -void WINAPI IDirect3DDevice8Impl_SetGammaRamp(LPDIRECT3DDEVICE8 iface, DWORD Flags, CONST D3DGAMMARAMP* pRamp) { - HDC hDC; + +HRESULT WINAPI IDirect3DDevice8Impl_GetDeviceCaps(LPDIRECT3DDEVICE8 iface, D3DCAPS8* pCaps) { IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + HRESULT hrc = D3D_OK; + WINED3DCAPS *pWineCaps; - FIXME("(%p) : pRamp@%p\n", This, pRamp); - hDC = GetDC(This->win_handle); - SetDeviceGammaRamp(hDC, (LPVOID) pRamp); - ReleaseDC(This->win_handle, hDC); - return; -} -void WINAPI IDirect3DDevice8Impl_GetGammaRamp(LPDIRECT3DDEVICE8 iface, D3DGAMMARAMP* pRamp) { - HDC hDC; - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + TRACE("(%p) : Relay pCaps %p \n", This, pCaps); + if(NULL == pCaps){ + return D3DERR_INVALIDCALL; + } + pWineCaps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINED3DCAPS)); + if(pWineCaps == NULL){ + return D3DERR_INVALIDCALL; /* well this is what MSDN says to return */ + } - FIXME("(%p) : pRamp@%p\n", This, pRamp); - hDC = GetDC(This->win_handle); - GetDeviceGammaRamp(hDC, pRamp); - ReleaseDC(This->win_handle, hDC); - return; + D3D8CAPSTOWINECAPS(pCaps, pWineCaps) + hrc = IWineD3DDevice_GetDeviceCaps(This->WineD3DDevice, pWineCaps); + HeapFree(GetProcessHeap(), 0, pWineCaps); + TRACE("Returning %p %p\n", This, pCaps); + return hrc; } -HRESULT WINAPI IDirect3DDevice8Impl_CreateTexture(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, UINT Levels, DWORD Usage, + +HRESULT WINAPI IDirect3DDevice8Impl_GetDisplayMode(LPDIRECT3DDEVICE8 iface, D3DDISPLAYMODE* pMode) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + TRACE("(%p) Relay\n", This); + return IWineD3DDevice_GetDisplayMode(This->WineD3DDevice, 0, pMode); +} + +HRESULT WINAPI IDirect3DDevice8Impl_GetCreationParameters(LPDIRECT3DDEVICE8 iface, D3DDEVICE_CREATION_PARAMETERS *pParameters) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + TRACE("(%p) Relay\n", This); + return IWineD3DDevice_GetCreationParameters(This->WineD3DDevice, pParameters); +} + +HRESULT WINAPI IDirect3DDevice8Impl_SetCursorProperties(LPDIRECT3DDEVICE8 iface, UINT XHotSpot, UINT YHotSpot, IDirect3DSurface8* pCursorBitmap) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + IDirect3DSurface8Impl *pSurface = (IDirect3DSurface8Impl*)pCursorBitmap; + TRACE("(%p) Relay\n", This); + return IWineD3DDevice_SetCursorProperties(This->WineD3DDevice,XHotSpot,YHotSpot,(IWineD3DSurface*)pSurface->wineD3DSurface); +} + +void WINAPI IDirect3DDevice8Impl_SetCursorPosition(LPDIRECT3DDEVICE8 iface, UINT XScreenSpace, UINT YScreenSpace, DWORD Flags) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + TRACE("(%p) Relay\n", This); + return IWineD3DDevice_SetCursorPosition(This->WineD3DDevice, XScreenSpace, YScreenSpace, Flags); +} + +BOOL WINAPI IDirect3DDevice8Impl_ShowCursor(LPDIRECT3DDEVICE8 iface, BOOL bShow) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + TRACE("(%p) Relay\n", This); + + return IWineD3DDevice_ShowCursor(This->WineD3DDevice, bShow); +} + +HRESULT WINAPI IDirect3DDevice8Impl_CreateAdditionalSwapChain(LPDIRECT3DDEVICE8 iface, D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DSwapChain8** pSwapChain) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + IDirect3DSwapChain8Impl* object; + HRESULT hrc = D3D_OK; + WINED3DPRESENT_PARAMETERS localParameters; + + TRACE("(%p) Relay\n", This); + + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); + if (NULL == object) { + FIXME("Allocation of memory failed\n"); + *pSwapChain = NULL; + return D3DERR_OUTOFVIDEOMEMORY; + } + object->ref = 1; + object->lpVtbl = &Direct3DSwapChain8_Vtbl; + + /* Allocate an associated WineD3DDevice object */ + localParameters.BackBufferWidth = &pPresentationParameters->BackBufferWidth; + localParameters.BackBufferHeight = &pPresentationParameters->BackBufferHeight; + localParameters.BackBufferFormat = (WINED3DFORMAT *)&pPresentationParameters->BackBufferFormat; + localParameters.BackBufferCount = &pPresentationParameters->BackBufferCount; + localParameters.MultiSampleType = &pPresentationParameters->MultiSampleType; + localParameters.MultiSampleQuality = NULL; /* d3d9 only */ + localParameters.SwapEffect = &pPresentationParameters->SwapEffect; + localParameters.hDeviceWindow = &pPresentationParameters->hDeviceWindow; + localParameters.Windowed = &pPresentationParameters->Windowed; + localParameters.EnableAutoDepthStencil = &pPresentationParameters->EnableAutoDepthStencil; + localParameters.AutoDepthStencilFormat = (WINED3DFORMAT *)&pPresentationParameters->AutoDepthStencilFormat; + localParameters.Flags = &pPresentationParameters->Flags; + localParameters.FullScreen_RefreshRateInHz = &pPresentationParameters->FullScreen_RefreshRateInHz; + localParameters.PresentationInterval = &pPresentationParameters->FullScreen_PresentationInterval; + + + hrc = IWineD3DDevice_CreateAdditionalSwapChain(This->WineD3DDevice, &localParameters, &object->wineD3DSwapChain, (IUnknown*)object, D3D8CB_CreateRenderTarget, D3D8CB_CreateDepthStencilSurface); + if (hrc != D3D_OK) { + FIXME("(%p) call to IWineD3DDevice_CreateAdditionalSwapChain failed\n", This); + HeapFree(GetProcessHeap(), 0 , object); + *pSwapChain = NULL; + }else{ + *pSwapChain = (IDirect3DSwapChain8 *)object; + } + TRACE("(%p) returning %p\n", This, *pSwapChain); + return hrc; +} + +HRESULT WINAPI IDirect3DDevice8Impl_Reset(LPDIRECT3DDEVICE8 iface, D3DPRESENT_PARAMETERS* pPresentationParameters) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + WINED3DPRESENT_PARAMETERS localParameters; + TRACE("(%p) Relay pPresentationParameters(%p)\n", This, pPresentationParameters); +/* FINDME: FIXME: */ + localParameters.BackBufferWidth = &pPresentationParameters->BackBufferWidth; + localParameters.BackBufferHeight = &pPresentationParameters->BackBufferHeight; + localParameters.BackBufferFormat = (WINED3DFORMAT *)&pPresentationParameters->BackBufferFormat; + localParameters.BackBufferCount = &pPresentationParameters->BackBufferCount; + localParameters.MultiSampleType = &pPresentationParameters->MultiSampleType; + localParameters.MultiSampleQuality = NULL; /* D3d9 only */ + localParameters.SwapEffect = &pPresentationParameters->SwapEffect; + localParameters.hDeviceWindow = &pPresentationParameters->hDeviceWindow; + localParameters.Windowed = &pPresentationParameters->Windowed; + localParameters.EnableAutoDepthStencil = &pPresentationParameters->EnableAutoDepthStencil; + localParameters.AutoDepthStencilFormat = (WINED3DFORMAT *)&pPresentationParameters->AutoDepthStencilFormat; + localParameters.Flags = &pPresentationParameters->Flags; + localParameters.FullScreen_RefreshRateInHz = &pPresentationParameters->FullScreen_RefreshRateInHz; + localParameters.PresentationInterval = &pPresentationParameters->FullScreen_PresentationInterval; + return IWineD3DDevice_Reset(This->WineD3DDevice, &localParameters); +} + +HRESULT WINAPI IDirect3DDevice8Impl_Present(LPDIRECT3DDEVICE8 iface, CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + TRACE("(%p) Relay\n", This); + return IWineD3DDevice_Present(This->WineD3DDevice, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion); +} + +HRESULT WINAPI IDirect3DDevice8Impl_GetBackBuffer(LPDIRECT3DDEVICE8 iface, UINT BackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface8** ppBackBuffer) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + IWineD3DSurface *retSurface = NULL; + HRESULT rc = D3D_OK; + + TRACE("(%p) Relay\n", This); + + rc = IWineD3DDevice_GetBackBuffer(This->WineD3DDevice, 0, BackBuffer, Type, (IWineD3DSurface **)&retSurface); + if (rc == D3D_OK && NULL != retSurface && NULL != ppBackBuffer) { + IWineD3DSurface_GetParent(retSurface, (IUnknown **)ppBackBuffer); + IWineD3DSurface_Release(retSurface); + } + return rc; +} + +HRESULT WINAPI IDirect3DDevice8Impl_GetRasterStatus(LPDIRECT3DDEVICE8 iface, D3DRASTER_STATUS* pRasterStatus) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + TRACE("(%p) Relay\n", This); + + return IWineD3DDevice_GetRasterStatus(This->WineD3DDevice, 0, pRasterStatus); +} + +void WINAPI IDirect3DDevice8Impl_SetGammaRamp(LPDIRECT3DDEVICE8 iface, DWORD Flags, CONST D3DGAMMARAMP* pRamp) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + TRACE("(%p) Relay\n", This); + + return IWineD3DDevice_SetGammaRamp(This->WineD3DDevice, 0, Flags, pRamp); +} + +void WINAPI IDirect3DDevice8Impl_GetGammaRamp(LPDIRECT3DDEVICE8 iface, D3DGAMMARAMP* pRamp) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + TRACE("(%p) Relay\n", This); + + return IWineD3DDevice_GetGammaRamp(This->WineD3DDevice, 0, pRamp); +} + +HRESULT WINAPI IDirect3DDevice8Impl_CreateTexture(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DTexture8 **ppTexture) { IDirect3DTexture8Impl *object; IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; @@ -687,7 +317,8 @@ HRESULT WINAPI IDirect3DDevice8Impl_CreateTexture(LPDIRECT3DDEVICE8 iface, UIN TRACE("(%p) Created Texture %p, %p\n",This,object,object->wineD3DTexture); return hrc; } -HRESULT WINAPI IDirect3DDevice8Impl_CreateVolumeTexture(LPDIRECT3DDEVICE8 iface, + +HRESULT WINAPI IDirect3DDevice8Impl_CreateVolumeTexture(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, UINT Depth, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DVolumeTexture8** ppVolumeTexture) { @@ -723,7 +354,8 @@ HRESULT WINAPI IDirect3DDevice8Impl_CreateVolumeTexture(LPDIRECT3DDEVICE8 ifac TRACE("(%p) returning %p\n", This , *ppVolumeTexture); return hrc; } -HRESULT WINAPI IDirect3DDevice8Impl_CreateCubeTexture(LPDIRECT3DDEVICE8 iface, UINT EdgeLength, UINT Levels, DWORD Usage, + +HRESULT WINAPI IDirect3DDevice8Impl_CreateCubeTexture(LPDIRECT3DDEVICE8 iface, UINT EdgeLength, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DCubeTexture8** ppCubeTexture) { IDirect3DCubeTexture8Impl *object; @@ -760,58 +392,68 @@ HRESULT WINAPI IDirect3DDevice8Impl_CreateCubeTexture(LPDIRECT3DDEVICE8 iface, TRACE("(%p) returning %p\n",This, *ppCubeTexture); return hr; } -HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexBuffer(LPDIRECT3DDEVICE8 iface, UINT Size, DWORD Usage, DWORD FVF, D3DPOOL Pool, IDirect3DVertexBuffer8** ppVertexBuffer) { - IDirect3DVertexBuffer8Impl *object; +HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexBuffer(LPDIRECT3DDEVICE8 iface, UINT Size, DWORD Usage, DWORD FVF, D3DPOOL Pool, IDirect3DVertexBuffer8** ppVertexBuffer) { + IDirect3DVertexBuffer8Impl *object; IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + HRESULT hrc = D3D_OK; /* Allocate the storage for the device */ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVertexBuffer8Impl)); + if (NULL == object) { + FIXME("Allocation of memory failed\n"); + *ppVertexBuffer = NULL; + return D3DERR_OUTOFVIDEOMEMORY; + } + object->lpVtbl = &Direct3DVertexBuffer8_Vtbl; - object->Device = This; - object->ResourceType = D3DRTYPE_VERTEXBUFFER; object->ref = 1; - object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Size); - object->currentDesc.Usage = Usage; - object->currentDesc.Pool = Pool; - object->currentDesc.FVF = FVF; - object->currentDesc.Size = Size; + hrc = IWineD3DDevice_CreateVertexBuffer(This->WineD3DDevice, Size, Usage, FVF, Pool, &(object->wineD3DVertexBuffer), NULL, (IUnknown *)object); - TRACE("(%p) : Size=%d, Usage=%ld, FVF=%lx, Pool=%d - Memory@%p, Iface@%p\n", This, Size, Usage, FVF, Pool, object->allocatedMemory, object); + if (D3D_OK != hrc) { - *ppVertexBuffer = (LPDIRECT3DVERTEXBUFFER8) object; - - return D3D_OK; + /* free up object */ + FIXME("(%p) call to IWineD3DDevice_CreateVertexBuffer failed\n", This); + HeapFree(GetProcessHeap(), 0, object); + *ppVertexBuffer = NULL; + } else { + *ppVertexBuffer = (LPDIRECT3DVERTEXBUFFER8) object; + } + return hrc; } -HRESULT WINAPI IDirect3DDevice8Impl_CreateIndexBuffer(LPDIRECT3DDEVICE8 iface, UINT Length, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DIndexBuffer8** ppIndexBuffer) { + +HRESULT WINAPI IDirect3DDevice8Impl_CreateIndexBuffer(LPDIRECT3DDEVICE8 iface, UINT Length, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DIndexBuffer8** ppIndexBuffer) { IDirect3DIndexBuffer8Impl *object; - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - TRACE("(%p) : Len=%d, Use=%lx, Format=(%u,%s), Pool=%d\n", This, Length, Usage, Format, debug_d3dformat(Format), Pool); + HRESULT hrc = D3D_OK; + TRACE("(%p) Relay\n", This); /* Allocate the storage for the device */ - object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DIndexBuffer8Impl)); + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); + if (NULL == object) { + FIXME("Allocation of memory failed\n"); + *ppIndexBuffer = NULL; + return D3DERR_OUTOFVIDEOMEMORY; + } + object->lpVtbl = &Direct3DIndexBuffer8_Vtbl; - object->Device = This; object->ref = 1; - object->ResourceType = D3DRTYPE_INDEXBUFFER; + TRACE("Calling wined3d create index buffer\n"); + hrc = IWineD3DDevice_CreateIndexBuffer(This->WineD3DDevice, Length, Usage, Format, Pool, &object->wineD3DIndexBuffer, NULL, (IUnknown *)object); - object->currentDesc.Type = D3DRTYPE_INDEXBUFFER; - object->currentDesc.Usage = Usage; - object->currentDesc.Pool = Pool; - object->currentDesc.Format = Format; - object->currentDesc.Size = Length; + if (D3D_OK != hrc) { - object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Length); - - TRACE("(%p) : Iface@%p allocatedMem @ %p\n", This, object, object->allocatedMemory); - - *ppIndexBuffer = (LPDIRECT3DINDEXBUFFER8) object; - - return D3D_OK; + /* free up object */ + FIXME("(%p) call to IWineD3DDevice_CreateIndexBuffer failed\n", This); + HeapFree(GetProcessHeap(), 0, object); + *ppIndexBuffer = NULL; + } else { + *ppIndexBuffer = (LPDIRECT3DINDEXBUFFER8)object; + } + return hrc; } -HRESULT WINAPI IDirect3DDevice8Impl_CreateSurface(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, D3DFORMAT Format, BOOL Lockable, BOOL Discard, UINT Level, IDirect3DSurface8 **ppSurface,D3DRESOURCETYPE Type, UINT Usage,D3DPOOL Pool, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality) { +HRESULT WINAPI IDirect3DDevice8Impl_CreateSurface(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, D3DFORMAT Format, BOOL Lockable, BOOL Discard, UINT Level, IDirect3DSurface8 **ppSurface,D3DRESOURCETYPE Type, UINT Usage,D3DPOOL Pool, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality) { HRESULT hrc; IDirect3DSurface8Impl *object; IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; @@ -857,12 +499,13 @@ HRESULT WINAPI IDirect3DDevice8Impl_CreateSurface(LPDIRECT3DDEVICE8 iface, UINT return hrc; } -HRESULT WINAPI IDirect3DDevice8Impl_CreateRenderTarget(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, BOOL Lockable, IDirect3DSurface8** ppSurface) { +HRESULT WINAPI IDirect3DDevice8Impl_CreateRenderTarget(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, BOOL Lockable, IDirect3DSurface8** ppSurface) { TRACE("Relay\n"); return IDirect3DDevice8Impl_CreateSurface(iface, Width, Height, Format, Lockable, FALSE /* Discard */, 0 /* Level */ , ppSurface, D3DRTYPE_SURFACE, D3DUSAGE_RENDERTARGET, D3DPOOL_DEFAULT, MultiSample, 0); } -HRESULT WINAPI IDirect3DDevice8Impl_CreateDepthStencilSurface(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, IDirect3DSurface8** ppSurface) { + +HRESULT WINAPI IDirect3DDevice8Impl_CreateDepthStencilSurface(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, IDirect3DSurface8** ppSurface) { TRACE("Relay\n"); /* TODO: Verify that Discard is false */ return IDirect3DDevice8Impl_CreateSurface(iface, Width, Height, Format, TRUE /* Lockable */, FALSE, 0 /* Level */ @@ -870,13 +513,13 @@ HRESULT WINAPI IDirect3DDevice8Impl_CreateDepthStencilSurface(LPDIRECT3DDEVICE D3DPOOL_DEFAULT, MultiSample, 0); } -HRESULT WINAPI IDirect3DDevice8Impl_CreateImageSurface(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, D3DFORMAT Format, IDirect3DSurface8** ppSurface) { +HRESULT WINAPI IDirect3DDevice8Impl_CreateImageSurface(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, D3DFORMAT Format, IDirect3DSurface8** ppSurface) { TRACE("Relay\n"); return IDirect3DDevice8Impl_CreateSurface(iface, Width, Height, Format, TRUE /* Loackable */ , FALSE /*Discard*/ , 0 /* Level */ , ppSurface, D3DRTYPE_SURFACE, 0 /* Usage (undefined/none) */ , D3DPOOL_SCRATCH, D3DMULTISAMPLE_NONE, 0 /* MultisampleQuality */); } -HRESULT WINAPI IDirect3DDevice8Impl_CopyRects(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8 *pSourceSurface, CONST RECT *pSourceRects, UINT cRects, IDirect3DSurface8 *pDestinationSurface, CONST POINT *pDestPoints) { +HRESULT WINAPI IDirect3DDevice8Impl_CopyRects(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8 *pSourceSurface, CONST RECT *pSourceRects, UINT cRects, IDirect3DSurface8 *pDestinationSurface, CONST POINT *pDestPoints) { IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; TRACE("(%p) Relay\n" , This); @@ -885,3263 +528,840 @@ HRESULT WINAPI IDirect3DDevice8Impl_CopyRects(LPDIRECT3DDEVICE8 iface, IDirect pSourceRects, cRects, pDestinationSurface == NULL ? NULL : ((IDirect3DSurface8Impl *)pDestinationSurface)->wineD3DSurface, pDestPoints); } -HRESULT WINAPI IDirect3DDevice8Impl_UpdateTexture(LPDIRECT3DDEVICE8 iface, IDirect3DBaseTexture8* pSourceTexture, IDirect3DBaseTexture8* pDestinationTexture) { +HRESULT WINAPI IDirect3DDevice8Impl_UpdateTexture(LPDIRECT3DDEVICE8 iface, IDirect3DBaseTexture8* pSourceTexture, IDirect3DBaseTexture8* pDestinationTexture) { IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; TRACE("(%p) Relay\n" , This); return IWineD3DDevice_UpdateTexture(This->WineD3DDevice, ((IDirect3DBaseTexture8Impl *)pSourceTexture)->wineD3DBaseTexture, ((IDirect3DBaseTexture8Impl *)pDestinationTexture)->wineD3DBaseTexture); } -HRESULT WINAPI IDirect3DDevice8Impl_GetFrontBuffer(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pDestSurface) { - HRESULT hr; - D3DLOCKED_RECT lockedRect; - RECT wantedRect; - GLint prev_store; - GLint prev_read; +HRESULT WINAPI IDirect3DDevice8Impl_GetFrontBuffer(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pDestSurface) { IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + IDirect3DSurface8Impl *destSurface = (IDirect3DSurface8Impl *)pDestSurface; - FIXME("(%p) : Should return whole screen, only returns GL context window in top left corner\n", This); + TRACE("(%p) Relay\n" , This); - if (D3DFMT_A8R8G8B8 != D3D8_SURFACE(((IDirect3DSurface8Impl*)pDestSurface))->resource.format) { - ERR("(%p) : surface(%p) has an invalid format\n", This, pDestSurface); - return D3DERR_INVALIDCALL; - } - - wantedRect.left = 0; - wantedRect.top = 0; - wantedRect.right = This->PresentParms.BackBufferWidth; - wantedRect.bottom = This->PresentParms.BackBufferHeight; - - hr = IDirect3DSurface8Impl_LockRect(pDestSurface, &lockedRect, &wantedRect, 0); - if (FAILED(hr)) { - ERR("(%p) : cannot lock surface\n", This); - return D3DERR_INVALIDCALL; + if (pDestSurface == NULL) { + WARN("(%p) : Caller passed NULL as pDestSurface returning D3DERR_INVALIDCALL\n", This); + return D3DERR_INVALIDCALL; } - ENTER_GL(); - - glFlush(); - vcheckGLcall("glFlush"); - glGetIntegerv(GL_READ_BUFFER, &prev_read); - vcheckGLcall("glIntegerv"); - glGetIntegerv(GL_PACK_SWAP_BYTES, &prev_store); - vcheckGLcall("glIntegerv"); - - glReadBuffer(GL_FRONT); - vcheckGLcall("glReadBuffer"); - glPixelStorei(GL_PACK_SWAP_BYTES, TRUE); - vcheckGLcall("glPixelStorei"); - /* stupid copy */ - { - unsigned long j; - for (j = 0; j < This->PresentParms.BackBufferHeight; ++j) { - glReadPixels(0, This->PresentParms.BackBufferHeight - j - 1, This->PresentParms.BackBufferWidth, 1, - GL_BGRA, GL_UNSIGNED_BYTE, ((char*) lockedRect.pBits) + (j * lockedRect.Pitch)); - vcheckGLcall("glReadPixels"); - } - } - glPixelStorei(GL_PACK_SWAP_BYTES, prev_store); - vcheckGLcall("glPixelStorei"); - glReadBuffer(prev_read); - vcheckGLcall("glReadBuffer"); - - LEAVE_GL(); - - hr = IDirect3DSurface8Impl_UnlockRect(pDestSurface); - return hr; + return IWineD3DDevice_GetFrontBufferData(This->WineD3DDevice, 0, destSurface->wineD3DSurface); } -HRESULT WINAPI IDirect3DDevice8Impl_SetRenderTarget(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pRenderTarget, IDirect3DSurface8* pNewZStencil) { - HRESULT hr = D3D_OK; - D3DVIEWPORT8 viewport; +HRESULT WINAPI IDirect3DDevice8Impl_SetRenderTarget(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pRenderTarget, IDirect3DSurface8* pNewZStencil) { IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + IDirect3DSurface8Impl *pSurface = (IDirect3DSurface8Impl *)pRenderTarget; + IDirect3DSurface8Impl *pZSurface = (IDirect3DSurface8Impl *)pNewZStencil; + TRACE("(%p) Relay\n" , This); - /* If pRenderTarget == NULL, it seems to default to back buffer */ - if (pRenderTarget == NULL) pRenderTarget = (IDirect3DSurface8*)This->backBuffer; - - /* For ease of code later on, handle a null depth as leave alone - - Have not tested real d3d for this case but doing this avoids - numerous null pointer checks */ - if (pNewZStencil == NULL) pNewZStencil = (IDirect3DSurface8*)This->stencilBufferTarget; + IWineD3DDevice_SetDepthStencilSurface(This->WineD3DDevice, NULL == pZSurface ? NULL : (IWineD3DSurface *)pZSurface->wineD3DSurface); - /* If we are trying to set what we already have, don't bother */ - if ((IDirect3DSurface8Impl*) pRenderTarget == This->renderTarget && (IDirect3DSurface8Impl*) pNewZStencil == This->stencilBufferTarget) { - TRACE("Trying to do a NOP SetRenderTarget operation\n"); - } else { - /* Otherwise, set the render target up */ - TRACE("(%p) : newRender@%p newZStencil@%p (default is backbuffer=(%p))\n", This, pRenderTarget, pNewZStencil, This->backBuffer); - IDirect3DDevice8Impl_CleanRender(iface); - hr = IDirect3DDevice8Impl_ActiveRender(iface, pRenderTarget, pNewZStencil); - } - - if (SUCCEEDED(hr)) { - /* Finally, reset the viewport as the MSDN states. */ - viewport.Height = D3D8_SURFACE(((IDirect3DSurface8Impl*)pRenderTarget))->currentDesc.Height; - viewport.Width = D3D8_SURFACE(((IDirect3DSurface8Impl*)pRenderTarget))->currentDesc.Width; - viewport.X = 0; - viewport.Y = 0; - viewport.MaxZ = 1.0f; - viewport.MinZ = 0.0f; - IDirect3DDevice8Impl_SetViewport(iface, &viewport); - } - - return hr; + return IWineD3DDevice_SetRenderTarget(This->WineD3DDevice, 0, (IWineD3DSurface *)pSurface->wineD3DSurface); } HRESULT WINAPI IDirect3DDevice8Impl_GetRenderTarget(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8** ppRenderTarget) { IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + HRESULT hr = D3D_OK; + IWineD3DSurface *pRenderTarget; - TRACE("(%p)->returning (%p) default is backbuffer=(%p)\n", This, This->renderTarget, This->backBuffer); - - *ppRenderTarget = (LPDIRECT3DSURFACE8) This->renderTarget; - IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppRenderTarget); - - return D3D_OK; + TRACE("(%p) Relay\n" , This); + + if (ppRenderTarget == NULL) { + return D3DERR_INVALIDCALL; + } + hr = IWineD3DDevice_GetRenderTarget(This->WineD3DDevice, 0, &pRenderTarget); + + if (hr == D3D_OK && pRenderTarget != NULL) { + IWineD3DResource_GetParent((IWineD3DResource *)pRenderTarget,(IUnknown**)ppRenderTarget); + IWineD3DResource_Release((IWineD3DResource *)pRenderTarget); + } else { + FIXME("Call to IWineD3DDevice_GetRenderTarget failed\n"); + *ppRenderTarget = NULL; + } + + return hr; } HRESULT WINAPI IDirect3DDevice8Impl_GetDepthStencilSurface(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8** ppZStencilSurface) { IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + HRESULT hr = D3D_OK; + IWineD3DSurface *pZStencilSurface; - TRACE("(%p)->(%p) default(%p)\n", This, This->stencilBufferTarget, This->depthStencilBuffer); - - /* Note inc ref on returned surface */ - *ppZStencilSurface = (LPDIRECT3DSURFACE8) This->stencilBufferTarget; - if (NULL != *ppZStencilSurface) IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppZStencilSurface); + TRACE("(%p) Relay\n" , This); + if(ppZStencilSurface == NULL){ + return D3DERR_INVALIDCALL; + } + + hr=IWineD3DDevice_GetDepthStencilSurface(This->WineD3DDevice,&pZStencilSurface); + if(hr == D3D_OK && pZStencilSurface != NULL){ + IWineD3DResource_GetParent((IWineD3DResource *)pZStencilSurface,(IUnknown**)ppZStencilSurface); + IWineD3DResource_Release((IWineD3DResource *)pZStencilSurface); + }else{ + FIXME("Call to IWineD3DDevice_GetRenderTarget failed\n"); + *ppZStencilSurface = NULL; + } return D3D_OK; } -HRESULT WINAPI IDirect3DDevice8Impl_BeginScene(LPDIRECT3DDEVICE8 iface) { +HRESULT WINAPI IDirect3DDevice8Impl_BeginScene(LPDIRECT3DDEVICE8 iface) { IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; return IWineD3DDevice_BeginScene(This->WineD3DDevice); } -HRESULT WINAPI IDirect3DDevice8Impl_EndScene(LPDIRECT3DDEVICE8 iface) { - IDirect3DBaseTexture8* cont = NULL; +HRESULT WINAPI IDirect3DDevice8Impl_EndScene(LPDIRECT3DDEVICE8 iface) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + TRACE("(%p) Relay\n" , This); + + return IWineD3DDevice_EndScene(This->WineD3DDevice); +} + +HRESULT WINAPI IDirect3DDevice8Impl_Clear(LPDIRECT3DDEVICE8 iface, DWORD Count, CONST D3DRECT* pRects, DWORD Flags, D3DCOLOR Color, float Z, DWORD Stencil) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + TRACE("(%p) Relay\n" , This); + + return IWineD3DDevice_Clear(This->WineD3DDevice, Count, pRects, Flags, Color, Z, Stencil); +} + +HRESULT WINAPI IDirect3DDevice8Impl_SetTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX* lpMatrix) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + TRACE("(%p) Relay\n" , This); + + return IWineD3DDevice_SetTransform(This->WineD3DDevice, State, lpMatrix); +} + +HRESULT WINAPI IDirect3DDevice8Impl_GetTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE State,D3DMATRIX* pMatrix) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + TRACE("(%p) Relay\n" , This); + + return IWineD3DDevice_GetTransform(This->WineD3DDevice, State, pMatrix); +} + +HRESULT WINAPI IDirect3DDevice8Impl_MultiplyTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX* pMatrix) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + TRACE("(%p) Relay\n" , This); + + return IWineD3DDevice_MultiplyTransform(This->WineD3DDevice, State, pMatrix); +} + +HRESULT WINAPI IDirect3DDevice8Impl_SetViewport(LPDIRECT3DDEVICE8 iface, CONST D3DVIEWPORT8* pViewport) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + TRACE("(%p) Relay\n" , This); + + return IWineD3DDevice_SetViewport(This->WineD3DDevice, (const WINED3DVIEWPORT *)pViewport); +} + +HRESULT WINAPI IDirect3DDevice8Impl_GetViewport(LPDIRECT3DDEVICE8 iface, D3DVIEWPORT8* pViewport) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + TRACE("(%p) Relay\n" , This); + + return IWineD3DDevice_GetViewport(This->WineD3DDevice, (WINED3DVIEWPORT *)pViewport); +} + +HRESULT WINAPI IDirect3DDevice8Impl_SetMaterial(LPDIRECT3DDEVICE8 iface, CONST D3DMATERIAL8* pMaterial) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + TRACE("(%p) Relay\n" , This); +/* FIXME: Verify that D3DMATERIAL8 ~= WINED3DMATERIAL */ + return IWineD3DDevice_SetMaterial(This->WineD3DDevice, (const WINED3DMATERIAL *)pMaterial); +} + +HRESULT WINAPI IDirect3DDevice8Impl_GetMaterial(LPDIRECT3DDEVICE8 iface, D3DMATERIAL8* pMaterial) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + TRACE("(%p) Relay\n" , This); +/* FIXME: Verify that D3DMATERIAL8 ~= WINED3DMATERIAL */ + return IWineD3DDevice_GetMaterial(This->WineD3DDevice, (WINED3DMATERIAL *)pMaterial); +} + +HRESULT WINAPI IDirect3DDevice8Impl_SetLight(LPDIRECT3DDEVICE8 iface, DWORD Index, CONST D3DLIGHT8* pLight) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + TRACE("(%p) Relay\n" , This); +/* FIXME: Verify that D3DLIGHT8 ~= WINED3DLIGHT */ + return IWineD3DDevice_SetLight(This->WineD3DDevice, Index, (const WINED3DLIGHT *)pLight); +} + +HRESULT WINAPI IDirect3DDevice8Impl_GetLight(LPDIRECT3DDEVICE8 iface, DWORD Index,D3DLIGHT8* pLight) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + TRACE("(%p) Relay\n" , This); +/* FIXME: Verify that D3DLIGHT8 ~= WINED3DLIGHT */ + return IWineD3DDevice_GetLight(This->WineD3DDevice, Index, (WINED3DLIGHT *)pLight); +} + +HRESULT WINAPI IDirect3DDevice8Impl_LightEnable(LPDIRECT3DDEVICE8 iface, DWORD Index,BOOL Enable) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + TRACE("(%p) Relay\n" , This); + + return IWineD3DDevice_SetLightEnable(This->WineD3DDevice, Index, Enable); +} + +HRESULT WINAPI IDirect3DDevice8Impl_GetLightEnable(LPDIRECT3DDEVICE8 iface, DWORD Index,BOOL* pEnable) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + TRACE("(%p) Relay\n" , This); + + return IWineD3DDevice_GetLightEnable(This->WineD3DDevice, Index, pEnable); +} + +HRESULT WINAPI IDirect3DDevice8Impl_SetClipPlane(LPDIRECT3DDEVICE8 iface, DWORD Index,CONST float* pPlane) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + TRACE("(%p) Relay\n" , This); + + return IWineD3DDevice_SetClipPlane(This->WineD3DDevice, Index, pPlane); +} + +HRESULT WINAPI IDirect3DDevice8Impl_GetClipPlane(LPDIRECT3DDEVICE8 iface, DWORD Index,float* pPlane) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + TRACE("(%p) Relay\n" , This); + + return IWineD3DDevice_GetClipPlane(This->WineD3DDevice, Index, pPlane); +} + +HRESULT WINAPI IDirect3DDevice8Impl_SetRenderState(LPDIRECT3DDEVICE8 iface, D3DRENDERSTATETYPE State,DWORD Value) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + TRACE("(%p) Relay\n" , This); + + return IWineD3DDevice_SetRenderState(This->WineD3DDevice, State, Value); +} + +HRESULT WINAPI IDirect3DDevice8Impl_GetRenderState(LPDIRECT3DDEVICE8 iface, D3DRENDERSTATETYPE State,DWORD* pValue) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + TRACE("(%p) Relay\n" , This); + + return IWineD3DDevice_GetRenderState(This->WineD3DDevice, State, pValue); +} + +HRESULT WINAPI IDirect3DDevice8Impl_BeginStateBlock(LPDIRECT3DDEVICE8 iface) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + + TRACE("(%p)\n", This); + + return IWineD3DDevice_BeginStateBlock(This->WineD3DDevice); +} + +HRESULT WINAPI IDirect3DDevice8Impl_EndStateBlock(LPDIRECT3DDEVICE8 iface, DWORD* pToken) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; HRESULT hr; - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - TRACE("(%p)\n", This); + IWineD3DStateBlock* wineD3DStateBlock; + IDirect3DStateBlock8Impl* object; - ENTER_GL(); + TRACE("(%p) Relay\n", This); - glFlush(); - checkGLcall("glFlush"); - -#if 0 /* Useful for debugging sometimes! */ - printf("Hit Enter ...\n"); - getchar(); -#endif - if ((This->frontBuffer != This->renderTarget) && (This->backBuffer != This->renderTarget)) { -#if 0 - GLenum prev_read; - glGetIntegerv(GL_READ_BUFFER, &prev_read); - vcheckGLcall("glIntegerv"); - glReadBuffer(GL_FRONT); - vcheckGLcall("glReadBuffer"); - { - long j; - long pitch = This->renderTarget->myDesc.Width * This->renderTarget->bytesPerPixel; - - if (This->renderTarget->myDesc.Format == D3DFMT_DXT1) /* DXT1 is half byte per pixel */ - pitch = pitch / 2; - - for (j = 0; j < This->renderTarget->myDesc.Height; ++j) { - glReadPixels(0, - This->renderTarget->myDesc.Height - j - 1, - This->renderTarget->myDesc.Width, - 1, - D3DFmt2GLFmt(This, This->renderTarget->myDesc.Format), - D3DFmt2GLType(This, This->renderTarget->myDesc.Format), - This->renderTarget->allocatedMemory + j * pitch); - vcheckGLcall("glReadPixels"); - } - } - glReadBuffer(prev_read); - vcheckGLcall("glReadBuffer"); -#endif - - hr = IDirect3DSurface8_GetContainer((LPDIRECT3DSURFACE8) This->renderTarget, &IID_IDirect3DBaseTexture8, (void**) &cont); - if (SUCCEEDED(hr) && NULL != cont) { - /** always dirtify for now. we must find a better way to see that surface have been modified */ - D3D8_SURFACE(This->renderTarget)->inPBuffer = TRUE; - D3D8_SURFACE(This->renderTarget)->inTexture = FALSE; - IDirect3DBaseTexture8Impl_SetDirty(cont, TRUE); - IDirect3DBaseTexture8_PreLoad(cont); - D3D8_SURFACE(This->renderTarget)->inPBuffer = FALSE; - IDirect3DBaseTexture8Impl_Release(cont); - cont = NULL; - } - } - - LEAVE_GL(); - return D3D_OK; -} -HRESULT WINAPI IDirect3DDevice8Impl_Clear(LPDIRECT3DDEVICE8 iface, DWORD Count, CONST D3DRECT* pRects, DWORD Flags, D3DCOLOR Color, float Z, DWORD Stencil) { - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - - /* TODO: From MSDN This method fails if you specify the D3DCLEAR_ZBUFFER or D3DCLEAR_STENCIL flags when the - render target does not have an attached depth buffer. Similarly, if you specify the D3DCLEAR_STENCIL flag - when the depth-buffer format does not contain stencil buffer information, this method fails. */ - GLbitfield glMask = 0; - GLboolean old_ztest; - GLfloat old_z_clear_value; - GLint old_stencil_clear_value; - GLfloat old_color_clear_value[4]; - unsigned int i; - CONST D3DRECT* curRect; - - TRACE("(%p) Count (%ld), pRects (%p), Flags (%lx), Z (%f), Stencil (%ld)\n", This, - Count, pRects, Flags, Z, Stencil); - - ENTER_GL(); - glEnable(GL_SCISSOR_TEST); - checkGLcall("glEnable GL_SCISSOR_TEST"); - if (Count > 0 && pRects) { - curRect = pRects; - } else { - curRect = NULL; - } - - /* Only set the values up once, as they are not changing */ - if (Flags & D3DCLEAR_STENCIL) { - glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &old_stencil_clear_value); - glClearStencil(Stencil); - checkGLcall("glClearStencil"); - glMask = glMask | GL_STENCIL_BUFFER_BIT; - glStencilMask(0xFFFFFFFF); - } - - if (Flags & D3DCLEAR_ZBUFFER) { - glGetBooleanv(GL_DEPTH_WRITEMASK, &old_ztest); - glDepthMask(GL_TRUE); - glGetFloatv(GL_DEPTH_CLEAR_VALUE, &old_z_clear_value); - glClearDepth(Z); - checkGLcall("glClearDepth"); - glMask = glMask | GL_DEPTH_BUFFER_BIT; - } - - if (Flags & D3DCLEAR_TARGET) { - TRACE("Clearing screen with glClear to color %lx\n", Color); - glGetFloatv(GL_COLOR_CLEAR_VALUE, old_color_clear_value); - glClearColor(D3DCOLOR_R(Color), - D3DCOLOR_G(Color), - D3DCOLOR_B(Color), - D3DCOLOR_A(Color)); - checkGLcall("glClearColor"); - - /* Clear ALL colors! */ - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - glMask = glMask | GL_COLOR_BUFFER_BIT; - } - - /* Now process each rect in turn */ - for (i = 0; i < Count || i == 0; i++) { - - if (curRect) { - /* Note gl uses lower left, width/height */ - TRACE("(%p) %p Rect=(%ld,%ld)->(%ld,%ld) glRect=(%ld,%ld), len=%ld, hei=%ld\n", This, curRect, - curRect->x1, curRect->y1, curRect->x2, curRect->y2, - curRect->x1, (D3D8_SURFACE(This->renderTarget)->currentDesc.Height - curRect->y2), - curRect->x2 - curRect->x1, curRect->y2 - curRect->y1); - glScissor(curRect->x1, (D3D8_SURFACE(This->renderTarget)->currentDesc.Height - curRect->y2), - curRect->x2 - curRect->x1, curRect->y2 - curRect->y1); - checkGLcall("glScissor"); - } else { - glScissor(This->StateBlock->viewport.X, - (D3D8_SURFACE(This->renderTarget)->currentDesc.Height - (This->StateBlock->viewport.Y + This->StateBlock->viewport.Height)), - This->StateBlock->viewport.Width, - This->StateBlock->viewport.Height); - checkGLcall("glScissor"); - } - - /* Clear the selected rectangle (or full screen) */ - glClear(glMask); - checkGLcall("glClear"); - - /* Step to the next rectangle */ - if (curRect) curRect = curRect + sizeof(D3DRECT); - } - - /* Restore the old values (why..?) */ - if (Flags & D3DCLEAR_STENCIL) { - glClearStencil(old_stencil_clear_value); - glStencilMask(This->StateBlock->renderstate[D3DRS_STENCILWRITEMASK]); - } - if (Flags & D3DCLEAR_ZBUFFER) { - glDepthMask(old_ztest); - glClearDepth(old_z_clear_value); - } - if (Flags & D3DCLEAR_TARGET) { - glClearColor(old_color_clear_value[0], - old_color_clear_value[1], - old_color_clear_value[2], - old_color_clear_value[3]); - glColorMask(This->StateBlock->renderstate[D3DRS_COLORWRITEENABLE] & D3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE, - This->StateBlock->renderstate[D3DRS_COLORWRITEENABLE] & D3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE, - This->StateBlock->renderstate[D3DRS_COLORWRITEENABLE] & D3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE, - This->StateBlock->renderstate[D3DRS_COLORWRITEENABLE] & D3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE); - } - - glDisable(GL_SCISSOR_TEST); - checkGLcall("glDisable"); - LEAVE_GL(); - - return D3D_OK; -} -HRESULT WINAPI IDirect3DDevice8Impl_SetTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE d3dts, CONST D3DMATRIX* lpmatrix) { - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - unsigned int k; - - /* Most of this routine, comments included copied from ddraw tree initially: */ - TRACE("(%p) : State=%d\n", This, d3dts); - - /* Handle recording of state blocks */ - if (This->isRecordingState) { - TRACE("Recording... not performing anything\n"); - This->UpdateStateBlock->Changed.transform[d3dts] = TRUE; - This->UpdateStateBlock->Set.transform[d3dts] = TRUE; - memcpy(&This->UpdateStateBlock->transforms[d3dts], lpmatrix, sizeof(D3DMATRIX)); - return D3D_OK; - } - - /* - * if the new matrix is the same as the current one, - * we cut off any further processing. this seems to be a reasonable - * optimization because as was noticed, some apps (warcraft3 for example) - * tend towards setting the same matrix repeatedly for some dumb reason. - * - * From here on we assume that the new matrix is different, wherever it matters - * but note + /* Tell wineD3D to endstatablock before anything else (in case we run out + * of memory later and cause locking problems) */ - if (!memcmp(&This->StateBlock->transforms[d3dts].u.m[0][0], lpmatrix, sizeof(D3DMATRIX))) { - TRACE("The app is setting the same matrix over again\n"); - return D3D_OK; - } else { - conv_mat(lpmatrix, &This->StateBlock->transforms[d3dts].u.m[0][0]); + hr = IWineD3DDevice_EndStateBlock(This->WineD3DDevice , &wineD3DStateBlock); + if (hr != D3D_OK) { + FIXME("IWineD3DDevice_EndStateBlock returned an error\n"); + return hr; } - /* - ScreenCoord = ProjectionMat * ViewMat * WorldMat * ObjectCoord - where ViewMat = Camera space, WorldMat = world space. + /* allocate a new IDirectD3DStateBlock */ + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY ,sizeof(IDirect3DStateBlock8Impl)); + object->ref = 1; + object->lpVtbl = &Direct3DStateBlock8_Vtbl; - In OpenGL, camera and world space is combined into GL_MODELVIEW - matrix. The Projection matrix stay projection matrix. - */ + object->wineD3DStateBlock = wineD3DStateBlock; - /* Capture the times we can just ignore the change */ - if (d3dts == D3DTS_WORLDMATRIX(0)) { - This->modelview_valid = FALSE; - return D3D_OK; + *pToken = (DWORD)object; + TRACE("(%p)Returning %p %p\n", This, object, wineD3DStateBlock); - } else if (d3dts == D3DTS_PROJECTION) { - This->proj_valid = FALSE; - return D3D_OK; - - } else if (d3dts >= D3DTS_WORLDMATRIX(1) && d3dts <= D3DTS_WORLDMATRIX(255)) { /* Indexed Vertex Blending Matrices 256 -> 511 */ - /* Use arb_vertex_blend or NV_VERTEX_WEIGHTING? */ - FIXME("D3DTS_WORLDMATRIX(1..255) not handled\n"); - return D3D_OK; - } - - /* Chances are we really are going to have to change a matrix */ - ENTER_GL(); - - if (d3dts >= D3DTS_TEXTURE0 && d3dts <= D3DTS_TEXTURE7) { /* handle texture matrices */ - if (d3dts < GL_LIMITS(textures)) { - int tex = d3dts - D3DTS_TEXTURE0; -#if defined(GL_VERSION_1_3) - glActiveTexture(GL_TEXTURE0 + tex); - checkGLcall("glActiveTexture"); -#else - glActiveTextureARB(GL_TEXTURE0_ARB + tex); - checkGLcall("glActiveTextureARB"); -#endif - set_texture_matrix((const float *)lpmatrix, This->UpdateStateBlock->texture_state[tex][D3DTSS_TEXTURETRANSFORMFLAGS]); - } - - } else if (d3dts == D3DTS_VIEW) { /* handle the VIEW matrice */ - - PLIGHTINFOEL *lightChain = NULL; - float identity[16] = {1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1}; - This->modelview_valid = FALSE; - This->view_ident = !memcmp(lpmatrix, identity, 16*sizeof(float)); - glMatrixMode(GL_MODELVIEW); - checkGLcall("glMatrixMode(GL_MODELVIEW)"); - glPushMatrix(); - glLoadMatrixf((const float *)lpmatrix); - checkGLcall("glLoadMatrixf(...)"); - - /* If we are changing the View matrix, reset the light and clipping planes to the new view - * NOTE: We have to reset the positions even if the light/plane is not currently - * enabled, since the call to enable it will not reset the position. - * NOTE2: Apparently texture transforms do NOT need reapplying - */ - - /* Reset lights */ - lightChain = This->StateBlock->lights; - while (lightChain && lightChain->glIndex != -1) { - glLightfv(GL_LIGHT0 + lightChain->glIndex, GL_POSITION, lightChain->lightPosn); - checkGLcall("glLightfv posn"); - glLightfv(GL_LIGHT0 + lightChain->glIndex, GL_SPOT_DIRECTION, lightChain->lightDirn); - checkGLcall("glLightfv dirn"); - lightChain = lightChain->next; - } - /* Reset Clipping Planes if clipping is enabled */ - for (k = 0; k < GL_LIMITS(clipplanes); k++) { - glClipPlane(GL_CLIP_PLANE0 + k, This->StateBlock->clipplane[k]); - checkGLcall("glClipPlane"); - } - glPopMatrix(); - - } else { /* What was requested!?? */ - WARN("invalid matrix specified: %i\n", d3dts); - - } - - /* Release lock, all done */ - LEAVE_GL(); - return D3D_OK; - -} -HRESULT WINAPI IDirect3DDevice8Impl_GetTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE State,D3DMATRIX* pMatrix) { - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - TRACE("(%p) : for State %d\n", This, State); - memcpy(pMatrix, &This->StateBlock->transforms[State], sizeof(D3DMATRIX)); - return D3D_OK; + return hr; } -HRESULT WINAPI IDirect3DDevice8Impl_MultiplyTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX* pMatrix) { - D3DMATRIX *mat = NULL; - D3DMATRIX temp; +HRESULT WINAPI IDirect3DDevice8Impl_ApplyStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) { + IDirect3DStateBlock8Impl *pSB = (IDirect3DStateBlock8Impl*) Token; + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - /* Note: Using UpdateStateBlock means it would be recorded in a state block change, - but works regardless of recording being on. - If this is found to be wrong, change to StateBlock. */ - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - TRACE("(%p) : For state %u\n", This, State); + TRACE("(%p) %p Relay \n", This, pSB); - if (State < HIGHEST_TRANSFORMSTATE) - { - mat = &This->UpdateStateBlock->transforms[State]; - } else { - FIXME("Unhandled transform state!!\n"); - } - - /* Copied from ddraw code: */ - temp.u.s._11 = (mat->u.s._11 * pMatrix->u.s._11) + (mat->u.s._21 * pMatrix->u.s._12) + (mat->u.s._31 * pMatrix->u.s._13) + (mat->u.s._41 * pMatrix->u.s._14); - temp.u.s._21 = (mat->u.s._11 * pMatrix->u.s._21) + (mat->u.s._21 * pMatrix->u.s._22) + (mat->u.s._31 * pMatrix->u.s._23) + (mat->u.s._41 * pMatrix->u.s._24); - temp.u.s._31 = (mat->u.s._11 * pMatrix->u.s._31) + (mat->u.s._21 * pMatrix->u.s._32) + (mat->u.s._31 * pMatrix->u.s._33) + (mat->u.s._41 * pMatrix->u.s._34); - temp.u.s._41 = (mat->u.s._11 * pMatrix->u.s._41) + (mat->u.s._21 * pMatrix->u.s._42) + (mat->u.s._31 * pMatrix->u.s._43) + (mat->u.s._41 * pMatrix->u.s._44); - - temp.u.s._12 = (mat->u.s._12 * pMatrix->u.s._11) + (mat->u.s._22 * pMatrix->u.s._12) + (mat->u.s._32 * pMatrix->u.s._13) + (mat->u.s._42 * pMatrix->u.s._14); - temp.u.s._22 = (mat->u.s._12 * pMatrix->u.s._21) + (mat->u.s._22 * pMatrix->u.s._22) + (mat->u.s._32 * pMatrix->u.s._23) + (mat->u.s._42 * pMatrix->u.s._24); - temp.u.s._32 = (mat->u.s._12 * pMatrix->u.s._31) + (mat->u.s._22 * pMatrix->u.s._32) + (mat->u.s._32 * pMatrix->u.s._33) + (mat->u.s._42 * pMatrix->u.s._34); - temp.u.s._42 = (mat->u.s._12 * pMatrix->u.s._41) + (mat->u.s._22 * pMatrix->u.s._42) + (mat->u.s._32 * pMatrix->u.s._43) + (mat->u.s._42 * pMatrix->u.s._44); - - temp.u.s._13 = (mat->u.s._13 * pMatrix->u.s._11) + (mat->u.s._23 * pMatrix->u.s._12) + (mat->u.s._33 * pMatrix->u.s._13) + (mat->u.s._43 * pMatrix->u.s._14); - temp.u.s._23 = (mat->u.s._13 * pMatrix->u.s._21) + (mat->u.s._23 * pMatrix->u.s._22) + (mat->u.s._33 * pMatrix->u.s._23) + (mat->u.s._43 * pMatrix->u.s._24); - temp.u.s._33 = (mat->u.s._13 * pMatrix->u.s._31) + (mat->u.s._23 * pMatrix->u.s._32) + (mat->u.s._33 * pMatrix->u.s._33) + (mat->u.s._43 * pMatrix->u.s._34); - temp.u.s._43 = (mat->u.s._13 * pMatrix->u.s._41) + (mat->u.s._23 * pMatrix->u.s._42) + (mat->u.s._33 * pMatrix->u.s._43) + (mat->u.s._43 * pMatrix->u.s._44); - - temp.u.s._14 = (mat->u.s._14 * pMatrix->u.s._11) + (mat->u.s._24 * pMatrix->u.s._12) + (mat->u.s._34 * pMatrix->u.s._13) + (mat->u.s._44 * pMatrix->u.s._14); - temp.u.s._24 = (mat->u.s._14 * pMatrix->u.s._21) + (mat->u.s._24 * pMatrix->u.s._22) + (mat->u.s._34 * pMatrix->u.s._23) + (mat->u.s._44 * pMatrix->u.s._24); - temp.u.s._34 = (mat->u.s._14 * pMatrix->u.s._31) + (mat->u.s._24 * pMatrix->u.s._32) + (mat->u.s._34 * pMatrix->u.s._33) + (mat->u.s._44 * pMatrix->u.s._34); - temp.u.s._44 = (mat->u.s._14 * pMatrix->u.s._41) + (mat->u.s._24 * pMatrix->u.s._42) + (mat->u.s._34 * pMatrix->u.s._43) + (mat->u.s._44 * pMatrix->u.s._44); - - /* Apply change via set transform - will reapply to eg. lights this way */ - IDirect3DDevice8Impl_SetTransform(iface, State, &temp); - return D3D_OK; + return IWineD3DStateBlock_Apply(pSB->wineD3DStateBlock); } -HRESULT WINAPI IDirect3DDevice8Impl_SetViewport(LPDIRECT3DDEVICE8 iface, CONST D3DVIEWPORT8* pViewport) { + +HRESULT WINAPI IDirect3DDevice8Impl_CaptureStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) { + IDirect3DStateBlock8Impl* pSB = (IDirect3DStateBlock8Impl *)Token; IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - TRACE("(%p)\n", This); - This->UpdateStateBlock->Changed.viewport = TRUE; - This->UpdateStateBlock->Set.viewport = TRUE; - memcpy(&This->UpdateStateBlock->viewport, pViewport, sizeof(D3DVIEWPORT8)); + TRACE("(%p) %p Relay \n", This, pSB); - /* Handle recording of state blocks */ - if (This->isRecordingState) { - TRACE("Recording... not performing anything\n"); - return D3D_OK; - } - - ENTER_GL(); - - TRACE("(%p) : x=%ld, y=%ld, wid=%ld, hei=%ld, minz=%f, maxz=%f\n", This, - pViewport->X, pViewport->Y, pViewport->Width, pViewport->Height, pViewport->MinZ, pViewport->MaxZ); - - glDepthRange(pViewport->MinZ, pViewport->MaxZ); - checkGLcall("glDepthRange"); - /* Note: GL requires lower left, DirectX supplies upper left */ - glViewport(pViewport->X, (D3D8_SURFACE(This->renderTarget)->currentDesc.Height - (pViewport->Y + pViewport->Height)), - pViewport->Width, pViewport->Height); - checkGLcall("glViewport"); - - LEAVE_GL(); - - return D3D_OK; - -} -HRESULT WINAPI IDirect3DDevice8Impl_GetViewport(LPDIRECT3DDEVICE8 iface, D3DVIEWPORT8* pViewport) { - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - TRACE("(%p)\n", This); - memcpy(pViewport, &This->StateBlock->viewport, sizeof(D3DVIEWPORT8)); - return D3D_OK; + return IWineD3DStateBlock_Capture(pSB->wineD3DStateBlock); } -HRESULT WINAPI IDirect3DDevice8Impl_SetMaterial(LPDIRECT3DDEVICE8 iface, CONST D3DMATERIAL8* pMaterial) { +HRESULT WINAPI IDirect3DDevice8Impl_DeleteStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) { + IDirect3DStateBlock8Impl* pSB = (IDirect3DStateBlock8Impl *)Token; IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - This->UpdateStateBlock->Changed.material = TRUE; - This->UpdateStateBlock->Set.material = TRUE; - memcpy(&This->UpdateStateBlock->material, pMaterial, sizeof(D3DMATERIAL8)); + TRACE("(%p) Relay \n", This); - /* Handle recording of state blocks */ - if (This->isRecordingState) { - TRACE("Recording... not performing anything\n"); - return D3D_OK; - } + while(IUnknown_Release((IUnknown *)pSB)); - ENTER_GL(); - TRACE("(%p) : Diffuse (%f,%f,%f,%f)\n", This, pMaterial->Diffuse.r, pMaterial->Diffuse.g, pMaterial->Diffuse.b, pMaterial->Diffuse.a); - TRACE("(%p) : Ambient (%f,%f,%f,%f)\n", This, pMaterial->Ambient.r, pMaterial->Ambient.g, pMaterial->Ambient.b, pMaterial->Ambient.a); - TRACE("(%p) : Specular (%f,%f,%f,%f)\n", This, pMaterial->Specular.r, pMaterial->Specular.g, pMaterial->Specular.b, pMaterial->Specular.a); - TRACE("(%p) : Emissive (%f,%f,%f,%f)\n", This, pMaterial->Emissive.r, pMaterial->Emissive.g, pMaterial->Emissive.b, pMaterial->Emissive.a); - TRACE("(%p) : Power (%f)\n", This, pMaterial->Power); - - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float*) &This->UpdateStateBlock->material.Ambient); - checkGLcall("glMaterialfv"); - glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float*) &This->UpdateStateBlock->material.Diffuse); - checkGLcall("glMaterialfv"); - - /* Only change material color if specular is enabled, otherwise it is set to black */ - if (This->StateBlock->renderstate[D3DRS_SPECULARENABLE]) { - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float*) &This->UpdateStateBlock->material.Specular); - checkGLcall("glMaterialfv"); - } else { - float black[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]); - checkGLcall("glMaterialfv"); - } - glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float*) &This->UpdateStateBlock->material.Emissive); - checkGLcall("glMaterialfv"); - glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, This->UpdateStateBlock->material.Power); - checkGLcall("glMaterialf"); - - LEAVE_GL(); return D3D_OK; } -HRESULT WINAPI IDirect3DDevice8Impl_GetMaterial(LPDIRECT3DDEVICE8 iface, D3DMATERIAL8* pMaterial) { + +HRESULT WINAPI IDirect3DDevice8Impl_CreateStateBlock(LPDIRECT3DDEVICE8 iface, D3DSTATEBLOCKTYPE Type, DWORD* pToken) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + IDirect3DStateBlock8Impl *object; + HRESULT hrc = D3D_OK; + + TRACE("(%p) Relay\n", This); + + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DStateBlock8Impl)); + if (NULL == object) { + FIXME("(%p) Failed to allocate %d bytes\n", This, sizeof(IDirect3DStateBlock8Impl)); + *pToken = 0; + return E_OUTOFMEMORY; + } + object->lpVtbl = &Direct3DStateBlock8_Vtbl; + object->ref = 1; + + hrc = IWineD3DDevice_CreateStateBlock(This->WineD3DDevice, (WINED3DSTATEBLOCKTYPE)Type, &object->wineD3DStateBlock, (IUnknown *)object); + if(D3D_OK != hrc){ + FIXME("(%p) Call to IWineD3DDevice_CreateStateBlock failed.\n", This); + HeapFree(GetProcessHeap(), 0, object); + *pToken = 0; + } else { + *pToken = (DWORD)object; + } + TRACE("(%p) returning token (ptr to stateblock) of %p\n", This, object); + + return hrc; +} + +HRESULT WINAPI IDirect3DDevice8Impl_SetClipStatus(LPDIRECT3DDEVICE8 iface, CONST D3DCLIPSTATUS8* pClipStatus) { IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - memcpy(pMaterial, &This->UpdateStateBlock->material, sizeof (D3DMATERIAL8)); - TRACE("(%p) : Diffuse (%f,%f,%f,%f)\n", This, pMaterial->Diffuse.r, pMaterial->Diffuse.g, pMaterial->Diffuse.b, pMaterial->Diffuse.a); - TRACE("(%p) : Ambient (%f,%f,%f,%f)\n", This, pMaterial->Ambient.r, pMaterial->Ambient.g, pMaterial->Ambient.b, pMaterial->Ambient.a); - TRACE("(%p) : Specular (%f,%f,%f,%f)\n", This, pMaterial->Specular.r, pMaterial->Specular.g, pMaterial->Specular.b, pMaterial->Specular.a); - TRACE("(%p) : Emissive (%f,%f,%f,%f)\n", This, pMaterial->Emissive.r, pMaterial->Emissive.g, pMaterial->Emissive.b, pMaterial->Emissive.a); - TRACE("(%p) : Power (%f)\n", This, pMaterial->Power); - return D3D_OK; + TRACE("(%p) Relay\n" , This); +/* FIXME: Verify that D3DCLIPSTATUS8 ~= WINED3DCLIPSTATUS */ + return IWineD3DDevice_SetClipStatus(This->WineD3DDevice, (const WINED3DCLIPSTATUS *)pClipStatus); } -/* Note lights are real special cases. Although the device caps state only eg. 8 are supported, - you can reference any indexes you want as long as that number max are enabled are any - one point in time! Therefore since the indexes can be anything, we need a linked list of them. - However, this causes stateblock problems. When capturing the state block, I duplicate the list, - but when recording, just build a chain pretty much of commands to be replayed. */ - -HRESULT WINAPI IDirect3DDevice8Impl_SetLight(LPDIRECT3DDEVICE8 iface, DWORD Index, CONST D3DLIGHT8* pLight) { - float rho; - PLIGHTINFOEL *object, *temp; - +HRESULT WINAPI IDirect3DDevice8Impl_GetClipStatus(LPDIRECT3DDEVICE8 iface, D3DCLIPSTATUS8* pClipStatus) { IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - TRACE("(%p) : Idx(%ld), pLight(%p)\n", This, Index, pLight); + TRACE("(%p) Relay\n" , This); - /* If recording state block, just add to end of lights chain */ - if (This->isRecordingState) { - object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PLIGHTINFOEL)); - if (NULL == object) { - return D3DERR_OUTOFVIDEOMEMORY; - } - memcpy(&object->OriginalParms, pLight, sizeof(D3DLIGHT8)); - object->OriginalIndex = Index; - object->glIndex = -1; - object->changed = TRUE; - - /* Add to the END of the chain of lights changes to be replayed */ - if (This->UpdateStateBlock->lights == NULL) { - This->UpdateStateBlock->lights = object; - } else { - temp = This->UpdateStateBlock->lights; - while (temp->next != NULL) temp=temp->next; - temp->next = object; - } - TRACE("Recording... not performing anything more\n"); - return D3D_OK; - } - - /* Ok, not recording any longer so do real work */ - object = This->StateBlock->lights; - while (object != NULL && object->OriginalIndex != Index) object = object->next; - - /* If we didn't find it in the list of lights, time to add it */ - if (object == NULL) { - PLIGHTINFOEL *insertAt,*prevPos; - - object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PLIGHTINFOEL)); - if (NULL == object) { - return D3DERR_OUTOFVIDEOMEMORY; - } - object->OriginalIndex = Index; - object->glIndex = -1; - - /* Add it to the front of list with the idea that lights will be changed as needed - BUT after any lights currently assigned GL indexes */ - insertAt = This->StateBlock->lights; - prevPos = NULL; - while (insertAt != NULL && insertAt->glIndex != -1) { - prevPos = insertAt; - insertAt = insertAt->next; - } - - if (insertAt == NULL && prevPos == NULL) { /* Start of list */ - This->StateBlock->lights = object; - } else if (insertAt == NULL) { /* End of list */ - prevPos->next = object; - object->prev = prevPos; - } else { /* Middle of chain */ - if (prevPos == NULL) { - This->StateBlock->lights = object; - } else { - prevPos->next = object; - } - object->prev = prevPos; - object->next = insertAt; - insertAt->prev = object; - } - } - - /* Initialze the object */ - TRACE("Light %ld setting to type %d, Diffuse(%f,%f,%f,%f), Specular(%f,%f,%f,%f), Ambient(%f,%f,%f,%f)\n", Index, pLight->Type, - pLight->Diffuse.r, pLight->Diffuse.g, pLight->Diffuse.b, pLight->Diffuse.a, - pLight->Specular.r, pLight->Specular.g, pLight->Specular.b, pLight->Specular.a, - pLight->Ambient.r, pLight->Ambient.g, pLight->Ambient.b, pLight->Ambient.a); - TRACE("... Pos(%f,%f,%f), Dirn(%f,%f,%f)\n", pLight->Position.x, pLight->Position.y, pLight->Position.z, - pLight->Direction.x, pLight->Direction.y, pLight->Direction.z); - TRACE("... Range(%f), Falloff(%f), Theta(%f), Phi(%f)\n", pLight->Range, pLight->Falloff, pLight->Theta, pLight->Phi); - - /* Save away the information */ - memcpy(&object->OriginalParms, pLight, sizeof(D3DLIGHT8)); - - switch (pLight->Type) { - case D3DLIGHT_POINT: - /* Position */ - object->lightPosn[0] = pLight->Position.x; - object->lightPosn[1] = pLight->Position.y; - object->lightPosn[2] = pLight->Position.z; - object->lightPosn[3] = 1.0f; - object->cutoff = 180.0f; - /* FIXME: Range */ - break; - - case D3DLIGHT_DIRECTIONAL: - /* Direction */ - object->lightPosn[0] = -pLight->Direction.x; - object->lightPosn[1] = -pLight->Direction.y; - object->lightPosn[2] = -pLight->Direction.z; - object->lightPosn[3] = 0.0; - object->exponent = 0.0f; - object->cutoff = 180.0f; - break; - - case D3DLIGHT_SPOT: - /* Position */ - object->lightPosn[0] = pLight->Position.x; - object->lightPosn[1] = pLight->Position.y; - object->lightPosn[2] = pLight->Position.z; - object->lightPosn[3] = 1.0; - - /* Direction */ - object->lightDirn[0] = pLight->Direction.x; - object->lightDirn[1] = pLight->Direction.y; - object->lightDirn[2] = pLight->Direction.z; - object->lightDirn[3] = 1.0; - - /* - * opengl-ish and d3d-ish spot lights use too different models for the - * light "intensity" as a function of the angle towards the main light direction, - * so we only can approximate very roughly. - * however spot lights are rather rarely used in games (if ever used at all). - * furthermore if still used, probably nobody pays attention to such details. - */ - if (pLight->Falloff == 0) { - rho = 6.28f; - } else { - rho = pLight->Theta + (pLight->Phi - pLight->Theta)/(2*pLight->Falloff); - } - if (rho < 0.0001) rho = 0.0001f; - object->exponent = -0.3/log(cos(rho/2)); - object->cutoff = pLight->Phi*90/M_PI; - - /* FIXME: Range */ - break; - - default: - FIXME("Unrecognized light type %d\n", pLight->Type); - } - - /* Update the live definitions if the light is currently assigned a glIndex */ - if (object->glIndex != -1) { - setup_light(iface, object->glIndex, object); - } - return D3D_OK; + return IWineD3DDevice_GetClipStatus(This->WineD3DDevice, (WINED3DCLIPSTATUS *)pClipStatus); } -HRESULT WINAPI IDirect3DDevice8Impl_GetLight(LPDIRECT3DDEVICE8 iface, DWORD Index,D3DLIGHT8* pLight) { - PLIGHTINFOEL *lightInfo = NULL; - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - TRACE("(%p) : Idx(%ld), pLight(%p)\n", This, Index, pLight); - - /* Locate the light in the live lights */ - lightInfo = This->StateBlock->lights; - while (lightInfo != NULL && lightInfo->OriginalIndex != Index) lightInfo = lightInfo->next; - if (lightInfo == NULL) { - TRACE("Light information requested but light not defined\n"); +HRESULT WINAPI IDirect3DDevice8Impl_GetTexture(LPDIRECT3DDEVICE8 iface, DWORD Stage,IDirect3DBaseTexture8** ppTexture) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + IWineD3DBaseTexture *retTexture = NULL; + HRESULT rc = D3D_OK; + + TRACE("(%p) Relay\n" , This); + + if(ppTexture == NULL){ return D3DERR_INVALIDCALL; } - memcpy(pLight, &lightInfo->OriginalParms, sizeof(D3DLIGHT8)); - return D3D_OK; -} -HRESULT WINAPI IDirect3DDevice8Impl_LightEnable(LPDIRECT3DDEVICE8 iface, DWORD Index,BOOL Enable) { - PLIGHTINFOEL *lightInfo = NULL; - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - TRACE("(%p) : Idx(%ld), enable? %d\n", This, Index, Enable); - - /* If recording state block, just add to end of lights chain with changedEnable set to true */ - if (This->isRecordingState) { - lightInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PLIGHTINFOEL)); - if (NULL == lightInfo) { - return D3DERR_OUTOFVIDEOMEMORY; - } - lightInfo->OriginalIndex = Index; - lightInfo->glIndex = -1; - lightInfo->enabledChanged = TRUE; - - /* Add to the END of the chain of lights changes to be replayed */ - if (This->UpdateStateBlock->lights == NULL) { - This->UpdateStateBlock->lights = lightInfo; - } else { - PLIGHTINFOEL *temp = This->UpdateStateBlock->lights; - while (temp->next != NULL) temp=temp->next; - temp->next = lightInfo; - } - TRACE("Recording... not performing anything more\n"); - return D3D_OK; - } - - /* Not recording... So, locate the light in the live lights */ - lightInfo = This->StateBlock->lights; - while (lightInfo != NULL && lightInfo->OriginalIndex != Index) lightInfo = lightInfo->next; - - /* Special case - enabling an undefined light creates one with a strict set of parms! */ - if (lightInfo == NULL) { - D3DLIGHT8 lightParms; - /* Warning - untested code :-) Prob safe to change fixme to a trace but - wait until someone confirms it seems to work! */ - TRACE("Light enabled requested but light not defined, so defining one!\n"); - lightParms.Type = D3DLIGHT_DIRECTIONAL; - lightParms.Diffuse.r = 1.0; - lightParms.Diffuse.g = 1.0; - lightParms.Diffuse.b = 1.0; - lightParms.Diffuse.a = 0.0; - lightParms.Specular.r = 0.0; - lightParms.Specular.g = 0.0; - lightParms.Specular.b = 0.0; - lightParms.Specular.a = 0.0; - lightParms.Ambient.r = 0.0; - lightParms.Ambient.g = 0.0; - lightParms.Ambient.b = 0.0; - lightParms.Ambient.a = 0.0; - lightParms.Position.x = 0.0; - lightParms.Position.y = 0.0; - lightParms.Position.z = 0.0; - lightParms.Direction.x = 0.0; - lightParms.Direction.y = 0.0; - lightParms.Direction.z = 1.0; - lightParms.Range = 0.0; - lightParms.Falloff = 0.0; - lightParms.Attenuation0 = 0.0; - lightParms.Attenuation1 = 0.0; - lightParms.Attenuation2 = 0.0; - lightParms.Theta = 0.0; - lightParms.Phi = 0.0; - IDirect3DDevice8Impl_SetLight(iface, Index, &lightParms); - - /* Search for it again! Should be fairly quick as near head of list */ - lightInfo = This->StateBlock->lights; - while (lightInfo != NULL && lightInfo->OriginalIndex != Index) lightInfo = lightInfo->next; - if (lightInfo == NULL) { - FIXME("Adding default lights has failed dismally\n"); - return D3DERR_INVALIDCALL; - } - } - - /* OK, we now have a light... */ - if (Enable == FALSE) { - - /* If we are disabling it, check it was enabled, and - still only do something if it has assigned a glIndex (which it should have!) */ - if (lightInfo->lightEnabled && (lightInfo->glIndex != -1)) { - TRACE("Disabling light set up at gl idx %ld\n", lightInfo->glIndex); - ENTER_GL(); - glDisable(GL_LIGHT0 + lightInfo->glIndex); - checkGLcall("glDisable GL_LIGHT0+Index"); - LEAVE_GL(); - } else { - TRACE("Nothing to do as light was not enabled\n"); - } - lightInfo->lightEnabled = FALSE; + rc = IWineD3DDevice_GetTexture(This->WineD3DDevice, Stage, (IWineD3DBaseTexture **)&retTexture); + if (rc == D3D_OK && NULL != retTexture) { + IWineD3DBaseTexture_GetParent(retTexture, (IUnknown **)ppTexture); + IWineD3DBaseTexture_Release(retTexture); } else { - - /* We are enabling it. If it is enabled, its really simple */ - if (lightInfo->lightEnabled) { - /* nop */ - TRACE("Nothing to do as light was enabled\n"); - - /* If it already has a glIndex, its still simple */ - } else if (lightInfo->glIndex != -1) { - TRACE("Reusing light as already set up at gl idx %ld\n", lightInfo->glIndex); - lightInfo->lightEnabled = TRUE; - ENTER_GL(); - glEnable(GL_LIGHT0 + lightInfo->glIndex); - checkGLcall("glEnable GL_LIGHT0+Index already setup"); - LEAVE_GL(); - - /* Otherwise got to find space - lights are ordered gl indexes first */ - } else { - PLIGHTINFOEL *bsf = NULL; - PLIGHTINFOEL *pos = This->StateBlock->lights; - PLIGHTINFOEL *prev = NULL; - int Index= 0; - int glIndex = -1; - - /* Try to minimize changes as much as possible */ - while (pos != NULL && pos->glIndex != -1 && Index < This->maxConcurrentLights) { - - /* Try to remember which index can be replaced if necessary */ - if (bsf==NULL && pos->lightEnabled == FALSE) { - /* Found a light we can replace, save as best replacement */ - bsf = pos; - } - - /* Step to next space */ - prev = pos; - pos = pos->next; - Index ++; - } - - /* If we have too many active lights, fail the call */ - if ((Index == This->maxConcurrentLights) && (bsf == NULL)) { - FIXME("Program requests too many concurrent lights\n"); - return D3DERR_INVALIDCALL; - - /* If we have allocated all lights, but not all are enabled, - reuse one which is not enabled */ - } else if (Index == This->maxConcurrentLights) { - /* use bsf - Simply swap the new light and the BSF one */ - PLIGHTINFOEL *bsfNext = bsf->next; - PLIGHTINFOEL *bsfPrev = bsf->prev; - - /* Sort out ends */ - if (lightInfo->next != NULL) lightInfo->next->prev = bsf; - if (bsf->prev != NULL) { - bsf->prev->next = lightInfo; - } else { - This->StateBlock->lights = lightInfo; - } - - /* If not side by side, lots of chains to update */ - if (bsf->next != lightInfo) { - lightInfo->prev->next = bsf; - bsf->next->prev = lightInfo; - bsf->next = lightInfo->next; - bsf->prev = lightInfo->prev; - lightInfo->next = bsfNext; - lightInfo->prev = bsfPrev; - - } else { - /* Simple swaps */ - bsf->prev = lightInfo; - bsf->next = lightInfo->next; - lightInfo->next = bsf; - lightInfo->prev = bsfPrev; - } - - - /* Update states */ - glIndex = bsf->glIndex; - bsf->glIndex = -1; - lightInfo->glIndex = glIndex; - lightInfo->lightEnabled = TRUE; - - /* Finally set up the light in gl itself */ - TRACE("Replacing light which was set up at gl idx %ld\n", lightInfo->glIndex); - ENTER_GL(); - setup_light(iface, glIndex, lightInfo); - glEnable(GL_LIGHT0 + glIndex); - checkGLcall("glEnable GL_LIGHT0 new setup"); - LEAVE_GL(); - - /* If we reached the end of the allocated lights, with space in the - gl lights, setup a new light */ - } else if (pos->glIndex == -1) { - - /* We reached the end of the allocated gl lights, so already - know the index of the next one! */ - glIndex = Index; - lightInfo->glIndex = glIndex; - lightInfo->lightEnabled = TRUE; - - /* In an ideal world, its already in the right place */ - if (lightInfo->prev == NULL || lightInfo->prev->glIndex!=-1) { - /* No need to move it */ - } else { - /* Remove this light from the list */ - lightInfo->prev->next = lightInfo->next; - if (lightInfo->next != NULL) { - lightInfo->next->prev = lightInfo->prev; - } - - /* Add in at appropriate place (inbetween prev and pos) */ - lightInfo->prev = prev; - lightInfo->next = pos; - if (prev == NULL) { - This->StateBlock->lights = lightInfo; - } else { - prev->next = lightInfo; - } - if (pos != NULL) { - pos->prev = lightInfo; - } - } - - /* Finally set up the light in gl itself */ - TRACE("Defining new light at gl idx %ld\n", lightInfo->glIndex); - ENTER_GL(); - setup_light(iface, glIndex, lightInfo); - glEnable(GL_LIGHT0 + glIndex); - checkGLcall("glEnable GL_LIGHT0 new setup"); - LEAVE_GL(); - - } - } + FIXME("Call to get texture (%ld) failed (%p) \n", Stage, retTexture); + *ppTexture = NULL; } - return D3D_OK; -} -HRESULT WINAPI IDirect3DDevice8Impl_GetLightEnable(LPDIRECT3DDEVICE8 iface, DWORD Index,BOOL* pEnable) { - PLIGHTINFOEL *lightInfo = NULL; - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - TRACE("(%p) : for idx(%ld)\n", This, Index); - - /* Locate the light in the live lights */ - lightInfo = This->StateBlock->lights; - while (lightInfo != NULL && lightInfo->OriginalIndex != Index) lightInfo = lightInfo->next; - - if (lightInfo == NULL) { - TRACE("Light enabled state requested but light not defined\n"); - return D3DERR_INVALIDCALL; - } - *pEnable = lightInfo->lightEnabled; - return D3D_OK; + return rc; } -HRESULT WINAPI IDirect3DDevice8Impl_SetClipPlane(LPDIRECT3DDEVICE8 iface, DWORD Index,CONST float* pPlane) { + +HRESULT WINAPI IDirect3DDevice8Impl_SetTexture(LPDIRECT3DDEVICE8 iface, DWORD Stage, IDirect3DBaseTexture8* pTexture) { IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - TRACE("(%p) : for idx %ld, %p\n", This, Index, pPlane); + TRACE("(%p) Relay %ld %p\n" , This, Stage, pTexture); - /* Validate Index */ - if (Index >= GL_LIMITS(clipplanes)) { - TRACE("Application has requested clipplane this device doesn't support\n"); - return D3DERR_INVALIDCALL; - } - - This->UpdateStateBlock->Changed.clipplane[Index] = TRUE; - This->UpdateStateBlock->Set.clipplane[Index] = TRUE; - This->UpdateStateBlock->clipplane[Index][0] = pPlane[0]; - This->UpdateStateBlock->clipplane[Index][1] = pPlane[1]; - This->UpdateStateBlock->clipplane[Index][2] = pPlane[2]; - This->UpdateStateBlock->clipplane[Index][3] = pPlane[3]; - - /* Handle recording of state blocks */ - if (This->isRecordingState) { - TRACE("Recording... not performing anything\n"); - return D3D_OK; - } - - /* Apply it */ - - ENTER_GL(); - - /* Clip Plane settings are affected by the model view in OpenGL, the View transform in direct3d */ - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0]); - - TRACE("Clipplane [%f,%f,%f,%f]\n", - This->UpdateStateBlock->clipplane[Index][0], - This->UpdateStateBlock->clipplane[Index][1], - This->UpdateStateBlock->clipplane[Index][2], - This->UpdateStateBlock->clipplane[Index][3]); - glClipPlane(GL_CLIP_PLANE0 + Index, This->UpdateStateBlock->clipplane[Index]); - checkGLcall("glClipPlane"); - - glPopMatrix(); - - LEAVE_GL(); - - return D3D_OK; -} -HRESULT WINAPI IDirect3DDevice8Impl_GetClipPlane(LPDIRECT3DDEVICE8 iface, DWORD Index,float* pPlane) { - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - TRACE("(%p) : for idx %ld\n", This, Index); - - /* Validate Index */ - if (Index >= GL_LIMITS(clipplanes)) { - TRACE("Application has requested clipplane this device doesn't support\n"); - return D3DERR_INVALIDCALL; - } - - pPlane[0] = This->StateBlock->clipplane[Index][0]; - pPlane[1] = This->StateBlock->clipplane[Index][1]; - pPlane[2] = This->StateBlock->clipplane[Index][2]; - pPlane[3] = This->StateBlock->clipplane[Index][3]; - return D3D_OK; -} -HRESULT WINAPI IDirect3DDevice8Impl_SetRenderState(LPDIRECT3DDEVICE8 iface, D3DRENDERSTATETYPE State,DWORD Value) { - union { - DWORD d; - float f; - } tmpvalue; - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - DWORD OldValue = This->StateBlock->renderstate[State]; - - TRACE("(%p)->state = %s(%d), value = %ld\n", This, debug_d3drenderstate(State), State, Value); - This->UpdateStateBlock->Changed.renderstate[State] = TRUE; - This->UpdateStateBlock->Set.renderstate[State] = TRUE; - This->UpdateStateBlock->renderstate[State] = Value; - - /* Handle recording of state blocks */ - if (This->isRecordingState) { - TRACE("Recording... not performing anything\n"); - return D3D_OK; - } - - ENTER_GL(); - - switch (State) { - case D3DRS_FILLMODE : - switch ((D3DFILLMODE) Value) { - case D3DFILL_POINT : glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); break; - case D3DFILL_WIREFRAME : glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); break; - case D3DFILL_SOLID : glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); break; - default: - FIXME("Unrecognized D3DRS_FILLMODE value %ld\n", Value); - } - checkGLcall("glPolygonMode (fillmode)"); - break; - - case D3DRS_LIGHTING : - if (Value) { - glEnable(GL_LIGHTING); - checkGLcall("glEnable GL_LIGHTING"); - } else { - glDisable(GL_LIGHTING); - checkGLcall("glDisable GL_LIGHTING"); - } - break; - - case D3DRS_ZENABLE : - switch ((D3DZBUFFERTYPE) Value) { - case D3DZB_FALSE: - glDisable(GL_DEPTH_TEST); - checkGLcall("glDisable GL_DEPTH_TEST"); - break; - case D3DZB_TRUE: - glEnable(GL_DEPTH_TEST); - checkGLcall("glEnable GL_DEPTH_TEST"); - break; - case D3DZB_USEW: - glEnable(GL_DEPTH_TEST); - checkGLcall("glEnable GL_DEPTH_TEST"); - FIXME("W buffer is not well handled\n"); - break; - default: - FIXME("Unrecognized D3DZBUFFERTYPE value %ld\n", Value); - } - break; - - case D3DRS_CULLMODE : - - /* If we are culling "back faces with clockwise vertices" then - set front faces to be counter clockwise and enable culling - of back faces */ - switch ((D3DCULL) Value) { - case D3DCULL_NONE: - glDisable(GL_CULL_FACE); - checkGLcall("glDisable GL_CULL_FACE"); - break; - case D3DCULL_CW: - glEnable(GL_CULL_FACE); - checkGLcall("glEnable GL_CULL_FACE"); - if (This->renderUpsideDown) { - glFrontFace(GL_CW); - checkGLcall("glFrontFace GL_CW"); - } else { - glFrontFace(GL_CCW); - checkGLcall("glFrontFace GL_CCW"); - } - glCullFace(GL_BACK); - break; - case D3DCULL_CCW: - glEnable(GL_CULL_FACE); - checkGLcall("glEnable GL_CULL_FACE"); - if (This->renderUpsideDown) { - glFrontFace(GL_CCW); - checkGLcall("glFrontFace GL_CCW"); - } else { - glFrontFace(GL_CW); - checkGLcall("glFrontFace GL_CW"); - } - glCullFace(GL_BACK); - break; - default: - FIXME("Unrecognized/Unhandled D3DCULL value %ld\n", Value); - } - break; - - case D3DRS_SHADEMODE : - switch ((D3DSHADEMODE) Value) { - case D3DSHADE_FLAT: - glShadeModel(GL_FLAT); - checkGLcall("glShadeModel"); - break; - case D3DSHADE_GOURAUD: - glShadeModel(GL_SMOOTH); - checkGLcall("glShadeModel"); - break; - case D3DSHADE_PHONG: - FIXME("D3DSHADE_PHONG isn't supported?\n"); - - LEAVE_GL(); - return D3DERR_INVALIDCALL; - default: - FIXME("Unrecognized/Unhandled D3DSHADEMODE value %ld\n", Value); - } - break; - - case D3DRS_DITHERENABLE : - if (Value) { - glEnable(GL_DITHER); - checkGLcall("glEnable GL_DITHER"); - } else { - glDisable(GL_DITHER); - checkGLcall("glDisable GL_DITHER"); - } - break; - - case D3DRS_ZWRITEENABLE : - if (Value) { - glDepthMask(1); - checkGLcall("glDepthMask"); - } else { - glDepthMask(0); - checkGLcall("glDepthMask"); - } - break; - - case D3DRS_ZFUNC : - { - int glParm = GL_LESS; - - switch ((D3DCMPFUNC) Value) { - case D3DCMP_NEVER: glParm=GL_NEVER; break; - case D3DCMP_LESS: glParm=GL_LESS; break; - case D3DCMP_EQUAL: glParm=GL_EQUAL; break; - case D3DCMP_LESSEQUAL: glParm=GL_LEQUAL; break; - case D3DCMP_GREATER: glParm=GL_GREATER; break; - case D3DCMP_NOTEQUAL: glParm=GL_NOTEQUAL; break; - case D3DCMP_GREATEREQUAL: glParm=GL_GEQUAL; break; - case D3DCMP_ALWAYS: glParm=GL_ALWAYS; break; - default: - FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value); - } - glDepthFunc(glParm); - checkGLcall("glDepthFunc"); - } - break; - - case D3DRS_AMBIENT : - { - float col[4]; - D3DCOLORTOGLFLOAT4(Value, col); - TRACE("Setting ambient to (%f,%f,%f,%f)\n", col[0], col[1], col[2], col[3]); - glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col); - checkGLcall("glLightModel for MODEL_AMBIENT"); - - } - break; - - case D3DRS_ALPHABLENDENABLE : - if (Value) { - glEnable(GL_BLEND); - checkGLcall("glEnable GL_BLEND"); - } else { - glDisable(GL_BLEND); - checkGLcall("glDisable GL_BLEND"); - }; - break; - - case D3DRS_SRCBLEND : - case D3DRS_DESTBLEND : - { - int newVal = GL_ZERO; - switch (Value) { - case D3DBLEND_ZERO : newVal = GL_ZERO; break; - case D3DBLEND_ONE : newVal = GL_ONE; break; - case D3DBLEND_SRCCOLOR : newVal = GL_SRC_COLOR; break; - case D3DBLEND_INVSRCCOLOR : newVal = GL_ONE_MINUS_SRC_COLOR; break; - case D3DBLEND_SRCALPHA : newVal = GL_SRC_ALPHA; break; - case D3DBLEND_INVSRCALPHA : newVal = GL_ONE_MINUS_SRC_ALPHA; break; - case D3DBLEND_DESTALPHA : newVal = GL_DST_ALPHA; break; - case D3DBLEND_INVDESTALPHA : newVal = GL_ONE_MINUS_DST_ALPHA; break; - case D3DBLEND_DESTCOLOR : newVal = GL_DST_COLOR; break; - case D3DBLEND_INVDESTCOLOR : newVal = GL_ONE_MINUS_DST_COLOR; break; - case D3DBLEND_SRCALPHASAT : newVal = GL_SRC_ALPHA_SATURATE; break; - - case D3DBLEND_BOTHSRCALPHA : newVal = GL_SRC_ALPHA; - This->srcBlend = newVal; - This->dstBlend = newVal; - break; - - case D3DBLEND_BOTHINVSRCALPHA : newVal = GL_ONE_MINUS_SRC_ALPHA; - This->srcBlend = newVal; - This->dstBlend = newVal; - break; - default: - FIXME("Unrecognized src/dest blend value %ld (%d)\n", Value, State); - } - - if (State == D3DRS_SRCBLEND) This->srcBlend = newVal; - if (State == D3DRS_DESTBLEND) This->dstBlend = newVal; - TRACE("glBlendFunc src=%x, dst=%x\n", This->srcBlend, This->dstBlend); - glBlendFunc(This->srcBlend, This->dstBlend); - - checkGLcall("glBlendFunc"); - } - break; - - case D3DRS_ALPHATESTENABLE : - if (Value) { - glEnable(GL_ALPHA_TEST); - checkGLcall("glEnable GL_ALPHA_TEST"); - } else { - glDisable(GL_ALPHA_TEST); - checkGLcall("glDisable GL_ALPHA_TEST"); - } - break; - - case D3DRS_ALPHAFUNC : - { - int glParm = GL_LESS; - float ref = ((float) This->StateBlock->renderstate[D3DRS_ALPHAREF]) / 255.0f; - - switch ((D3DCMPFUNC) Value) { - case D3DCMP_NEVER: glParm = GL_NEVER; break; - case D3DCMP_LESS: glParm = GL_LESS; break; - case D3DCMP_EQUAL: glParm = GL_EQUAL; break; - case D3DCMP_LESSEQUAL: glParm = GL_LEQUAL; break; - case D3DCMP_GREATER: glParm = GL_GREATER; break; - case D3DCMP_NOTEQUAL: glParm = GL_NOTEQUAL; break; - case D3DCMP_GREATEREQUAL: glParm = GL_GEQUAL; break; - case D3DCMP_ALWAYS: glParm = GL_ALWAYS; break; - default: - FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value); - } - TRACE("glAlphaFunc with Parm=%x, ref=%f\n", glParm, ref); - glAlphaFunc(glParm, ref); - This->alphafunc = glParm; - checkGLcall("glAlphaFunc"); - } - break; - - case D3DRS_ALPHAREF : - { - int glParm = This->alphafunc; - float ref = 1.0f; - - ref = ((float) Value) / 255.0f; - TRACE("glAlphaFunc with Parm=%x, ref=%f\n", glParm, ref); - glAlphaFunc(glParm, ref); - checkGLcall("glAlphaFunc"); - } - break; - - case D3DRS_CLIPPLANEENABLE : - case D3DRS_CLIPPING : - { - /* Ensure we only do the changed clip planes */ - DWORD enable = 0xFFFFFFFF; - DWORD disable = 0x00000000; - - /* If enabling / disabling all */ - if (State == D3DRS_CLIPPING) { - if (Value) { - enable = This->StateBlock->renderstate[D3DRS_CLIPPLANEENABLE]; - disable = 0x00; - } else { - disable = This->StateBlock->renderstate[D3DRS_CLIPPLANEENABLE]; - enable = 0x00; - } - } else { - enable = Value & ~OldValue; - disable = ~Value & OldValue; - } - - if (enable & D3DCLIPPLANE0) { glEnable(GL_CLIP_PLANE0); checkGLcall("glEnable(clip plane 0)"); } - if (enable & D3DCLIPPLANE1) { glEnable(GL_CLIP_PLANE1); checkGLcall("glEnable(clip plane 1)"); } - if (enable & D3DCLIPPLANE2) { glEnable(GL_CLIP_PLANE2); checkGLcall("glEnable(clip plane 2)"); } - if (enable & D3DCLIPPLANE3) { glEnable(GL_CLIP_PLANE3); checkGLcall("glEnable(clip plane 3)"); } - if (enable & D3DCLIPPLANE4) { glEnable(GL_CLIP_PLANE4); checkGLcall("glEnable(clip plane 4)"); } - if (enable & D3DCLIPPLANE5) { glEnable(GL_CLIP_PLANE5); checkGLcall("glEnable(clip plane 5)"); } - - if (disable & D3DCLIPPLANE0) { glDisable(GL_CLIP_PLANE0); checkGLcall("glDisable(clip plane 0)"); } - if (disable & D3DCLIPPLANE1) { glDisable(GL_CLIP_PLANE1); checkGLcall("glDisable(clip plane 1)"); } - if (disable & D3DCLIPPLANE2) { glDisable(GL_CLIP_PLANE2); checkGLcall("glDisable(clip plane 2)"); } - if (disable & D3DCLIPPLANE3) { glDisable(GL_CLIP_PLANE3); checkGLcall("glDisable(clip plane 3)"); } - if (disable & D3DCLIPPLANE4) { glDisable(GL_CLIP_PLANE4); checkGLcall("glDisable(clip plane 4)"); } - if (disable & D3DCLIPPLANE5) { glDisable(GL_CLIP_PLANE5); checkGLcall("glDisable(clip plane 5)"); } - - /** update clipping status */ - if (enable) { - This->StateBlock->clip_status.ClipUnion = 0; - This->StateBlock->clip_status.ClipIntersection = 0xFFFFFFFF; - } else { - This->StateBlock->clip_status.ClipUnion = 0; - This->StateBlock->clip_status.ClipIntersection = 0; - } - } - break; - - case D3DRS_BLENDOP : - { - int glParm = GL_FUNC_ADD; - - switch ((D3DBLENDOP) Value) { - case D3DBLENDOP_ADD : glParm = GL_FUNC_ADD; break; - case D3DBLENDOP_SUBTRACT : glParm = GL_FUNC_SUBTRACT; break; - case D3DBLENDOP_REVSUBTRACT : glParm = GL_FUNC_REVERSE_SUBTRACT; break; - case D3DBLENDOP_MIN : glParm = GL_MIN; break; - case D3DBLENDOP_MAX : glParm = GL_MAX; break; - default: - FIXME("Unrecognized/Unhandled D3DBLENDOP value %ld\n", Value); - } - TRACE("glBlendEquation(%x)\n", glParm); - glBlendEquation(glParm); - checkGLcall("glBlendEquation"); - } - break; - - case D3DRS_TEXTUREFACTOR : - { - unsigned int i; - - /* Note the texture color applies to all textures whereas - GL_TEXTURE_ENV_COLOR applies to active only */ - float col[4]; - D3DCOLORTOGLFLOAT4(Value, col); - /* Set the default alpha blend color */ - glBlendColor(col[0], col[1], col[2], col[3]); - checkGLcall("glBlendColor"); - - /* And now the default texture color as well */ - for (i = 0; i < GL_LIMITS(textures); i++) { - - /* Note the D3DRS value applies to all textures, but GL has one - per texture, so apply it now ready to be used! */ - if (GL_SUPPORT(ARB_MULTITEXTURE)) { -#if defined(GL_VERSION_1_3) - glActiveTexture(GL_TEXTURE0 + i); -#else - glActiveTextureARB(GL_TEXTURE0_ARB + i); -#endif - checkGLcall("Activate texture.. to update const color"); - } else if (i>0) { - FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n"); - } - - glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]); - checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);"); - } - } - break; - - case D3DRS_SPECULARENABLE : - { - /* Originally this used glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR) - and (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR) to swap between enabled/disabled - specular color. This is wrong: - Separate specular color means the specular colour is maintained separately, whereas - single color means it is merged in. However in both cases they are being used to - some extent. - To disable specular color, set it explicitly to black and turn off GL_COLOR_SUM_EXT - NOTE: If not supported don't give FIXMEs the impact is really minimal and very few people are - running 1.4 yet! - */ - if (Value) { - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float*) &This->UpdateStateBlock->material.Specular); - checkGLcall("glMaterialfv"); - if (GL_SUPPORT(EXT_SECONDARY_COLOR)) { - glEnable(GL_COLOR_SUM_EXT); - } else { - TRACE("Specular colors cannot be enabled in this version of opengl\n"); - } - checkGLcall("glEnable(GL_COLOR_SUM)"); - } else { - float black[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - - /* for the case of enabled lighting: */ - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]); - checkGLcall("glMaterialfv"); - - /* for the case of disabled lighting: */ - if (GL_SUPPORT(EXT_SECONDARY_COLOR)) { - glDisable(GL_COLOR_SUM_EXT); - } else { - TRACE("Specular colors cannot be disabled in this version of opengl\n"); - } - checkGLcall("glDisable(GL_COLOR_SUM)"); - } - } - break; - - case D3DRS_STENCILENABLE : - if (Value) { - glEnable(GL_STENCIL_TEST); - checkGLcall("glEnable GL_STENCIL_TEST"); - } else { - glDisable(GL_STENCIL_TEST); - checkGLcall("glDisable GL_STENCIL_TEST"); - } - break; - - case D3DRS_STENCILFUNC : - { - int glParm = GL_ALWAYS; - int ref = This->StateBlock->renderstate[D3DRS_STENCILREF]; - GLuint mask = This->StateBlock->renderstate[D3DRS_STENCILMASK]; - - switch ((D3DCMPFUNC) Value) { - case D3DCMP_NEVER: glParm=GL_NEVER; break; - case D3DCMP_LESS: glParm=GL_LESS; break; - case D3DCMP_EQUAL: glParm=GL_EQUAL; break; - case D3DCMP_LESSEQUAL: glParm=GL_LEQUAL; break; - case D3DCMP_GREATER: glParm=GL_GREATER; break; - case D3DCMP_NOTEQUAL: glParm=GL_NOTEQUAL; break; - case D3DCMP_GREATEREQUAL: glParm=GL_GEQUAL; break; - case D3DCMP_ALWAYS: glParm=GL_ALWAYS; break; - default: - FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value); - } - TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask); - This->stencilfunc = glParm; - glStencilFunc(glParm, ref, mask); - checkGLcall("glStencilFunc"); - } - break; - - case D3DRS_STENCILREF : - { - int glParm = This->stencilfunc; - int ref = 0; - GLuint mask = This->StateBlock->renderstate[D3DRS_STENCILMASK]; - - ref = Value; - TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask); - glStencilFunc(glParm, ref, mask); - checkGLcall("glStencilFunc"); - } - break; - - case D3DRS_STENCILMASK : - { - int glParm = This->stencilfunc; - int ref = This->StateBlock->renderstate[D3DRS_STENCILREF]; - GLuint mask = Value; - - TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask); - glStencilFunc(glParm, ref, mask); - checkGLcall("glStencilFunc"); - } - break; - - case D3DRS_STENCILFAIL : - { - GLenum fail ; - GLint zpass ; - GLint zfail ; - - fail = StencilOp(Value); - glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass); - checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);"); - glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail); - checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);"); - - TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass); - glStencilOp(fail, zfail, zpass); - checkGLcall("glStencilOp(fail, zfail, zpass);"); - } - break; - case D3DRS_STENCILZFAIL : - { - GLint fail ; - GLint zpass ; - GLenum zfail ; - - glGetIntegerv(GL_STENCIL_FAIL, &fail); - checkGLcall("glGetIntegerv(GL_STENCIL_FAIL, &fail);"); - glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass); - checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);"); - zfail = StencilOp(Value); - - TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass); - glStencilOp(fail, zfail, zpass); - checkGLcall("glStencilOp(fail, zfail, zpass);"); - } - break; - case D3DRS_STENCILPASS : - { - GLint fail ; - GLenum zpass ; - GLint zfail ; - - glGetIntegerv(GL_STENCIL_FAIL, &fail); - checkGLcall("glGetIntegerv(GL_STENCIL_FAIL, &fail);"); - zpass = StencilOp(Value); - glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail); - checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);"); - - TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass); - glStencilOp(fail, zfail, zpass); - checkGLcall("glStencilOp(fail, zfail, zpass);"); - } - break; - - case D3DRS_STENCILWRITEMASK : - { - glStencilMask(Value); - TRACE("glStencilMask(%lu)\n", Value); - checkGLcall("glStencilMask"); - } - break; - - case D3DRS_FOGENABLE : - { - if (Value/* && This->StateBlock->renderstate[D3DRS_FOGTABLEMODE] != D3DFOG_NONE*/) { - glEnable(GL_FOG); - checkGLcall("glEnable GL_FOG"); - } else { - glDisable(GL_FOG); - checkGLcall("glDisable GL_FOG"); - } - } - break; - - case D3DRS_RANGEFOGENABLE : - { - if (Value) { - TRACE("Enabled RANGEFOG"); - } else { - TRACE("Disabled RANGEFOG"); - } - } - break; - - case D3DRS_FOGCOLOR : - { - float col[4]; - D3DCOLORTOGLFLOAT4(Value, col); - /* Set the default alpha blend color */ - glFogfv(GL_FOG_COLOR, &col[0]); - checkGLcall("glFog GL_FOG_COLOR"); - } - break; - - case D3DRS_FOGTABLEMODE : - { - glHint(GL_FOG_HINT, GL_NICEST); - switch (Value) { - case D3DFOG_NONE: /* I don't know what to do here */ checkGLcall("glFogi(GL_FOG_MODE, GL_EXP"); break; - case D3DFOG_EXP: glFogi(GL_FOG_MODE, GL_EXP); checkGLcall("glFogi(GL_FOG_MODE, GL_EXP"); break; - case D3DFOG_EXP2: glFogi(GL_FOG_MODE, GL_EXP2); checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2"); break; - case D3DFOG_LINEAR: glFogi(GL_FOG_MODE, GL_LINEAR); checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR"); break; - default: - FIXME("Unsupported Value(%lu) for D3DRS_FOGTABLEMODE!\n", Value); - } - if (GL_SUPPORT(NV_FOG_DISTANCE)) { - glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV); - } - } - break; - - case D3DRS_FOGVERTEXMODE : - { - glHint(GL_FOG_HINT, GL_FASTEST); - switch (Value) { - case D3DFOG_NONE: /* I don't know what to do here */ checkGLcall("glFogi(GL_FOG_MODE, GL_EXP"); break; - case D3DFOG_EXP: glFogi(GL_FOG_MODE, GL_EXP); checkGLcall("glFogi(GL_FOG_MODE, GL_EXP"); break; - case D3DFOG_EXP2: glFogi(GL_FOG_MODE, GL_EXP2); checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2"); break; - case D3DFOG_LINEAR: glFogi(GL_FOG_MODE, GL_LINEAR); checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR"); break; - default: - FIXME("Unsupported Value(%lu) for D3DRS_FOGTABLEMODE!\n", Value); - } - if (GL_SUPPORT(NV_FOG_DISTANCE)) { - glFogi(GL_FOG_DISTANCE_MODE_NV, This->StateBlock->renderstate[D3DRS_RANGEFOGENABLE] ? GL_EYE_RADIAL_NV : GL_EYE_PLANE_ABSOLUTE_NV); - } - } - break; - - case D3DRS_FOGSTART : - { - tmpvalue.d = Value; - glFogfv(GL_FOG_START, &tmpvalue.f); - checkGLcall("glFogf(GL_FOG_START, (float) Value)"); - TRACE("Fog Start == %f\n", tmpvalue.f); - } - break; - - case D3DRS_FOGEND : - { - tmpvalue.d = Value; - glFogfv(GL_FOG_END, &tmpvalue.f); - checkGLcall("glFogf(GL_FOG_END, (float) Value)"); - TRACE("Fog End == %f\n", tmpvalue.f); - } - break; - - case D3DRS_FOGDENSITY : - { - tmpvalue.d = Value; - glFogfv(GL_FOG_DENSITY, &tmpvalue.f); - checkGLcall("glFogf(GL_FOG_DENSITY, (float) Value)"); - } - break; - - case D3DRS_VERTEXBLEND : - { - This->UpdateStateBlock->vertex_blend = (D3DVERTEXBLENDFLAGS) Value; - TRACE("Vertex Blending state to %ld\n", Value); - } - break; - - case D3DRS_TWEENFACTOR : - { - tmpvalue.d = Value; - This->UpdateStateBlock->tween_factor = tmpvalue.f; - TRACE("Vertex Blending Tween Factor to %f\n", This->UpdateStateBlock->tween_factor); - } - break; - - case D3DRS_INDEXEDVERTEXBLENDENABLE : - { - TRACE("Indexed Vertex Blend Enable to %ul\n", (BOOL) Value); - } - break; - - case D3DRS_COLORVERTEX : - case D3DRS_DIFFUSEMATERIALSOURCE : - case D3DRS_SPECULARMATERIALSOURCE : - case D3DRS_AMBIENTMATERIALSOURCE : - case D3DRS_EMISSIVEMATERIALSOURCE : - { - GLenum Parm = GL_AMBIENT_AND_DIFFUSE; - - if (This->StateBlock->renderstate[D3DRS_COLORVERTEX]) { - TRACE("diff %ld, amb %ld, emis %ld, spec %ld\n", - This->StateBlock->renderstate[D3DRS_DIFFUSEMATERIALSOURCE], - This->StateBlock->renderstate[D3DRS_AMBIENTMATERIALSOURCE], - This->StateBlock->renderstate[D3DRS_EMISSIVEMATERIALSOURCE], - This->StateBlock->renderstate[D3DRS_SPECULARMATERIALSOURCE]); - - if (This->StateBlock->renderstate[D3DRS_DIFFUSEMATERIALSOURCE] == D3DMCS_COLOR1) { - if (This->StateBlock->renderstate[D3DRS_AMBIENTMATERIALSOURCE] == D3DMCS_COLOR1) { - Parm = GL_AMBIENT_AND_DIFFUSE; - } else { - Parm = GL_DIFFUSE; - } - } else if (This->StateBlock->renderstate[D3DRS_AMBIENTMATERIALSOURCE] == D3DMCS_COLOR1) { - Parm = GL_AMBIENT; - } else if (This->StateBlock->renderstate[D3DRS_EMISSIVEMATERIALSOURCE] == D3DMCS_COLOR1) { - Parm = GL_EMISSION; - } else if (This->StateBlock->renderstate[D3DRS_SPECULARMATERIALSOURCE] == D3DMCS_COLOR1) { - Parm = GL_SPECULAR; - } else { - Parm = -1; - } - - if (Parm == -1) { - if (This->tracking_color != DISABLED_TRACKING) This->tracking_color = NEEDS_DISABLE; - } else { - This->tracking_color = NEEDS_TRACKING; - This->tracking_parm = Parm; - } - - } else { - if (This->tracking_color != DISABLED_TRACKING) This->tracking_color = NEEDS_DISABLE; - } - } - break; - - case D3DRS_LINEPATTERN : - { - union { - DWORD d; - D3DLINEPATTERN lp; - } tmppattern; - tmppattern.d = Value; - - TRACE("Line pattern: repeat %d bits %x\n", tmppattern.lp.wRepeatFactor, tmppattern.lp.wLinePattern); - - if (tmppattern.lp.wRepeatFactor) { - glLineStipple(tmppattern.lp.wRepeatFactor, tmppattern.lp.wLinePattern); - checkGLcall("glLineStipple(repeat, linepattern)"); - glEnable(GL_LINE_STIPPLE); - checkGLcall("glEnable(GL_LINE_STIPPLE);"); - } else { - glDisable(GL_LINE_STIPPLE); - checkGLcall("glDisable(GL_LINE_STIPPLE);"); - } - } - break; - - case D3DRS_ZBIAS : - { - if (Value) { - tmpvalue.d = Value; - TRACE("ZBias value %f\n", tmpvalue.f); - glPolygonOffset(0, -tmpvalue.f); - checkGLcall("glPolygonOffset(0, -Value)"); - glEnable(GL_POLYGON_OFFSET_FILL); - checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL);"); - glEnable(GL_POLYGON_OFFSET_LINE); - checkGLcall("glEnable(GL_POLYGON_OFFSET_LINE);"); - glEnable(GL_POLYGON_OFFSET_POINT); - checkGLcall("glEnable(GL_POLYGON_OFFSET_POINT);"); - } else { - glDisable(GL_POLYGON_OFFSET_FILL); - checkGLcall("glDisable(GL_POLYGON_OFFSET_FILL);"); - glDisable(GL_POLYGON_OFFSET_LINE); - checkGLcall("glDisable(GL_POLYGON_OFFSET_LINE);"); - glDisable(GL_POLYGON_OFFSET_POINT); - checkGLcall("glDisable(GL_POLYGON_OFFSET_POINT);"); - } - } - break; - - case D3DRS_NORMALIZENORMALS : - if (Value) { - glEnable(GL_NORMALIZE); - checkGLcall("glEnable(GL_NORMALIZE);"); - } else { - glDisable(GL_NORMALIZE); - checkGLcall("glDisable(GL_NORMALIZE);"); - } - break; - - case D3DRS_POINTSIZE : - tmpvalue.d = Value; - TRACE("Set point size to %f\n", tmpvalue.f); - glPointSize(tmpvalue.f); - checkGLcall("glPointSize(...);"); - break; - - case D3DRS_POINTSIZE_MIN : - if (GL_SUPPORT(EXT_POINT_PARAMETERS)) { - tmpvalue.d = Value; - GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MIN_EXT, tmpvalue.f); - checkGLcall("glPointParameterfEXT(...);"); - } else { - FIXME("D3DRS_POINTSIZE_MIN not supported on this opengl\n"); - } - break; - - case D3DRS_POINTSIZE_MAX : - if (GL_SUPPORT(EXT_POINT_PARAMETERS)) { - tmpvalue.d = Value; - GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MAX_EXT, tmpvalue.f); - checkGLcall("glPointParameterfEXT(...);"); - } else { - FIXME("D3DRS_POINTSIZE_MAX not supported on this opengl\n"); - } - break; - - case D3DRS_POINTSCALE_A : - case D3DRS_POINTSCALE_B : - case D3DRS_POINTSCALE_C : - case D3DRS_POINTSCALEENABLE : - { - /* - * POINTSCALEENABLE controls how point size value is treated. If set to - * true, the point size is scaled with respect to height of viewport. - * When set to false point size is in pixels. - * - * http://msdn.microsoft.com/library/en-us/directx9_c/point_sprites.asp - */ - - /* Default values */ - GLfloat att[3] = {1.0f, 0.0f, 0.0f}; - - /* - * Minium valid point size for OpenGL is 1.0f. For Direct3D it is 0.0f. - * This means that OpenGL will clamp really small point sizes to 1.0f. - * To correct for this we need to multiply by the scale factor when sizes - * are less than 1.0f. scale_factor = 1.0f / point_size. - */ - GLfloat pointSize = *((float*)&This->StateBlock->renderstate[D3DRS_POINTSIZE]); - GLfloat scaleFactor; - if(pointSize < 1.0f) { - scaleFactor = pointSize * pointSize; - } else { - scaleFactor = 1.0f; - } - - if(This->StateBlock->renderstate[D3DRS_POINTSCALEENABLE]) { - att[0] = *((float*)&This->StateBlock->renderstate[D3DRS_POINTSCALE_A]) / - (This->StateBlock->viewport.Height * This->StateBlock->viewport.Height * scaleFactor); - att[1] = *((float*)&This->StateBlock->renderstate[D3DRS_POINTSCALE_B]) / - (This->StateBlock->viewport.Height * This->StateBlock->viewport.Height * scaleFactor); - att[2] = *((float*)&This->StateBlock->renderstate[D3DRS_POINTSCALE_C]) / - (This->StateBlock->viewport.Height * This->StateBlock->viewport.Height * scaleFactor); - } - - if(GL_SUPPORT(ARB_POINT_PARAMETERS)) { - GL_EXTCALL(glPointParameterfvARB)(GL_POINT_DISTANCE_ATTENUATION_ARB, att); - checkGLcall("glPointParameterfvARB(GL_DISTANCE_ATTENUATION_ARB, ..."); - } - else if(GL_SUPPORT(EXT_POINT_PARAMETERS)) { - GL_EXTCALL(glPointParameterfvEXT)(GL_DISTANCE_ATTENUATION_EXT, att); - checkGLcall("glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, ..."); - } - else { - TRACE("POINT_PARAMETERS not supported in this version of opengl\n"); - } - break; - } - case D3DRS_COLORWRITEENABLE : - { - TRACE("Color mask: r(%d) g(%d) b(%d) a(%d)\n", - Value & D3DCOLORWRITEENABLE_RED ? 1 : 0, - Value & D3DCOLORWRITEENABLE_GREEN ? 1 : 0, - Value & D3DCOLORWRITEENABLE_BLUE ? 1 : 0, - Value & D3DCOLORWRITEENABLE_ALPHA ? 1 : 0); - glColorMask(Value & D3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE, - Value & D3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE, - Value & D3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE, - Value & D3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE); - checkGLcall("glColorMask(...)"); - } - break; - - case D3DRS_LOCALVIEWER : - { - GLint state = (Value) ? 1 : 0; - TRACE("Local Viewer Enable to %ul\n", (BOOL) Value); - glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, state); - } - break; - - case D3DRS_LASTPIXEL : - { - if (Value) { - TRACE("Last Pixel Drawing Enabled\n"); - } else { - FIXME("Last Pixel Drawing Disabled, not handled yet\n"); - } - } - break; - - case D3DRS_SOFTWAREVERTEXPROCESSING : - { - if (Value) { - TRACE("Software Processing Enabled\n"); - } else { - TRACE("Software Processing Disabled\n"); - } - } - break; - - /** not supported */ - case D3DRS_ZVISIBLE : - { - LEAVE_GL(); - return D3DERR_INVALIDCALL; - } - - /* Unhandled yet...! */ - case D3DRS_EDGEANTIALIAS : - { - if(Value) { - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); - checkGLcall("glEnable GL_BLEND"); - glEnable(GL_LINE_SMOOTH); - checkGLcall("glEnable Gl_LINE_SMOOTH"); - } else { - glDisable(GL_BLEND); - checkGLcall("glDisable GL_BLEND"); - glDisable(GL_LINE_SMOOTH); - checkGLcall("glDisable GL_LINE_SMOOTH"); - } - break; - } - case D3DRS_WRAP0 : - case D3DRS_WRAP1 : - case D3DRS_WRAP2 : - case D3DRS_WRAP3 : - case D3DRS_WRAP4 : - case D3DRS_WRAP5 : - case D3DRS_WRAP6 : - case D3DRS_WRAP7 : - { - FIXME("(%p)->(%d,%ld) not handled yet\n", This, State, Value); - break; - } - case D3DRS_POINTSPRITEENABLE : - { - if (!GL_SUPPORT(ARB_POINT_SPRITE)) { - TRACE("Point sprites not supported\n"); - break; - } - - /* - * Point sprites are always enabled. Value controls texture coordinate - * replacement mode. Must be set true for point sprites to use - * textures. - */ - glEnable(GL_POINT_SPRITE_ARB); - checkGLcall("glEnable GL_POINT_SPRITE_ARB"); - - if (Value) { - glTexEnvf(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, TRUE); - } else { - glTexEnvf(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, FALSE); - } - break; - } - case D3DRS_MULTISAMPLEANTIALIAS : - { - if (!GL_SUPPORT(ARB_MULTISAMPLE)) { - TRACE("Multisample antialiasing not supported\n"); - break; - } - - if(Value) { - glEnable(GL_MULTISAMPLE_ARB); - checkGLcall("glEnable GL_MULTISAMPLE_ARB"); - } else { - glDisable(GL_MULTISAMPLE_ARB); - checkGLcall("glDisable GL_MULTISAMPLE_ARB"); - } - break; - } - case D3DRS_MULTISAMPLEMASK : - case D3DRS_PATCHEDGESTYLE : - case D3DRS_PATCHSEGMENTS : - case D3DRS_DEBUGMONITORTOKEN : - case D3DRS_POSITIONORDER : - case D3DRS_NORMALORDER : - /*Put back later: FIXME("(%p)->(%d,%ld) not handled yet\n", This, State, Value); */ - FIXME("(%p)->(%d,%ld) not handled yet\n", This, State, Value); - break; - default: - FIXME("(%p)->(%d,%ld) unrecognized\n", This, State, Value); - } - - LEAVE_GL(); - - return D3D_OK; -} -HRESULT WINAPI IDirect3DDevice8Impl_GetRenderState(LPDIRECT3DDEVICE8 iface, D3DRENDERSTATETYPE State,DWORD* pValue) { - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - TRACE("(%p) for State %d = %ld\n", This, State, This->UpdateStateBlock->renderstate[State]); - *pValue = This->StateBlock->renderstate[State]; - return D3D_OK; -} -HRESULT WINAPI IDirect3DDevice8Impl_BeginStateBlock(LPDIRECT3DDEVICE8 iface) { - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - - TRACE("(%p)\n", This); - - return IDirect3DDeviceImpl_BeginStateBlock(This); -} -HRESULT WINAPI IDirect3DDevice8Impl_EndStateBlock(LPDIRECT3DDEVICE8 iface, DWORD* pToken) { - IDirect3DStateBlockImpl* pSB; - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - HRESULT res; - - TRACE("(%p)\n", This); - - res = IDirect3DDeviceImpl_EndStateBlock(This, &pSB); - *pToken = (DWORD) pSB; - return res; -} - -HRESULT WINAPI IDirect3DDevice8Impl_ApplyStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) { - IDirect3DStateBlockImpl* pSB = (IDirect3DStateBlockImpl*) Token; - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - - TRACE("(%p)\n", This); - - return IDirect3DDeviceImpl_ApplyStateBlock(This, pSB); - -} -HRESULT WINAPI IDirect3DDevice8Impl_CaptureStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) { - IDirect3DStateBlockImpl* pSB = (IDirect3DStateBlockImpl*) Token; - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - - TRACE("(%p)\n", This); - - return IDirect3DDeviceImpl_CaptureStateBlock(This, pSB); -} -HRESULT WINAPI IDirect3DDevice8Impl_DeleteStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) { - IDirect3DStateBlockImpl* pSB = (IDirect3DStateBlockImpl*) Token; - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - - TRACE("(%p)\n", This); - - return IDirect3DDeviceImpl_DeleteStateBlock(This, pSB); -} - -HRESULT WINAPI IDirect3DDevice8Impl_CreateStateBlock(LPDIRECT3DDEVICE8 iface, D3DSTATEBLOCKTYPE Type, DWORD* pToken) { - IDirect3DStateBlockImpl* pSB; - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - HRESULT res; - - TRACE("(%p) : for type %d\n", This, Type); - - res = IDirect3DDeviceImpl_CreateStateBlock(This, Type, &pSB); - *pToken = (DWORD) pSB; - return res; -} - -HRESULT WINAPI IDirect3DDevice8Impl_SetClipStatus(LPDIRECT3DDEVICE8 iface, CONST D3DCLIPSTATUS8* pClipStatus) { - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - FIXME("(%p) : stub\n", This); - if (NULL == pClipStatus) { - return D3DERR_INVALIDCALL; - } - This->UpdateStateBlock->clip_status.ClipUnion = pClipStatus->ClipUnion; - This->UpdateStateBlock->clip_status.ClipIntersection = pClipStatus->ClipIntersection; - return D3D_OK; -} -HRESULT WINAPI IDirect3DDevice8Impl_GetClipStatus(LPDIRECT3DDEVICE8 iface, D3DCLIPSTATUS8* pClipStatus) { - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - FIXME("(%p) : stub\n", This); - if (NULL == pClipStatus) { - return D3DERR_INVALIDCALL; - } - pClipStatus->ClipUnion = This->UpdateStateBlock->clip_status.ClipUnion; - pClipStatus->ClipIntersection = This->UpdateStateBlock->clip_status.ClipIntersection; - return D3D_OK; -} -HRESULT WINAPI IDirect3DDevice8Impl_GetTexture(LPDIRECT3DDEVICE8 iface, DWORD Stage,IDirect3DBaseTexture8** ppTexture) { - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - TRACE("(%p) : returning %p for stage %ld\n", This, This->UpdateStateBlock->textures[Stage], Stage); - *ppTexture = (LPDIRECT3DBASETEXTURE8) This->UpdateStateBlock->textures[Stage]; - if (*ppTexture) - IDirect3DBaseTexture8Impl_AddRef(*ppTexture); - return D3D_OK; -} -HRESULT WINAPI IDirect3DDevice8Impl_SetTexture(LPDIRECT3DDEVICE8 iface, DWORD Stage, IDirect3DBaseTexture8* pTexture) { - - IDirect3DBaseTexture8 *oldTxt; - BOOL reapplyStates = TRUE; - INT oldTextureDimensions = -1; - DWORD reapplyFlags = 0; - - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - D3DRESOURCETYPE textureType; - - oldTxt = This->UpdateStateBlock->textures[Stage]; - TRACE("(%p) : Stage(%ld), Texture (%p)\n", This, Stage, pTexture); - - /* Reject invalid texture units */ - if (Stage >= GL_LIMITS(textures)) { - TRACE("Attempt to access invalid texture rejected\n"); - return D3DERR_INVALIDCALL; - } - - This->UpdateStateBlock->Set.textures[Stage] = TRUE; - This->UpdateStateBlock->Changed.textures[Stage] = TRUE; - This->UpdateStateBlock->textures[Stage] = pTexture; - - /* Handle recording of state blocks */ - if (This->isRecordingState) { - TRACE("Recording... not performing anything\n"); - return D3D_OK; - } - - oldTextureDimensions = This->UpdateStateBlock->textureDimensions[Stage]; - ENTER_GL(); - - /* Make appropriate texture active */ - if (GL_SUPPORT(ARB_MULTITEXTURE)) { -#if defined(GL_VERSION_1_3) - glActiveTexture(GL_TEXTURE0 + Stage); - checkGLcall("glActiveTexture"); -#else - glActiveTextureARB(GL_TEXTURE0_ARB + Stage); - checkGLcall("glActiveTextureARB"); -#endif - } else if (Stage>0) { - FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n"); - } - - /* Decrement the count of the previous texture */ - if (NULL != oldTxt) { - IDirect3DBaseTexture8Impl_Release(oldTxt); - } - - if (NULL != pTexture) { - IDirect3DBaseTexture8Impl_AddRef((LPDIRECT3DBASETEXTURE8) This->UpdateStateBlock->textures[Stage]); - - /* Now setup the texture appropraitly */ - textureType = IDirect3DBaseTexture8Impl_GetType(pTexture); - if (textureType == D3DRTYPE_TEXTURE) { - if (oldTxt == pTexture && IDirect3DBaseTexture8Impl_IsDirty(pTexture)) { - TRACE("Skipping setting texture as old == new\n"); - reapplyStates = FALSE; - } else { - /* Standard 2D texture */ - TRACE("Standard 2d texture\n"); - This->UpdateStateBlock->textureDimensions[Stage] = GL_TEXTURE_2D; - - /* Load up the texture now */ - IDirect3DTexture8Impl_PreLoad((LPDIRECT3DTEXTURE8) pTexture); - } - } else if (textureType == D3DRTYPE_VOLUMETEXTURE) { - if (oldTxt == pTexture && IDirect3DBaseTexture8Impl_IsDirty(pTexture)) { - TRACE("Skipping setting texture as old == new\n"); - reapplyStates = FALSE; - } else { - /* Standard 3D (volume) texture */ - TRACE("Standard 3d texture\n"); - This->UpdateStateBlock->textureDimensions[Stage] = GL_TEXTURE_3D; - - /* Load up the texture now */ - IDirect3DVolumeTexture8Impl_PreLoad((LPDIRECT3DVOLUMETEXTURE8) pTexture); - } - } else if (textureType == D3DRTYPE_CUBETEXTURE) { - if (oldTxt == pTexture && IDirect3DBaseTexture8Impl_IsDirty(pTexture)) { - TRACE("Skipping setting texture as old == new\n"); - reapplyStates = FALSE; - } else { - /* Standard Cube texture */ - TRACE("Standard Cube texture\n"); - This->UpdateStateBlock->textureDimensions[Stage] = GL_TEXTURE_CUBE_MAP_ARB; - - /* Load up the texture now */ - IDirect3DCubeTexture8Impl_PreLoad((LPDIRECT3DCUBETEXTURE8) pTexture); - } - } else { - FIXME("(%p) : Incorrect type for a texture : (%d,%s)\n", This, textureType, debug_d3dressourcetype(textureType)); - } - } else { - TRACE("Setting to no texture (ie default texture)\n"); - This->UpdateStateBlock->textureDimensions[Stage] = GL_TEXTURE_1D; - glBindTexture(GL_TEXTURE_1D, This->dummyTextureName[Stage]); - checkGLcall("glBindTexture"); - TRACE("Bound dummy Texture to stage %ld (gl name %d)\n", Stage, This->dummyTextureName[Stage]); - } - - /* Disable the old texture binding and enable the new one (unless operations are disabled) */ - if (oldTextureDimensions != This->UpdateStateBlock->textureDimensions[Stage]) { - glDisable(oldTextureDimensions); - checkGLcall("Disable oldTextureDimensions"); - if (This->StateBlock->texture_state[Stage][D3DTSS_COLOROP] != D3DTOP_DISABLE) { - glEnable(This->UpdateStateBlock->textureDimensions[Stage]); - checkGLcall("glEnable new texture dimensions"); - } - - /* If Alpha arg1 is texture then handle the special case when there changes between a - texture and no texture - See comments in set_tex_op */ - if ((This->StateBlock->texture_state[Stage][D3DTSS_ALPHAARG1] == D3DTA_TEXTURE) && - (((oldTxt == NULL) && (pTexture != NULL)) || ((pTexture == NULL) && (oldTxt != NULL)))) - { - reapplyFlags |= REAPPLY_ALPHAOP; - } - } - - - /* Even if the texture has been set to null, reapply the stages as a null texture to directx requires - a dummy texture in opengl, and we always need to ensure the current view of the TextureStates apply */ - if (reapplyStates) { - setupTextureStates(iface, Stage, reapplyFlags); - } - - LEAVE_GL(); - - return D3D_OK; + return IWineD3DDevice_SetTexture(This->WineD3DDevice, Stage, + pTexture==NULL ? NULL : ((IDirect3DBaseTexture8Impl *)pTexture)->wineD3DBaseTexture); } HRESULT WINAPI IDirect3DDevice8Impl_GetTextureStageState(LPDIRECT3DDEVICE8 iface, DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD* pValue) { IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - TRACE("(%p) : requesting Stage %ld, Type %d getting %ld\n", This, Stage, Type, This->UpdateStateBlock->texture_state[Stage][Type]); - *pValue = This->UpdateStateBlock->texture_state[Stage][Type]; - return D3D_OK; -} + TRACE("(%p) Relay\n" , This); -HRESULT WINAPI IDirect3DDevice8Impl_SetTextureStageState(LPDIRECT3DDEVICE8 iface, DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value) { - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - union { - float f; - DWORD d; - } tmpvalue; - - /* FIXME: Handle 3d textures? What if TSS value set before set texture? Need to reapply all values? */ - - TRACE("(%p) : Stage=%ld, Type=%s(%d), Value=%ld\n", This, Stage, debug_d3dtexturestate(Type), Type, Value); - - /* Reject invalid texture units */ - if (Stage >= GL_LIMITS(textures)) { - TRACE("Attempt to access invalid texture rejected\n"); - return D3DERR_INVALIDCALL; - } - - This->UpdateStateBlock->Changed.texture_state[Stage][Type] = TRUE; - This->UpdateStateBlock->Set.texture_state[Stage][Type] = TRUE; - This->UpdateStateBlock->texture_state[Stage][Type] = Value; - - /* Handle recording of state blocks */ - if (This->isRecordingState) { - TRACE("Recording... not performing anything\n"); - return D3D_OK; - } - - ENTER_GL(); - - /* Make appropriate texture active */ - VTRACE(("Activating appropriate texture state %ld\n", Stage)); - if (GL_SUPPORT(ARB_MULTITEXTURE)) { -#if defined(GL_VERSION_1_3) - glActiveTexture(GL_TEXTURE0 + Stage); - vcheckGLcall("glActiveTexture"); -#else - glActiveTextureARB(GL_TEXTURE0_ARB + Stage); - vcheckGLcall("glActiveTextureARB"); -#endif - } else if (Stage > 0) { - FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n"); - } - - switch (Type) { - - case D3DTSS_MINFILTER : - case D3DTSS_MIPFILTER : - { - DWORD ValueMIN = This->StateBlock->texture_state[Stage][D3DTSS_MINFILTER]; - DWORD ValueMIP = This->StateBlock->texture_state[Stage][D3DTSS_MIPFILTER]; - GLint realVal = GL_LINEAR; - - if (ValueMIN == D3DTEXF_NONE) { - /* Doesn't really make sense - Windows just seems to disable - mipmapping when this occurs */ - FIXME("Odd - minfilter of none, just disabling mipmaps\n"); - realVal = GL_LINEAR; - } else if (ValueMIN == D3DTEXF_POINT) { - /* GL_NEAREST_* */ - if (ValueMIP == D3DTEXF_NONE) { - realVal = GL_NEAREST; - } else if (ValueMIP == D3DTEXF_POINT) { - realVal = GL_NEAREST_MIPMAP_NEAREST; - } else if (ValueMIP == D3DTEXF_LINEAR) { - realVal = GL_NEAREST_MIPMAP_LINEAR; - } else { - FIXME("Unhandled D3DTSS_MIPFILTER value of %ld\n", ValueMIP); - realVal = GL_NEAREST; - } - } else if (ValueMIN == D3DTEXF_LINEAR) { - /* GL_LINEAR_* */ - if (ValueMIP == D3DTEXF_NONE) { - realVal = GL_LINEAR; - } else if (ValueMIP == D3DTEXF_POINT) { - realVal = GL_LINEAR_MIPMAP_NEAREST; - } else if (ValueMIP == D3DTEXF_LINEAR) { - realVal = GL_LINEAR_MIPMAP_LINEAR; - } else { - FIXME("Unhandled D3DTSS_MIPFILTER value of %ld\n", ValueMIP); - realVal = GL_LINEAR; - } - } else if (ValueMIN == D3DTEXF_ANISOTROPIC) { - if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) { - if (ValueMIP == D3DTEXF_NONE) { - realVal = GL_LINEAR_MIPMAP_LINEAR; - } else if (ValueMIP == D3DTEXF_POINT) { - realVal = GL_LINEAR_MIPMAP_NEAREST; - } else if (ValueMIP == D3DTEXF_LINEAR) { - realVal = GL_LINEAR_MIPMAP_LINEAR; - } else { - FIXME("Unhandled D3DTSS_MIPFILTER value of %ld\n", ValueMIP); - realVal = GL_LINEAR; - } - } else { - WARN("Trying to use ANISOTROPIC_FILTERING for D3DTSS_MINFILTER. But not supported by OpenGL driver\n"); - realVal = GL_LINEAR; - } - } else { - FIXME("Unhandled D3DTSS_MINFILTER value of %ld\n", ValueMIN); - realVal = GL_LINEAR_MIPMAP_LINEAR; - } - - TRACE("ValueMIN=%ld, ValueMIP=%ld, setting MINFILTER to %x\n", ValueMIN, ValueMIP, realVal); - glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_MIN_FILTER, realVal); - checkGLcall("glTexParameter GL_TEXTURE_MIN_FILTER, ..."); - /** - * if we juste choose to use ANISOTROPIC filtering, refresh openGL state - */ - if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC) && D3DTEXF_ANISOTROPIC == ValueMIN) { - glTexParameteri(This->StateBlock->textureDimensions[Stage], - GL_TEXTURE_MAX_ANISOTROPY_EXT, - This->StateBlock->texture_state[Stage][D3DTSS_MAXANISOTROPY]); - checkGLcall("glTexParameter GL_TEXTURE_MAX_ANISOTROPY_EXT, ..."); - } - } + switch(Type) { + case D3DTSS_ADDRESSU: + Type = WINED3DSAMP_ADDRESSU; break; - - case D3DTSS_MAGFILTER : - { - DWORD ValueMAG = This->StateBlock->texture_state[Stage][D3DTSS_MAGFILTER]; - GLint realVal = GL_NEAREST; - - if (ValueMAG == D3DTEXF_POINT) { - realVal = GL_NEAREST; - } else if (ValueMAG == D3DTEXF_LINEAR) { - realVal = GL_LINEAR; - } else if (ValueMAG == D3DTEXF_ANISOTROPIC) { - if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) { - realVal = GL_LINEAR; - } else { - FIXME("Trying to use ANISOTROPIC_FILTERING for D3DTSS_MAGFILTER. But not supported by current OpenGL driver\n"); - realVal = GL_NEAREST; - } - } else { - FIXME("Unhandled D3DTSS_MAGFILTER value of %ld\n", ValueMAG); - realVal = GL_NEAREST; - } - TRACE("ValueMAG=%ld setting MAGFILTER to %x\n", ValueMAG, realVal); - glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_MAG_FILTER, realVal); - checkGLcall("glTexParameter GL_TEXTURE_MAG_FILTER, ..."); - /** - * if we juste choose to use ANISOTROPIC filtering, refresh openGL state - */ - if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC) && D3DTEXF_ANISOTROPIC == ValueMAG) { - glTexParameteri(This->StateBlock->textureDimensions[Stage], - GL_TEXTURE_MAX_ANISOTROPY_EXT, - This->StateBlock->texture_state[Stage][D3DTSS_MAXANISOTROPY]); - checkGLcall("glTexParameter GL_TEXTURE_MAX_ANISOTROPY_EXT, ..."); - } - } - break; - - case D3DTSS_MAXMIPLEVEL : - { - /** - * Not really the same, but the more apprioprate than nothing - */ - glTexParameteri(This->StateBlock->textureDimensions[Stage], - GL_TEXTURE_BASE_LEVEL, - This->StateBlock->texture_state[Stage][D3DTSS_MAXMIPLEVEL]); - checkGLcall("glTexParameteri GL_TEXTURE_BASE_LEVEL ..."); - } - break; - - case D3DTSS_MAXANISOTROPY : - { - if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) { - glTexParameteri(This->StateBlock->textureDimensions[Stage], - GL_TEXTURE_MAX_ANISOTROPY_EXT, - This->StateBlock->texture_state[Stage][D3DTSS_MAXANISOTROPY]); - checkGLcall("glTexParameteri GL_TEXTURE_MAX_ANISOTROPY_EXT ..."); - } - } - break; - - case D3DTSS_MIPMAPLODBIAS : - { - if (GL_SUPPORT(EXT_TEXTURE_LOD_BIAS)) { - tmpvalue.d = Value; - glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, - GL_TEXTURE_LOD_BIAS_EXT, - tmpvalue.f); - checkGLcall("glTexEnvi GL_TEXTURE_LOD_BIAS_EXT ..."); - } - } - break; - - case D3DTSS_ALPHAOP : - case D3DTSS_COLOROP : - { - - if ((Value == D3DTOP_DISABLE) && (Type == D3DTSS_COLOROP)) { - /* TODO: Disable by making this and all later levels disabled */ - glDisable(GL_TEXTURE_1D); - checkGLcall("Disable GL_TEXTURE_1D"); - glDisable(GL_TEXTURE_2D); - checkGLcall("Disable GL_TEXTURE_2D"); - glDisable(GL_TEXTURE_3D); - checkGLcall("Disable GL_TEXTURE_3D"); - break; /* Don't bother setting the texture operations */ - } else { - /* Enable only the appropriate texture dimension */ - if (Type == D3DTSS_COLOROP) { - if (This->StateBlock->textureDimensions[Stage] == GL_TEXTURE_1D) { - glEnable(GL_TEXTURE_1D); - checkGLcall("Enable GL_TEXTURE_1D"); - } else { - glDisable(GL_TEXTURE_1D); - checkGLcall("Disable GL_TEXTURE_1D"); - } - if (This->StateBlock->textureDimensions[Stage] == GL_TEXTURE_2D) { - if (GL_SUPPORT(NV_TEXTURE_SHADER) && This->texture_shader_active) { - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_2D); - checkGLcall("Enable GL_TEXTURE_2D"); - } else { - glEnable(GL_TEXTURE_2D); - checkGLcall("Enable GL_TEXTURE_2D"); - } - } else { - glDisable(GL_TEXTURE_2D); - checkGLcall("Disable GL_TEXTURE_2D"); - } - if (This->StateBlock->textureDimensions[Stage] == GL_TEXTURE_3D) { - glEnable(GL_TEXTURE_3D); - checkGLcall("Enable GL_TEXTURE_3D"); - } else { - glDisable(GL_TEXTURE_3D); - checkGLcall("Disable GL_TEXTURE_3D"); - } - if (This->StateBlock->textureDimensions[Stage] == GL_TEXTURE_CUBE_MAP_ARB) { - glEnable(GL_TEXTURE_CUBE_MAP_ARB); - checkGLcall("Enable GL_TEXTURE_CUBE_MAP"); - } else { - glDisable(GL_TEXTURE_CUBE_MAP_ARB); - checkGLcall("Disable GL_TEXTURE_CUBE_MAP"); - } - } - } - /* Drop through... (Except disable case) */ - case D3DTSS_COLORARG0 : - case D3DTSS_COLORARG1 : - case D3DTSS_COLORARG2 : - case D3DTSS_ALPHAARG0 : - case D3DTSS_ALPHAARG1 : - case D3DTSS_ALPHAARG2 : - { - BOOL isAlphaArg = (Type == D3DTSS_ALPHAOP || Type == D3DTSS_ALPHAARG1 || - Type == D3DTSS_ALPHAARG2 || Type == D3DTSS_ALPHAARG0); - if (isAlphaArg) { - set_tex_op(iface, TRUE, Stage, This->StateBlock->texture_state[Stage][D3DTSS_ALPHAOP], - This->StateBlock->texture_state[Stage][D3DTSS_ALPHAARG1], - This->StateBlock->texture_state[Stage][D3DTSS_ALPHAARG2], - This->StateBlock->texture_state[Stage][D3DTSS_ALPHAARG0]); - } else { - set_tex_op(iface, FALSE, Stage, This->StateBlock->texture_state[Stage][D3DTSS_COLOROP], - This->StateBlock->texture_state[Stage][D3DTSS_COLORARG1], - This->StateBlock->texture_state[Stage][D3DTSS_COLORARG2], - This->StateBlock->texture_state[Stage][D3DTSS_COLORARG0]); - } - } - break; - } - - case D3DTSS_ADDRESSU : - case D3DTSS_ADDRESSV : - case D3DTSS_ADDRESSW : - { - GLint wrapParm = GL_REPEAT; - - switch (Value) { - case D3DTADDRESS_WRAP: wrapParm = GL_REPEAT; break; - case D3DTADDRESS_CLAMP: wrapParm = GL_CLAMP_TO_EDGE; break; - case D3DTADDRESS_BORDER: - { - if (GL_SUPPORT(ARB_TEXTURE_BORDER_CLAMP)) { - wrapParm = GL_CLAMP_TO_BORDER_ARB; - } else { - /* FIXME: Not right, but better */ - FIXME("Unrecognized or unsupported D3DTADDRESS_* value %ld, state %d\n", Value, Type); - wrapParm = GL_REPEAT; - } - } - break; - case D3DTADDRESS_MIRROR: - { - if (GL_SUPPORT(ARB_TEXTURE_MIRRORED_REPEAT)) { - wrapParm = GL_MIRRORED_REPEAT_ARB; - } else { - /* Unsupported in OpenGL pre-1.4 */ - FIXME("Unsupported D3DTADDRESS_MIRROR (needs GL_ARB_texture_mirrored_repeat) state %d\n", Type); - wrapParm = GL_REPEAT; - } - } - break; - case D3DTADDRESS_MIRRORONCE: - { - if (GL_SUPPORT(ATI_TEXTURE_MIRROR_ONCE)) { - wrapParm = GL_MIRROR_CLAMP_TO_EDGE_ATI; - } else { - FIXME("Unsupported D3DTADDRESS_MIRRORONCE (needs GL_ATI_texture_mirror_once) state %d\n", Type); - wrapParm = GL_REPEAT; - } - } - break; - - default: - FIXME("Unrecognized or unsupported D3DTADDRESS_* value %ld, state %d\n", Value, Type); - wrapParm = GL_REPEAT; - } - - switch (Type) { - case D3DTSS_ADDRESSU: - TRACE("Setting WRAP_S to %d for %x\n", wrapParm, This->StateBlock->textureDimensions[Stage]); - glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_WRAP_S, wrapParm); - checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_S, wrapParm)"); - break; - case D3DTSS_ADDRESSV: - TRACE("Setting WRAP_T to %d for %x\n", wrapParm, This->StateBlock->textureDimensions[Stage]); - glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_WRAP_T, wrapParm); - checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_T, wrapParm)"); - break; - case D3DTSS_ADDRESSW: - TRACE("Setting WRAP_R to %d for %x\n", wrapParm, This->StateBlock->textureDimensions[Stage]); - glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_WRAP_R, wrapParm); - checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_R, wrapParm)"); - break; - default: /* nop */ - break; /** stupic compilator */ - } - } + case D3DTSS_ADDRESSV: + Type = WINED3DSAMP_ADDRESSV; break; - - case D3DTSS_BORDERCOLOR : - { - float col[4]; - D3DCOLORTOGLFLOAT4(Value, col); - TRACE("Setting border color for %x to %lx\n", This->StateBlock->textureDimensions[Stage], Value); - glTexParameterfv(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_BORDER_COLOR, &col[0]); - checkGLcall("glTexParameteri(..., GL_TEXTURE_BORDER_COLOR, ...)"); - } + case D3DTSS_ADDRESSW: + Type = WINED3DSAMP_ADDRESSW; break; - - case D3DTSS_TEXCOORDINDEX : - { - /* Values 0-7 are indexes into the FVF tex coords - See comments in DrawPrimitive */ - - /* FIXME: From MSDN: The D3DTSS_TCI_* flags are mutually exclusive. If you include - one flag, you can still specify an index value, which the system uses to - determine the texture wrapping mode. - eg. SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION | 1 ); - means use the vertex position (camera-space) as the input texture coordinates - for this texture stage, and the wrap mode set in the D3DRS_WRAP1 render - state. We do not (yet) support the D3DRENDERSTATE_WRAPx values, nor tie them up - to the TEXCOORDINDEX value */ - - /** - * Be careful the value of the mask 0xF0000 come from d3d8types.h infos - */ - switch (Value & 0xFFFF0000) { - case D3DTSS_TCI_PASSTHRU: - /*Use the specified texture coordinates contained within the vertex format. This value resolves to zero.*/ - glDisable(GL_TEXTURE_GEN_S); - glDisable(GL_TEXTURE_GEN_T); - glDisable(GL_TEXTURE_GEN_R); - checkGLcall("glDisable(GL_TEXTURE_GEN_S,T,R)"); - break; - - case D3DTSS_TCI_CAMERASPACEPOSITION: - /* CameraSpacePosition means use the vertex position, transformed to camera space, - as the input texture coordinates for this stage's texture transformation. This - equates roughly to EYE_LINEAR */ - { - float s_plane[] = { 1.0, 0.0, 0.0, 0.0 }; - float t_plane[] = { 0.0, 1.0, 0.0, 0.0 }; - float r_plane[] = { 0.0, 0.0, 1.0, 0.0 }; - float q_plane[] = { 0.0, 0.0, 0.0, 1.0 }; - TRACE("D3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane\n"); - - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - glTexGenfv(GL_S, GL_EYE_PLANE, s_plane); - glTexGenfv(GL_T, GL_EYE_PLANE, t_plane); - glTexGenfv(GL_R, GL_EYE_PLANE, r_plane); - glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane); - glPopMatrix(); - - TRACE("D3DTSS_TCI_CAMERASPACEPOSITION - Set GL_TEXTURE_GEN_x and GL_x, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR\n"); - glEnable(GL_TEXTURE_GEN_S); - checkGLcall("glEnable(GL_TEXTURE_GEN_S);"); - glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); - checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)"); - glEnable(GL_TEXTURE_GEN_T); - checkGLcall("glEnable(GL_TEXTURE_GEN_T);"); - glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); - checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)"); - glEnable(GL_TEXTURE_GEN_R); - checkGLcall("glEnable(GL_TEXTURE_GEN_R);"); - glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); - checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)"); - } - break; - - case D3DTSS_TCI_CAMERASPACENORMAL: - { - if (GL_SUPPORT(NV_TEXGEN_REFLECTION)) { - float s_plane[] = { 1.0, 0.0, 0.0, 0.0 }; - float t_plane[] = { 0.0, 1.0, 0.0, 0.0 }; - float r_plane[] = { 0.0, 0.0, 1.0, 0.0 }; - float q_plane[] = { 0.0, 0.0, 0.0, 1.0 }; - TRACE("D3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane\n"); - - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - glTexGenfv(GL_S, GL_EYE_PLANE, s_plane); - glTexGenfv(GL_T, GL_EYE_PLANE, t_plane); - glTexGenfv(GL_R, GL_EYE_PLANE, r_plane); - glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane); - glPopMatrix(); - - glEnable(GL_TEXTURE_GEN_S); - checkGLcall("glEnable(GL_TEXTURE_GEN_S);"); - glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV); - checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV)"); - glEnable(GL_TEXTURE_GEN_T); - checkGLcall("glEnable(GL_TEXTURE_GEN_T);"); - glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV); - checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV)"); - glEnable(GL_TEXTURE_GEN_R); - checkGLcall("glEnable(GL_TEXTURE_GEN_R);"); - glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV); - checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV)"); - } - } - break; - - case D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR: - { - if (GL_SUPPORT(NV_TEXGEN_REFLECTION)) { - float s_plane[] = { 1.0, 0.0, 0.0, 0.0 }; - float t_plane[] = { 0.0, 1.0, 0.0, 0.0 }; - float r_plane[] = { 0.0, 0.0, 1.0, 0.0 }; - float q_plane[] = { 0.0, 0.0, 0.0, 1.0 }; - TRACE("D3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane\n"); - - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - glTexGenfv(GL_S, GL_EYE_PLANE, s_plane); - glTexGenfv(GL_T, GL_EYE_PLANE, t_plane); - glTexGenfv(GL_R, GL_EYE_PLANE, r_plane); - glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane); - glPopMatrix(); - - glEnable(GL_TEXTURE_GEN_S); - checkGLcall("glEnable(GL_TEXTURE_GEN_S);"); - glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV); - checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV)"); - glEnable(GL_TEXTURE_GEN_T); - checkGLcall("glEnable(GL_TEXTURE_GEN_T);"); - glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV); - checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV)"); - glEnable(GL_TEXTURE_GEN_R); - checkGLcall("glEnable(GL_TEXTURE_GEN_R);"); - glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV); - checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV)"); - } - } - break; - - /* Unhandled types: */ - default: - /* Todo: */ - /* ? disable GL_TEXTURE_GEN_n ? */ - glDisable(GL_TEXTURE_GEN_S); - glDisable(GL_TEXTURE_GEN_T); - glDisable(GL_TEXTURE_GEN_R); - FIXME("Unhandled D3DTSS_TEXCOORDINDEX %lx\n", Value); - break; - } - } + case D3DTSS_BORDERCOLOR: + Type = WINED3DSAMP_BORDERCOLOR; break; - - /* Unhandled */ - case D3DTSS_TEXTURETRANSFORMFLAGS : - set_texture_matrix((float *)&This->StateBlock->transforms[D3DTS_TEXTURE0 + Stage].u.m[0][0], Value); - break; - - case D3DTSS_BUMPENVMAT00 : - case D3DTSS_BUMPENVMAT01 : - TRACE("BUMPENVMAT0%u Stage=%ld, Type=%d, Value =%ld\n", Type - D3DTSS_BUMPENVMAT00, Stage, Type, Value); + case D3DTSS_MAGFILTER: + Type = WINED3DSAMP_MAGFILTER; break; - case D3DTSS_BUMPENVMAT10 : - case D3DTSS_BUMPENVMAT11 : - TRACE("BUMPENVMAT1%u Stage=%ld, Type=%d, Value =%ld\n", Type - D3DTSS_BUMPENVMAT10, Stage, Type, Value); + case D3DTSS_MAXANISOTROPY: + Type = WINED3DSAMP_MAXANISOTROPY; + break; + case D3DTSS_MAXMIPLEVEL: + Type = WINED3DSAMP_MAXMIPLEVEL; + break; + case D3DTSS_MINFILTER: + Type = WINED3DSAMP_MINFILTER; + break; + case D3DTSS_MIPFILTER: + Type = WINED3DSAMP_MIPFILTER; + break; + case D3DTSS_MIPMAPLODBIAS: + Type = WINED3DSAMP_MIPMAPLODBIAS; break; - - case D3DTSS_BUMPENVLSCALE : - TRACE("BUMPENVLSCALE Stage=%ld, Type=%d, Value =%ld\n", Stage, Type, Value); - break; - - case D3DTSS_BUMPENVLOFFSET : - TRACE("BUMPENVLOFFSET Stage=%ld, Type=%d, Value =%ld\n", Stage, Type, Value); - break; - - case D3DTSS_RESULTARG : - TRACE("RESULTARG Still a stub, Stage=%ld, Type=%d, Value =%ld\n", Stage, Type, Value); - break; - default: - /* Put back later: FIXME("(%p) : stub, Stage=%ld, Type=%d, Value =%ld\n", This, Stage, Type, Value); */ - TRACE("Still a stub, Stage=%ld, Type=%d, Value =%ld\n", Stage, Type, Value); + return IWineD3DDevice_GetTextureStageState(This->WineD3DDevice, Stage, Type, pValue); } - LEAVE_GL(); + return IWineD3DDevice_GetSamplerState(This->WineD3DDevice, Stage, Type, pValue); +} - return D3D_OK; -} -HRESULT WINAPI IDirect3DDevice8Impl_ValidateDevice(LPDIRECT3DDEVICE8 iface, DWORD* pNumPasses) { +HRESULT WINAPI IDirect3DDevice8Impl_SetTextureStageState(LPDIRECT3DDEVICE8 iface, DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value) { IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - TRACE("(%p) : stub\n", This); /* FIXME: Needs doing, but called often and is harmless */ - return D3D_OK; -} -HRESULT WINAPI IDirect3DDevice8Impl_GetInfo(LPDIRECT3DDEVICE8 iface, DWORD DevInfoID, void* pDevInfoStruct, DWORD DevInfoStructSize) { - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - FIXME("(%p) : stub\n", This); - return D3D_OK; -} -HRESULT WINAPI IDirect3DDevice8Impl_SetPaletteEntries(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber, CONST PALETTEENTRY* pEntries) { - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - FIXME("(%p) : setting p[%u] <= RGBA(%02x,%02x,%02x,%02x)\n", This, PaletteNumber, - pEntries->peRed, pEntries->peGreen, pEntries->peBlue, pEntries->peFlags); - if (PaletteNumber >= MAX_PALETTES) { - return D3DERR_INVALIDCALL; + TRACE("(%p) Relay\n" , This); + + switch(Type) { + case D3DTSS_ADDRESSU: + Type = WINED3DSAMP_ADDRESSU; + break; + case D3DTSS_ADDRESSV: + Type = WINED3DSAMP_ADDRESSV; + break; + case D3DTSS_ADDRESSW: + Type = WINED3DSAMP_ADDRESSW; + break; + case D3DTSS_BORDERCOLOR: + Type = WINED3DSAMP_BORDERCOLOR; + break; + case D3DTSS_MAGFILTER: + Type = WINED3DSAMP_MAGFILTER; + break; + case D3DTSS_MAXANISOTROPY: + Type = WINED3DSAMP_MAXANISOTROPY; + break; + case D3DTSS_MAXMIPLEVEL: + Type = WINED3DSAMP_MAXMIPLEVEL; + break; + case D3DTSS_MINFILTER: + Type = WINED3DSAMP_MINFILTER; + break; + case D3DTSS_MIPFILTER: + Type = WINED3DSAMP_MIPFILTER; + break; + case D3DTSS_MIPMAPLODBIAS: + Type = WINED3DSAMP_MIPMAPLODBIAS; + break; + default: + return IWineD3DDevice_SetTextureStageState(This->WineD3DDevice, Stage, Type, Value); } - memcpy(This->palettes[PaletteNumber], pEntries, 256 * sizeof(PALETTEENTRY)); - return D3D_OK; + + return IWineD3DDevice_SetSamplerState(This->WineD3DDevice, Stage, Type, Value); } -HRESULT WINAPI IDirect3DDevice8Impl_GetPaletteEntries(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber, PALETTEENTRY* pEntries) { + +HRESULT WINAPI IDirect3DDevice8Impl_ValidateDevice(LPDIRECT3DDEVICE8 iface, DWORD* pNumPasses) { IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - if (PaletteNumber >= MAX_PALETTES) { - return D3DERR_INVALIDCALL; - } - memcpy(pEntries, This->palettes[PaletteNumber], 256 * sizeof(PALETTEENTRY)); - FIXME("(%p) : returning p[%u] => RGBA(%02x,%02x,%02x,%02x)\n", This, PaletteNumber, - pEntries->peRed, pEntries->peGreen, pEntries->peBlue, pEntries->peFlags); - return D3D_OK; + TRACE("(%p) Relay\n" , This); + + return IWineD3DDevice_ValidateDevice(This->WineD3DDevice, pNumPasses); } -HRESULT WINAPI IDirect3DDevice8Impl_SetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber) { + +HRESULT WINAPI IDirect3DDevice8Impl_GetInfo(LPDIRECT3DDEVICE8 iface, DWORD DevInfoID, void* pDevInfoStruct, DWORD DevInfoStructSize) { IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - FIXME("(%p) : Setting to (%u)\n", This, PaletteNumber); - if (PaletteNumber >= MAX_PALETTES) { - return D3DERR_INVALIDCALL; - } - This->currentPalette = PaletteNumber; - -#if defined(GL_EXT_paletted_texture) - if (GL_SUPPORT(EXT_PALETTED_TEXTURE)) { - - ENTER_GL(); - - GL_EXTCALL(glColorTableEXT)(GL_TEXTURE_2D, /* target */ - GL_RGBA, /* internal format */ - 256, /* table size */ - GL_RGBA, /* table format */ - GL_UNSIGNED_BYTE, /* table type */ - This->palettes[PaletteNumber]); - checkGLcall("glColorTableEXT"); - - LEAVE_GL(); - - } else { - /* Delayed palette handling ... waiting for software emulation into preload code */ - } -#endif + FIXME("(%p) : stub\n", This); return D3D_OK; } + +HRESULT WINAPI IDirect3DDevice8Impl_SetPaletteEntries(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber, CONST PALETTEENTRY* pEntries) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + TRACE("(%p) Relay\n" , This); + + return IWineD3DDevice_SetPaletteEntries(This->WineD3DDevice, PaletteNumber, pEntries); +} + +HRESULT WINAPI IDirect3DDevice8Impl_GetPaletteEntries(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber, PALETTEENTRY* pEntries) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + TRACE("(%p) Relay\n" , This); + + return IWineD3DDevice_GetPaletteEntries(This->WineD3DDevice, PaletteNumber, pEntries); +} + +HRESULT WINAPI IDirect3DDevice8Impl_SetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + TRACE("(%p) Relay\n" , This); + + return IWineD3DDevice_SetCurrentTexturePalette(This->WineD3DDevice, PaletteNumber); +} + HRESULT WINAPI IDirect3DDevice8Impl_GetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface, UINT *PaletteNumber) { IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - *PaletteNumber = This->currentPalette; - FIXME("(%p) : Returning (%u)\n", This, *PaletteNumber); - return D3D_OK; -} -HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitive(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount) { + TRACE("(%p) Relay\n" , This); + return IWineD3DDevice_GetCurrentTexturePalette(This->WineD3DDevice, PaletteNumber); +} + +HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitive(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + TRACE("(%p) Relay\n" , This); + + return IWineD3DDevice_DrawPrimitive(This->WineD3DDevice, PrimitiveType, StartVertex, PrimitiveCount); +} + +HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitive(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType, + UINT MinVertexIndex,UINT NumVertices,UINT startIndex,UINT primCount) { IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - This->StateBlock->streamIsUP = FALSE; + TRACE("(%p) Relay\n" , This); - TRACE("(%p) : Type=(%d,%s), Start=%d, Count=%d\n", This, PrimitiveType, debug_d3dprimitivetype(PrimitiveType), StartVertex, PrimitiveCount); - drawPrimitive(iface, PrimitiveType, PrimitiveCount, StartVertex, -1, 0, NULL, 0); - - return D3D_OK; + return IWineD3DDevice_DrawIndexedPrimitive(This->WineD3DDevice, PrimitiveType, This->baseVertexIndex, MinVertexIndex, NumVertices, startIndex, primCount); } -HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitive(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType, - UINT minIndex,UINT NumVertices,UINT startIndex,UINT primCount) { - UINT idxStride = 2; - IDirect3DIndexBuffer8 *pIB; - D3DINDEXBUFFER_DESC IdxBufDsc; +HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitiveUP(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT PrimitiveCount,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride) { IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - pIB = This->StateBlock->pIndexData; - This->StateBlock->streamIsUP = FALSE; + TRACE("(%p) Relay\n" , This); - TRACE("(%p) : Type=(%d,%s), min=%d, CountV=%d, startIdx=%d, countP=%d\n", This, - PrimitiveType, debug_d3dprimitivetype(PrimitiveType), - minIndex, NumVertices, startIndex, primCount); - - IDirect3DIndexBuffer8Impl_GetDesc(pIB, &IdxBufDsc); - if (IdxBufDsc.Format == D3DFMT_INDEX16) { - idxStride = 2; - } else { - idxStride = 4; - } - - drawPrimitive(iface, PrimitiveType, primCount, This->StateBlock->baseVertexIndex, startIndex, idxStride, ((IDirect3DIndexBuffer8Impl *) pIB)->allocatedMemory, - minIndex); - - return D3D_OK; + return IWineD3DDevice_DrawPrimitiveUP(This->WineD3DDevice, PrimitiveType, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride); } -HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitiveUP(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT PrimitiveCount,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride) { - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - TRACE("(%p) : Type=(%d,%s), pCount=%d, pVtxData=%p, Stride=%d\n", This, PrimitiveType, debug_d3dprimitivetype(PrimitiveType), - PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride); - - if (This->StateBlock->stream_source[0] != NULL) IDirect3DVertexBuffer8Impl_Release(This->StateBlock->stream_source[0]); - - /* Note in the following, its not this type, but thats the purpose of streamIsUP */ - This->StateBlock->stream_source[0] = (IDirect3DVertexBuffer8 *)pVertexStreamZeroData; - This->StateBlock->stream_stride[0] = VertexStreamZeroStride; - This->StateBlock->streamIsUP = TRUE; - drawPrimitive(iface, PrimitiveType, PrimitiveCount, 0, 0, 0, NULL, 0); - This->StateBlock->stream_stride[0] = 0; - This->StateBlock->stream_source[0] = NULL; - - /*stream zero settings set to null at end */ - return D3D_OK; -} -HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitiveUP(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT MinVertexIndex, +HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitiveUP(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT MinVertexIndex, UINT NumVertexIndices,UINT PrimitiveCount,CONST void* pIndexData, D3DFORMAT IndexDataFormat,CONST void* pVertexStreamZeroData, UINT VertexStreamZeroStride) { - int idxStride; IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - TRACE("(%p) : Type=(%d,%s), MinVtxIdx=%d, NumVIdx=%d, PCount=%d, pidxdata=%p, IdxFmt=%d, pVtxdata=%p, stride=%d\n", This, PrimitiveType, debug_d3dprimitivetype(PrimitiveType), - MinVertexIndex, NumVertexIndices, PrimitiveCount, pIndexData, IndexDataFormat, pVertexStreamZeroData, VertexStreamZeroStride); + TRACE("(%p) Relay\n" , This); - if (This->StateBlock->stream_source[0] != NULL) IDirect3DVertexBuffer8Impl_Release(This->StateBlock->stream_source[0]); - if (IndexDataFormat == D3DFMT_INDEX16) { - idxStride = 2; - } else { - idxStride = 4; - } - - /* Note in the following, its not this type, but thats the purpose of streamIsUP */ - This->StateBlock->stream_source[0] = (IDirect3DVertexBuffer8 *)pVertexStreamZeroData; - This->StateBlock->streamIsUP = TRUE; - This->StateBlock->stream_stride[0] = VertexStreamZeroStride; - drawPrimitive(iface, PrimitiveType, PrimitiveCount, This->StateBlock->baseVertexIndex, 0, idxStride, pIndexData, MinVertexIndex); - - /*stream zero settings set to null at end */ - This->StateBlock->stream_source[0] = NULL; - This->StateBlock->stream_stride[0] = 0; - IDirect3DDevice8Impl_SetIndices(iface, NULL, 0); - - return D3D_OK; -} -HRESULT WINAPI IDirect3DDevice8Impl_ProcessVertices(LPDIRECT3DDEVICE8 iface, UINT SrcStartIndex,UINT DestIndex,UINT VertexCount,IDirect3DVertexBuffer8* pDestBuffer,DWORD Flags) { - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - FIXME("(%p) : stub\n", This); return D3D_OK; -} -HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pDeclaration, CONST DWORD* pFunction, DWORD* pHandle, DWORD Usage) { - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - IDirect3DVertexShaderImpl* object; - IDirect3DVertexShaderDeclarationImpl* attached_decl; - HRESULT res; - UINT i; - - TRACE_(d3d_shader)("(%p) : VertexShader not fully supported yet : Decl=%p, Func=%p, Usage=%lu\n", This, pDeclaration, pFunction, Usage); - if (NULL == pDeclaration || NULL == pHandle) { /* pFunction can be NULL see MSDN */ - return D3DERR_INVALIDCALL; - } - for (i = 1; NULL != VertexShaders[i] && i < sizeof(VertexShaders) / sizeof(IDirect3DVertexShaderImpl*); ++i) ; - if (i >= sizeof(VertexShaders) / sizeof(IDirect3DVertexShaderImpl*)) { - return D3DERR_OUTOFVIDEOMEMORY; - } - - /** Create the Vertex Shader */ - res = IDirect3DDeviceImpl_CreateVertexShader(This, pFunction, Usage, &object); - /** TODO: check FAILED(res) */ - - /** Create and Bind the Vertex Shader Declaration */ - res = IDirect3DDeviceImpl_CreateVertexShaderDeclaration8(This, pDeclaration, &attached_decl); - /** TODO: check FAILED(res) */ - - VertexShaders[i] = object; - VertexShaderDeclarations[i] = attached_decl; - *pHandle = VS_HIGHESTFIXEDFXF + i; - TRACE("Finished creating vertex shader %lx\n", *pHandle); - - return D3D_OK; -} -HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) { - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - - This->UpdateStateBlock->VertexShader = Handle; - This->UpdateStateBlock->Changed.vertexShader = TRUE; - This->UpdateStateBlock->Set.vertexShader = TRUE; - - if (Handle > VS_HIGHESTFIXEDFXF) { /* only valid with non FVF shaders */ - TRACE_(d3d_shader)("(%p) : Created shader, Handle=%lx\n", This, Handle); - This->UpdateStateBlock->vertexShaderDecl = VERTEX_SHADER_DECL(Handle); - This->UpdateStateBlock->Changed.vertexShaderDecl = TRUE; - This->UpdateStateBlock->Set.vertexShaderDecl = TRUE; - } else { /* use a fvf, so desactivate the vshader decl */ - TRACE("(%p) : FVF Shader, Handle=%lx\n", This, Handle); - This->UpdateStateBlock->vertexShaderDecl = NULL; - This->UpdateStateBlock->Changed.vertexShaderDecl = TRUE; - This->UpdateStateBlock->Set.vertexShaderDecl = TRUE; - } - /* Handle recording of state blocks */ - if (This->isRecordingState) { - TRACE("Recording... not performing anything\n"); - return D3D_OK; - } - /** - * TODO: merge HAL shaders context switching from prototype - */ - return D3D_OK; -} -HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD* pHandle) { - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - TRACE_(d3d_shader)("(%p) : GetVertexShader returning %ld\n", This, This->StateBlock->VertexShader); - *pHandle = This->StateBlock->VertexShader; - return D3D_OK; + return IWineD3DDevice_DrawIndexedPrimitiveUP(This->WineD3DDevice, PrimitiveType, MinVertexIndex, NumVertexIndices, PrimitiveCount, + pIndexData, IndexDataFormat, pVertexStreamZeroData, VertexStreamZeroStride); } -HRESULT WINAPI IDirect3DDevice8Impl_DeleteVertexShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) { +HRESULT WINAPI IDirect3DDevice8Impl_ProcessVertices(LPDIRECT3DDEVICE8 iface, UINT SrcStartIndex,UINT DestIndex,UINT VertexCount,IDirect3DVertexBuffer8* pDestBuffer,DWORD Flags) { IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - IDirect3DVertexShaderImpl* object; - IDirect3DVertexShaderDeclarationImpl* attached_decl; + TRACE("(%p) Relay\n" , This); - if (Handle <= VS_HIGHESTFIXEDFXF) { /* only delete user defined shaders */ - return D3DERR_INVALIDCALL; - } + return IWineD3DDevice_ProcessVertices(This->WineD3DDevice,SrcStartIndex, DestIndex, VertexCount, ((IDirect3DVertexBuffer8Impl *)pDestBuffer)->wineD3DVertexBuffer, NULL, Flags); +} - /** - * Delete Vertex Shader - */ - object = VertexShaders[Handle - VS_HIGHESTFIXEDFXF]; +HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pDeclaration, CONST DWORD* pFunction, DWORD* ppShader, DWORD Usage) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + HRESULT hrc = D3D_OK; + IDirect3DVertexShader8Impl *object; + + /* Setup a stub object for now */ + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); + TRACE("(%p) : pFunction(%p), ppShader(%p)\n", This, pFunction, ppShader); if (NULL == object) { - return D3DERR_INVALIDCALL; - } - TRACE_(d3d_shader)("(%p) : freing VertexShader %p\n", This, object); - /* TODO: check validity of object */ - HeapFree(GetProcessHeap(), 0, (void *)object->function); - if (object->prgId != 0) { - GL_EXTCALL(glDeleteProgramsARB( 1, &object->prgId )); - } - HeapFree(GetProcessHeap(), 0, (void *)object->data); - HeapFree(GetProcessHeap(), 0, (void *)object); - VertexShaders[Handle - VS_HIGHESTFIXEDFXF] = NULL; - - /** - * Delete Vertex Shader Declaration - */ - attached_decl = VertexShaderDeclarations[Handle - VS_HIGHESTFIXEDFXF]; - if (NULL == attached_decl) { - return D3DERR_INVALIDCALL; - } - TRACE_(d3d_shader)("(%p) : freing VertexShaderDeclaration %p\n", This, attached_decl); - /* TODO: check validity of object */ - HeapFree(GetProcessHeap(), 0, (void *)attached_decl->pDeclaration8); - HeapFree(GetProcessHeap(), 0, (void *)attached_decl); - VertexShaderDeclarations[Handle - VS_HIGHESTFIXEDFXF] = NULL; - - return D3D_OK; -} - -HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, CONST void* pConstantData, DWORD ConstantCount) { - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - - if (Register + ConstantCount > D3D8_VSHADER_MAX_CONSTANTS) { - ERR_(d3d_shader)("(%p) : SetVertexShaderConstant C[%lu] invalid\n", This, Register); - return D3DERR_INVALIDCALL; - } - if (NULL == pConstantData) { - return D3DERR_INVALIDCALL; - } - if (ConstantCount > 1) { - const FLOAT* f = (const FLOAT*)pConstantData; - UINT i; - TRACE_(d3d_shader)("(%p) : SetVertexShaderConstant C[%lu..%lu]=\n", This, Register, Register + ConstantCount - 1); - for (i = 0; i < ConstantCount; ++i) { - TRACE_(d3d_shader)("{%f, %f, %f, %f}\n", f[0], f[1], f[2], f[3]); - f += 4; - } - } else { - const FLOAT* f = (const FLOAT*) pConstantData; - TRACE_(d3d_shader)("(%p) : SetVertexShaderConstant, C[%lu]={%f, %f, %f, %f}\n", This, Register, f[0], f[1], f[2], f[3]); - } - This->UpdateStateBlock->Changed.vertexShaderConstant = TRUE; - memcpy(&This->UpdateStateBlock->vertexShaderConstant[Register], pConstantData, ConstantCount * 4 * sizeof(FLOAT)); - return D3D_OK; -} -HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, void* pConstantData, DWORD ConstantCount) { - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - - TRACE_(d3d_shader)("(%p) : C[%lu] count=%ld\n", This, Register, ConstantCount); - if (Register + ConstantCount > D3D8_VSHADER_MAX_CONSTANTS) { - return D3DERR_INVALIDCALL; - } - if (NULL == pConstantData) { - return D3DERR_INVALIDCALL; - } - memcpy(pConstantData, &This->UpdateStateBlock->vertexShaderConstant[Register], ConstantCount * 4 * sizeof(FLOAT)); - return D3D_OK; -} -HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderDeclaration(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) { - /*IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;*/ - IDirect3DVertexShaderDeclarationImpl* attached_decl; - - attached_decl = VERTEX_SHADER_DECL(Handle); - if (NULL == attached_decl) { - return D3DERR_INVALIDCALL; - } - return IDirect3DVertexShaderDeclarationImpl_GetDeclaration8(attached_decl, pData, (UINT*) pSizeOfData); -} -HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) { - /*IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;*/ - IDirect3DVertexShaderImpl* object; - - object = VERTEX_SHADER(Handle); - if (NULL == object) { - return D3DERR_INVALIDCALL; - } - return IDirect3DVertexShaderImpl_GetFunction(object, pData, (UINT*) pSizeOfData); -} - -HRESULT WINAPI IDirect3DDevice8Impl_SetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8* pIndexData, UINT BaseVertexIndex) { - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - IDirect3DIndexBuffer8 *oldIdxs; - - TRACE("(%p) : Setting to %p, base %d\n", This, pIndexData, BaseVertexIndex); - oldIdxs = This->StateBlock->pIndexData; - - This->UpdateStateBlock->Changed.Indices = TRUE; - This->UpdateStateBlock->Set.Indices = TRUE; - This->UpdateStateBlock->pIndexData = pIndexData; - This->UpdateStateBlock->baseVertexIndex = BaseVertexIndex; - - /* Handle recording of state blocks */ - if (This->isRecordingState) { - TRACE("Recording... not performing anything\n"); - return D3D_OK; + FIXME("Allocation of memory failed\n"); + *ppShader = 0; + return D3DERR_OUTOFVIDEOMEMORY; } - if (pIndexData) IDirect3DIndexBuffer8Impl_AddRefInt(This->StateBlock->pIndexData); - if (oldIdxs) IDirect3DIndexBuffer8Impl_ReleaseInt(oldIdxs); - return D3D_OK; -} -HRESULT WINAPI IDirect3DDevice8Impl_GetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8** ppIndexData,UINT* pBaseVertexIndex) { - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - FIXME("(%p) : stub\n", This); + object->ref = 1; + object->lpVtbl = &Direct3DVertexShader8_Vtbl; + /* Usage is missing ..*/ + hrc = IWineD3DDevice_CreateVertexShader(This->WineD3DDevice, pDeclaration, pFunction, &object->wineD3DVertexShader, (IUnknown *)object); - *ppIndexData = This->StateBlock->pIndexData; - /* up ref count on ppindexdata */ - if (*ppIndexData) IDirect3DIndexBuffer8Impl_AddRef(*ppIndexData); - *pBaseVertexIndex = This->StateBlock->baseVertexIndex; - - return D3D_OK; -} -HRESULT WINAPI IDirect3DDevice8Impl_CreatePixelShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pFunction, DWORD* pHandle) { - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - IDirect3DPixelShaderImpl* object; - HRESULT res; - UINT i; - - TRACE_(d3d_shader)("(%p) : PixelShader not fully supported yet : Func=%p\n", This, pFunction); - if (NULL == pFunction || NULL == pHandle) { - return D3DERR_INVALIDCALL; - } - for (i = 1; NULL != PixelShaders[i] && i < sizeof(PixelShaders) / sizeof(IDirect3DPixelShaderImpl*); ++i) ; - if (i >= sizeof(PixelShaders) / sizeof(IDirect3DPixelShaderImpl*)) { - return D3DERR_OUTOFVIDEOMEMORY; - } - - /** Create the Pixel Shader */ - res = IDirect3DDeviceImpl_CreatePixelShader(This, pFunction, &object); - if (SUCCEEDED(res)) { - PixelShaders[i] = object; - *pHandle = VS_HIGHESTFIXEDFXF + i; - return D3D_OK; - } - *pHandle = 0xFFFFFFFF; - return res; -} - -HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) { - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - - This->UpdateStateBlock->PixelShader = Handle; - This->UpdateStateBlock->Changed.pixelShader = TRUE; - This->UpdateStateBlock->Set.pixelShader = TRUE; - - /* Handle recording of state blocks */ - if (This->isRecordingState) { - TRACE_(d3d_shader)("Recording... not performing anything\n"); - return D3D_OK; - } - - if (Handle != 0) { - TRACE_(d3d_shader)("(%p) : Set pixel shader with handle %lx\n", This, Handle); + if (FAILED(hrc)) { + /* free up object */ + FIXME("Call to IWineD3DDevice_CreateVertexShader failed\n"); + HeapFree(GetProcessHeap(), 0, object); + *ppShader = 0; } else { - TRACE_(d3d_shader)("(%p) : Remove pixel shader\n", This); + /* TODO: Store the VS declarations locally so that they can be derefferenced with a value higher than VS_HIGHESTFIXEDFXF */ + DWORD i = 0; + while(This->vShaders[i] != NULL && i < MAX_SHADERS) ++i; + if (MAX_SHADERS == i) { + FIXME("(%p) : Number of shaders exceeds the maximum number of possible shaders\n", This); + hrc = E_OUTOFMEMORY; + } else { + This->vShaders[i] = object; + *ppShader = i + VS_HIGHESTFIXEDFXF + 1; + } } + TRACE("(%p) : returning %p\n", This, object); - return D3D_OK; + return hrc; } -HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD* pHandle) { +HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD pShader) { IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - TRACE_(d3d_shader)("(%p) : GetPixelShader returning %ld\n", This, This->StateBlock->PixelShader); - *pHandle = This->StateBlock->PixelShader; - return D3D_OK; + HRESULT hrc = D3D_OK; + + TRACE("(%p) : Relay \n", This); + if (VS_HIGHESTFIXEDFXF >= pShader) { + TRACE("Setting FVF, %d %ld\n", VS_HIGHESTFIXEDFXF, pShader); + IWineD3DDevice_SetFVF(This->WineD3DDevice, pShader); + } else { + FIXME("Setting shader\n"); + if (MAX_SHADERS <= pShader - (VS_HIGHESTFIXEDFXF + 1)) { + FIXME("(%p) : Number of shaders exceeds the maximum number of possible shaders\n", This); + hrc = D3DERR_INVALIDCALL; + } else { + /* IDirect3DVertexShader8Impl *shader = This->vShaders[pShader - (VS_HIGHESTFIXEDFXF + 1)]; */ + /* hrc = IWineD3DDevice_SetVertexShader(This->WineD3DDevice, 0 == shader ? NULL : shader->wineD3DVertexShader); */ + } + } + TRACE("(%p) : returning hr(%lu) \n", This, hrc); + + return hrc; } -HRESULT WINAPI IDirect3DDevice8Impl_DeletePixelShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) { +HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD* ppShader) { IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - IDirect3DPixelShaderImpl* object; + IWineD3DVertexShader *pShader; + HRESULT hrc = D3D_OK; - if (Handle <= VS_HIGHESTFIXEDFXF) { /* only delete user defined shaders */ - return D3DERR_INVALIDCALL; + TRACE("(%p) : Relay device@%p \n", This, This->WineD3DDevice); + hrc = IWineD3DDevice_GetVertexShader(This->WineD3DDevice, &pShader); + if (D3D_OK == hrc) { + if(0 != pShader) { + DWORD i = 0; + hrc = IWineD3DVertexShader_GetParent(pShader, (IUnknown **)ppShader); + IWineD3DVertexShader_Release(pShader); + while(This->vShaders[i] != (IDirect3DVertexShader8Impl *)ppShader && i < MAX_SHADERS) ++i; + if (i < MAX_SHADERS) { + *ppShader = i + VS_HIGHESTFIXEDFXF + 1; + } else { + WARN("(%p) : Couldn't find math for shader %p in d3d7 shadres list\n", This, (IDirect3DVertexShader8Impl *)ppShader); + *ppShader = 0; + } + } else { + WARN("(%p) : The shader has been set to NULL\n", This); + + /* TODO: Find out what should be returned, e.g. the FVF */ + *ppShader = 0; + hrc = D3DERR_INVALIDCALL; + } + } else { + WARN("(%p) : Call to IWineD3DDevice_GetVertexShader failed %lu (device %p)\n", This, hrc, This->WineD3DDevice); } - object = PixelShaders[Handle - VS_HIGHESTFIXEDFXF]; + TRACE("(%p) : returning %p\n", This, (IDirect3DVertexShader8 *)*ppShader); + + return hrc; +} + +HRESULT WINAPI IDirect3DDevice8Impl_DeleteVertexShader(LPDIRECT3DDEVICE8 iface, DWORD pShader) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + HRESULT hrc = D3D_OK; + TRACE("(%p) Relay\n", This); + if (VS_HIGHESTFIXEDFXF <= pShader) { + WARN("(%p) : Caller as passed a shader below the valud of VS_HIGHESTFIXEDFXF\n", This); + hrc = D3DERR_INVALIDCALL; + } else if (MAX_SHADERS <= pShader - (VS_HIGHESTFIXEDFXF + 1)) { + FIXME("(%p) : Caller as passed a shader greater than the maximum number of shaders\n", This); + hrc = D3DERR_INVALIDCALL; + } else { + IDirect3DVertexShader8Impl *shader = This->vShaders[pShader - (VS_HIGHESTFIXEDFXF + 1)]; + while(IUnknown_Release((IUnknown *)shader)); + This->vShaders[pShader - (VS_HIGHESTFIXEDFXF + 1)] = NULL; + hrc = D3D_OK; + } + + return hrc; +} + +HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, CONST void* pConstantData, DWORD ConstantCount) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + TRACE("(%p) : Relay\n", This); + + return IWineD3DDevice_SetVertexShaderConstantF(This->WineD3DDevice, Register, (CONST float *)pConstantData, ConstantCount); +} + +HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, void* pConstantData, DWORD ConstantCount) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + TRACE("(%p) : Relay\n", This); + + return IWineD3DDevice_GetVertexShaderConstantF(This->WineD3DDevice, Register, (float *)pConstantData, ConstantCount); +} + +HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderDeclaration(LPDIRECT3DDEVICE8 iface, DWORD pVertexShader, void* pData, DWORD* pSizeOfData) { + IDirect3DVertexShader8Impl *This = (IDirect3DVertexShader8Impl *)pVertexShader; + + TRACE("(%p) : Relay\n", This); +/* return IWineD3DVertexShader_GetDeclaration(This->wineD3DVertexShader, pData, (UINT *)pSizeOfData); */ + return D3DERR_INVALIDCALL; +} +HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD pVertexShader, void* pData, DWORD* pSizeOfData) { + IDirect3DVertexShader8Impl *This = (IDirect3DVertexShader8Impl *)pVertexShader; + + TRACE("(%p) : Relay\n", This); + return IWineD3DVertexShader_GetFunction(This->wineD3DVertexShader, pData, (UINT *)pSizeOfData); +} + +HRESULT WINAPI IDirect3DDevice8Impl_SetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8* pIndexData, UINT baseVertexIndex) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + TRACE("(%p) Relay\n", This); +/* FIXME: store base vertex index properly */ + This->baseVertexIndex = baseVertexIndex; + return IWineD3DDevice_SetIndices(This->WineD3DDevice, + NULL == pIndexData ? NULL : ((IDirect3DIndexBuffer8Impl *)pIndexData)->wineD3DIndexBuffer, + 0); +} + +HRESULT WINAPI IDirect3DDevice8Impl_GetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8** ppIndexData,UINT* pBaseVertexIndex) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + IWineD3DIndexBuffer *retIndexData = NULL; + HRESULT rc = D3D_OK; + UINT tmp; + + TRACE("(%p) Relay\n", This); + + if(ppIndexData == NULL){ + return D3DERR_INVALIDCALL; + } + + rc = IWineD3DDevice_GetIndices(This->WineD3DDevice, &retIndexData, &tmp); + if (D3D_OK == rc && NULL != retIndexData) { + IWineD3DVertexBuffer_GetParent(retIndexData, (IUnknown **)ppIndexData); + IWineD3DVertexBuffer_Release(retIndexData); + } else { + if(rc != D3D_OK) FIXME("Call to GetIndices failed\n"); + *ppIndexData = NULL; + } +/* FIXME: store base vertex index properly */ + *pBaseVertexIndex = This->baseVertexIndex; + return rc; +} +HRESULT WINAPI IDirect3DDevice8Impl_CreatePixelShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pFunction, DWORD* ppShader) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + IDirect3DPixelShader8Impl *object; + HRESULT hrc = D3D_OK; + + if (NULL == ppShader) { + TRACE("(%p) Invalid call\n", This); + return D3DERR_INVALIDCALL; + } + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); + if (NULL == object) { - return D3DERR_INVALIDCALL; + return E_OUTOFMEMORY; + } else { + + object->ref = 1; + object->lpVtbl = &Direct3DPixelShader8_Vtbl; + hrc = IWineD3DDevice_CreatePixelShader(This->WineD3DDevice, pFunction, &object->wineD3DPixelShader , (IUnknown *)object); + if (D3D_OK != hrc) { + FIXME("(%p) call to IWineD3DDevice_CreatePixelShader failed\n", This); + HeapFree(GetProcessHeap(), 0 , object); + *ppShader = 0; + } else { + *ppShader = (DWORD)object; + } + } - TRACE_(d3d_shader)("(%p) : freeing PixelShader %p\n", This, object); - /* TODO: check validity of object before free */ - HeapFree(GetProcessHeap(), 0, (void *)object->function); - if (object->prgId != 0) { - GL_EXTCALL(glDeleteProgramsARB( 1, &object->prgId )); + + TRACE("(%p) : returning %p\n", This, (void *)*ppShader); + return hrc; +} + +HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD pShader) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + IDirect3DPixelShader8Impl *shader = (IDirect3DPixelShader8Impl *)pShader; + TRACE("(%p) Relay\n", This); + + return IWineD3DDevice_SetPixelShader(This->WineD3DDevice, shader == NULL ? NULL :shader->wineD3DPixelShader); +} + +HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD* ppShader) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + IWineD3DPixelShader *object; + + HRESULT hrc = D3D_OK; + TRACE("(%p) Relay\n", This); + if (NULL == ppShader) { + TRACE("(%p) Invalid call\n", This); + return D3DERR_INVALIDCALL; + } + + hrc = IWineD3DDevice_GetPixelShader(This->WineD3DDevice, &object); + if (D3D_OK == hrc && NULL != object) { + hrc = IWineD3DPixelShader_GetParent(object, (IUnknown **)ppShader); + IWineD3DPixelShader_Release(object); + } else { + *ppShader = (DWORD)NULL; + } + + TRACE("(%p) : returning %p\n", This, (void *)*ppShader); + return hrc; +} + +HRESULT WINAPI IDirect3DDevice8Impl_DeletePixelShader(LPDIRECT3DDEVICE8 iface, DWORD pShader) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + IDirect3DPixelShader8Impl *shader = (IDirect3DPixelShader8Impl *)pShader; + TRACE("(%p) Relay\n", This); + + if (NULL != shader) { + while(IUnknown_Release((IUnknown *)shader)); } - HeapFree(GetProcessHeap(), 0, (void *)object->data); - HeapFree(GetProcessHeap(), 0, (void *)object); - PixelShaders[Handle - VS_HIGHESTFIXEDFXF] = NULL; return D3D_OK; } HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, CONST void* pConstantData, DWORD ConstantCount) { - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - - if (Register + ConstantCount > D3D8_PSHADER_MAX_CONSTANTS) { - ERR_(d3d_shader)("(%p) : SetPixelShaderConstant C[%lu] invalid\n", This, Register); - return D3DERR_INVALIDCALL; - } - if (NULL == pConstantData) { - return D3DERR_INVALIDCALL; - } - if (ConstantCount > 1) { - const FLOAT* f = (const FLOAT*)pConstantData; - UINT i; - TRACE_(d3d_shader)("(%p) : SetPixelShaderConstant C[%lu..%lu]=\n", This, Register, Register + ConstantCount - 1); - for (i = 0; i < ConstantCount; ++i) { - TRACE_(d3d_shader)("{%f, %f, %f, %f}\n", f[0], f[1], f[2], f[3]); - f += 4; - } - } else { - const FLOAT* f = (const FLOAT*) pConstantData; - TRACE_(d3d_shader)("(%p) : SetPixelShaderConstant, C[%lu]={%f, %f, %f, %f}\n", This, Register, f[0], f[1], f[2], f[3]); - } - This->UpdateStateBlock->Changed.pixelShaderConstant = TRUE; - memcpy(&This->UpdateStateBlock->pixelShaderConstant[Register], pConstantData, ConstantCount * 4 * sizeof(FLOAT)); - return D3D_OK; -} -HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, void* pConstantData, DWORD ConstantCount) { - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - - TRACE_(d3d_shader)("(%p) : C[%lu] count=%ld\n", This, Register, ConstantCount); - if (Register + ConstantCount > D3D8_PSHADER_MAX_CONSTANTS) { - return D3DERR_INVALIDCALL; - } - if (NULL == pConstantData) { - return D3DERR_INVALIDCALL; - } - memcpy(pConstantData, &This->UpdateStateBlock->pixelShaderConstant[Register], ConstantCount * 4 * sizeof(FLOAT)); - return D3D_OK; -} -HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) { - IDirect3DPixelShaderImpl* object; - - object = PIXEL_SHADER(Handle); - if (NULL == object) { - return D3DERR_INVALIDCALL; - } - return IDirect3DPixelShaderImpl_GetFunction(object, pData, (UINT*) pSizeOfData); -} -HRESULT WINAPI IDirect3DDevice8Impl_DrawRectPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DRECTPATCH_INFO* pRectPatchInfo) { IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - FIXME("(%p) : stub\n", This); return D3D_OK; -} -HRESULT WINAPI IDirect3DDevice8Impl_DrawTriPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DTRIPATCH_INFO* pTriPatchInfo) { - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - FIXME("(%p) : stub\n", This); return D3D_OK; -} -HRESULT WINAPI IDirect3DDevice8Impl_DeletePatch(LPDIRECT3DDEVICE8 iface, UINT Handle) { - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - FIXME("(%p) : stub\n", This); return D3D_OK; + TRACE("(%p) Relay\n", This); + + return IWineD3DDevice_SetPixelShaderConstantF(This->WineD3DDevice, Register, (CONST float *)pConstantData, ConstantCount); } -HRESULT WINAPI IDirect3DDevice8Impl_SetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8* pStreamData,UINT Stride) { - IDirect3DVertexBuffer8 *oldSrc; +HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, void* pConstantData, DWORD ConstantCount) { IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + TRACE("(%p) Relay\n", This); - oldSrc = This->StateBlock->stream_source[StreamNumber]; - TRACE("(%p) : StreamNo: %d, OldStream (%p), NewStream (%p), NewStride %d\n", This, StreamNumber, oldSrc, pStreamData, Stride); + return IWineD3DDevice_GetPixelShaderConstantF(This->WineD3DDevice, Register, (float *)pConstantData, ConstantCount); +} - This->UpdateStateBlock->Changed.stream_source[StreamNumber] = TRUE; - This->UpdateStateBlock->Set.stream_source[StreamNumber] = TRUE; - This->UpdateStateBlock->stream_stride[StreamNumber] = Stride; - This->UpdateStateBlock->stream_source[StreamNumber] = pStreamData; +HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD pPixelShader, void* pData, DWORD* pSizeOfData) { + IDirect3DPixelShader8Impl *This = (IDirect3DPixelShader8Impl *)pPixelShader; - /* Handle recording of state blocks */ - if (This->isRecordingState) { - TRACE("Recording... not performing anything\n"); - return D3D_OK; + TRACE("(%p) : Relay\n", This); + return IWineD3DPixelShader_GetFunction(This->wineD3DPixelShader, pData, (UINT *)pSizeOfData); +} + +HRESULT WINAPI IDirect3DDevice8Impl_DrawRectPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DRECTPATCH_INFO* pRectPatchInfo) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + TRACE("(%p) Relay\n", This); + + return IWineD3DDevice_DrawRectPatch(This->WineD3DDevice, Handle, pNumSegs, pRectPatchInfo); +} + +HRESULT WINAPI IDirect3DDevice8Impl_DrawTriPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DTRIPATCH_INFO* pTriPatchInfo) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + TRACE("(%p) Relay\n", This); + + return IWineD3DDevice_DrawTriPatch(This->WineD3DDevice, Handle, pNumSegs, pTriPatchInfo); +} + +HRESULT WINAPI IDirect3DDevice8Impl_DeletePatch(LPDIRECT3DDEVICE8 iface, UINT Handle) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + TRACE("(%p) Relay\n", This); + + return IWineD3DDevice_DeletePatch(This->WineD3DDevice, Handle); +} + +HRESULT WINAPI IDirect3DDevice8Impl_SetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8* pStreamData,UINT Stride) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + TRACE("(%p) Relay\n" , This); + + return IWineD3DDevice_SetStreamSource(This->WineD3DDevice, StreamNumber, + NULL == pStreamData ? NULL : ((IDirect3DVertexBuffer8Impl *)pStreamData)->wineD3DVertexBuffer, + 0/* Offset in bytes */, Stride); +} + +HRESULT WINAPI IDirect3DDevice8Impl_GetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8** pStream,UINT* pStride) { + IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; + IWineD3DVertexBuffer *retStream = NULL; + HRESULT rc = D3D_OK; + + TRACE("(%p) Relay\n" , This); + + if(pStream == NULL){ + return D3DERR_INVALIDCALL; } - if (pStreamData != NULL) IDirect3DVertexBuffer8Impl_AddRefInt(pStreamData); - if (oldSrc != NULL) IDirect3DVertexBuffer8Impl_ReleaseInt(oldSrc); - return D3D_OK; -} -HRESULT WINAPI IDirect3DDevice8Impl_GetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8** pStream,UINT* pStride) { - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - TRACE("(%p) : StreamNo: %d, Stream (%p), Stride %d\n", This, StreamNumber, This->StateBlock->stream_source[StreamNumber], This->StateBlock->stream_stride[StreamNumber]); - *pStream = This->StateBlock->stream_source[StreamNumber]; - *pStride = This->StateBlock->stream_stride[StreamNumber]; - if (*pStream != NULL) IDirect3DVertexBuffer8Impl_AddRef((LPDIRECT3DVERTEXBUFFER8) *pStream); - return D3D_OK; + rc = IWineD3DDevice_GetStreamSource(This->WineD3DDevice, StreamNumber, (IWineD3DVertexBuffer **)&retStream, 0 /* Offset in bytes */, pStride); + if (rc == D3D_OK && NULL != retStream) { + IWineD3DVertexBuffer_GetParent(retStream, (IUnknown **)pStream); + IWineD3DVertexBuffer_Release(retStream); + }else{ + FIXME("Call to GetStreamSource failed %p\n", pStride); + *pStream = NULL; + } + + return rc; } @@ -4246,257 +1466,6 @@ const IDirect3DDevice8Vtbl Direct3DDevice8_Vtbl = IDirect3DDevice8Impl_DeletePatch }; -HRESULT WINAPI IDirect3DDevice8Impl_CleanRender(LPDIRECT3DDEVICE8 iface) -{ -#if defined(GL_VERSION_1_3) /* @see comments on ActiveRender */ - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - - ENTER_GL(); - -#if 0 - if (This->glCtx != This->render_ctx) { - glXDestroyContext(This->display, This->render_ctx); - This->render_ctx = This->glCtx; - } -#endif - if (This->win != This->drawable) { - glXDestroyPbuffer(This->display, This->drawable); - This->drawable = This->win; - } - - LEAVE_GL(); - -#endif - return D3D_OK; -} - -HRESULT WINAPI IDirect3DDevice8Impl_ActiveRender(LPDIRECT3DDEVICE8 iface, - IDirect3DSurface8* RenderSurface, - IDirect3DSurface8* StencilSurface) { - - HRESULT ret = D3DERR_INVALIDCALL; - /** - * Currently only active for GLX >= 1.3 - * for others versions we'll have to use GLXPixmaps - * - * normally we must test GLX_VERSION_1_3 but nvidia headers are not correct - * as they implements GLX 1.3 but only define GLX_VERSION_1_2 - * so only check OpenGL version - */ -#if defined(GL_VERSION_1_3) - GLXFBConfig* cfgs = NULL; - int nCfgs = 0; - int attribs[256]; - int nAttribs = 0; - D3DFORMAT BackBufferFormat = D3D8_SURFACE(((IDirect3DSurface8Impl*) RenderSurface))->resource.format; - D3DFORMAT StencilBufferFormat = (NULL != StencilSurface) ? D3D8_SURFACE(((IDirect3DSurface8Impl*) StencilSurface))->resource.format : 0; - UINT Width = D3D8_SURFACE(((IDirect3DSurface8Impl*) RenderSurface))->currentDesc.Width; - UINT Height = D3D8_SURFACE(((IDirect3DSurface8Impl*) RenderSurface))->currentDesc.Height; - IDirect3DSurface8Impl* tmp; - - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - -#define PUSH1(att) attribs[nAttribs++] = (att); -#define PUSH2(att,value) attribs[nAttribs++] = (att); attribs[nAttribs++] = (value); - - PUSH2(GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT); - PUSH2(GLX_X_RENDERABLE, TRUE); - PUSH2(GLX_DOUBLEBUFFER, TRUE); - - switch (BackBufferFormat) { - /* color buffer */ - case D3DFMT_P8: - PUSH2(GLX_RENDER_TYPE, GLX_COLOR_INDEX_BIT); - PUSH2(GLX_BUFFER_SIZE, 8); - PUSH2(GLX_DOUBLEBUFFER, TRUE); - break; - - case D3DFMT_R3G3B2: - PUSH2(GLX_RENDER_TYPE, GLX_RGBA_BIT); - PUSH2(GLX_RED_SIZE, 3); - PUSH2(GLX_GREEN_SIZE, 3); - PUSH2(GLX_BLUE_SIZE, 2); - break; - - case D3DFMT_A1R5G5B5: - PUSH2(GLX_ALPHA_SIZE, 1); - case D3DFMT_X1R5G5B5: - PUSH2(GLX_RED_SIZE, 5); - PUSH2(GLX_GREEN_SIZE, 5); - PUSH2(GLX_BLUE_SIZE, 5); - break; - - case D3DFMT_R5G6B5: - PUSH2(GLX_RED_SIZE, 5); - PUSH2(GLX_GREEN_SIZE, 6); - PUSH2(GLX_BLUE_SIZE, 5); - break; - - case D3DFMT_A4R4G4B4: - PUSH2(GLX_ALPHA_SIZE, 4); - case D3DFMT_X4R4G4B4: - PUSH2(GLX_RED_SIZE, 4); - PUSH2(GLX_GREEN_SIZE, 4); - PUSH2(GLX_BLUE_SIZE, 4); - break; - - case D3DFMT_A8R8G8B8: - PUSH2(GLX_ALPHA_SIZE, 8); - case D3DFMT_R8G8B8: - case D3DFMT_X8R8G8B8: - PUSH2(GLX_RED_SIZE, 8); - PUSH2(GLX_GREEN_SIZE, 8); - PUSH2(GLX_BLUE_SIZE, 8); - break; - - default: - break; - } - - switch (StencilBufferFormat) { - case D3DFMT_D16_LOCKABLE: - case D3DFMT_D16: - PUSH2(GLX_DEPTH_SIZE, 16); - break; - - case D3DFMT_D15S1: - PUSH2(GLX_DEPTH_SIZE, 15); - break; - - case D3DFMT_D24X8: - PUSH2(GLX_DEPTH_SIZE, 24); - break; - - case D3DFMT_D24X4S4: - PUSH2(GLX_DEPTH_SIZE, 24); - PUSH2(GLX_STENCIL_SIZE, 4); - break; - - case D3DFMT_D24S8: - PUSH2(GLX_DEPTH_SIZE, 24); - PUSH2(GLX_STENCIL_SIZE, 8); - break; - - case D3DFMT_D32: - PUSH2(GLX_DEPTH_SIZE, 24); - break; - - default: - break; - } - - PUSH1(None); - - ENTER_GL(); - - cfgs = glXChooseFBConfig(This->display, DefaultScreen(This->display), attribs, &nCfgs); - if (NULL != cfgs) { -#ifdef EXTRA_TRACES - int i; - for (i = 0; i < nCfgs; ++i) { - TRACE("for (%u,%s)/(%u,%s) found config[%d]@%p\n", BackBufferFormat, debug_d3dformat(BackBufferFormat), StencilBufferFormat, debug_d3dformat(StencilBufferFormat), i, cfgs[i]); - } -#endif - - if (NULL != This->renderTarget) { - /*GLenum prev_read; */ - glFlush(); - vcheckGLcall("glFlush"); - -#ifdef EXTRA_TRACES - /** very very useful debug code */ - glXSwapBuffers(This->display, This->drawable); - printf("Hit Enter to get next frame ...\n"); - getchar(); -#endif - -#if 0 - glGetIntegerv(GL_READ_BUFFER, &prev_read); - vcheckGLcall("glIntegerv"); - glReadBuffer(GL_BACK); - vcheckGLcall("glReadBuffer"); - { - long j; - long pitch = This->renderTarget->myDesc.Width * This->renderTarget->bytesPerPixel; - - if (This->renderTarget->myDesc.Format == D3DFMT_DXT1) /* DXT1 is half byte per pixel */ - pitch = pitch / 2; - - for (j = 0; j < This->renderTarget->myDesc.Height; ++j) { - glReadPixels(0, - This->renderTarget->myDesc.Height - j - 1, - This->renderTarget->myDesc.Width, - 1, - D3DFmt2GLFmt(This, This->renderTarget->myDesc.Format), - D3DFmt2GLType(This, This->renderTarget->myDesc.Format), - This->renderTarget->allocatedMemory + j * pitch); - vcheckGLcall("glReadPixels"); - } - } - glReadBuffer(prev_read); - vcheckGLcall("glReadBuffer"); -#endif - } - - if (BackBufferFormat != D3D8_SURFACE(This->renderTarget)->resource.format && - StencilBufferFormat != D3D8_SURFACE(This->stencilBufferTarget)->resource.format) { - nAttribs = 0; - PUSH2(GLX_PBUFFER_WIDTH, Width); - PUSH2(GLX_PBUFFER_HEIGHT, Height); - PUSH1(None); - This->drawable = glXCreatePbuffer(This->display, cfgs[0], attribs); - - This->render_ctx = glXCreateNewContext(This->display, cfgs[0], GLX_RGBA_TYPE, This->glCtx, TRUE); - if (NULL == This->render_ctx) { - ERR("cannot create glxContext\n"); - } - - glFlush(); - glXSwapBuffers(This->display, This->drawable); - if (glXMakeContextCurrent(This->display, This->drawable, This->drawable, This->render_ctx) == False) { - TRACE("Error in setting current context: context %p drawable %ld (default %ld)!\n", This->glCtx, This->drawable, This->win); - } - checkGLcall("glXMakeContextCurrent"); - } - - tmp = This->renderTarget; - This->renderTarget = (IDirect3DSurface8Impl*) RenderSurface; - IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) This->renderTarget); - IDirect3DSurface8Impl_Release((LPDIRECT3DSURFACE8) tmp); - - tmp = This->stencilBufferTarget; - This->stencilBufferTarget = (IDirect3DSurface8Impl*) StencilSurface; - if (NULL != This->stencilBufferTarget) IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) This->stencilBufferTarget); - if (NULL != tmp) IDirect3DSurface8Impl_Release((LPDIRECT3DSURFACE8) tmp); - - { - DWORD value; - /* The surface must be rendered upside down to cancel the flip produce by glCopyTexImage */ - This->renderUpsideDown = (This->renderTarget != This->frontBuffer) && (This->renderTarget != This->backBuffer); - /* Force updating the cull mode */ - IDirect3DDevice8_GetRenderState(iface, D3DRS_CULLMODE, &value); - IDirect3DDevice8_SetRenderState(iface, D3DRS_CULLMODE, value); - /* Force updating projection matrix */ - This->last_was_rhw = FALSE; - This->proj_valid = FALSE; - } - - ret = D3D_OK; - - } else { - ERR("cannot get valides GLXFBConfig for (%u,%s)/(%u,%s)\n", BackBufferFormat, debug_d3dformat(BackBufferFormat), StencilBufferFormat, debug_d3dformat(StencilBufferFormat)); - } - -#undef PUSH1 -#undef PUSH2 - - LEAVE_GL(); - -#endif - - return ret; -} - /* Internal function called back during the CreateDevice to create a render target */ HRESULT WINAPI D3D8CB_CreateSurface(IUnknown *device, UINT Width, UINT Height, WINED3DFORMAT Format, DWORD Usage, D3DPOOL Pool, UINT Level, diff --git a/dlls/d3d8/directx.c b/dlls/d3d8/directx.c index a3235cc71c7..1366fc63656 100644 --- a/dlls/d3d8/directx.c +++ b/dlls/d3d8/directx.c @@ -35,52 +35,21 @@ #include "d3d8_private.h" -WINE_DEFAULT_DEBUG_CHANNEL(d3d); - -/* x11drv GDI escapes */ -#define X11DRV_ESCAPE 6789 -enum x11drv_escape_codes -{ - X11DRV_GET_DISPLAY, /* get X11 display for a DC */ - X11DRV_GET_DRAWABLE, /* get current drawable for a DC */ - X11DRV_GET_FONT, /* get current X font for a DC */ -}; - -#define NUM_FORMATS 7 -static const D3DFORMAT device_formats[NUM_FORMATS] = { - D3DFMT_P8, - D3DFMT_R3G3B2, - D3DFMT_R5G6B5, - D3DFMT_X1R5G5B5, - D3DFMT_X4R4G4B4, - D3DFMT_R8G8B8, - D3DFMT_X8R8G8B8 -}; - -/* retrieve the X display to use on a given DC */ -inline static Display *get_display( HDC hdc ) -{ - Display *display; - enum x11drv_escape_codes escape = X11DRV_GET_DISPLAY; - - if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape, - sizeof(display), (LPSTR)&display )) display = NULL; - return display; -} +WINE_DEFAULT_DEBUG_CHANNEL(d3d8); /* IDirect3D IUnknown parts follow: */ -HRESULT WINAPI IDirect3D8Impl_QueryInterface(LPDIRECT3D8 iface,REFIID riid,LPVOID *ppobj) +HRESULT WINAPI IDirect3D8Impl_QueryInterface(LPDIRECT3D8 iface, REFIID riid,LPVOID *ppobj) { IDirect3D8Impl *This = (IDirect3D8Impl *)iface; if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IDirect3D8)) { - IDirect3D8Impl_AddRef(iface); + IUnknown_AddRef(iface); *ppobj = This; return D3D_OK; } - WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj); + WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid),ppobj); return E_NOINTERFACE; } @@ -100,13 +69,15 @@ ULONG WINAPI IDirect3D8Impl_Release(LPDIRECT3D8 iface) { TRACE("(%p) : ReleaseRef to %ld\n", This, ref); if (ref == 0) { + TRACE("Releasing wined3d %p\n", This->WineD3D); IWineD3D_Release(This->WineD3D); HeapFree(GetProcessHeap(), 0, This); } + return ref; } -/* IDirect3D Interface follow: */ +/* IDirect3D8 Interface follow: */ HRESULT WINAPI IDirect3D8Impl_RegisterSoftwareDevice (LPDIRECT3D8 iface, void* pInitializeFunction) { IDirect3D8Impl *This = (IDirect3D8Impl *)iface; return IWineD3D_RegisterSoftwareDevice(This->WineD3D, pInitializeFunction); @@ -125,28 +96,29 @@ HRESULT WINAPI IDirect3D8Impl_GetAdapterIdentifier (LPDIRECT3D8 iface, /* dx8 and dx9 have different structures to be filled in, with incompatible layouts so pass in pointers to the places to be filled via an internal structure */ - adapter_id.Driver = pIdentifier->Driver; - adapter_id.Description = pIdentifier->Description; - adapter_id.DeviceName = NULL; - adapter_id.DriverVersion = &pIdentifier->DriverVersion; - adapter_id.VendorId = &pIdentifier->VendorId; - adapter_id.DeviceId = &pIdentifier->DeviceId; - adapter_id.SubSysId = &pIdentifier->SubSysId; - adapter_id.Revision = &pIdentifier->Revision; + adapter_id.Driver = pIdentifier->Driver; + adapter_id.Description = pIdentifier->Description; + adapter_id.DeviceName = NULL; /* d3d9 only */ + adapter_id.DriverVersion = &pIdentifier->DriverVersion; + adapter_id.VendorId = &pIdentifier->VendorId; + adapter_id.DeviceId = &pIdentifier->DeviceId; + adapter_id.SubSysId = &pIdentifier->SubSysId; + adapter_id.Revision = &pIdentifier->Revision; adapter_id.DeviceIdentifier = &pIdentifier->DeviceIdentifier; - adapter_id.WHQLLevel = &pIdentifier->WHQLLevel; + adapter_id.WHQLLevel = &pIdentifier->WHQLLevel; return IWineD3D_GetAdapterIdentifier(This->WineD3D, Adapter, Flags, &adapter_id); } UINT WINAPI IDirect3D8Impl_GetAdapterModeCount (LPDIRECT3D8 iface,UINT Adapter) { IDirect3D8Impl *This = (IDirect3D8Impl *)iface; - return IWineD3D_GetAdapterModeCount(This->WineD3D, Adapter, D3DFMT_UNKNOWN); + return IWineD3D_GetAdapterModeCount(This->WineD3D, Adapter, 0 /* format */); } HRESULT WINAPI IDirect3D8Impl_EnumAdapterModes (LPDIRECT3D8 iface, UINT Adapter, UINT Mode, D3DDISPLAYMODE* pMode) { IDirect3D8Impl *This = (IDirect3D8Impl *)iface; - return IWineD3D_EnumAdapterModes(This->WineD3D, Adapter, D3DFMT_UNKNOWN, Mode, pMode); + /* FIXME: USe a constant WINED3DFOTMAT_ANY, or something similar */ + return IWineD3D_EnumAdapterModes(This->WineD3D, Adapter, 0 /* format */, Mode, pMode); } HRESULT WINAPI IDirect3D8Impl_GetAdapterDisplayMode (LPDIRECT3D8 iface, UINT Adapter, D3DDISPLAYMODE* pMode) { @@ -220,12 +192,15 @@ HRESULT WINAPI D3D8CB_CreateRenderTarget(IUnknown *device, UINT Width, UINT Heig HRESULT res = D3D_OK; IDirect3DSurface8Impl *d3dSurface = NULL; - /* Note - Throw away MultisampleQuality and SharedHandle - only relevant for d3d9 */ + TRACE("(%p) call back\n", device); res = IDirect3DDevice8_CreateRenderTarget((IDirect3DDevice8 *)device, Width, Height, (D3DFORMAT)Format, MultiSample, Lockable, (IDirect3DSurface8 **)&d3dSurface); - if (res == D3D_OK) { - *ppSurface = d3dSurface->wineD3DSurface; + + if (SUCCEEDED(res)) { + *ppSurface = d3dSurface->wineD3DSurface; + } else { + *ppSurface = NULL; } return res; } @@ -236,15 +211,16 @@ HRESULT WINAPI D3D8CB_CreateAdditionalSwapChain(IUnknown *device, IWineD3DSwapChain ** ppSwapChain){ HRESULT res = D3D_OK; IDirect3DSwapChain8Impl *d3dSwapChain = NULL; - /* We have to pass the presentation parameters back and forth */ D3DPRESENT_PARAMETERS localParameters; + TRACE("(%p) call back\n", device); + localParameters.BackBufferWidth = *(pPresentationParameters->BackBufferWidth); localParameters.BackBufferHeight = *(pPresentationParameters->BackBufferHeight); localParameters.BackBufferFormat = *(pPresentationParameters->BackBufferFormat); localParameters.BackBufferCount = *(pPresentationParameters->BackBufferCount); localParameters.MultiSampleType = *(pPresentationParameters->MultiSampleType); - /* d3d9 only */ - /* localParameters.MultiSampleQuality = *(pPresentationParameters->MultiSampleQuality); */ + /* d3d9 only */ + /* localParameters.MultiSampleQuality = *(pPresentationParameters->MultiSampleQuality); */ localParameters.SwapEffect = *(pPresentationParameters->SwapEffect); localParameters.hDeviceWindow = *(pPresentationParameters->hDeviceWindow); localParameters.Windowed = *(pPresentationParameters->Windowed); @@ -252,307 +228,120 @@ HRESULT WINAPI D3D8CB_CreateAdditionalSwapChain(IUnknown *device, localParameters.AutoDepthStencilFormat = *(pPresentationParameters->AutoDepthStencilFormat); localParameters.Flags = *(pPresentationParameters->Flags); localParameters.FullScreen_RefreshRateInHz = *(pPresentationParameters->FullScreen_RefreshRateInHz); -/* not in d3d8 */ -/* localParameters.PresentationInterval = *(pPresentationParameters->PresentationInterval); */ + /* d3d9 only */ + /* localParameters.PresentationInterval = *(pPresentationParameters->PresentationInterval); */ - TRACE("(%p) rellaying\n", device); /*copy the presentation parameters*/ res = IDirect3DDevice8_CreateAdditionalSwapChain((IDirect3DDevice8 *)device, &localParameters, (IDirect3DSwapChain8 **)&d3dSwapChain); - if (res == D3D_OK){ + if (res == D3D_OK && d3dSwapChain != NULL){ *ppSwapChain = d3dSwapChain->wineD3DSwapChain; } else { - FIXME("failed to create additional swap chain\n"); *ppSwapChain = NULL; } - /* Copy back the presentation parameters */ - TRACE("(%p) setting up return parameters\n", device); - *pPresentationParameters->BackBufferWidth = localParameters.BackBufferWidth; - *pPresentationParameters->BackBufferHeight = localParameters.BackBufferHeight; - *pPresentationParameters->BackBufferFormat = localParameters.BackBufferFormat; - *pPresentationParameters->BackBufferCount = localParameters.BackBufferCount; - *pPresentationParameters->MultiSampleType = localParameters.MultiSampleType; -/* *pPresentationParameters->MultiSampleQuality leave alone in case wined3d set something internally */ - *pPresentationParameters->SwapEffect = localParameters.SwapEffect; - *pPresentationParameters->hDeviceWindow = localParameters.hDeviceWindow; - *pPresentationParameters->Windowed = localParameters.Windowed; - *pPresentationParameters->EnableAutoDepthStencil = localParameters.EnableAutoDepthStencil; - *pPresentationParameters->AutoDepthStencilFormat = localParameters.AutoDepthStencilFormat; - *pPresentationParameters->Flags = localParameters.Flags; - *pPresentationParameters->FullScreen_RefreshRateInHz = localParameters.FullScreen_RefreshRateInHz; -/* *pPresentationParameters->PresentationInterval leave alone in case wined3d set something internally */ + + /*Copy back the presentation parameters*/ + *pPresentationParameters->BackBufferWidth = localParameters.BackBufferWidth; + *pPresentationParameters->BackBufferHeight = localParameters.BackBufferHeight; + *pPresentationParameters->BackBufferFormat = localParameters.BackBufferFormat; + *pPresentationParameters->BackBufferCount = localParameters.BackBufferCount; + *pPresentationParameters->MultiSampleType = localParameters.MultiSampleType; + /* d3d9 only */ + /* *pPresentationParameters->MultiSampleQuality = localParameters.MultiSampleQuality; */ + *pPresentationParameters->SwapEffect = localParameters.SwapEffect; + *pPresentationParameters->hDeviceWindow = localParameters.hDeviceWindow; + *pPresentationParameters->Windowed = localParameters.Windowed; + *pPresentationParameters->EnableAutoDepthStencil = localParameters.EnableAutoDepthStencil; + *pPresentationParameters->AutoDepthStencilFormat = localParameters.AutoDepthStencilFormat; + *pPresentationParameters->Flags = localParameters.Flags; + *pPresentationParameters->FullScreen_RefreshRateInHz = localParameters.FullScreen_RefreshRateInHz; + /* d3d9 only */ + /* *pPresentationParameters->PresentationInterval = localParameters.PresentationInterval; */ return res; } -HRESULT WINAPI IDirect3D8Impl_CreateDevice (LPDIRECT3D8 iface, - UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, - DWORD BehaviourFlags, D3DPRESENT_PARAMETERS* pPresentationParameters, - IDirect3DDevice8** ppReturnedDeviceInterface) { - IDirect3DDevice8Impl *object; - HWND whichHWND; - int num; - XVisualInfo template; - HDC hDc; +/* Internal function called back during the CreateDevice to create a render target */ +HRESULT WINAPI D3D8CB_CreateDepthStencilSurface(IUnknown *device, UINT Width, UINT Height, + WINED3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, + DWORD MultisampleQuality, BOOL Discard, + IWineD3DSurface** ppSurface, HANDLE* pSharedHandle) { + HRESULT res = D3D_OK; + IDirect3DSurface8Impl *d3dSurface = NULL; + TRACE("(%p) call back\n", device); + + res = IDirect3DDevice8_CreateDepthStencilSurface((IDirect3DDevice8 *)device, Width, Height, + (D3DFORMAT)Format, MultiSample, (IDirect3DSurface8 **)&d3dSurface); + if (res == D3D_OK) { + *ppSurface = d3dSurface->wineD3DSurface; + } + return res; +} + +HRESULT WINAPI IDirect3D8Impl_CreateDevice(LPDIRECT3D8 iface, UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, + DWORD BehaviourFlags, D3DPRESENT_PARAMETERS* pPresentationParameters, + IDirect3DDevice8** ppReturnedDeviceInterface) { + + IDirect3D8Impl *This = (IDirect3D8Impl *)iface; + IDirect3DDevice8Impl *object = NULL; WINED3DPRESENT_PARAMETERS localParameters; + HRESULT hr; + TRACE("(%p) Relay \n", This); - IDirect3D8Impl *This = (IDirect3D8Impl *)iface; - TRACE("(%p)->(Adptr:%d, DevType: %x, FocusHwnd: %p, BehFlags: %lx, PresParms: %p, RetDevInt: %p)\n", This, Adapter, DeviceType, - hFocusWindow, BehaviourFlags, pPresentationParameters, ppReturnedDeviceInterface); - + /* Check the validity range of the adapter parameter */ if (Adapter >= IDirect3D8Impl_GetAdapterCount(iface)) { + *ppReturnedDeviceInterface = NULL; return D3DERR_INVALIDCALL; } - /* Allocate the storage for the device */ + /* Allocate the storage for the device object */ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DDevice8Impl)); if (NULL == object) { - return D3DERR_OUTOFVIDEOMEMORY; + FIXME("Allocation of memory failed\n"); + *ppReturnedDeviceInterface = NULL; + return D3DERR_OUTOFVIDEOMEMORY; } + object->lpVtbl = &Direct3DDevice8_Vtbl; object->ref = 1; - object->direct3d8 = This; - /** The device AddRef the direct3d8 Interface else crash in propers clients codes */ - IDirect3D8_AddRef((LPDIRECT3D8) object->direct3d8); + *ppReturnedDeviceInterface = (IDirect3DDevice8 *)object; /* Allocate an associated WineD3DDevice object */ localParameters.BackBufferWidth = &pPresentationParameters->BackBufferWidth; localParameters.BackBufferHeight = &pPresentationParameters->BackBufferHeight; - localParameters.BackBufferFormat = (WINED3DFORMAT *)&pPresentationParameters->BackBufferFormat; - localParameters.BackBufferCount = &pPresentationParameters->BackBufferCount; - localParameters.MultiSampleType = &pPresentationParameters->MultiSampleType; - localParameters.MultiSampleQuality = NULL; /* New at dx9 */ - localParameters.SwapEffect = &pPresentationParameters->SwapEffect; - localParameters.hDeviceWindow = &pPresentationParameters->hDeviceWindow; - localParameters.Windowed = &pPresentationParameters->Windowed; - localParameters.EnableAutoDepthStencil = &pPresentationParameters->EnableAutoDepthStencil; - localParameters.AutoDepthStencilFormat = (WINED3DFORMAT *)&pPresentationParameters->AutoDepthStencilFormat; - localParameters.Flags = &pPresentationParameters->Flags; - localParameters.FullScreen_RefreshRateInHz = &pPresentationParameters->FullScreen_RefreshRateInHz; - localParameters.PresentationInterval = &pPresentationParameters->FullScreen_PresentationInterval; /* Renamed in dx9 */ - IWineD3D_CreateDevice(This->WineD3D, Adapter, DeviceType, hFocusWindow, BehaviourFlags, &localParameters, &object->WineD3DDevice, (IUnknown *)object, D3D8CB_CreateAdditionalSwapChain); + localParameters.BackBufferFormat = (WINED3DFORMAT *)&pPresentationParameters->BackBufferFormat; + localParameters.BackBufferCount = &pPresentationParameters->BackBufferCount; + localParameters.MultiSampleType = &pPresentationParameters->MultiSampleType; + /* d3d9 only */ + localParameters.MultiSampleQuality = NULL; + localParameters.SwapEffect = &pPresentationParameters->SwapEffect; + localParameters.hDeviceWindow = &pPresentationParameters->hDeviceWindow; + localParameters.Windowed = &pPresentationParameters->Windowed; + localParameters.EnableAutoDepthStencil = &pPresentationParameters->EnableAutoDepthStencil; + localParameters.AutoDepthStencilFormat = (WINED3DFORMAT *)&pPresentationParameters->AutoDepthStencilFormat; + localParameters.Flags = &pPresentationParameters->Flags; + localParameters.FullScreen_RefreshRateInHz = &pPresentationParameters->FullScreen_RefreshRateInHz; + localParameters.PresentationInterval = &pPresentationParameters->FullScreen_PresentationInterval;/* Renamed in dx9 */ - /** use StateBlock Factory here, for creating the startup stateBlock */ - object->StateBlock = NULL; - IDirect3DDeviceImpl_CreateStateBlock(object, D3DSBT_ALL, NULL); - object->UpdateStateBlock = object->StateBlock; - - /* Save the creation parameters */ - object->CreateParms.AdapterOrdinal = Adapter; - object->CreateParms.DeviceType = DeviceType; - object->CreateParms.hFocusWindow = hFocusWindow; - object->CreateParms.BehaviorFlags = BehaviourFlags; - - *ppReturnedDeviceInterface = (LPDIRECT3DDEVICE8) object; - - /* Initialize settings */ - object->PresentParms.BackBufferCount = 1; /* Opengl only supports one? */ - object->adapterNo = Adapter; - object->devType = DeviceType; - - /* Initialize openGl - Note the visual is chosen as the window is created and the glcontext cannot - use different properties after that point in time. FIXME: How to handle when requested format - doesn't match actual visual? Cannot choose one here - code removed as it ONLY works if the one - it chooses is identical to the one already being used! */ - /* FIXME: Handle stencil appropriately via EnableAutoDepthStencil / AutoDepthStencilFormat */ - - /* Which hwnd are we using? */ - whichHWND = pPresentationParameters->hDeviceWindow; - if (!whichHWND) { - whichHWND = hFocusWindow; - } - whichHWND = GetAncestor(whichHWND, GA_ROOT); - if ( !( object->win = (Window)GetPropA(whichHWND, "__wine_x11_whole_window") ) ) { - ERR("Can't get drawable (window), HWND:%p doesn't have the property __wine_x11_whole_window\n", whichHWND); - return D3DERR_NOTAVAILABLE; - } - object->win_handle = whichHWND; - - hDc = GetDC(whichHWND); - object->display = get_display(hDc); - - TRACE("(%p)->(DepthStencil:(%u,%s), BackBufferFormat:(%u,%s))\n", This, - pPresentationParameters->AutoDepthStencilFormat, debug_d3dformat(pPresentationParameters->AutoDepthStencilFormat), - pPresentationParameters->BackBufferFormat, debug_d3dformat(pPresentationParameters->BackBufferFormat)); - - ENTER_GL(); - - /* Create a context based off the properties of the existing visual */ - template.visualid = (VisualID)GetPropA(GetDesktopWindow(), "__wine_x11_visual_id"); - object->visInfo = XGetVisualInfo(object->display, VisualIDMask, &template, &num); - if (NULL == object->visInfo) { - ERR("cannot really get XVisual\n"); - LEAVE_GL(); - return D3DERR_NOTAVAILABLE; - } - object->glCtx = glXCreateContext(object->display, object->visInfo, NULL, GL_TRUE); - if (NULL == object->glCtx) { - ERR("cannot create glxContext\n"); - LEAVE_GL(); - return D3DERR_NOTAVAILABLE; - } - LEAVE_GL(); - - ReleaseDC(whichHWND, hDc); - - if (object->glCtx == NULL) { - ERR("Error in context creation !\n"); - return D3DERR_INVALIDCALL; + hr =IWineD3D_CreateDevice(This->WineD3D, Adapter, DeviceType, hFocusWindow, BehaviourFlags, &localParameters, &object->WineD3DDevice, (IUnknown *)object, D3D8CB_CreateAdditionalSwapChain); + + if (hr == D3D_OK) { + TRACE("(%p) : Created Device %p\n", This, object); } else { - TRACE("Context created (HWND=%p, glContext=%p, Window=%ld, VisInfo=%p)\n", - whichHWND, object->glCtx, object->win, object->visInfo); + HeapFree(GetProcessHeap(), 0, object); + *ppReturnedDeviceInterface = NULL; } - /* If not windowed, need to go fullscreen, and resize the HWND to the appropriate */ - /* dimensions */ - if (!pPresentationParameters->Windowed) { -#if 1 - DEVMODEW devmode; - HDC hdc; - int bpp = 0; - memset(&devmode, 0, sizeof(DEVMODEW)); - devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; - MultiByteToWideChar(CP_ACP, 0, "Gamers CG", -1, devmode.dmDeviceName, CCHDEVICENAME); - hdc = CreateDCA("DISPLAY", NULL, NULL, NULL); - bpp = GetDeviceCaps(hdc, BITSPIXEL); - DeleteDC(hdc); - devmode.dmBitsPerPel = (bpp >= 24) ? 32 : bpp;/*Stupid XVidMode cannot change bpp D3DFmtGetBpp(object, pPresentationParameters->BackBufferFormat);*/ - devmode.dmPelsWidth = pPresentationParameters->BackBufferWidth; - devmode.dmPelsHeight = pPresentationParameters->BackBufferHeight; - ChangeDisplaySettingsExW(devmode.dmDeviceName, &devmode, object->win_handle, CDS_FULLSCREEN, NULL); -#else - FIXME("Requested full screen support not implemented, expect windowed operation\n"); -#endif - - /* Make popup window */ - SetWindowLongA(whichHWND, GWL_STYLE, WS_POPUP); - SetWindowPos(object->win_handle, HWND_TOP, 0, 0, - pPresentationParameters->BackBufferWidth, - pPresentationParameters->BackBufferHeight, SWP_SHOWWINDOW | SWP_FRAMECHANGED); - } - - TRACE("Creating back buffer\n"); - /* MSDN: If Windowed is TRUE and either of the BackBufferWidth/Height values is zero, - then the corresponding dimension of the client area of the hDeviceWindow - (or the focus window, if hDeviceWindow is NULL) is taken. */ - if (pPresentationParameters->Windowed && ((pPresentationParameters->BackBufferWidth == 0) || - (pPresentationParameters->BackBufferHeight == 0))) { - RECT Rect; - - GetClientRect(whichHWND, &Rect); - - if (pPresentationParameters->BackBufferWidth == 0) { - pPresentationParameters->BackBufferWidth = Rect.right; - TRACE("Updating width to %d\n", pPresentationParameters->BackBufferWidth); - } - if (pPresentationParameters->BackBufferHeight == 0) { - pPresentationParameters->BackBufferHeight = Rect.bottom; - TRACE("Updating height to %d\n", pPresentationParameters->BackBufferHeight); - } - } - - /* Save the presentation parms now filled in correctly */ - memcpy(&object->PresentParms, pPresentationParameters, sizeof(D3DPRESENT_PARAMETERS)); - - - IDirect3DDevice8Impl_CreateRenderTarget((LPDIRECT3DDEVICE8) object, - pPresentationParameters->BackBufferWidth, - pPresentationParameters->BackBufferHeight, - pPresentationParameters->BackBufferFormat, - pPresentationParameters->MultiSampleType, - TRUE, - (LPDIRECT3DSURFACE8*) &object->frontBuffer); - - IDirect3DDevice8Impl_CreateRenderTarget((LPDIRECT3DDEVICE8) object, - pPresentationParameters->BackBufferWidth, - pPresentationParameters->BackBufferHeight, - pPresentationParameters->BackBufferFormat, - pPresentationParameters->MultiSampleType, - TRUE, - (LPDIRECT3DSURFACE8*) &object->backBuffer); - - if (pPresentationParameters->EnableAutoDepthStencil) { - IDirect3DDevice8Impl_CreateDepthStencilSurface((LPDIRECT3DDEVICE8) object, - pPresentationParameters->BackBufferWidth, - pPresentationParameters->BackBufferHeight, - pPresentationParameters->AutoDepthStencilFormat, - D3DMULTISAMPLE_NONE, - (LPDIRECT3DSURFACE8*) &object->depthStencilBuffer); - } else { - object->depthStencilBuffer = NULL; - } - TRACE("FrontBuf @ %p, BackBuf @ %p, DepthStencil @ %p\n",object->frontBuffer, object->backBuffer, object->depthStencilBuffer); - - /* init the default renderTarget management */ - object->drawable = object->win; - object->render_ctx = object->glCtx; - object->renderTarget = object->backBuffer; - IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) object->renderTarget); - object->stencilBufferTarget = object->depthStencilBuffer; - if (NULL != object->stencilBufferTarget) { - IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) object->stencilBufferTarget); - } - - ENTER_GL(); - - if (glXMakeCurrent(object->display, object->win, object->glCtx) == False) { - ERR("Error in setting current context (context %p drawable %ld)!\n", object->glCtx, object->win); - } - checkGLcall("glXMakeCurrent"); - - /* Clear the screen */ - glClearColor(1.0, 0.0, 0.0, 0.0); - checkGLcall("glClearColor"); - glColor3f(1.0, 1.0, 1.0); - checkGLcall("glColor3f"); - - glEnable(GL_LIGHTING); - checkGLcall("glEnable"); - - glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); - checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);"); - - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); - checkGLcall("glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);"); - - glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR); - checkGLcall("glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);"); - - /* Setup all the devices defaults */ - IDirect3DDeviceImpl_InitStartupStateBlock(object); - - LEAVE_GL(); - - { /* Set a default viewport */ - D3DVIEWPORT8 vp; - vp.X = 0; - vp.Y = 0; - vp.Width = pPresentationParameters->BackBufferWidth; - vp.Height = pPresentationParameters->BackBufferHeight; - vp.MinZ = 0.0f; - vp.MaxZ = 1.0f; - IDirect3DDevice8Impl_SetViewport((LPDIRECT3DDEVICE8) object, &vp); - } - - /* Initialize the current view state */ - object->modelview_valid = 1; - object->proj_valid = 0; - object->view_ident = 1; - object->last_was_rhw = 0; - glGetIntegerv(GL_MAX_LIGHTS, &object->maxConcurrentLights); - TRACE("(%p,%d) All defaults now set up, leaving CreateDevice with %p\n", This, Adapter, object); - - /* Clear the screen */ - IDirect3DDevice8Impl_Clear((LPDIRECT3DDEVICE8) object, 0, NULL, D3DCLEAR_STENCIL|D3DCLEAR_ZBUFFER|D3DCLEAR_TARGET, 0x00, 1.0, 0); - - return D3D_OK; + return hr; } const IDirect3D8Vtbl Direct3D8_Vtbl = { + /* IUnknown */ IDirect3D8Impl_QueryInterface, IDirect3D8Impl_AddRef, IDirect3D8Impl_Release, + /* IDirect3D8 */ IDirect3D8Impl_RegisterSoftwareDevice, IDirect3D8Impl_GetAdapterCount, IDirect3D8Impl_GetAdapterIdentifier, diff --git a/dlls/d3d8/drawprim.c b/dlls/d3d8/drawprim.c deleted file mode 100644 index 445aefd4fad..00000000000 --- a/dlls/d3d8/drawprim.c +++ /dev/null @@ -1,1663 +0,0 @@ -/* - * D3D8 utils - * - * Copyright 2002-2004 Jason Edmeades - * Copyright 2002-2004 Raphael Junqueira - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "config.h" - -#include -#include - -#define NONAMELESSUNION -#define NONAMELESSSTRUCT -#include "windef.h" -#include "winbase.h" -#include "winuser.h" -#include "wingdi.h" -#include "wine/debug.h" - -#include "d3d8_private.h" - -WINE_DEFAULT_DEBUG_CHANNEL(d3d); -WINE_DECLARE_DEBUG_CHANNEL(d3d_shader); - -extern IDirect3DVertexShaderImpl* VertexShaders[64]; -extern IDirect3DVertexShaderDeclarationImpl* VertexShaderDeclarations[64]; -extern IDirect3DPixelShaderImpl* PixelShaders[64]; - -/* Useful holding place for 4 floats */ -typedef struct _D3DVECTOR_4 { - float x; - float y; - float z; - float w; -} D3DVECTOR_4; - -#undef GL_VERSION_1_4 /* To be fixed, caused by mesa headers */ - -/* Returns bits for what is expected from the fixed function pipeline, and whether - a vertex shader will be in use. Note the fvf bits returned may be split over - multiple streams only if the vertex shader was created, otherwise it all relates - to stream 0 */ -static BOOL initializeFVF(LPDIRECT3DDEVICE8 iface, - DWORD *FVFbits, /* What to expect in the FVF across all streams */ - BOOL *useVertexShaderFunction) /* Should we use the vertex shader */ -{ - - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - - /* The first thing to work out is if we are using the fixed function pipeline - which is either SetVertexShader with < VS_HIGHESTFIXEDFXF - in which case this - is the FVF, or with a shader which was created with no function - in which - case there is an FVF per declared stream. If this occurs, we also maintain - an 'OR' of all the FVF's together so we know what to expect across all the - streams */ - - if (This->UpdateStateBlock->VertexShader <= VS_HIGHESTFIXEDFXF) { - - /* Use this as the FVF */ - *FVFbits = This->UpdateStateBlock->VertexShader; - *useVertexShaderFunction = FALSE; - TRACE("FVF explicitally defined, using fixed function pipeline with FVF=%lx\n", *FVFbits); - - } else { - - /* Use created shader */ - IDirect3DVertexShaderImpl* vertex_shader = NULL; - vertex_shader = VERTEX_SHADER(This->UpdateStateBlock->VertexShader); - - if (vertex_shader == NULL) { - - /* Hmm - User pulled figure out of the air? Unlikely, probably a bug */ - ERR("trying to use unitialised vertex shader: %lu\n", This->UpdateStateBlock->VertexShader); - return TRUE; - - } else { - - *FVFbits = This->UpdateStateBlock->vertexShaderDecl->allFVF; - - if (vertex_shader->function == NULL) { - /* No function, so many streams supplied plus FVF definition pre stream */ - *useVertexShaderFunction = FALSE; - TRACE("vertex shader (%lx) declared without program, using fixed function pipeline with FVF=%lx\n", - This->StateBlock->VertexShader, *FVFbits); - } else { - /* Vertex shader needs calling */ - *useVertexShaderFunction = TRUE; - TRACE("vertex shader will be used (unusued FVF=%lx)\n", *FVFbits); - } - } - } - return FALSE; -} - -/* Issues the glBegin call for gl given the primitive type and count */ -static DWORD primitiveToGl(D3DPRIMITIVETYPE PrimitiveType, - DWORD NumPrimitives, - GLenum *primType) -{ - DWORD NumVertexes = NumPrimitives; - - switch (PrimitiveType) { - case D3DPT_POINTLIST: - TRACE("POINTS\n"); - *primType = GL_POINTS; - NumVertexes = NumPrimitives; - break; - - case D3DPT_LINELIST: - TRACE("LINES\n"); - *primType = GL_LINES; - NumVertexes = NumPrimitives * 2; - break; - - case D3DPT_LINESTRIP: - TRACE("LINE_STRIP\n"); - *primType = GL_LINE_STRIP; - NumVertexes = NumPrimitives + 1; - break; - - case D3DPT_TRIANGLELIST: - TRACE("TRIANGLES\n"); - *primType = GL_TRIANGLES; - NumVertexes = NumPrimitives * 3; - break; - - case D3DPT_TRIANGLESTRIP: - TRACE("TRIANGLE_STRIP\n"); - *primType = GL_TRIANGLE_STRIP; - NumVertexes = NumPrimitives + 2; - break; - - case D3DPT_TRIANGLEFAN: - TRACE("TRIANGLE_FAN\n"); - *primType = GL_TRIANGLE_FAN; - NumVertexes = NumPrimitives + 2; - break; - - default: - FIXME("Unhandled primitive\n"); - *primType = GL_POINTS; - break; - } - return NumVertexes; -} - -/* Ensure the appropriate material states are set up - only change - state if really required */ -static void init_materials(LPDIRECT3DDEVICE8 iface, BOOL isDiffuseSupplied) { - - BOOL requires_material_reset = FALSE; - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - - if (This->tracking_color == NEEDS_TRACKING && isDiffuseSupplied) { - /* If we have not set up the material color tracking, do it now as required */ - glDisable(GL_COLOR_MATERIAL); /* Note: Man pages state must enable AFTER calling glColorMaterial! Required?*/ - checkGLcall("glDisable GL_COLOR_MATERIAL"); - TRACE("glColorMaterial Parm=%x\n", This->tracking_parm); - glColorMaterial(GL_FRONT_AND_BACK, This->tracking_parm); - checkGLcall("glColorMaterial(GL_FRONT_AND_BACK, Parm)"); - glEnable(GL_COLOR_MATERIAL); - checkGLcall("glEnable GL_COLOR_MATERIAL"); - This->tracking_color = IS_TRACKING; - requires_material_reset = TRUE; /* Restore material settings as will be used */ - - } else if ((This->tracking_color == IS_TRACKING && isDiffuseSupplied == FALSE) || - (This->tracking_color == NEEDS_TRACKING && isDiffuseSupplied == FALSE)) { - /* If we are tracking the current color but one isn't supplied, don't! */ - glDisable(GL_COLOR_MATERIAL); - checkGLcall("glDisable GL_COLOR_MATERIAL"); - This->tracking_color = NEEDS_TRACKING; - requires_material_reset = TRUE; /* Restore material settings as will be used */ - - } else if (This->tracking_color == IS_TRACKING && isDiffuseSupplied) { - /* No need to reset material colors since no change to gl_color_material */ - requires_material_reset = FALSE; - - } else if (This->tracking_color == NEEDS_DISABLE) { - glDisable(GL_COLOR_MATERIAL); - checkGLcall("glDisable GL_COLOR_MATERIAL"); - This->tracking_color = DISABLED_TRACKING; - requires_material_reset = TRUE; /* Restore material settings as will be used */ - } - - /* Reset the material colors which may have been tracking the color*/ - if (requires_material_reset) { - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float*) &This->StateBlock->material.Ambient); - checkGLcall("glMaterialfv"); - glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float*) &This->StateBlock->material.Diffuse); - checkGLcall("glMaterialfv"); - if (This->StateBlock->renderstate[D3DRS_SPECULARENABLE]) { - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float*) &This->StateBlock->material.Specular); - checkGLcall("glMaterialfv"); - } else { - float black[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]); - checkGLcall("glMaterialfv"); - } - glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float*) &This->StateBlock->material.Emissive); - checkGLcall("glMaterialfv"); - } - -} - -static GLfloat invymat[16]={ - 1.0f, 0.0f, 0.0f, 0.0f, - 0.0f, -1.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f}; - -/* Setup views - Transformed & lit if RHW, else untransformed. - Only unlit if Normals are supplied - Returns: Whether to restore lighting afterwards */ -static BOOL primitiveInitState(LPDIRECT3DDEVICE8 iface, BOOL vtx_transformed, BOOL vtx_lit, BOOL useVS) { - - BOOL isLightingOn = FALSE; - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - - /* If no normals, DISABLE lighting otherwise, don't touch lighing as it is - set by the appropriate render state. Note Vertex Shader output is already lit */ - if (vtx_lit || useVS) { - isLightingOn = glIsEnabled(GL_LIGHTING); - glDisable(GL_LIGHTING); - checkGLcall("glDisable(GL_LIGHTING);"); - TRACE("Disabled lighting as no normals supplied, old state = %d\n", isLightingOn); - } - - if (!useVS && vtx_transformed) { - - /* If the last draw was transformed as well, no need to reapply all the matrixes */ - if (!This->last_was_rhw) { - - double X, Y, height, width, minZ, maxZ; - This->last_was_rhw = TRUE; - - /* Transformed already into viewport coordinates, so we do not need transform - matrices. Reset all matrices to identity and leave the default matrix in world - mode. */ - glMatrixMode(GL_MODELVIEW); - checkGLcall("glMatrixMode"); - glLoadIdentity(); - checkGLcall("glLoadIdentity"); - - glMatrixMode(GL_PROJECTION); - checkGLcall("glMatrixMode"); - glLoadIdentity(); - checkGLcall("glLoadIdentity"); - - /* Set up the viewport to be full viewport */ - X = This->StateBlock->viewport.X; - Y = This->StateBlock->viewport.Y; - height = This->StateBlock->viewport.Height; - width = This->StateBlock->viewport.Width; - minZ = This->StateBlock->viewport.MinZ; - maxZ = This->StateBlock->viewport.MaxZ; - TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, -minZ, -maxZ); - glOrtho(X, X + width, Y + height, Y, -minZ, -maxZ); - checkGLcall("glOrtho"); - - /* Window Coord 0 is the middle of the first pixel, so translate by half - a pixel (See comment above glTranslate below) */ - glTranslatef(0.5, 0.5, 0); - checkGLcall("glTranslatef(0.5, 0.5, 0)"); - if (This->renderUpsideDown) { - glMultMatrixf(invymat); - checkGLcall("glMultMatrixf(invymat)"); - } - } - - } else { - - /* Untransformed, so relies on the view and projection matrices */ - - if (!useVS && (This->last_was_rhw || !This->modelview_valid)) { - /* Only reapply when have to */ - This->modelview_valid = TRUE; - glMatrixMode(GL_MODELVIEW); - checkGLcall("glMatrixMode"); - - /* In the general case, the view matrix is the identity matrix */ - if (This->view_ident) { - glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_WORLDMATRIX(0)].u.m[0][0]); - checkGLcall("glLoadMatrixf"); - } else { - glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0]); - checkGLcall("glLoadMatrixf"); - glMultMatrixf((float *) &This->StateBlock->transforms[D3DTS_WORLDMATRIX(0)].u.m[0][0]); - checkGLcall("glMultMatrixf"); - } - } - - if (!useVS && (This->last_was_rhw || !This->proj_valid)) { - /* Only reapply when have to */ - This->proj_valid = TRUE; - glMatrixMode(GL_PROJECTION); - checkGLcall("glMatrixMode"); - - /* The rule is that the window coordinate 0 does not correspond to the - beginning of the first pixel, but the center of the first pixel. - As a consequence if you want to correctly draw one line exactly from - the left to the right end of the viewport (with all matrices set to - be identity), the x coords of both ends of the line would be not - -1 and 1 respectively but (-1-1/viewport_widh) and (1-1/viewport_width) - instead. */ - glLoadIdentity(); - glTranslatef(1.0/This->StateBlock->viewport.Width, -1.0/This->StateBlock->viewport.Height, 0); - checkGLcall("glTranslatef (1.0/width, -1.0/height, 0)"); - - if (This->renderUpsideDown) { - glMultMatrixf(invymat); - checkGLcall("glMultMatrixf(invymat)"); - } - glMultMatrixf((float *) &This->StateBlock->transforms[D3DTS_PROJECTION].u.m[0][0]); - checkGLcall("glLoadMatrixf"); - } - - /* Vertex Shader output is already transformed, so set up identity matrices */ - /* FIXME: Actually, only true for software emulated ones, so when h/w ones - come along this needs to take into account whether s/w ones were - requested or not */ - if (useVS) { - glMatrixMode(GL_MODELVIEW); - checkGLcall("glMatrixMode"); - glLoadIdentity(); - glMatrixMode(GL_PROJECTION); - checkGLcall("glMatrixMode"); - glLoadIdentity(); - /* Window Coord 0 is the middle of the first pixel, so translate by half - a pixel (See comment above glTranslate above) */ - glTranslatef(1.0/This->StateBlock->viewport.Width, -1.0/This->StateBlock->viewport.Height, 0); - checkGLcall("glTranslatef (1.0/width, -1.0/height, 0)"); - if (This->renderUpsideDown) { - glMultMatrixf(invymat); - checkGLcall("glMultMatrixf(invymat)"); - } - This->modelview_valid = FALSE; - This->proj_valid = FALSE; - } - This->last_was_rhw = FALSE; - } - return isLightingOn; -} - -static void primitiveConvertToStridedData(LPDIRECT3DDEVICE8 iface, Direct3DVertexStridedData *strided, LONG BaseVertexIndex) { - - short LoopThroughTo = 0; - short nStream; - BOOL canDoViaGLPointers = TRUE; - int numBlends; - int numTextures; - int textureNo; - int coordIdxInfo = 0x00; /* Information on number of coords supplied */ - int numCoords[8]; /* Holding place for D3DFVF_TEXTUREFORMATx */ - - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - - /* OK, Now to setup the data locations - For the non-created vertex shaders, the VertexShader var holds the real - FVF and only stream 0 matters - For the created vertex shaders, there is an FVF per stream */ - if (!This->StateBlock->streamIsUP && (This->UpdateStateBlock->VertexShader > VS_HIGHESTFIXEDFXF)) { - LoopThroughTo = MAX_STREAMS; - } else { - LoopThroughTo = 1; - } - - /* Work through stream by stream */ - for (nStream=0; nStreamStateBlock->stream_stride[nStream]; - BYTE *data = NULL; - DWORD thisFVF = 0; - - /* Skip empty streams */ - if (This->StateBlock->stream_source[nStream] == NULL) continue; - - /* Retrieve appropriate FVF */ - if (LoopThroughTo == 1) { /* VertexShader is FVF */ - thisFVF = This->UpdateStateBlock->VertexShader; - /* Handle memory passed directly as well as vertex buffers */ - if (This->StateBlock->streamIsUP) { - data = (BYTE *)This->StateBlock->stream_source[nStream]; - } else { - data = ((IDirect3DVertexBuffer8Impl *)This->StateBlock->stream_source[nStream])->allocatedMemory; - } - } else { - thisFVF = This->StateBlock->vertexShaderDecl->fvf[nStream]; - data = ((IDirect3DVertexBuffer8Impl *)This->StateBlock->stream_source[nStream])->allocatedMemory; - } - VTRACE(("FVF for stream %d is %lx\n", nStream, thisFVF)); - if (thisFVF == 0) continue; - - /* Now convert the stream into pointers */ - - /* Shuffle to the beginning of the vertexes to render and index from there */ - data = data + (BaseVertexIndex * stride); - - /* Either 3 or 4 floats depending on the FVF */ - /* FIXME: Can blending data be in a different stream to the position data? - and if so using the fixed pipeline how do we handle it */ - if (thisFVF & D3DFVF_POSITION_MASK) { - strided->u.s.position.lpData = data; - strided->u.s.position.dwType = D3DVSDT_FLOAT3; - strided->u.s.position.dwStride = stride; - data += 3 * sizeof(float); - if (thisFVF & D3DFVF_XYZRHW) { - strided->u.s.position.dwType = D3DVSDT_FLOAT4; - data += sizeof(float); - } - } - - /* Blending is numBlends * FLOATs followed by a DWORD for UBYTE4 */ - /** do we have to Check This->UpdateStateBlock->renderstate[D3DRS_INDEXEDVERTEXBLENDENABLE] ? */ - numBlends = ((thisFVF & D3DFVF_POSITION_MASK) >> 1) - 2 + - ((FALSE == (thisFVF & D3DFVF_LASTBETA_UBYTE4)) ? 0 : -1); /* WARNING can be < 0 because -2 */ - if (numBlends > 0) { - canDoViaGLPointers = FALSE; - strided->u.s.blendWeights.lpData = data; - strided->u.s.blendWeights.dwType = D3DVSDT_FLOAT1 + (numBlends - 1); - strided->u.s.blendWeights.dwStride = stride; - data += numBlends * sizeof(FLOAT); - - if (thisFVF & D3DFVF_LASTBETA_UBYTE4) { - strided->u.s.blendMatrixIndices.lpData = data; - strided->u.s.blendMatrixIndices.dwType = D3DVSDT_UBYTE4; - strided->u.s.blendMatrixIndices.dwStride= stride; - data += sizeof(DWORD); - } - } - - /* Normal is always 3 floats */ - if (thisFVF & D3DFVF_NORMAL) { - strided->u.s.normal.lpData = data; - strided->u.s.normal.dwType = D3DVSDT_FLOAT3; - strided->u.s.normal.dwStride = stride; - data += 3 * sizeof(FLOAT); - } - - /* Pointsize is a single float */ - if (thisFVF & D3DFVF_PSIZE) { - strided->u.s.pSize.lpData = data; - strided->u.s.pSize.dwType = D3DVSDT_FLOAT1; - strided->u.s.pSize.dwStride = stride; - data += sizeof(FLOAT); - } - - /* Diffuse is 4 unsigned bytes */ - if (thisFVF & D3DFVF_DIFFUSE) { - strided->u.s.diffuse.lpData = data; - strided->u.s.diffuse.dwType = D3DVSDT_SHORT4; - strided->u.s.diffuse.dwStride = stride; - data += sizeof(DWORD); - } - - /* Specular is 4 unsigned bytes */ - if (thisFVF & D3DFVF_SPECULAR) { - strided->u.s.specular.lpData = data; - strided->u.s.specular.dwType = D3DVSDT_SHORT4; - strided->u.s.specular.dwStride = stride; - data += sizeof(DWORD); - } - - /* Texture coords */ - numTextures = (thisFVF & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT; - coordIdxInfo = (thisFVF & 0x00FF0000) >> 16; /* 16 is from definition of D3DFVF_TEXCOORDSIZE1, and is 8 (0-7 stages) * 2bits long */ - - /* numTextures indicates the number of texture coordinates supplied */ - /* However, the first set may not be for stage 0 texture - it all */ - /* depends on D3DTSS_TEXCOORDINDEX. */ - /* The number of bytes for each coordinate set is based off */ - /* D3DFVF_TEXCOORDSIZEn, which are the bottom 2 bits */ - - /* So, for each supplied texture extract the coords */ - for (textureNo = 0; textureNo < numTextures; ++textureNo) { - - strided->u.s.texCoords[textureNo].lpData = data; - strided->u.s.texCoords[textureNo].dwType = D3DVSDT_FLOAT1; - strided->u.s.texCoords[textureNo].dwStride = stride; - numCoords[textureNo] = coordIdxInfo & 0x03; - - /* Always one set */ - data += sizeof(float); - if (numCoords[textureNo] != D3DFVF_TEXTUREFORMAT1) { - strided->u.s.texCoords[textureNo].dwType = D3DVSDT_FLOAT2; - data += sizeof(float); - if (numCoords[textureNo] != D3DFVF_TEXTUREFORMAT2) { - strided->u.s.texCoords[textureNo].dwType = D3DVSDT_FLOAT3; - data += sizeof(float); - if (numCoords[textureNo] != D3DFVF_TEXTUREFORMAT3) { - strided->u.s.texCoords[textureNo].dwType = D3DVSDT_FLOAT4; - data += sizeof(float); - } - } - } - coordIdxInfo = coordIdxInfo >> 2; /* Drop bottom two bits */ - } - } -} - -/* Draw a single vertex using this information */ -static void draw_vertex(LPDIRECT3DDEVICE8 iface, /* interface */ - BOOL isXYZ, float x, float y, float z, float rhw, /* xyzn position*/ - BOOL isNormal, float nx, float ny, float nz, /* normal */ - BOOL isDiffuse, float *dRGBA, /* 1st colors */ - BOOL isSpecular, float *sRGB, /* 2ndry colors */ - BOOL isPtSize, float ptSize, /* pointSize */ - D3DVECTOR_4 *texcoords, int *numcoords) /* texture info */ -{ - unsigned int textureNo; - float s, t, r, q; - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - - /* Diffuse -------------------------------- */ - if (isDiffuse) { - glColor4fv(dRGBA); - VTRACE(("glColor4f: r,g,b,a=%f,%f,%f,%f\n", dRGBA[0], dRGBA[1], dRGBA[2], dRGBA[3])); - } - - /* Specular Colour ------------------------------------------*/ - if (isSpecular) { - if (GL_SUPPORT(EXT_SECONDARY_COLOR)) { - GL_EXTCALL(glSecondaryColor3fvEXT(sRGB)); - VTRACE(("glSecondaryColor4f: r,g,b=%f,%f,%f\n", sRGB[0], sRGB[1], sRGB[2])); - } else { - VTRACE(("Specular color extensions not supplied\n")); - } - } - - /* Normal -------------------------------- */ - if (isNormal) { - VTRACE(("glNormal:nx,ny,nz=%f,%f,%f\n", nx,ny,nz)); - glNormal3f(nx, ny, nz); - } - - /* Point Size ----------------------------------------------*/ - if (isPtSize) { - - /* no such functionality in the fixed function GL pipeline */ - FIXME("Cannot change ptSize here in openGl\n"); - } - - /* Texture coords --------------------------- */ - for (textureNo = 0; textureNo < GL_LIMITS(textures); ++textureNo) { - - if (!GL_SUPPORT(ARB_MULTITEXTURE) && textureNo > 0) { - FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n"); - continue ; - } - - /* Query tex coords */ - if (This->StateBlock->textures[textureNo] != NULL) { - - int coordIdx = This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXCOORDINDEX]; - if (coordIdx > 7) { - VTRACE(("tex: %d - Skip tex coords, as being system generated\n", textureNo)); - continue; - } else if (numcoords[coordIdx] == 0) { - TRACE("tex: %d - Skipping tex coords, as no data supplied or no coords supplied\n", textureNo); - continue; - } else { - - /* Initialize vars */ - s = 0.0f; - t = 0.0f; - r = 0.0f; - q = 0.0f; - - switch (numcoords[coordIdx]) { - case 4: q = texcoords[coordIdx].w; /* drop through */ - case 3: r = texcoords[coordIdx].z; /* drop through */ - case 2: t = texcoords[coordIdx].y; /* drop through */ - case 1: s = texcoords[coordIdx].x; - } - - switch (numcoords[coordIdx]) { /* Supply the provided texture coords */ - case D3DTTFF_COUNT1: - VTRACE(("tex:%d, s=%f\n", textureNo, s)); - if (GL_SUPPORT(ARB_MULTITEXTURE)) { -#if defined(GL_VERSION_1_3) - glMultiTexCoord1f(GL_TEXTURE0 + textureNo, s); -#else - glMultiTexCoord1fARB(GL_TEXTURE0_ARB + textureNo, s); -#endif - } else { - glTexCoord1f(s); - } - break; - case D3DTTFF_COUNT2: - VTRACE(("tex:%d, s=%f, t=%f\n", textureNo, s, t)); - if (GL_SUPPORT(ARB_MULTITEXTURE)) { -#if defined(GL_VERSION_1_3) - glMultiTexCoord2f(GL_TEXTURE0 + textureNo, s, t); -#else - glMultiTexCoord2fARB(GL_TEXTURE0_ARB + textureNo, s, t); -#endif - } else { - glTexCoord2f(s, t); - } - break; - case D3DTTFF_COUNT3: - VTRACE(("tex:%d, s=%f, t=%f, r=%f\n", textureNo, s, t, r)); - if (GL_SUPPORT(ARB_MULTITEXTURE)) { -#if defined(GL_VERSION_1_3) - glMultiTexCoord3f(GL_TEXTURE0 + textureNo, s, t, r); -#else - glMultiTexCoord3fARB(GL_TEXTURE0_ARB + textureNo, s, t, r); -#endif - } else { - glTexCoord3f(s, t, r); - } - break; - case D3DTTFF_COUNT4: - VTRACE(("tex:%d, s=%f, t=%f, r=%f, q=%f\n", textureNo, s, t, r, q)); - if (GL_SUPPORT(ARB_MULTITEXTURE)) { -#if defined(GL_VERSION_1_3) - glMultiTexCoord4f(GL_TEXTURE0 + textureNo, s, t, r, q); -#else - glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, s, t, r, q); -#endif - } else { - glTexCoord4f(s, t, r, q); - } - break; - default: - FIXME("Should not get here as numCoords should be 0->4 (%x)!\n", numcoords[coordIdx]); - } - } - } - } /* End of textures */ - - /* Position -------------------------------- */ - if (isXYZ) { - if (1.0f == rhw || rhw < 0.00001f) { - VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f\n", x,y,z)); - glVertex3f(x, y, z); - } else { - /* Cannot optimize by dividing through by rhw as rhw is required - later for perspective in the GL pipeline for vertex shaders */ - VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f / rhw=%f\n", x,y,z,rhw)); - glVertex4f(x,y,z,rhw); - } - } -} - -/* - * Actually draw using the supplied information. - * Faster GL version using pointers to data, harder to debug though - * Note does not handle vertex shaders yet - */ -static void drawStridedFast(LPDIRECT3DDEVICE8 iface, Direct3DVertexStridedData *sd, - int PrimitiveType, ULONG NumPrimitives, - const void *idxData, short idxSize, ULONG minIndex, ULONG startIdx) { - unsigned int textureNo = 0; - GLenum glPrimType = GL_POINTS; - int NumVertexes = NumPrimitives; - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - - TRACE("Using fast vertex array code\n"); - - /* Vertex Pointers -----------------------------------------*/ - if (sd->u.s.position.lpData != NULL) { - - /* Note dwType == float3 or float4 == 2 or 3 */ - VTRACE(("glVertexPointer(%ld, GL_FLOAT, %ld, %p)\n", - sd->u.s.position.dwStride, - sd->u.s.position.dwType + 1, - sd->u.s.position.lpData)); - - /* Disable RHW mode as 'w' coord handling for rhw mode should - not impact screen position whereas in GL it does. This may - result in very slightly distored textures in rhw mode, but - a very minimal different */ - glVertexPointer(3, GL_FLOAT, /* RHW: Was 'sd->u.s.position.dwType + 1' */ - sd->u.s.position.dwStride, - sd->u.s.position.lpData); - checkGLcall("glVertexPointer(...)"); - glEnableClientState(GL_VERTEX_ARRAY); - checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)"); - - } else { - - glDisableClientState(GL_VERTEX_ARRAY); - checkGLcall("glDisableClientState(GL_VERTEX_ARRAY)"); - } - - /* Blend Data ----------------------------------------------*/ - if ((sd->u.s.blendWeights.lpData != NULL) || - (sd->u.s.blendMatrixIndices.lpData != NULL)) { - /* FIXME: Won't get here as will drop to slow method */ - FIXME("Blending not supported in fast draw routine\n"); - -#if 0 /* Vertex blend support needs to be added */ - if (GL_SUPPORT(ARB_VERTEX_BLEND)) { - /*FIXME("TODO\n");*/ - } else if (GL_SUPPORT(EXT_VERTEX_WEIGHTING)) { - /*FIXME("TODO\n");*/ - /* - GLExtCall(glVertexWeightPointerEXT)(numBlends, GL_FLOAT, skip, curPos); - checkGLcall("glVertexWeightPointerEXT(numBlends, ...)"); - glEnableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT); - checkGLcall("glEnableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT)"); - */ - } else { - FIXME("unsupported blending in openGl\n"); - } - } else { - if (GL_SUPPORT(ARB_VERTEX_BLEND)) { - FIXME("TODO\n"); - } else if (GL_SUPPORT(EXT_VERTEX_WEIGHTING)) { - FIXME("TODO\n"); - /* - glDisableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT); - checkGLcall("glDisableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT)"); - */ - } -#endif - } - - /* Normals -------------------------------------------------*/ - if (sd->u.s.normal.lpData != NULL) { - - /* Note dwType == float3 or float4 == 2 or 3 */ - VTRACE(("glNormalPointer(GL_FLOAT, %ld, %p)\n", - sd->u.s.normal.dwStride, - sd->u.s.normal.lpData)); - glNormalPointer(GL_FLOAT, - sd->u.s.normal.dwStride, - sd->u.s.normal.lpData); - checkGLcall("glNormalPointer(...)"); - glEnableClientState(GL_NORMAL_ARRAY); - checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)"); - - } else { - - glDisableClientState(GL_NORMAL_ARRAY); - checkGLcall("glDisableClientState(GL_NORMAL_ARRAY)"); - glNormal3f(0, 0, 1); - checkGLcall("glNormal3f(0, 0, 1)"); - } - - /* Point Size ----------------------------------------------*/ - if (sd->u.s.pSize.lpData != NULL) { - - /* no such functionality in the fixed function GL pipeline */ - /* FIXME: Won't get here as will drop to slow method */ - FIXME("Cannot change ptSize here in openGl\n"); - } - - /* Diffuse Colour ------------------------------------------*/ - /* WARNING: Data here MUST be in RGBA format, so cannot */ - /* go directly into fast mode from app pgm, because */ - /* directx requires data in BGRA format. */ - if (sd->u.s.diffuse.lpData != NULL) { - - /* Note dwType == float3 or float4 == 2 or 3 */ - VTRACE(("glColorPointer(4, GL_UNSIGNED_BYTE, %ld, %p)\n", - sd->u.s.diffuse.dwStride, - sd->u.s.diffuse.lpData)); - glColorPointer(4, GL_UNSIGNED_BYTE, - sd->u.s.diffuse.dwStride, - sd->u.s.diffuse.lpData); - checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)"); - glEnableClientState(GL_COLOR_ARRAY); - checkGLcall("glEnableClientState(GL_COLOR_ARRAY)"); - - } else { - - glDisableClientState(GL_COLOR_ARRAY); - checkGLcall("glDisableClientState(GL_COLOR_ARRAY)"); - glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - checkGLcall("glColor4f(1, 1, 1, 1)"); - } - - /* Specular Colour ------------------------------------------*/ - if (sd->u.s.specular.lpData != NULL) { - - /* Note dwType == float3 or float4 == 2 or 3 */ - VTRACE(("glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, %ld, %p)\n", - sd->u.s.specular.dwStride, - sd->u.s.specular.lpData)); - - if (GL_SUPPORT(EXT_SECONDARY_COLOR)) { - GL_EXTCALL(glSecondaryColorPointerEXT)(4, GL_UNSIGNED_BYTE, - sd->u.s.specular.dwStride, - sd->u.s.specular.lpData); - vcheckGLcall("glSecondaryColorPointerEXT(4, GL_UNSIGNED_BYTE, ...)"); - glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT); - vcheckGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)"); - } else { - /* Missing specular color is not critical, no warnings */ - VTRACE(("Specular colour is not supported in this GL implementation\n")); - } - - } else { - - if (GL_SUPPORT(EXT_SECONDARY_COLOR)) { - glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT); - checkGLcall("glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)"); - GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0); - checkGLcall("glSecondaryColor3fEXT(0, 0, 0)"); - } else { - /* Missing specular color is not critical, no warnings */ - VTRACE(("Specular colour is not supported in this GL implementation\n")); - } - } - - /* Texture coords -------------------------------------------*/ - for (textureNo = 0; textureNo < GL_LIMITS(textures); ++textureNo) { - - /* Select the correct texture stage */ -#if defined(GL_VERSION_1_3) - glClientActiveTexture(GL_TEXTURE0 + textureNo); -#else - glClientActiveTextureARB(GL_TEXTURE0_ARB + textureNo); -#endif - - /* Query tex coords */ - if (This->StateBlock->textures[textureNo] != NULL) { - int coordIdx = This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXCOORDINDEX]; - - if (!GL_SUPPORT(ARB_MULTITEXTURE) && textureNo > 0) { - FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n"); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); -#if defined(GL_VERSION_1_3) - glMultiTexCoord4f(GL_TEXTURE0 + textureNo, 0, 0, 0, 1); -#else - glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1); -#endif - continue; - } - - if (coordIdx > 7) { - VTRACE(("tex: %d - Skip tex coords, as being system generated\n", textureNo)); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); -#if defined(GL_VERSION_1_3) - glMultiTexCoord4f(GL_TEXTURE0 + textureNo, 0, 0, 0, 1); -#else - glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1); -#endif - } else if (sd->u.s.texCoords[coordIdx].lpData == NULL) { - VTRACE(("Bound texture but no texture coordinates supplied, so skipping\n")); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); -#if defined(GL_VERSION_1_3) - glMultiTexCoord4f(GL_TEXTURE0 + textureNo, 0, 0, 0, 1); -#else - glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1); -#endif - } else { - - /* The coords to supply depend completely on the fvf / vertex shader */ - GLint size; - GLenum type; - - switch (sd->u.s.texCoords[coordIdx].dwType) { - case D3DVSDT_FLOAT1: size = 1, type = GL_FLOAT; break; - case D3DVSDT_FLOAT2: size = 2, type = GL_FLOAT; break; - case D3DVSDT_FLOAT3: size = 3, type = GL_FLOAT; break; - case D3DVSDT_FLOAT4: size = 4, type = GL_FLOAT; break; - case D3DVSDT_SHORT2: size = 2, type = GL_SHORT; break; - case D3DVSDT_SHORT4: size = 4, type = GL_SHORT; break; - case D3DVSDT_UBYTE4: size = 4, type = GL_UNSIGNED_BYTE; break; - default: FIXME("Unrecognized data type %ld\n", sd->u.s.texCoords[coordIdx].dwType); - size = 4; type = GL_UNSIGNED_BYTE; - } - - glTexCoordPointer(size, type, sd->u.s.texCoords[coordIdx].dwStride, sd->u.s.texCoords[coordIdx].lpData); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - } - } else { - glDisableClientState(GL_TEXTURE_COORD_ARRAY); -#if defined(GL_VERSION_1_3) - glMultiTexCoord4f(GL_TEXTURE0 + textureNo, 0, 0, 0, 1); -#else - glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1); -#endif - } - } - - /* Ok, Work out which primitive is requested and how many vertexes that - will be */ - NumVertexes = primitiveToGl(PrimitiveType, NumPrimitives, &glPrimType); - - /* Finally do the drawing */ - if (idxData != NULL) { - - TRACE("glElements(%x, %d, %ld, ...)\n", glPrimType, NumVertexes, minIndex); -#if 1 /* FIXME: Want to use DrawRangeElements, but wrong calculation! */ - glDrawElements(glPrimType, NumVertexes, idxSize==2?GL_UNSIGNED_SHORT:GL_UNSIGNED_INT, - (const char *)idxData+(idxSize * startIdx)); -#else - glDrawRangeElements(glPrimType, minIndex, minIndex+NumVertexes-1, NumVertexes, - idxSize==2?GL_UNSIGNED_SHORT:GL_UNSIGNED_INT, - (const char *)idxData+(idxSize * startIdx)); -#endif - checkGLcall("glDrawRangeElements"); - - } else { - - /* Note first is now zero as we shuffled along earlier */ - TRACE("glDrawArrays(%x, 0, %d)\n", glPrimType, NumVertexes); - glDrawArrays(glPrimType, 0, NumVertexes); - checkGLcall("glDrawArrays"); - - } -} - -/* - * Actually draw using the supplied information. - * Slower GL version which extracts info about each vertex in turn - */ -static void drawStridedSlow(LPDIRECT3DDEVICE8 iface, Direct3DVertexStridedData *sd, - int PrimitiveType, ULONG NumPrimitives, - const void *idxData, short idxSize, ULONG minIndex, ULONG startIdx) { - - unsigned int textureNo = 0; - GLenum glPrimType = GL_POINTS; - int NumVertexes = NumPrimitives; - const short *pIdxBufS = NULL; - const long *pIdxBufL = NULL; - LONG SkipnStrides = 0; - LONG vx_index; - float x = 0.0f, y = 0.0f, z = 0.0f; /* x,y,z coordinates */ - float nx = 0.0f, ny = 0.0, nz = 0.0f; /* normal x,y,z coordinates */ - float rhw = 0.0f; /* rhw */ - float ptSize = 0.0f; /* Point size */ - DWORD diffuseColor = 0xFFFFFFFF; /* Diffuse Color */ - DWORD specularColor = 0; /* Specular Color */ - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - - TRACE("Using slow vertex array code\n"); - - /* Variable Initialization */ - if (idxData != NULL) { - if (idxSize == 2) pIdxBufS = (const short *) idxData; - else pIdxBufL = (const long *) idxData; - } - - /* Ok, Work out which primitive is requested and how many vertexes that will be */ - NumVertexes = primitiveToGl(PrimitiveType, NumPrimitives, &glPrimType); - - /* Start drawing in GL */ - VTRACE(("glBegin(%x)\n", glPrimType)); - glBegin(glPrimType); - - /* For each primitive */ - for (vx_index = 0; vx_index < NumVertexes; vx_index++) { - - /* Initialize diffuse color */ - diffuseColor = 0xFFFFFFFF; - - /* For indexed data, we need to go a few more strides in */ - if (idxData != NULL) { - - /* Indexed so work out the number of strides to skip */ - if (idxSize == 2) { - VTRACE(("Idx for vertex %ld = %d\n", vx_index, pIdxBufS[startIdx+vx_index])); - SkipnStrides = pIdxBufS[startIdx+vx_index]; - } else { - VTRACE(("Idx for vertex %ld = %ld\n", vx_index, pIdxBufL[startIdx+vx_index])); - SkipnStrides = pIdxBufL[startIdx+vx_index]; - } - } - - /* Position Information ------------------ */ - if (sd->u.s.position.lpData != NULL) { - - float *ptrToCoords = (float *)(sd->u.s.position.lpData + (SkipnStrides * sd->u.s.position.dwStride)); - x = ptrToCoords[0]; - y = ptrToCoords[1]; - z = ptrToCoords[2]; - rhw = 1.0; - VTRACE(("x,y,z=%f,%f,%f\n", x,y,z)); - - /* RHW follows, only if transformed, ie 4 floats were provided */ - if (sd->u.s.position.dwType == D3DVSDT_FLOAT4) { - rhw = ptrToCoords[3]; - VTRACE(("rhw=%f\n", rhw)); - } - } - - /* Blending data -------------------------- */ - if (sd->u.s.blendWeights.lpData != NULL) { - /*float *ptrToCoords = (float *)(sd->u.s.blendWeights.lpData + (SkipnStrides * sd->u.s.blendWeights.dwStride));*/ - FIXME("Blending not supported yet\n"); - - if (sd->u.s.blendMatrixIndices.lpData != NULL) { - /*DWORD *ptrToCoords = (DWORD *)(sd->u.s.blendMatrixIndices.lpData + (SkipnStrides * sd->u.s.blendMatrixIndices.dwStride));*/ - } - } - - /* Vertex Normal Data (untransformed only)- */ - if (sd->u.s.normal.lpData != NULL) { - - float *ptrToCoords = (float *)(sd->u.s.normal.lpData + (SkipnStrides * sd->u.s.normal.dwStride)); - nx = ptrToCoords[0]; - ny = ptrToCoords[1]; - nz = ptrToCoords[2]; - VTRACE(("nx,ny,nz=%f,%f,%f\n", nx, ny, nz)); - } - - /* Point Size ----------------------------- */ - if (sd->u.s.pSize.lpData != NULL) { - - float *ptrToCoords = (float *)(sd->u.s.pSize.lpData + (SkipnStrides * sd->u.s.pSize.dwStride)); - ptSize = ptrToCoords[0]; - VTRACE(("ptSize=%f\n", ptSize)); - FIXME("No support for ptSize yet\n"); - } - - /* Diffuse -------------------------------- */ - if (sd->u.s.diffuse.lpData != NULL) { - - DWORD *ptrToCoords = (DWORD *)(sd->u.s.diffuse.lpData + (SkipnStrides * sd->u.s.diffuse.dwStride)); - diffuseColor = ptrToCoords[0]; - VTRACE(("diffuseColor=%lx\n", diffuseColor)); - } - - /* Specular -------------------------------- */ - if (sd->u.s.specular.lpData != NULL) { - - DWORD *ptrToCoords = (DWORD *)(sd->u.s.specular.lpData + (SkipnStrides * sd->u.s.specular.dwStride)); - specularColor = ptrToCoords[0]; - VTRACE(("specularColor=%lx\n", specularColor)); - } - - /* Texture coords --------------------------- */ - for (textureNo = 0; textureNo < GL_LIMITS(textures); ++textureNo) { - - if (!GL_SUPPORT(ARB_MULTITEXTURE) && textureNo > 0) { - FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n"); - continue ; - } - - /* Query tex coords */ - if (This->StateBlock->textures[textureNo] != NULL) { - - int coordIdx = This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXCOORDINDEX]; - - if (coordIdx > 7) { - VTRACE(("tex: %d - Skip tex coords, as being system generated\n", textureNo)); - continue; - } else if (sd->u.s.texCoords[coordIdx].lpData == NULL) { - TRACE("tex: %d - Skipping tex coords, as no data supplied\n", textureNo); - continue; - } else { - - float* ptrToCoords = (float*) (sd->u.s.texCoords[coordIdx].lpData + (SkipnStrides * sd->u.s.texCoords[coordIdx].dwStride)); - int coordsToUse = sd->u.s.texCoords[coordIdx].dwType + 1; /* 0 == D3DVSDT_FLOAT1 etc */ - float s = 0.0, t = 0.0, r = 0.0, q = 0.0; - - /* The coords to supply depend completely on the fvf / vertex shader */ - switch (coordsToUse) { - case 4: q = ptrToCoords[3]; /* drop through */ - case 3: r = ptrToCoords[2]; /* drop through */ - case 2: t = ptrToCoords[1]; /* drop through */ - case 1: s = ptrToCoords[0]; - } - - /* Projected is more 'fun' - Move the last coord to the 'q' - parameter (see comments under D3DTSS_TEXTURETRANSFORMFLAGS */ - if ((This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] != D3DTTFF_DISABLE) && - (This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] & D3DTTFF_PROJECTED)) { - - if (This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] & D3DTTFF_PROJECTED) { - switch (coordsToUse) { - case 0: /* Drop Through */ - case 1: - FIXME("D3DTTFF_PROJECTED but only zero or one coordinate?\n"); - break; - case 2: - q = t; - t = 0.0; - coordsToUse = 4; - break; - case 3: - q = r; - r = 0.0; - coordsToUse = 4; - break; - case 4: /* Nop here */ - break; - default: - FIXME("Unexpected D3DTSS_TEXTURETRANSFORMFLAGS value of %ld\n", - This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] & D3DTTFF_PROJECTED); - } - } - } - - switch (coordsToUse) { /* Supply the provided texture coords */ - case D3DTTFF_COUNT1: - VTRACE(("tex:%d, s=%f\n", textureNo, s)); - if (GL_SUPPORT(ARB_MULTITEXTURE)) { -#if defined(GL_VERSION_1_3) - glMultiTexCoord1f(GL_TEXTURE0 + textureNo, s); -#else - glMultiTexCoord1fARB(GL_TEXTURE0_ARB + textureNo, s); -#endif - } else { - glTexCoord1f(s); - } - break; - case D3DTTFF_COUNT2: - VTRACE(("tex:%d, s=%f, t=%f\n", textureNo, s, t)); - if (GL_SUPPORT(ARB_MULTITEXTURE)) { -#if defined(GL_VERSION_1_3) - glMultiTexCoord2f(GL_TEXTURE0 + textureNo, s, t); -#else - glMultiTexCoord2fARB(GL_TEXTURE0_ARB + textureNo, s, t); -#endif - } else { - glTexCoord2f(s, t); - } - break; - case D3DTTFF_COUNT3: - VTRACE(("tex:%d, s=%f, t=%f, r=%f\n", textureNo, s, t, r)); - if (GL_SUPPORT(ARB_MULTITEXTURE)) { -#if defined(GL_VERSION_1_3) - glMultiTexCoord3f(GL_TEXTURE0 + textureNo, s, t, r); -#else - glMultiTexCoord3fARB(GL_TEXTURE0_ARB + textureNo, s, t, r); -#endif - } else { - glTexCoord3f(s, t, r); - } - break; - case D3DTTFF_COUNT4: - VTRACE(("tex:%d, s=%f, t=%f, r=%f, q=%f\n", textureNo, s, t, r, q)); - if (GL_SUPPORT(ARB_MULTITEXTURE)) { -#if defined(GL_VERSION_1_3) - glMultiTexCoord4f(GL_TEXTURE0 + textureNo, s, t, r, q); -#else - glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, s, t, r, q); -#endif - } else { - glTexCoord4f(s, t, r, q); - } - break; - default: - FIXME("Should not get here as coordsToUse is two bits only (%x)!\n", coordsToUse); - } - } - } - } /* End of textures */ - - /* Diffuse -------------------------------- */ - if (sd->u.s.diffuse.lpData != NULL) { - glColor4ub(D3DCOLOR_B_R(diffuseColor), - D3DCOLOR_B_G(diffuseColor), - D3DCOLOR_B_B(diffuseColor), - D3DCOLOR_B_A(diffuseColor)); - VTRACE(("glColor4ub: r,g,b,a=%u,%u,%u,%u\n", - D3DCOLOR_B_R(diffuseColor), - D3DCOLOR_B_G(diffuseColor), - D3DCOLOR_B_B(diffuseColor), - D3DCOLOR_B_A(diffuseColor))); - } else { - if (vx_index == 0) glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - } - - /* Specular ------------------------------- */ - if (sd->u.s.specular.lpData != NULL) { - VTRACE(("glSecondaryColor4ub: r,g,b=%u,%u,%u\n", - D3DCOLOR_B_R(specularColor), - D3DCOLOR_B_G(specularColor), - D3DCOLOR_B_B(specularColor))); - if (GL_SUPPORT(EXT_SECONDARY_COLOR)) { - GL_EXTCALL(glSecondaryColor3ubEXT)( - D3DCOLOR_B_R(specularColor), - D3DCOLOR_B_G(specularColor), - D3DCOLOR_B_B(specularColor)); - } else { - /* Do not worry if specular colour missing and disable request */ - VTRACE(("Specular color extensions not supplied\n")); - } - } else { - if (vx_index == 0) { - if (GL_SUPPORT(EXT_SECONDARY_COLOR)) { - GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0); - } else { - /* Do not worry if specular colour missing and disable request */ - VTRACE(("Specular color extensions not supplied\n")); - } - } - } - - /* Normal -------------------------------- */ - if (sd->u.s.normal.lpData != NULL) { - VTRACE(("glNormal:nx,ny,nz=%f,%f,%f\n", nx,ny,nz)); - glNormal3f(nx, ny, nz); - } else { - if (vx_index == 0) glNormal3f(0, 0, 1); - } - - /* Position -------------------------------- */ - if (sd->u.s.position.lpData != NULL) { - if (1.0f == rhw || ((rhw < 0.0001f) && (rhw > -0.0001f))) { - VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f\n", x,y,z)); - glVertex3f(x, y, z); - } else { - GLfloat w = 1.0 / rhw; - VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f / rhw=%f\n", x,y,z,rhw)); - glVertex4f(x*w, y*w, z*w, w); - } - } - - /* For non indexed mode, step onto next parts */ - if (idxData == NULL) { - SkipnStrides += 1; - } - } - - glEnd(); - checkGLcall("glEnd and previous calls"); -} - -/* - * Draw with emulated vertex shaders - * Note: strided data is uninitialized, as we need to pass the vertex - * shader directly as ordering irs yet - */ -static void drawStridedSoftwareVS(LPDIRECT3DDEVICE8 iface, Direct3DVertexStridedData *sd, - int PrimitiveType, ULONG NumPrimitives, - const void *idxData, short idxSize, ULONG minIndex, ULONG startIdx) { - - unsigned int textureNo = 0; - GLenum glPrimType = GL_POINTS; - int NumVertexes = NumPrimitives; - const short *pIdxBufS = NULL; - const long *pIdxBufL = NULL; - LONG SkipnStrides = 0; - LONG vx_index; - float x = 0.0f, y = 0.0f, z = 0.0f; /* x,y,z coordinates */ - float rhw = 0.0f; /* rhw */ - float ptSize = 0.0f; /* Point size */ - D3DVECTOR_4 texcoords[8]; /* Texture Coords */ - int numcoords[8]; /* Number of coords */ - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - - IDirect3DVertexShaderImpl* vertex_shader = NULL; - - TRACE("Using slow software vertex shader code\n"); - - /* Variable Initialization */ - if (idxData != NULL) { - if (idxSize == 2) pIdxBufS = (const short *) idxData; - else pIdxBufL = (const long *) idxData; - } - - /* Ok, Work out which primitive is requested and how many vertexes that will be */ - NumVertexes = primitiveToGl(PrimitiveType, NumPrimitives, &glPrimType); - - /* Retrieve the VS information */ - vertex_shader = VERTEX_SHADER(This->StateBlock->VertexShader); - - /* Start drawing in GL */ - VTRACE(("glBegin(%x)\n", glPrimType)); - glBegin(glPrimType); - - /* For each primitive */ - for (vx_index = 0; vx_index < NumVertexes; vx_index++) { - - /* For indexed data, we need to go a few more strides in */ - if (idxData != NULL) { - - /* Indexed so work out the number of strides to skip */ - if (idxSize == 2) { - VTRACE(("Idx for vertex %ld = %d\n", vx_index, pIdxBufS[startIdx+vx_index])); - SkipnStrides = pIdxBufS[startIdx+vx_index]; - } else { - VTRACE(("Idx for vertex %ld = %ld\n", vx_index, pIdxBufL[startIdx+vx_index])); - SkipnStrides = pIdxBufL[startIdx+vx_index]; - } - } - - /* Fill the vertex shader input */ - IDirect3DDeviceImpl_FillVertexShaderInputSW(This, vertex_shader, SkipnStrides); - - /* Initialize the output fields to the same defaults as it would normally have */ - memset(&vertex_shader->output, 0, sizeof(VSHADEROUTPUTDATA8)); - vertex_shader->output.oD[0].x = 1.0; - vertex_shader->output.oD[0].y = 1.0; - vertex_shader->output.oD[0].z = 1.0; - vertex_shader->output.oD[0].w = 1.0; - - /* Now execute the vertex shader */ - IDirect3DVertexShaderImpl_ExecuteSW(vertex_shader, &vertex_shader->input, &vertex_shader->output); - - /* - TRACE_VECTOR(vertex_shader->output.oPos); - TRACE_VECTOR(vertex_shader->output.oD[0]); - TRACE_VECTOR(vertex_shader->output.oD[1]); - TRACE_VECTOR(vertex_shader->output.oT[0]); - TRACE_VECTOR(vertex_shader->output.oT[1]); - TRACE_VECTOR(vertex_shader->input.V[0]); - TRACE_VECTOR(vertex_shader->data->C[0]); - TRACE_VECTOR(vertex_shader->data->C[1]); - TRACE_VECTOR(vertex_shader->data->C[2]); - TRACE_VECTOR(vertex_shader->data->C[3]); - TRACE_VECTOR(vertex_shader->data->C[4]); - TRACE_VECTOR(vertex_shader->data->C[5]); - TRACE_VECTOR(vertex_shader->data->C[6]); - TRACE_VECTOR(vertex_shader->data->C[7]); - */ - - /* Extract out the output */ - /*FIXME: Fog coords? */ - x = vertex_shader->output.oPos.x; - y = vertex_shader->output.oPos.y; - z = vertex_shader->output.oPos.z; - rhw = vertex_shader->output.oPos.w; - ptSize = vertex_shader->output.oPts.x; /* Fixme - Is this right? */ - - /** Update textures coords using vertex_shader->output.oT[0->7] */ - memset(texcoords, 0x00, sizeof(texcoords)); - memset(numcoords, 0x00, sizeof(numcoords)); - for (textureNo = 0; textureNo < GL_LIMITS(textures); ++textureNo) { - if (This->StateBlock->textures[textureNo] != NULL) { - texcoords[textureNo].x = vertex_shader->output.oT[textureNo].x; - texcoords[textureNo].y = vertex_shader->output.oT[textureNo].y; - texcoords[textureNo].z = vertex_shader->output.oT[textureNo].z; - texcoords[textureNo].w = vertex_shader->output.oT[textureNo].w; - if (This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] != D3DTTFF_DISABLE) { - numcoords[textureNo] = This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] & ~D3DTTFF_PROJECTED; - } else { - switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8) This->StateBlock->textures[textureNo])) { - case D3DRTYPE_TEXTURE: numcoords[textureNo] = 2; break; - case D3DRTYPE_VOLUMETEXTURE: numcoords[textureNo] = 3; break; - default: numcoords[textureNo] = 4; - } - } - } else { - numcoords[textureNo] = 0; - } - } - - /* Draw using this information */ - draw_vertex(iface, - TRUE, x, y, z, rhw, - TRUE, 0.0f, 0.0f, 1.0f, - TRUE, (float*) &vertex_shader->output.oD[0], - TRUE, (float*) &vertex_shader->output.oD[1], - FALSE, ptSize, /* FIXME: Change back when supported */ - texcoords, numcoords); - - /* For non indexed mode, step onto next parts */ - if (idxData == NULL) { - SkipnStrides += 1; - } - - } /* for each vertex */ - - glEnd(); - checkGLcall("glEnd and previous calls"); -} - -static void drawStridedHardwareVS(LPDIRECT3DDEVICE8 iface, Direct3DVertexStridedData *sd, - int PrimitiveType, ULONG NumPrimitives, - const void *idxData, short idxSize, ULONG minIndex, ULONG startIdx) { - - IDirect3DVertexShaderImpl* vertex_shader = NULL; - int i; - int NumVertexes; - GLenum glPrimType; - int maxAttribs; - - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - TRACE("Drawing with hardware vertex shaders\n"); - - /* Retrieve the VS information */ - vertex_shader = VERTEX_SHADER(This->StateBlock->VertexShader); - - /* Enable the Vertex Shader */ - GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, vertex_shader->prgId)); - checkGLcall("glBindProgramARB(GL_VERTEX_PROGRAM_ARB, vertex_shader->prgId);"); - glEnable(GL_VERTEX_PROGRAM_ARB); - checkGLcall("glEnable(GL_VERTEX_PROGRAM_ARB);"); - - /* Update the constants */ - for (i=0; iStateBlock->vertexShaderConstant[i])); - checkGLcall("glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB"); - } - - /* Set up the vertex.attr[n] inputs */ - IDirect3DDeviceImpl_FillVertexShaderInputArbHW(This, vertex_shader, 0); - - /* Ok, Work out which primitive is requested and how many vertexes that - will be */ - NumVertexes = primitiveToGl(PrimitiveType, NumPrimitives, &glPrimType); - - /* Finally do the drawing */ - if (idxData != NULL) { - - TRACE("glElements(%x, %d, %ld, ...)\n", glPrimType, NumVertexes, minIndex); -#if 1 /* FIXME: Want to use DrawRangeElements, but wrong calculation! */ - glDrawElements(glPrimType, NumVertexes, idxSize==2?GL_UNSIGNED_SHORT:GL_UNSIGNED_INT, - (const char *)idxData+(idxSize * startIdx)); -#else - glDrawRangeElements(glPrimType, minIndex, minIndex+NumVertexes-1, NumVertexes, - idxSize==2?GL_UNSIGNED_SHORT:GL_UNSIGNED_INT, - (const char *)idxData+(idxSize * startIdx)); -#endif - checkGLcall("glDrawRangeElements"); - - } else { - - /* Note first is now zero as we shuffled along earlier */ - TRACE("glDrawArrays(%x, 0, %d)\n", glPrimType, NumVertexes); - glDrawArrays(glPrimType, 0, NumVertexes); - checkGLcall("glDrawArrays"); - - } - - { - GLint errPos; - glGetIntegerv( GL_PROGRAM_ERROR_POSITION_ARB, &errPos ); - if (errPos != -1) - FIXME("HW VertexShader Error at position: %d\n%s\n", errPos, glGetString( GL_PROGRAM_ERROR_STRING_ARB) ); - } - - - /* Leave all the attribs disabled */ - glGetIntegerv( GL_MAX_VERTEX_ATTRIBS_ARB, &maxAttribs); - /* MESA does not support it right not */ - if (glGetError() != GL_NO_ERROR) - maxAttribs = 16; - for (i=0; iUpdateStateBlock->VertexShader); - memset(&vertex_shader->input, 0, sizeof(VSHADERINPUTDATA8)); - - useHW = (((vs_mode == VS_HW) && GL_SUPPORT(ARB_VERTEX_PROGRAM)) && - This->devType != D3DDEVTYPE_REF && - !This->StateBlock->renderstate[D3DRS_SOFTWAREVERTEXPROCESSING] && - vertex_shader->usage != D3DUSAGE_SOFTWAREPROCESSING); - - /** init Constants */ - if (This->UpdateStateBlock->Changed.vertexShaderConstant) { - TRACE_(d3d_shader)("vertex shader initializing constants\n"); - IDirect3DVertexShaderImpl_SetConstantF(vertex_shader, 0, (CONST FLOAT*) &This->UpdateStateBlock->vertexShaderConstant[0], 96); - } - } - - /* Ok, we will be updating the screen from here onwards so grab the lock */ - ENTER_GL(); - - /* If we will be using a pixel, do some initialization for it */ - if ((pixel_shader = PIXEL_SHADER(This->UpdateStateBlock->PixelShader))) { - TRACE("drawing with pixel shader handle %p\n", pixel_shader); - memset(&pixel_shader->input, 0, sizeof(PSHADERINPUTDATA8)); - - GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, pixel_shader->prgId)); - checkGLcall("glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, pixel_shader->prgId);"); - glEnable(GL_FRAGMENT_PROGRAM_ARB); - checkGLcall("glEnable(GL_FRAGMENT_PROGRAM_ARB);"); - - /* init Constants */ - if (This->UpdateStateBlock->Changed.pixelShaderConstant) { - TRACE_(d3d_shader)("pixel shader initializing constants %p\n",pixel_shader); - IDirect3DPixelShaderImpl_SetConstantF(pixel_shader, 0, (CONST FLOAT*) &This->UpdateStateBlock->pixelShaderConstant[0], 8); - } - /* Update the constants */ - for (i=0; iStateBlock->pixelShaderConstant[i])); - checkGLcall("glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB"); - } - } - - /* Setup transform matrices and sort out */ - if (useHW) { - /* Lighting is not completely bypassed with ATI drivers although it should be. Mesa is ok from this respect... - So make sure lighting is disabled. */ - isLightingOn = glIsEnabled(GL_LIGHTING); - glDisable(GL_LIGHTING); - checkGLcall("glDisable(GL_LIGHTING);"); - TRACE("Disabled lighting as no normals supplied, old state = %d\n", isLightingOn); - } else - isLightingOn = primitiveInitState(iface, - fvf & D3DFVF_XYZRHW, - !(fvf & D3DFVF_NORMAL), - useVertexShaderFunction); - - /* Initialize all values to null */ - if (useVertexShaderFunction == FALSE) { - memset(&dataLocations, 0x00, sizeof(dataLocations)); - - /* Convert to strided data */ - primitiveConvertToStridedData(iface, &dataLocations, StartVertexIndex); - - /* Dump out what parts we have supplied */ - TRACE("Strided Data (from FVF/VS): %lx\n", fvf); - TRACE_STRIDED((&dataLocations), position); - TRACE_STRIDED((&dataLocations), blendWeights); - TRACE_STRIDED((&dataLocations), blendMatrixIndices); - TRACE_STRIDED((&dataLocations), normal); - TRACE_STRIDED((&dataLocations), pSize); - TRACE_STRIDED((&dataLocations), diffuse); - TRACE_STRIDED((&dataLocations), specular); - TRACE_STRIDED((&dataLocations), texCoords[0]); - TRACE_STRIDED((&dataLocations), texCoords[1]); - TRACE_STRIDED((&dataLocations), texCoords[2]); - TRACE_STRIDED((&dataLocations), texCoords[3]); - TRACE_STRIDED((&dataLocations), texCoords[4]); - TRACE_STRIDED((&dataLocations), texCoords[5]); - TRACE_STRIDED((&dataLocations), texCoords[6]); - TRACE_STRIDED((&dataLocations), texCoords[7]); - } - - /* Now initialize the materials state */ - init_materials(iface, (dataLocations.u.s.diffuse.lpData != NULL)); - - /* And re-upload any dirty textures */ - for (i=0; iStateBlock->textures[i] != NULL) && - (IDirect3DBaseTexture8Impl_IsDirty(This->StateBlock->textures[i]))) - { - /* Load up the texture now */ - IDirect3DTexture8Impl_PreLoad((LPDIRECT3DTEXTURE8) This->StateBlock->textures[i]); - } - } - - /* Now draw the graphics to the screen */ - if (useVertexShaderFunction) { - - /* Ideally, we should have software FV and hardware VS, possibly - depending on the device type? */ - - if (useHW) { - TRACE("Swap HW vertex shader\n"); - drawStridedHardwareVS(iface, &dataLocations, PrimitiveType, NumPrimitives, - idxData, idxSize, minIndex, StartIdx); - } else { - /* We will have to use the very, very slow emulation layer */ - TRACE("Swap SW vertex shader\n"); - drawStridedSoftwareVS(iface, &dataLocations, PrimitiveType, NumPrimitives, - idxData, idxSize, minIndex, StartIdx); - } - - } else if ((dataLocations.u.s.pSize.lpData != NULL) || - (dataLocations.u.s.diffuse.lpData != NULL) || - (dataLocations.u.s.blendWeights.lpData != NULL)) { - - /* Fixme, Ideally, only use the per-vertex code for software HAL - but until opengl supports all the functions returned to setup - vertex arrays, we need to drop down to the slow mechanism for - certain functions */ - - /* We will have to use the slow version of GL per vertex setup */ - drawStridedSlow(iface, &dataLocations, PrimitiveType, NumPrimitives, - idxData, idxSize, minIndex, StartIdx); - - } else { - - /* We can use the fast version of GL pointers */ - drawStridedFast(iface, &dataLocations, PrimitiveType, NumPrimitives, - idxData, idxSize, minIndex, StartIdx); - } - - /* If vertex shaders or no normals, restore previous lighting state */ - if (useVertexShaderFunction || !(fvf & D3DFVF_NORMAL)) { - if (isLightingOn) glEnable(GL_LIGHTING); - else glDisable(GL_LIGHTING); - TRACE("Restored lighting to original state\n"); - } - - if (pixel_shader) - { -#if 0 - GLint errPos; - glGetIntegerv( GL_PROGRAM_ERROR_POSITION_ARB, &errPos ); - if (errPos != -1) - FIXME("HW PixelShader Error at position: %d\n%s\n", errPos, glGetString( GL_PROGRAM_ERROR_STRING_ARB) ); -#endif - glDisable(GL_FRAGMENT_PROGRAM_ARB); - } - - /* Finshed updating the screen, restore lock */ - LEAVE_GL(); - TRACE("Done all gl drawing\n"); - - /* Diagnostics */ -#if defined(SHOW_FRAME_MAKEUP) - { - if (isDumpingFrames) { - D3DLOCKED_RECT r; - char buffer[80]; - IDirect3DSurface8Impl_LockRect((LPDIRECT3DSURFACE8) This->renderTarget, &r, NULL, D3DLOCK_READONLY); - sprintf(buffer, "/tmp/backbuffer_%ld.ppm", primCounter); - TRACE("Saving screenshot %s\n", buffer); - IDirect3DSurface8Impl_SaveSnapshot((LPDIRECT3DSURFACE8) This->renderTarget, buffer); - IDirect3DSurface8Impl_UnlockRect((LPDIRECT3DSURFACE8) This->renderTarget); - -#if defined(SHOW_TEXTURE_MAKEUP) - { - LPDIRECT3DSURFACE8 pSur; - int textureNo; - for (textureNo = 0; textureNo < GL_LIMITS(textures); ++textureNo) { - if (This->StateBlock->textures[textureNo] != NULL) { - sprintf(buffer, "/tmp/texture_%ld_%d.ppm", primCounter, textureNo); - TRACE("Saving texture %s (Format:%s)\n", buffer, debug_d3dformat(((IDirect3DBaseTexture8Impl *)This->StateBlock->textures[textureNo])->format)); - IDirect3DTexture8Impl_GetSurfaceLevel((LPDIRECT3DTEXTURE8) This->StateBlock->textures[textureNo], 0, &pSur); - IDirect3DSurface8Impl_SaveSnapshot(pSur, buffer); - IDirect3DSurface8Impl_Release(pSur); - } - } - } -#endif - primCounter = primCounter + 1; - } - } -#endif -} diff --git a/dlls/d3d8/indexbuffer.c b/dlls/d3d8/indexbuffer.c index 2163f2faf4b..7d18a449ab4 100644 --- a/dlls/d3d8/indexbuffer.c +++ b/dlls/d3d8/indexbuffer.c @@ -1,7 +1,7 @@ /* * IDirect3DIndexBuffer8 implementation * - * Copyright 2002 Jason Edmeades + * Copyright 2005 Oliver Stieber * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -19,33 +19,23 @@ */ #include "config.h" - -#include - -#include "windef.h" -#include "winbase.h" -#include "winuser.h" -#include "wingdi.h" -#include "wine/debug.h" - #include "d3d8_private.h" -WINE_DEFAULT_DEBUG_CHANNEL(d3d); +WINE_DEFAULT_DEBUG_CHANNEL(d3d8); /* IDirect3DIndexBuffer8 IUnknown parts follow: */ -HRESULT WINAPI IDirect3DIndexBuffer8Impl_QueryInterface(LPDIRECT3DINDEXBUFFER8 iface,REFIID riid,LPVOID *ppobj) -{ +HRESULT WINAPI IDirect3DIndexBuffer8Impl_QueryInterface(LPDIRECT3DINDEXBUFFER8 iface, REFIID riid, LPVOID *ppobj) { IDirect3DIndexBuffer8Impl *This = (IDirect3DIndexBuffer8Impl *)iface; if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IDirect3DResource8) || IsEqualGUID(riid, &IID_IDirect3DIndexBuffer8)) { - IDirect3DIndexBuffer8Impl_AddRef(iface); + IUnknown_AddRef(iface); *ppobj = This; return D3D_OK; } - WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj); + WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj); return E_NOINTERFACE; } @@ -64,106 +54,89 @@ ULONG WINAPI IDirect3DIndexBuffer8Impl_Release(LPDIRECT3DINDEXBUFFER8 iface) { TRACE("(%p) : ReleaseRef to %ld\n", This, ref); - if (ref == 0 && 0 == This->refInt) { - HeapFree(GetProcessHeap(), 0, This->allocatedMemory); + if (ref == 0) { + IWineD3DIndexBuffer_Release(This->wineD3DIndexBuffer); HeapFree(GetProcessHeap(), 0, This); - } else if (0 == ref) { - WARN("(%p) : The application failed to set indicies NULL before releasing the index buffer, leak\n", This); } - return ref; } - -ULONG WINAPI IDirect3DIndexBuffer8Impl_AddRefInt(LPDIRECT3DINDEXBUFFER8 iface) { +/* IDirect3DIndexBuffer8 IDirect3DResource8 Interface follow: */ +HRESULT WINAPI IDirect3DIndexBuffer8Impl_GetDevice(LPDIRECT3DINDEXBUFFER8 iface, IDirect3DDevice8 **ppDevice) { IDirect3DIndexBuffer8Impl *This = (IDirect3DIndexBuffer8Impl *)iface; - ULONG refInt = InterlockedIncrement(&This->refInt); - - TRACE("(%p) : AddRefInt from %ld\n", This, refInt - 1); - - return refInt; + TRACE("(%p) Relay\n", This); + return IDirect3DResource8Impl_GetDevice((LPDIRECT3DRESOURCE8) This, ppDevice); } -ULONG WINAPI IDirect3DIndexBuffer8Impl_ReleaseInt(LPDIRECT3DINDEXBUFFER8 iface) { +HRESULT WINAPI IDirect3DIndexBuffer8Impl_SetPrivateData(LPDIRECT3DINDEXBUFFER8 iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) { IDirect3DIndexBuffer8Impl *This = (IDirect3DIndexBuffer8Impl *)iface; - ULONG refInt = InterlockedDecrement(&This->refInt); - - TRACE("(%p) : ReleaseRefInt to %ld\n", This, refInt); - - if (0 == This->ref && 0 == refInt) { - WARN("(%p) : Cleaning up after the calling application failed to release the indicies properly\n", This); - HeapFree(GetProcessHeap(), 0, This->allocatedMemory); - HeapFree(GetProcessHeap(), 0, This); - } - - return refInt; + TRACE("(%p) Relay\n", This); + return IWineD3DIndexBuffer_SetPrivateData(This->wineD3DIndexBuffer, refguid, pData, SizeOfData, Flags); } +HRESULT WINAPI IDirect3DIndexBuffer8Impl_GetPrivateData(LPDIRECT3DINDEXBUFFER8 iface, REFGUID refguid, void *pData, DWORD *pSizeOfData) { + IDirect3DIndexBuffer8Impl *This = (IDirect3DIndexBuffer8Impl *)iface; + TRACE("(%p) Relay\n", This); + return IWineD3DIndexBuffer_GetPrivateData(This->wineD3DIndexBuffer, refguid, pData, pSizeOfData); +} -/* IDirect3DResource Interface follow: */ -HRESULT WINAPI IDirect3DIndexBuffer8Impl_GetDevice(LPDIRECT3DINDEXBUFFER8 iface, IDirect3DDevice8** ppDevice) { +HRESULT WINAPI IDirect3DIndexBuffer8Impl_FreePrivateData(LPDIRECT3DINDEXBUFFER8 iface, REFGUID refguid) { IDirect3DIndexBuffer8Impl *This = (IDirect3DIndexBuffer8Impl *)iface; - TRACE("(%p) : returning %p\n", This, This->Device); - *ppDevice = (LPDIRECT3DDEVICE8) This->Device; - IDirect3DDevice8Impl_AddRef(*ppDevice); - return D3D_OK; + TRACE("(%p) Relay\n", This); + return IWineD3DIndexBuffer_FreePrivateData(This->wineD3DIndexBuffer, refguid); } -HRESULT WINAPI IDirect3DIndexBuffer8Impl_SetPrivateData(LPDIRECT3DINDEXBUFFER8 iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) { + +DWORD WINAPI IDirect3DIndexBuffer8Impl_SetPriority(LPDIRECT3DINDEXBUFFER8 iface, DWORD PriorityNew) { IDirect3DIndexBuffer8Impl *This = (IDirect3DIndexBuffer8Impl *)iface; - FIXME("(%p) : stub\n", This); return D3D_OK; + TRACE("(%p) Relay\n", This); + return IWineD3DIndexBuffer_SetPriority(This->wineD3DIndexBuffer, PriorityNew); } -HRESULT WINAPI IDirect3DIndexBuffer8Impl_GetPrivateData(LPDIRECT3DINDEXBUFFER8 iface, REFGUID refguid, void* pData, DWORD* pSizeOfData) { + +DWORD WINAPI IDirect3DIndexBuffer8Impl_GetPriority(LPDIRECT3DINDEXBUFFER8 iface) { IDirect3DIndexBuffer8Impl *This = (IDirect3DIndexBuffer8Impl *)iface; - FIXME("(%p) : stub\n", This); return D3D_OK; + TRACE("(%p) Relay\n", This); + return IWineD3DIndexBuffer_GetPriority(This->wineD3DIndexBuffer); } -HRESULT WINAPI IDirect3DIndexBuffer8Impl_FreePrivateData(LPDIRECT3DINDEXBUFFER8 iface, REFGUID refguid) { + +void WINAPI IDirect3DIndexBuffer8Impl_PreLoad(LPDIRECT3DINDEXBUFFER8 iface) { IDirect3DIndexBuffer8Impl *This = (IDirect3DIndexBuffer8Impl *)iface; - FIXME("(%p) : stub\n", This); return D3D_OK; -} -DWORD WINAPI IDirect3DIndexBuffer8Impl_SetPriority(LPDIRECT3DINDEXBUFFER8 iface, DWORD PriorityNew) { - IDirect3DIndexBuffer8Impl *This = (IDirect3DIndexBuffer8Impl *)iface; - FIXME("(%p) : stub\n", This); return D3D_OK; -} -DWORD WINAPI IDirect3DIndexBuffer8Impl_GetPriority(LPDIRECT3DINDEXBUFFER8 iface) { - IDirect3DIndexBuffer8Impl *This = (IDirect3DIndexBuffer8Impl *)iface; - FIXME("(%p) : stub\n", This); return D3D_OK; -} -void WINAPI IDirect3DIndexBuffer8Impl_PreLoad(LPDIRECT3DINDEXBUFFER8 iface) { - IDirect3DIndexBuffer8Impl *This = (IDirect3DIndexBuffer8Impl *)iface; - FIXME("(%p) : stub\n", This); + TRACE("(%p) Relay\n", This); + return IWineD3DIndexBuffer_PreLoad(This->wineD3DIndexBuffer); } + D3DRESOURCETYPE WINAPI IDirect3DIndexBuffer8Impl_GetType(LPDIRECT3DINDEXBUFFER8 iface) { IDirect3DIndexBuffer8Impl *This = (IDirect3DIndexBuffer8Impl *)iface; - TRACE("(%p) : returning %d\n", This, This->ResourceType); - return This->ResourceType; + TRACE("(%p) Relay\n", This); + return IWineD3DIndexBuffer_GetType(This->wineD3DIndexBuffer); } -/* IDirect3DIndexBuffer8 */ -HRESULT WINAPI IDirect3DIndexBuffer8Impl_Lock(LPDIRECT3DINDEXBUFFER8 iface, UINT OffsetToLock, UINT SizeToLock, BYTE** ppbData, DWORD Flags) { +/* IDirect3DIndexBuffer8 Interface follow: */ +HRESULT WINAPI IDirect3DIndexBuffer8Impl_Lock(LPDIRECT3DINDEXBUFFER8 iface, UINT OffsetToLock, UINT SizeToLock, BYTE **ppbData, DWORD Flags) { IDirect3DIndexBuffer8Impl *This = (IDirect3DIndexBuffer8Impl *)iface; - TRACE("(%p) : no locking yet, offset %d, size %d, Flags=%lx\n", This, OffsetToLock, SizeToLock, Flags); - *ppbData = (BYTE *)This->allocatedMemory + OffsetToLock; - return D3D_OK; + TRACE("(%p) Relay\n", This); + return IWineD3DIndexBuffer_Lock(This->wineD3DIndexBuffer, OffsetToLock, SizeToLock, ppbData, Flags); } -HRESULT WINAPI IDirect3DIndexBuffer8Impl_Unlock(LPDIRECT3DINDEXBUFFER8 iface) { +HRESULT WINAPI IDirect3DIndexBuffer8Impl_Unlock(LPDIRECT3DINDEXBUFFER8 iface) { IDirect3DIndexBuffer8Impl *This = (IDirect3DIndexBuffer8Impl *)iface; - TRACE("(%p) : stub\n", This); - return D3D_OK; + TRACE("(%p) Relay\n", This); + return IWineD3DIndexBuffer_Unlock(This->wineD3DIndexBuffer); } + HRESULT WINAPI IDirect3DIndexBuffer8Impl_GetDesc(LPDIRECT3DINDEXBUFFER8 iface, D3DINDEXBUFFER_DESC *pDesc) { IDirect3DIndexBuffer8Impl *This = (IDirect3DIndexBuffer8Impl *)iface; - - TRACE("(%p) : copying into %p\n", This, pDesc); - memcpy(pDesc, &This->currentDesc, sizeof(D3DINDEXBUFFER_DESC)); - return D3D_OK; + TRACE("(%p) Relay\n", This); + return IWineD3DIndexBuffer_GetDesc(This->wineD3DIndexBuffer, pDesc); } + const IDirect3DIndexBuffer8Vtbl Direct3DIndexBuffer8_Vtbl = { + /* IUnknown */ IDirect3DIndexBuffer8Impl_QueryInterface, IDirect3DIndexBuffer8Impl_AddRef, IDirect3DIndexBuffer8Impl_Release, + /* IDirect3DResource8 */ IDirect3DIndexBuffer8Impl_GetDevice, IDirect3DIndexBuffer8Impl_SetPrivateData, IDirect3DIndexBuffer8Impl_GetPrivateData, @@ -172,6 +145,7 @@ const IDirect3DIndexBuffer8Vtbl Direct3DIndexBuffer8_Vtbl = IDirect3DIndexBuffer8Impl_GetPriority, IDirect3DIndexBuffer8Impl_PreLoad, IDirect3DIndexBuffer8Impl_GetType, + /* IDirect3DIndexBuffer8 */ IDirect3DIndexBuffer8Impl_Lock, IDirect3DIndexBuffer8Impl_Unlock, IDirect3DIndexBuffer8Impl_GetDesc diff --git a/dlls/d3d8/pixelshader.c b/dlls/d3d8/pixelshader.c new file mode 100644 index 00000000000..d9170d57664 --- /dev/null +++ b/dlls/d3d8/pixelshader.c @@ -0,0 +1,94 @@ +/* + * IDirect3DPixelShader8 implementation + * + * Copyright 2002-2003 Jason Edmeades + * Raphael Junqueira + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "config.h" +#include "d3d8_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3d8); + +/* IDirect3DPixelShader8 IUnknown parts follow: */ +HRESULT WINAPI IDirect3DPixelShader8Impl_QueryInterface(IDirect3DPixelShader8 *iface, REFIID riid, LPVOID *ppobj) { + IDirect3DPixelShader8Impl *This = (IDirect3DPixelShader8Impl *)iface; + + if (IsEqualGUID(riid, &IID_IUnknown) + || IsEqualGUID(riid, &IID_IDirect3DPixelShader8)) { + IUnknown_AddRef(iface); + *ppobj = This; + return D3D_OK; + } + + WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj); + return E_NOINTERFACE; +} + +ULONG WINAPI IDirect3DPixelShader8Impl_AddRef(IDirect3DPixelShader8 *iface) { + IDirect3DPixelShader8Impl *This = (IDirect3DPixelShader8Impl *)iface; + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) : AddRef from %ld\n", This, ref - 1); + + return ref; +} + +ULONG WINAPI IDirect3DPixelShader8Impl_Release(IDirect3DPixelShader8 * iface) { + IDirect3DPixelShader8Impl *This = (IDirect3DPixelShader8Impl *)iface; + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) : ReleaseRef to %ld\n", This, ref); + + if (ref == 0) { + IWineD3DPixelShader_Release(This->wineD3DPixelShader); + HeapFree(GetProcessHeap(), 0, This); + } + return ref; +} + +/* IDirect3DPixelShader8 Interface follow: */ +HRESULT WINAPI IDirect3DPixelShader8Impl_GetDevice(IDirect3DPixelShader8 *iface, IDirect3DDevice8 **ppDevice) { + IDirect3DPixelShader8Impl *This = (IDirect3DPixelShader8Impl *)iface; + IWineD3DDevice *myDevice = NULL; + + TRACE("(%p) : Relay\n", This); + + IWineD3DPixelShader_GetDevice(This->wineD3DPixelShader, &myDevice); + IWineD3DDevice_GetParent(myDevice, (IUnknown **)ppDevice); + IWineD3DDevice_Release(myDevice); + TRACE("(%p) returing (%p)", This, *ppDevice); + return D3D_OK; +} + +HRESULT WINAPI IDirect3DPixelShader8Impl_GetFunction(IDirect3DPixelShader8 *iface, VOID *pData, UINT *pSizeOfData) { + IDirect3DPixelShader8Impl *This = (IDirect3DPixelShader8Impl *)iface; + TRACE("(%p) Relay\n", This); + return IWineD3DPixelShader_GetFunction(This->wineD3DPixelShader, pData, pSizeOfData); +} + + +const IDirect3DPixelShader8Vtbl Direct3DPixelShader8_Vtbl = +{ + /* IUnknown */ + IDirect3DPixelShader8Impl_QueryInterface, + IDirect3DPixelShader8Impl_AddRef, + IDirect3DPixelShader8Impl_Release, + /* IDirect3DPixelShader8 */ + IDirect3DPixelShader8Impl_GetDevice, + IDirect3DPixelShader8Impl_GetFunction +}; diff --git a/dlls/d3d8/resource.c b/dlls/d3d8/resource.c index d2595b35d2f..02696554028 100644 --- a/dlls/d3d8/resource.c +++ b/dlls/d3d8/resource.c @@ -1,7 +1,7 @@ /* * IDirect3DResource8 implementation * - * Copyright 2002 Jason Edmeades + * Copyright 2005 Oliver Stieber * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -19,32 +19,22 @@ */ #include "config.h" - -#include - -#include "windef.h" -#include "winbase.h" -#include "winuser.h" -#include "wingdi.h" -#include "wine/debug.h" - #include "d3d8_private.h" -WINE_DEFAULT_DEBUG_CHANNEL(d3d); +WINE_DEFAULT_DEBUG_CHANNEL(d3d8); -/* IDirect3DResource IUnknown parts follow: */ -HRESULT WINAPI IDirect3DResource8Impl_QueryInterface(LPDIRECT3DRESOURCE8 iface,REFIID riid,LPVOID *ppobj) -{ +/* IDirect3DResource8 IUnknown parts follow: */ +HRESULT WINAPI IDirect3DResource8Impl_QueryInterface(LPDIRECT3DRESOURCE8 iface, REFIID riid, LPVOID* ppobj) { IDirect3DResource8Impl *This = (IDirect3DResource8Impl *)iface; if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IDirect3DResource8)) { - IDirect3DResource8Impl_AddRef(iface); + IUnknown_AddRef(iface); *ppobj = This; return D3D_OK; } - WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj); + WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj); return E_NOINTERFACE; } @@ -63,49 +53,67 @@ ULONG WINAPI IDirect3DResource8Impl_Release(LPDIRECT3DRESOURCE8 iface) { TRACE("(%p) : ReleaseRef to %ld\n", This, ref); - if (ref == 0) + if (ref == 0) { + IWineD3DResource_Release(This->wineD3DResource); HeapFree(GetProcessHeap(), 0, This); + } return ref; } -/* IDirect3DResource Interface follow: */ -HRESULT WINAPI IDirect3DResource8Impl_GetDevice(LPDIRECT3DRESOURCE8 iface, IDirect3DDevice8** ppDevice) { +/* IDirect3DResource8 Interface follow: */ +HRESULT WINAPI IDirect3DResource8Impl_GetDevice(LPDIRECT3DRESOURCE8 iface, IDirect3DDevice8** ppDevice) { IDirect3DResource8Impl *This = (IDirect3DResource8Impl *)iface; - TRACE("(%p) : returning %p\n", This, This->Device); - *ppDevice = (LPDIRECT3DDEVICE8) This->Device; - IDirect3DDevice8Impl_AddRef(*ppDevice); + IWineD3DDevice *myDevice = NULL; + + TRACE("(%p) Relay\n", This); + + IWineD3DResource_GetDevice(This->wineD3DResource, &myDevice); + IWineD3DDevice_GetParent(myDevice, (IUnknown **)ppDevice); + IWineD3DDevice_Release(myDevice); return D3D_OK; } -HRESULT WINAPI IDirect3DResource8Impl_SetPrivateData(LPDIRECT3DRESOURCE8 iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) { + +HRESULT WINAPI IDirect3DResource8Impl_SetPrivateData(LPDIRECT3DRESOURCE8 iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) { IDirect3DResource8Impl *This = (IDirect3DResource8Impl *)iface; - FIXME("(%p) : stub\n", This); return D3D_OK; + TRACE("(%p) Relay\n", This); + return IWineD3DResource_SetPrivateData(This->wineD3DResource, refguid, pData, SizeOfData, Flags); } -HRESULT WINAPI IDirect3DResource8Impl_GetPrivateData(LPDIRECT3DRESOURCE8 iface, REFGUID refguid, void* pData, DWORD* pSizeOfData) { + +HRESULT WINAPI IDirect3DResource8Impl_GetPrivateData(LPDIRECT3DRESOURCE8 iface, REFGUID refguid, void* pData, DWORD* pSizeOfData) { IDirect3DResource8Impl *This = (IDirect3DResource8Impl *)iface; - FIXME("(%p) : stub\n", This); return D3D_OK; + TRACE("(%p) Relay\n", This); + return IWineD3DResource_GetPrivateData(This->wineD3DResource, refguid, pData, pSizeOfData); } -HRESULT WINAPI IDirect3DResource8Impl_FreePrivateData(LPDIRECT3DRESOURCE8 iface, REFGUID refguid) { + +HRESULT WINAPI IDirect3DResource8Impl_FreePrivateData(LPDIRECT3DRESOURCE8 iface, REFGUID refguid) { IDirect3DResource8Impl *This = (IDirect3DResource8Impl *)iface; - FIXME("(%p) : stub\n", This); return D3D_OK; + TRACE("(%p) Relay\n", This); + return IWineD3DResource_FreePrivateData(This->wineD3DResource, refguid); } -DWORD WINAPI IDirect3DResource8Impl_SetPriority(LPDIRECT3DRESOURCE8 iface, DWORD PriorityNew) { + +DWORD WINAPI IDirect3DResource8Impl_SetPriority(LPDIRECT3DRESOURCE8 iface, DWORD PriorityNew) { IDirect3DResource8Impl *This = (IDirect3DResource8Impl *)iface; - FIXME("(%p) : stub\n", This); - return 0; + TRACE("(%p) Relay\n", This); + return IWineD3DResource_SetPriority(This->wineD3DResource, PriorityNew); } -DWORD WINAPI IDirect3DResource8Impl_GetPriority(LPDIRECT3DRESOURCE8 iface) { + +DWORD WINAPI IDirect3DResource8Impl_GetPriority(LPDIRECT3DRESOURCE8 iface) { IDirect3DResource8Impl *This = (IDirect3DResource8Impl *)iface; - FIXME("(%p) : stub\n", This); - return 0; + TRACE("(%p) Relay\n", This); + return IWineD3DResource_GetPriority(This->wineD3DResource); } -void WINAPI IDirect3DResource8Impl_PreLoad(LPDIRECT3DRESOURCE8 iface) { + +void WINAPI IDirect3DResource8Impl_PreLoad(LPDIRECT3DRESOURCE8 iface) { IDirect3DResource8Impl *This = (IDirect3DResource8Impl *)iface; - FIXME("(%p) : stub\n", This); + TRACE("(%p) Relay\n", This); + IWineD3DResource_PreLoad(This->wineD3DResource); + return; } + D3DRESOURCETYPE WINAPI IDirect3DResource8Impl_GetType(LPDIRECT3DRESOURCE8 iface) { IDirect3DResource8Impl *This = (IDirect3DResource8Impl *)iface; - TRACE("(%p) : returning %d\n", This, This->ResourceType); - return This->ResourceType; + TRACE("(%p) Relay\n", This); + return IWineD3DResource_GetType(This->wineD3DResource); } const IDirect3DResource8Vtbl Direct3DResource8_Vtbl = diff --git a/dlls/d3d8/shader.c b/dlls/d3d8/shader.c deleted file mode 100644 index f52a0ed16f1..00000000000 --- a/dlls/d3d8/shader.c +++ /dev/null @@ -1,2386 +0,0 @@ -/* - * shaders implementation - * - * Copyright 2002-2004 Raphael Junqueira - * Copyright 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "config.h" - -#include -#include -#include - -#include "windef.h" -#include "winbase.h" -#include "winuser.h" -#include "wingdi.h" -#include "wine/debug.h" - -#include "d3d8_private.h" - -WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader); -WINE_DECLARE_DEBUG_CHANNEL(d3d_hw_shader); - -/* Shader debugging - Change the following line to enable debugging of software - vertex shaders */ -#if 0 /* Must not be 1 in cvs version */ -# define VSTRACE(A) TRACE A -# define TRACE_VSVECTOR(name) TRACE( #name "=(%f, %f, %f, %f)\n", name.x, name.y, name.z, name.w) -#else -# define VSTRACE(A) -# define TRACE_VSVECTOR(name) -#endif - -/** - * DirectX9 SDK download - * http://msdn.microsoft.com/library/default.asp?url=/downloads/list/directx.asp - * - * Exploring D3DX - * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndrive/html/directx07162002.asp - * - * Using Vertex Shaders - * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndrive/html/directx02192001.asp - * - * Dx9 New - * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/whatsnew.asp - * - * Dx9 Shaders - * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/Shaders/VertexShader2_0/VertexShader2_0.asp - * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/Shaders/VertexShader2_0/Instructions/Instructions.asp - * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/programmingguide/GettingStarted/VertexDeclaration/VertexDeclaration.asp - * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/Shaders/VertexShader3_0/VertexShader3_0.asp - * - * Dx9 D3DX - * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/programmingguide/advancedtopics/VertexPipe/matrixstack/matrixstack.asp - * - * FVF - * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/programmingguide/GettingStarted/VertexFormats/vformats.asp - * - * NVIDIA: DX8 Vertex Shader to NV Vertex Program - * http://developer.nvidia.com/view.asp?IO=vstovp - * - * NVIDIA: Memory Management with VAR - * http://developer.nvidia.com/view.asp?IO=var_memory_management - */ - -typedef void (*shader_fct_t)(); - -typedef struct SHADER_OPCODE { - CONST WORD opcode; - const char* name; - CONST UINT num_params; - shader_fct_t soft_fct; - DWORD min_version; - DWORD max_version; -} SHADER_OPCODE; - -/******************************* - * vshader functions software VM - */ - -void vshader_add(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1) { - d->x = s0->x + s1->x; - d->y = s0->y + s1->y; - d->z = s0->z + s1->z; - d->w = s0->w + s1->w; - VSTRACE(("executing add: s0=(%f, %f, %f, %f) s1=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n", - s0->x, s0->y, s0->z, s0->w, s1->x, s1->y, s1->z, s1->w, d->x, d->y, d->z, d->w)); -} - -void vshader_dp3(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1) { - d->x = d->y = d->z = d->w = s0->x * s1->x + s0->y * s1->y + s0->z * s1->z; - VSTRACE(("executing dp3: s0=(%f, %f, %f, %f) s1=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n", - s0->x, s0->y, s0->z, s0->w, s1->x, s1->y, s1->z, s1->w, d->x, d->y, d->z, d->w)); -} - -void vshader_dp4(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1) { - d->x = d->y = d->z = d->w = s0->x * s1->x + s0->y * s1->y + s0->z * s1->z + s0->w * s1->w; - VSTRACE(("executing dp4: s0=(%f, %f, %f, %f) s1=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n", - s0->x, s0->y, s0->z, s0->w, s1->x, s1->y, s1->z, s1->w, d->x, d->y, d->z, d->w)); -} - -void vshader_dst(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1) { - d->x = 1.0f; - d->y = s0->y * s1->y; - d->z = s0->z; - d->w = s1->w; - VSTRACE(("executing dst: s0=(%f, %f, %f, %f) s1=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n", - s0->x, s0->y, s0->z, s0->w, s1->x, s1->y, s1->z, s1->w, d->x, d->y, d->z, d->w)); -} - -void vshader_expp(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) { - union { - float f; - DWORD d; - } tmp; - - tmp.f = floorf(s0->w); - d->x = powf(2.0f, tmp.f); - d->y = s0->w - tmp.f; - - tmp.f = powf(2.0f, s0->w); - tmp.d &= 0xFFFFFF00U; - d->z = tmp.f; - d->w = 1.0f; - VSTRACE(("executing exp: s0=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n", - s0->x, s0->y, s0->z, s0->w, d->x, d->y, d->z, d->w)); -} - -void vshader_lit(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) { - d->x = 1.0f; - d->y = (0.0f < s0->x) ? s0->x : 0.0f; - d->z = (0.0f < s0->x && 0.0f < s0->y) ? powf(s0->y, s0->w) : 0.0f; - d->w = 1.0f; - VSTRACE(("executing lit: s0=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n", - s0->x, s0->y, s0->z, s0->w, d->x, d->y, d->z, d->w)); -} - -void vshader_logp(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) { - float tmp_f = fabsf(s0->w); - d->x = d->y = d->z = d->w = (0.0f != tmp_f) ? logf(tmp_f) / logf(2.0f) : -HUGE_VAL; - VSTRACE(("executing logp: s0=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n", - s0->x, s0->y, s0->z, s0->w, d->x, d->y, d->z, d->w)); -} - -void vshader_mad(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1, D3DSHADERVECTOR* s2) { - d->x = s0->x * s1->x + s2->x; - d->y = s0->y * s1->y + s2->y; - d->z = s0->z * s1->z + s2->z; - d->w = s0->w * s1->w + s2->w; - VSTRACE(("executing mad: s0=(%f, %f, %f, %f) s1=(%f, %f, %f, %f) s2=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n", - s0->x, s0->y, s0->z, s0->w, s1->x, s1->y, s1->z, s1->w, s2->x, s2->y, s2->z, s2->w, d->x, d->y, d->z, d->w)); -} - -void vshader_max(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1) { - d->x = (s0->x >= s1->x) ? s0->x : s1->x; - d->y = (s0->y >= s1->y) ? s0->y : s1->y; - d->z = (s0->z >= s1->z) ? s0->z : s1->z; - d->w = (s0->w >= s1->w) ? s0->w : s1->w; - VSTRACE(("executing max: s0=(%f, %f, %f, %f) s1=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n", - s0->x, s0->y, s0->z, s0->w, s1->x, s1->y, s1->z, s1->w, d->x, d->y, d->z, d->w)); -} - -void vshader_min(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1) { - d->x = (s0->x < s1->x) ? s0->x : s1->x; - d->y = (s0->y < s1->y) ? s0->y : s1->y; - d->z = (s0->z < s1->z) ? s0->z : s1->z; - d->w = (s0->w < s1->w) ? s0->w : s1->w; - VSTRACE(("executing min: s0=(%f, %f, %f, %f) s1=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n", - s0->x, s0->y, s0->z, s0->w, s1->x, s1->y, s1->z, s1->w, d->x, d->y, d->z, d->w)); -} - -void vshader_mov(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) { - d->x = s0->x; - d->y = s0->y; - d->z = s0->z; - d->w = s0->w; - VSTRACE(("executing mov: s0=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n", - s0->x, s0->y, s0->z, s0->w, d->x, d->y, d->z, d->w)); -} - -void vshader_mul(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1) { - d->x = s0->x * s1->x; - d->y = s0->y * s1->y; - d->z = s0->z * s1->z; - d->w = s0->w * s1->w; - VSTRACE(("executing mul: s0=(%f, %f, %f, %f) s1=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n", - s0->x, s0->y, s0->z, s0->w, s1->x, s1->y, s1->z, s1->w, d->x, d->y, d->z, d->w)); -} - -void vshader_nop(void) { - /* NOPPPP ahhh too easy ;) */ -} - -void vshader_rcp(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) { - d->x = d->y = d->z = d->w = (0.0f == s0->w) ? HUGE_VAL : 1.0f / s0->w; - VSTRACE(("executing rcp: s0=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n", - s0->x, s0->y, s0->z, s0->w, d->x, d->y, d->z, d->w)); -} - -void vshader_rsq(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) { - float tmp_f = fabsf(s0->w); - d->x = d->y = d->z = d->w = (0.0f == tmp_f) ? HUGE_VAL : ((1.0f != tmp_f) ? 1.0f / sqrtf(tmp_f) : 1.0f); - VSTRACE(("executing rsq: s0=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n", - s0->x, s0->y, s0->z, s0->w, d->x, d->y, d->z, d->w)); -} - -void vshader_sge(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1) { - d->x = (s0->x >= s1->x) ? 1.0f : 0.0f; - d->y = (s0->y >= s1->y) ? 1.0f : 0.0f; - d->z = (s0->z >= s1->z) ? 1.0f : 0.0f; - d->w = (s0->w >= s1->w) ? 1.0f : 0.0f; - VSTRACE(("executing sge: s0=(%f, %f, %f, %f) s1=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n", - s0->x, s0->y, s0->z, s0->w, s1->x, s1->y, s1->z, s1->w, d->x, d->y, d->z, d->w)); -} - -void vshader_slt(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1) { - d->x = (s0->x < s1->x) ? 1.0f : 0.0f; - d->y = (s0->y < s1->y) ? 1.0f : 0.0f; - d->z = (s0->z < s1->z) ? 1.0f : 0.0f; - d->w = (s0->w < s1->w) ? 1.0f : 0.0f; - VSTRACE(("executing slt: s0=(%f, %f, %f, %f) s1=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n", - s0->x, s0->y, s0->z, s0->w, s1->x, s1->y, s1->z, s1->w, d->x, d->y, d->z, d->w)); -} - -void vshader_sub(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1) { - d->x = s0->x - s1->x; - d->y = s0->y - s1->y; - d->z = s0->z - s1->z; - d->w = s0->w - s1->w; - VSTRACE(("executing sub: s0=(%f, %f, %f, %f) s1=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n", - s0->x, s0->y, s0->z, s0->w, s1->x, s1->y, s1->z, s1->w, d->x, d->y, d->z, d->w)); -} - -/** - * Version 1.1 specific - */ - -void vshader_exp(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) { - d->x = d->y = d->z = d->w = powf(2.0f, s0->w); - VSTRACE(("executing exp: s0=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n", - s0->x, s0->y, s0->z, s0->w, d->x, d->y, d->z, d->w)); -} - -void vshader_log(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) { - float tmp_f = fabsf(s0->w); - d->x = d->y = d->z = d->w = (0.0f != tmp_f) ? logf(tmp_f) / logf(2.0f) : -HUGE_VAL; - VSTRACE(("executing log: s0=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n", - s0->x, s0->y, s0->z, s0->w, d->x, d->y, d->z, d->w)); -} - -void vshader_frc(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) { - d->x = s0->x - floorf(s0->x); - d->y = s0->y - floorf(s0->y); - d->z = 0.0f; - d->w = 1.0f; - VSTRACE(("executing frc: s0=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n", - s0->x, s0->y, s0->z, s0->w, d->x, d->y, d->z, d->w)); -} - -typedef FLOAT D3DMATRIX44[4][4]; -typedef FLOAT D3DMATRIX43[3][4]; -typedef FLOAT D3DMATRIX34[4][3]; -typedef FLOAT D3DMATRIX33[3][3]; -typedef FLOAT D3DMATRIX32[2][3]; - -void vshader_m4x4(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, /*D3DSHADERVECTOR* mat1*/ D3DMATRIX44 mat) { - /* - * BuGGY CODE: here only if cast not work for copy/paste - D3DSHADERVECTOR* mat2 = mat1 + 1; - D3DSHADERVECTOR* mat3 = mat1 + 2; - D3DSHADERVECTOR* mat4 = mat1 + 3; - d->x = mat1->x * s0->x + mat2->x * s0->y + mat3->x * s0->z + mat4->x * s0->w; - d->y = mat1->y * s0->x + mat2->y * s0->y + mat3->y * s0->z + mat4->y * s0->w; - d->z = mat1->z * s0->x + mat2->z * s0->y + mat3->z * s0->z + mat4->z * s0->w; - d->w = mat1->w * s0->x + mat2->w * s0->y + mat3->w * s0->z + mat4->w * s0->w; - */ - d->x = mat[0][0] * s0->x + mat[0][1] * s0->y + mat[0][2] * s0->z + mat[0][3] * s0->w; - d->y = mat[1][0] * s0->x + mat[1][1] * s0->y + mat[1][2] * s0->z + mat[1][3] * s0->w; - d->z = mat[2][0] * s0->x + mat[2][1] * s0->y + mat[2][2] * s0->z + mat[2][3] * s0->w; - d->w = mat[3][0] * s0->x + mat[3][1] * s0->y + mat[3][2] * s0->z + mat[3][3] * s0->w; - VSTRACE(("executing m4x4(1): mat=(%f, %f, %f, %f) s0=(%f) d=(%f)\n", mat[0][0], mat[0][1], mat[0][2], mat[0][3], s0->x, d->x)); - VSTRACE(("executing m4x4(2): mat=(%f, %f, %f, %f) (%f) (%f)\n", mat[1][0], mat[1][1], mat[1][2], mat[1][3], s0->y, d->y)); - VSTRACE(("executing m4x4(3): mat=(%f, %f, %f, %f) X (%f) = (%f)\n", mat[2][0], mat[2][1], mat[2][2], mat[2][3], s0->z, d->z)); - VSTRACE(("executing m4x4(4): mat=(%f, %f, %f, %f) (%f) (%f)\n", mat[3][0], mat[3][1], mat[3][2], mat[3][3], s0->w, d->w)); -} - -void vshader_m4x3(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DMATRIX43 mat) { - d->x = mat[0][0] * s0->x + mat[0][1] * s0->y + mat[0][2] * s0->z + mat[0][3] * s0->w; - d->y = mat[1][0] * s0->x + mat[1][1] * s0->y + mat[1][2] * s0->z + mat[1][3] * s0->w; - d->z = mat[2][0] * s0->x + mat[2][1] * s0->y + mat[2][2] * s0->z + mat[2][3] * s0->w; - d->w = 1.0f; - VSTRACE(("executing m4x3(1): mat=(%f, %f, %f, %f) s0=(%f) d=(%f)\n", mat[0][0], mat[0][1], mat[0][2], mat[0][3], s0->x, d->x)); - VSTRACE(("executing m4x3(2): mat=(%f, %f, %f, %f) (%f) (%f)\n", mat[1][0], mat[1][1], mat[1][2], mat[1][3], s0->y, d->y)); - VSTRACE(("executing m4x3(3): mat=(%f, %f, %f, %f) X (%f) = (%f)\n", mat[2][0], mat[2][1], mat[2][2], mat[2][3], s0->z, d->z)); - VSTRACE(("executing m4x3(4): (%f) (%f)\n", s0->w, d->w)); -} - -void vshader_m3x4(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DMATRIX34 mat) { - d->x = mat[0][0] * s0->x + mat[0][1] * s0->y + mat[0][2] * s0->z; - d->y = mat[1][0] * s0->x + mat[1][1] * s0->y + mat[1][2] * s0->z; - d->z = mat[2][0] * s0->x + mat[2][1] * s0->y + mat[2][2] * s0->z; - d->w = mat[3][0] * s0->x + mat[3][1] * s0->y + mat[3][2] * s0->z; - VSTRACE(("executing m3x4(1): mat=(%f, %f, %f) s0=(%f) d=(%f) \n", mat[0][0], mat[0][1], mat[0][2], s0->x, d->x)); - VSTRACE(("executing m3x4(2): mat=(%f, %f, %f) (%f) (%f) \n", mat[1][0], mat[1][1], mat[1][2], s0->y, d->y)); - VSTRACE(("executing m3x4(3): mat=(%f, %f, %f) X (%f) = (%f) \n", mat[2][0], mat[2][1], mat[2][2], s0->z, d->z)); - VSTRACE(("executing m3x4(4): mat=(%f, %f, %f) (%f) (%f) \n", mat[3][0], mat[3][1], mat[3][2], s0->w, d->w)); -} - -void vshader_m3x3(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DMATRIX33 mat) { - d->x = mat[0][0] * s0->x + mat[0][1] * s0->y + mat[0][2] * s0->z; - d->y = mat[1][0] * s0->x + mat[1][1] * s0->y + mat[1][2] * s0->z; - d->z = mat[2][0] * s0->x + mat[2][1] * s0->y + mat[2][2] * s0->z; - d->w = 1.0f; - VSTRACE(("executing m3x3(1): mat=(%f, %f, %f) s0=(%f) d=(%f) \n", mat[0][0], mat[0][1], mat[0][2], s0->x, d->x)); - VSTRACE(("executing m3x3(2): mat=(%f, %f, %f) (%f) (%f) \n", mat[1][0], mat[1][1], mat[1][2], s0->y, d->y)); - VSTRACE(("executing m3x3(3): mat=(%f, %f, %f) X (%f) = (%f) \n", mat[2][0], mat[2][1], mat[2][2], s0->z, d->z)); - VSTRACE(("executing m3x3(4): (%f) \n", d->w)); -} - -void vshader_m3x2(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DMATRIX32 mat) { - FIXME("check\n"); - d->x = mat[0][0] * s0->x + mat[0][1] * s0->y + mat[0][2] * s0->z; - d->y = mat[1][0] * s0->x + mat[1][1] * s0->y + mat[1][2] * s0->z; - d->z = 0.0f; - d->w = 1.0f; -} - -/** - * Version 2.0 specific - */ -void vshader_lrp(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1, D3DSHADERVECTOR* s2, D3DSHADERVECTOR* s3) { - d->x = s0->x * (s1->x - s2->x) + s2->x; - d->y = s0->y * (s1->y - s2->y) + s2->y; - d->z = s0->z * (s1->z - s2->z) + s2->z; - d->w = s0->w * (s1->w - s2->w) + s2->x; -} - -/** - * log, exp, frc, m*x* seems to be macros ins ... to see - * Note opcode must be in uppercase if direct mapping to GL hw shaders - */ -static CONST SHADER_OPCODE vshader_ins [] = { - {D3DSIO_NOP, "NOP", 0, vshader_nop, 0, 0}, - {D3DSIO_MOV, "MOV", 2, vshader_mov, 0, 0}, - {D3DSIO_ADD, "ADD", 3, vshader_add, 0, 0}, - {D3DSIO_SUB, "SUB", 3, vshader_sub, 0, 0}, - {D3DSIO_MAD, "MAD", 4, vshader_mad, 0, 0}, - {D3DSIO_MUL, "MUL", 3, vshader_mul, 0, 0}, - {D3DSIO_RCP, "RCP", 2, vshader_rcp, 0, 0}, - {D3DSIO_RSQ, "RSQ", 2, vshader_rsq, 0, 0}, - {D3DSIO_DP3, "DP3", 3, vshader_dp3, 0, 0}, - {D3DSIO_DP4, "DP4", 3, vshader_dp4, 0, 0}, - {D3DSIO_MIN, "MIN", 3, vshader_min, 0, 0}, - {D3DSIO_MAX, "MAX", 3, vshader_max, 0, 0}, - {D3DSIO_SLT, "SLT", 3, vshader_slt, 0, 0}, - {D3DSIO_SGE, "SGE", 3, vshader_sge, 0, 0}, - {D3DSIO_EXP, "EXP", 2, vshader_exp, 0, 0}, - {D3DSIO_LOG, "LOG", 2, vshader_log, 0, 0}, - {D3DSIO_LIT, "LIT", 2, vshader_lit, 0, 0}, - {D3DSIO_DST, "DST", 3, vshader_dst, 0, 0}, - {D3DSIO_LRP, "LRP", 5, vshader_lrp, 0, 0}, - {D3DSIO_FRC, "FRC", 2, vshader_frc, 0, 0}, - {D3DSIO_M4x4, "M4X4", 3, vshader_m4x4, 0, 0}, - {D3DSIO_M4x3, "M4X3", 3, vshader_m4x3, 0, 0}, - {D3DSIO_M3x4, "M3X4", 3, vshader_m3x4, 0, 0}, - {D3DSIO_M3x3, "M3X3", 3, vshader_m3x3, 0, 0}, - {D3DSIO_M3x2, "M3X2", 3, vshader_m3x2, 0, 0}, - /** FIXME: use direct access so add the others opcodes as stubs */ - {D3DSIO_EXPP, "EXPP", 2, vshader_expp, 0, 0}, - {D3DSIO_LOGP, "LOGP", 2, vshader_logp, 0, 0}, - - {0, NULL, 0, NULL, 0, 0} -}; - - -inline static const SHADER_OPCODE* vshader_program_get_opcode(const DWORD code) { - DWORD i = 0; - /** TODO: use dichotomic search */ - while (NULL != vshader_ins[i].name) { - if ((code & D3DSI_OPCODE_MASK) == vshader_ins[i].opcode) { - return &vshader_ins[i]; - } - ++i; - } - return NULL; -} - -inline static BOOL vshader_is_version_token(DWORD token) { - return 0xFFFE0000 == (token & 0xFFFE0000); -} - -inline static BOOL vshader_is_comment_token(DWORD token) { - return D3DSIO_COMMENT == (token & D3DSI_OPCODE_MASK); -} - -inline static void vshader_program_dump_param(const DWORD param, int input) { - static const char* rastout_reg_names[] = { "oPos", "oFog", "oPts" }; - static const char swizzle_reg_chars[] = "xyzw"; - - DWORD reg = param & 0x00001FFF; - DWORD regtype = ((param & D3DSP_REGTYPE_MASK) >> D3DSP_REGTYPE_SHIFT); - - if ((param & D3DSP_SRCMOD_MASK) == D3DSPSM_NEG) TRACE("-"); - - switch (regtype << D3DSP_REGTYPE_SHIFT) { - case D3DSPR_TEMP: - TRACE("R[%lu]", reg); - break; - case D3DSPR_INPUT: - TRACE("V[%lu]", reg); - break; - case D3DSPR_CONST: - TRACE("C[%s%lu]", (param & D3DVS_ADDRMODE_RELATIVE) ? "a0.x + " : "", reg); - break; - case D3DSPR_ADDR: /*case D3DSPR_TEXTURE:*/ - TRACE("a[%lu]", reg); - break; - case D3DSPR_RASTOUT: - TRACE("%s", rastout_reg_names[reg]); - break; - case D3DSPR_ATTROUT: - TRACE("oD[%lu]", reg); - break; - case D3DSPR_TEXCRDOUT: - TRACE("oT[%lu]", reg); - break; - default: - break; - } - - if (!input) { - /** operand output */ - if ((param & D3DSP_WRITEMASK_ALL) != D3DSP_WRITEMASK_ALL) { - if (param & D3DSP_WRITEMASK_0) TRACE(".x"); - if (param & D3DSP_WRITEMASK_1) TRACE(".y"); - if (param & D3DSP_WRITEMASK_2) TRACE(".z"); - if (param & D3DSP_WRITEMASK_3) TRACE(".w"); - } - } else { - /** operand input */ - DWORD swizzle = (param & D3DVS_SWIZZLE_MASK) >> D3DVS_SWIZZLE_SHIFT; - DWORD swizzle_x = swizzle & 0x03; - DWORD swizzle_y = (swizzle >> 2) & 0x03; - DWORD swizzle_z = (swizzle >> 4) & 0x03; - DWORD swizzle_w = (swizzle >> 6) & 0x03; - /** - * swizzle bits fields: - * WWZZYYXX - */ - if ((D3DVS_NOSWIZZLE >> D3DVS_SWIZZLE_SHIFT) != swizzle) { /* ! D3DVS_NOSWIZZLE == 0xE4 << D3DVS_SWIZZLE_SHIFT */ - if (swizzle_x == swizzle_y && - swizzle_x == swizzle_z && - swizzle_x == swizzle_w) { - TRACE(".%c", swizzle_reg_chars[swizzle_x]); - } else { - TRACE(".%c%c%c%c", - swizzle_reg_chars[swizzle_x], - swizzle_reg_chars[swizzle_y], - swizzle_reg_chars[swizzle_z], - swizzle_reg_chars[swizzle_w]); - } - } - } -} - -inline static void vshader_program_add_param(const DWORD param, int input, char *hwLine) { - /*static const char* rastout_reg_names[] = { "oPos", "oFog", "oPts" }; */ - static const char* hwrastout_reg_names[] = { "result.position", "result.fogcoord", "result.pointsize" }; - static const char swizzle_reg_chars[] = "xyzw"; - - DWORD reg = param & 0x00001FFF; - DWORD regtype = ((param & D3DSP_REGTYPE_MASK) >> D3DSP_REGTYPE_SHIFT); - char tmpReg[255]; - - if ((param & D3DSP_SRCMOD_MASK) == D3DSPSM_NEG) { - strcat(hwLine, " -"); - } else { - strcat(hwLine, " "); - } - - switch (regtype << D3DSP_REGTYPE_SHIFT) { - case D3DSPR_TEMP: - sprintf(tmpReg, "T%lu", reg); - strcat(hwLine, tmpReg); - break; - case D3DSPR_INPUT: - sprintf(tmpReg, "vertex.attrib[%lu]", reg); - strcat(hwLine, tmpReg); - break; - case D3DSPR_CONST: - sprintf(tmpReg, "C[%s%lu]", (param & D3DVS_ADDRMODE_RELATIVE) ? "A0.x + " : "", reg); - strcat(hwLine, tmpReg); - break; - case D3DSPR_ADDR: /*case D3DSPR_TEXTURE:*/ - sprintf(tmpReg, "A%lu", reg); - strcat(hwLine, tmpReg); - break; - case D3DSPR_RASTOUT: - sprintf(tmpReg, "%s", hwrastout_reg_names[reg]); - strcat(hwLine, tmpReg); - break; - case D3DSPR_ATTROUT: - if (reg==0) { - strcat(hwLine, "result.color.primary"); - } else { - strcat(hwLine, "result.color.secondary"); - } - break; - case D3DSPR_TEXCRDOUT: - sprintf(tmpReg, "result.texcoord[%lu]", reg); - strcat(hwLine, tmpReg); - break; - default: - break; - } - - if (!input) { - /** operand output */ - if ((param & D3DSP_WRITEMASK_ALL) != D3DSP_WRITEMASK_ALL) { - strcat(hwLine, "."); - if (param & D3DSP_WRITEMASK_0) { - strcat(hwLine, "x"); - } - if (param & D3DSP_WRITEMASK_1) { - strcat(hwLine, "y"); - } - if (param & D3DSP_WRITEMASK_2) { - strcat(hwLine, "z"); - } - if (param & D3DSP_WRITEMASK_3) { - strcat(hwLine, "w"); - } - } - } else { - /** operand input */ - DWORD swizzle = (param & D3DVS_SWIZZLE_MASK) >> D3DVS_SWIZZLE_SHIFT; - DWORD swizzle_x = swizzle & 0x03; - DWORD swizzle_y = (swizzle >> 2) & 0x03; - DWORD swizzle_z = (swizzle >> 4) & 0x03; - DWORD swizzle_w = (swizzle >> 6) & 0x03; - /** - * swizzle bits fields: - * WWZZYYXX - */ - if ((D3DVS_NOSWIZZLE >> D3DVS_SWIZZLE_SHIFT) != swizzle) { /* ! D3DVS_NOSWIZZLE == 0xE4 << D3DVS_SWIZZLE_SHIFT */ - if (swizzle_x == swizzle_y && - swizzle_x == swizzle_z && - swizzle_x == swizzle_w) { - sprintf(tmpReg, ".%c", swizzle_reg_chars[swizzle_x]); - strcat(hwLine, tmpReg); - } else { - sprintf(tmpReg, ".%c%c%c%c", - swizzle_reg_chars[swizzle_x], - swizzle_reg_chars[swizzle_y], - swizzle_reg_chars[swizzle_z], - swizzle_reg_chars[swizzle_w]); - strcat(hwLine, tmpReg); - } - } - } -} - -DWORD MacroExpansion[4*4]; - -int ExpandMxMacro(DWORD macro_opcode, const DWORD* args) { - int i; - int nComponents = 0; - DWORD opcode =0; - switch(macro_opcode) { - case D3DSIO_M4x4: - nComponents = 4; - opcode = D3DSIO_DP4; - break; - case D3DSIO_M4x3: - nComponents = 3; - opcode = D3DSIO_DP4; - break; - case D3DSIO_M3x4: - nComponents = 4; - opcode = D3DSIO_DP3; - break; - case D3DSIO_M3x3: - nComponents = 3; - opcode = D3DSIO_DP3; - break; - case D3DSIO_M3x2: - nComponents = 2; - opcode = D3DSIO_DP3; - break; - default: - break; - } - for (i = 0; i < nComponents; i++) { - MacroExpansion[i*4+0] = opcode; - MacroExpansion[i*4+1] = ((*args) & ~D3DSP_WRITEMASK_ALL)|(D3DSP_WRITEMASK_0<device; - - pgmStr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 65535); /* 64kb should be enough */ - - /** - * First pass to determine what we need to declare: - * - Temporary variables - * - Address variables - */ - if (NULL != pToken) { - while (D3DVS_END() != *pToken) { - if (vshader_is_version_token(*pToken)) { - /** skip version */ - ++pToken; - continue; - } - if (vshader_is_comment_token(*pToken)) { /** comment */ - DWORD comment_len = (*pToken & D3DSI_COMMENTSIZE_MASK) >> D3DSI_COMMENTSIZE_SHIFT; - ++pToken; - pToken += comment_len; - continue; - } - curOpcode = vshader_program_get_opcode(*pToken); - ++pToken; - if (NULL == curOpcode) { - while (*pToken & 0x80000000) { - /* skip unrecognized opcode */ - ++pToken; - } - } else { - if (curOpcode->num_params > 0) { - regtype = ((((*pToken) & D3DSP_REGTYPE_MASK) >> D3DSP_REGTYPE_SHIFT) << D3DSP_REGTYPE_SHIFT); - reg = ((*pToken) & 0x00001FFF); - /** we should validate GL_MAX_PROGRAM_ADDRESS_REGISTERS_AR limits here */ - if (D3DSPR_ADDR == regtype && nUseAddressRegister <= reg) nUseAddressRegister = reg + 1; - /** we should validate GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB limits here */ - if (D3DSPR_TEMP == regtype && nUseTempRegister <= reg) nUseTempRegister = reg + 1; - ++pToken; - for (i = 1; i < curOpcode->num_params; ++i) { - regtype = ((((*pToken) & D3DSP_REGTYPE_MASK) >> D3DSP_REGTYPE_SHIFT) << D3DSP_REGTYPE_SHIFT); - reg = ((*pToken) & 0x00001FFF); - /** we should validate GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB limits here */ - if (D3DSPR_TEMP == regtype && nUseTempRegister <= reg) nUseTempRegister = reg + 1; - ++pToken; - } - } - } - } - } - - /** second pass, now generate */ - pToken = pFunction; - - if (NULL != pToken) { - while (1) { - tmpLine[0] = 0; - - if ((nRemInstr >= 0) && (--nRemInstr == -1)) - /* Macro is finished, continue normal path */ - pToken = pSavedToken; - - if (D3DVS_END() == *pToken) - break; - - if (vshader_is_version_token(*pToken)) { /** version */ - - /* Extract version *10 into integer value (ie. 1.0 == 10, 1.1==11 etc */ - int version = (((*pToken >> 8) & 0x0F) * 10) + (*pToken & 0x0F); - int numTemps; - int numConstants; - - TRACE_(d3d_hw_shader)("vs.%lu.%lu;\n", (*pToken >> 8) & 0x0F, (*pToken & 0x0F)); - - /* Each release of vertex shaders has had different numbers of temp registers */ - switch (version) { - case 10: - case 11: numTemps=12; - numConstants=96; - strcpy(tmpLine, "!!ARBvp1.0\n"); - TRACE_(d3d_hw_shader)("GL HW (%u) : %s", strlen(pgmStr), tmpLine); /* Don't add \n to this line as already in tmpLine */ - break; - case 20: numTemps=12; - numConstants=256; - strcpy(tmpLine, "!!ARBvp2.0\n"); - FIXME_(d3d_hw_shader)("No work done yet to support vs2.0 in hw\n"); - TRACE_(d3d_hw_shader)("GL HW (%u) : %s", strlen(pgmStr), tmpLine); /* Don't add \n to this line as already in tmpLine */ - break; - case 30: numTemps=32; - numConstants=256; - strcpy(tmpLine, "!!ARBvp3.0\n"); - FIXME_(d3d_hw_shader)("No work done yet to support vs3.0 in hw\n"); - TRACE_(d3d_hw_shader)("GL HW (%u) : %s", strlen(pgmStr), tmpLine); /* Don't add \n to this line as already in tmpLine */ - break; - default: - numTemps=12; - numConstants=96; - strcpy(tmpLine, "!!ARBvp1.0\n"); - FIXME_(d3d_hw_shader)("Unrecognized vertex shader version!\n"); - } - strcat(pgmStr,tmpLine); - ++lineNum; - - for (i = 0; i < nUseTempRegister/*we should check numTemps here*/; i++) { - sprintf(tmpLine, "TEMP T%ld;\n", i); - ++lineNum; - TRACE_(d3d_hw_shader)("GL HW (%u, %u) : %s", lineNum, strlen(pgmStr), tmpLine); /* Don't add \n to this line as already in tmpLine */ - strcat(pgmStr,tmpLine); - } - for (i = 0; i < nUseAddressRegister; i++) { - sprintf(tmpLine, "ADDRESS A%ld;\n", i); - ++lineNum; - TRACE_(d3d_hw_shader)("GL HW (%u, %u) : %s", lineNum, strlen(pgmStr), tmpLine); /* Don't add \n to this line as already in tmpLine */ - strcat(pgmStr,tmpLine); - } - /* Due to the dynamic constants binding mechanism, we need to declare - * all the constants for relative addressing. */ - /* Mesa supports nly 95 constants for VS1.X although we should have at least 96. */ - if (GL_VENDOR_NAME(This) == VENDOR_MESA || GL_VENDOR_NAME(This) == VENDOR_WINE) { - numConstants = 95; - } - sprintf(tmpLine, "PARAM C[%d] = { program.env[0..%d] };\n", numConstants, numConstants-1); - TRACE_(d3d_hw_shader)("GL HW (%u,%u) : %s", lineNum, strlen(pgmStr), tmpLine); /* Don't add \n to this line as already in tmpLine */ - strcat(pgmStr, tmpLine); - ++lineNum; - - ++pToken; - continue; - } - if (vshader_is_comment_token(*pToken)) { /** comment */ - DWORD comment_len = (*pToken & D3DSI_COMMENTSIZE_MASK) >> D3DSI_COMMENTSIZE_SHIFT; - ++pToken; - /*TRACE("comment[%ld] ;%s\n", comment_len, (char*)pToken);*/ - pToken += comment_len; - continue; - } - curOpcode = vshader_program_get_opcode(*pToken); - ++pToken; - if (NULL == curOpcode) { - /* unknown current opcode ... */ - while (*pToken & 0x80000000) { - TRACE_(d3d_hw_shader)("unrecognized opcode: %08lx\n", *pToken); - ++pToken; - } - } else { - /* Build opcode for GL vertex_program */ - switch (curOpcode->opcode) { - case D3DSIO_NOP: - continue; - case D3DSIO_MOV: - /* Address registers must be loaded with the ARL instruction */ - if (((*pToken) & D3DSP_REGTYPE_MASK) == D3DSPR_ADDR) { - if (0 < nUseAddressRegister) { - strcpy(tmpLine, "ARL"); - break; - } else - FIXME_(d3d_hw_shader)("Try to load an undeclared address register!\n"); - } - /* fall through */ - case D3DSIO_ADD: - case D3DSIO_SUB: - case D3DSIO_MAD: - case D3DSIO_MUL: - case D3DSIO_RCP: - case D3DSIO_RSQ: - case D3DSIO_DP3: - case D3DSIO_DP4: - case D3DSIO_MIN: - case D3DSIO_MAX: - case D3DSIO_SLT: - case D3DSIO_SGE: - case D3DSIO_LIT: - case D3DSIO_DST: - case D3DSIO_FRC: - strcpy(tmpLine, curOpcode->name); - break; - - case D3DSIO_EXPP: - strcpy(tmpLine, "EXP"); - break; - case D3DSIO_LOGP: - strcpy(tmpLine, "LOG"); - break; - case D3DSIO_EXP: - strcpy(tmpLine, "EX2"); - break; - case D3DSIO_LOG: - strcpy(tmpLine, "LG2"); - break; - - case D3DSIO_M4x4: - case D3DSIO_M4x3: - case D3DSIO_M3x4: - case D3DSIO_M3x3: - case D3DSIO_M3x2: - /* Expand the macro and get number of generated instruction */ - nRemInstr = ExpandMxMacro(curOpcode->opcode, pToken); - /* Save point to next instruction */ - pSavedToken = pToken + 3; - /* Execute expanded macro */ - pToken = MacroExpansion; - continue; - - default: - FIXME_(d3d_hw_shader)("Can't handle opcode %s in hwShader\n", curOpcode->name); - } - - if (curOpcode->num_params > 0) { - vshader_program_add_param(*pToken, 0, tmpLine); - - ++pToken; - for (i = 1; i < curOpcode->num_params; ++i) { - strcat(tmpLine, ","); - vshader_program_add_param(*pToken, 1, tmpLine); - ++pToken; - } - } - strcat(tmpLine,";\n"); - ++lineNum; - TRACE_(d3d_hw_shader)("GL HW (%u, %u) : %s", lineNum, strlen(pgmStr), tmpLine); /* Don't add \n to this line as already in tmpLine */ - strcat(pgmStr, tmpLine); - } - } - strcpy(tmpLine, "END\n"); - ++lineNum; - TRACE_(d3d_hw_shader)("GL HW (%u, %u) : %s", lineNum, strlen(pgmStr), tmpLine); /* Don't add \n to this line as already in tmpLine */ - strcat(pgmStr, tmpLine); - } - - /* Create the hw shader */ - GL_EXTCALL(glGenProgramsARB(1, &vshader->prgId)); - TRACE_(d3d_hw_shader)("Creating a hw vertex shader, prg=%d\n", vshader->prgId); - - GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, vshader->prgId)); - - /* Create the program and check for errors */ - GL_EXTCALL(glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, strlen(pgmStr), pgmStr)); - if (glGetError() == GL_INVALID_OPERATION) { - GLint errPos; - glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errPos); - FIXME_(d3d_hw_shader)("HW VertexShader Error at position: %d\n%s\n", errPos, glGetString(GL_PROGRAM_ERROR_STRING_ARB)); - vshader->prgId = -1; - } - - HeapFree(GetProcessHeap(), 0, pgmStr); -} - -inline static VOID IDirect3DVertexShaderImpl_ParseProgram(IDirect3DVertexShaderImpl* vshader, CONST DWORD* pFunction, int useHW) { - const DWORD* pToken = pFunction; - const SHADER_OPCODE* curOpcode = NULL; - DWORD len = 0; - DWORD i; - - if (NULL != pToken) { - while (D3DVS_END() != *pToken) { - if (vshader_is_version_token(*pToken)) { /** version */ - TRACE("vs.%lu.%lu\n", (*pToken >> 8) & 0x0F, (*pToken & 0x0F)); - ++pToken; - ++len; - continue; - } - if (vshader_is_comment_token(*pToken)) { /** comment */ - DWORD comment_len = (*pToken & D3DSI_COMMENTSIZE_MASK) >> D3DSI_COMMENTSIZE_SHIFT; - ++pToken; - /*TRACE("comment[%ld] ;%s\n", comment_len, (char*)pToken);*/ - pToken += comment_len; - len += comment_len + 1; - continue; - } - curOpcode = vshader_program_get_opcode(*pToken); - ++pToken; - ++len; - if (NULL == curOpcode) { - /* unknown current opcode ... */ - while (*pToken & 0x80000000) { - TRACE("unrecognized opcode: %08lx\n", *pToken); - ++pToken; - ++len; - } - } else { - TRACE("%s ", curOpcode->name); - if (curOpcode->num_params > 0) { - vshader_program_dump_param(*pToken, 0); - ++pToken; - ++len; - for (i = 1; i < curOpcode->num_params; ++i) { - TRACE(", "); - vshader_program_dump_param(*pToken, 1); - ++pToken; - ++len; - } - } - TRACE("\n"); - } - } - vshader->functionLength = (len + 1) * sizeof(DWORD); - } else { - vshader->functionLength = 1; /* no Function defined use fixed function vertex processing */ - } - - /* Generate HW shader in needed */ - if (useHW && NULL != pFunction) { - IDirect3DVertexShaderImpl_GenerateProgramArbHW(vshader, pFunction); - } - - /* copy the function ... because it will certainly be released by application */ - if (NULL != pFunction) { - vshader->function = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, vshader->functionLength); - memcpy(vshader->function, pFunction, vshader->functionLength); - } else { - vshader->function = NULL; - } -} - -HRESULT WINAPI IDirect3DDeviceImpl_CreateVertexShader(IDirect3DDevice8Impl* This, CONST DWORD* pFunction, DWORD Usage, IDirect3DVertexShaderImpl** ppVertexShader) { - IDirect3DVertexShaderImpl* object; - int useHW; - - object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVertexShaderImpl)); - if (NULL == object) { - *ppVertexShader = NULL; - return D3DERR_OUTOFVIDEOMEMORY; - } - /*object->lpVtbl = &Direct3DVextexShader9_Vtbl;*/ - object->device = This; /* FIXME: AddRef(This) */ - object->ref = 1; - - object->usage = Usage; - object->data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(VSHADERDATA8)); - - useHW = (((vs_mode == VS_HW) && GL_SUPPORT(ARB_VERTEX_PROGRAM)) && - This->devType != D3DDEVTYPE_REF && - object->usage != D3DUSAGE_SOFTWAREPROCESSING); - - IDirect3DVertexShaderImpl_ParseProgram(object, pFunction, useHW); - - *ppVertexShader = object; - return D3D_OK; -} - -BOOL IDirect3DVertexShaderImpl_ExecuteHAL(IDirect3DVertexShaderImpl* vshader, VSHADERINPUTDATA8* input, VSHADEROUTPUTDATA8* output) { - /** - * TODO: use the NV_vertex_program (or 1_1) extension - * and specifics vendors (ARB_vertex_program??) variants for it - */ - return TRUE; -} - -HRESULT WINAPI IDirect3DVertexShaderImpl_ExecuteSW(IDirect3DVertexShaderImpl* vshader, VSHADERINPUTDATA8* input, VSHADEROUTPUTDATA8* output) { - /** Vertex Shader Temporary Registers */ - D3DSHADERVECTOR R[12]; - /*D3DSHADERSCALAR A0;*/ - D3DSHADERVECTOR A[1]; - /** temporary Vector for modifier management */ - D3DSHADERVECTOR d; - D3DSHADERVECTOR s[3]; - /** parser datas */ - const DWORD* pToken = vshader->function; - const SHADER_OPCODE* curOpcode = NULL; - /** functions parameters */ - D3DSHADERVECTOR* p[5]; - D3DSHADERVECTOR* p_send[5]; - DWORD i; - - /** init temporary register */ - memset(R, 0, 12 * sizeof(D3DSHADERVECTOR)); - - /* vshader_program_parse(vshader); */ -#if 0 /* Must not be 1 in cvs */ - TRACE("Input:\n"); - TRACE_VSVECTOR(vshader->data->C[0]); - TRACE_VSVECTOR(vshader->data->C[1]); - TRACE_VSVECTOR(vshader->data->C[2]); - TRACE_VSVECTOR(vshader->data->C[3]); - TRACE_VSVECTOR(vshader->data->C[4]); - TRACE_VSVECTOR(vshader->data->C[5]); - TRACE_VSVECTOR(vshader->data->C[6]); - TRACE_VSVECTOR(vshader->data->C[7]); - TRACE_VSVECTOR(vshader->data->C[8]); - TRACE_VSVECTOR(vshader->data->C[64]); - TRACE_VSVECTOR(input->V[D3DVSDE_POSITION]); - TRACE_VSVECTOR(input->V[D3DVSDE_BLENDWEIGHT]); - TRACE_VSVECTOR(input->V[D3DVSDE_BLENDINDICES]); - TRACE_VSVECTOR(input->V[D3DVSDE_NORMAL]); - TRACE_VSVECTOR(input->V[D3DVSDE_PSIZE]); - TRACE_VSVECTOR(input->V[D3DVSDE_DIFFUSE]); - TRACE_VSVECTOR(input->V[D3DVSDE_SPECULAR]); - TRACE_VSVECTOR(input->V[D3DVSDE_TEXCOORD0]); - TRACE_VSVECTOR(input->V[D3DVSDE_TEXCOORD1]); -#endif - - TRACE_VSVECTOR(vshader->data->C[64]); - - /* the first dword is the version tag */ - /* TODO: parse it */ - - if (vshader_is_version_token(*pToken)) { /** version */ - ++pToken; - } - while (D3DVS_END() != *pToken) { - if (vshader_is_comment_token(*pToken)) { /** comment */ - DWORD comment_len = (*pToken & D3DSI_COMMENTSIZE_MASK) >> D3DSI_COMMENTSIZE_SHIFT; - ++pToken; - pToken += comment_len; - continue ; - } - curOpcode = vshader_program_get_opcode(*pToken); - ++pToken; - if (NULL == curOpcode) { - i = 0; - /* unknown current opcode ... */ - while (*pToken & 0x80000000) { - if (i == 0) { - TRACE("unrecognized opcode: pos=%d token=%08lX\n", (pToken - 1) - vshader->function, *(pToken - 1)); - } - TRACE("unrecognized opcode param: pos=%d token=%08lX what=", pToken - vshader->function, *pToken); - vshader_program_add_param(*pToken, i, NULL); /* Add function just used for trace error scenario */ - TRACE("\n"); - ++i; - ++pToken; - } - /*return FALSE;*/ - } else { - if (curOpcode->num_params > 0) { - /*TRACE(">> execting opcode: pos=%d opcode_name=%s token=%08lX\n", pToken - vshader->function, curOpcode->name, *pToken);*/ - for (i = 0; i < curOpcode->num_params; ++i) { - DWORD reg = pToken[i] & 0x00001FFF; - DWORD regtype = ((pToken[i] & D3DSP_REGTYPE_MASK) >> D3DSP_REGTYPE_SHIFT); - - switch (regtype << D3DSP_REGTYPE_SHIFT) { - case D3DSPR_TEMP: - /*TRACE("p[%d]=R[%d]\n", i, reg);*/ - p[i] = &R[reg]; - break; - case D3DSPR_INPUT: - /*TRACE("p[%d]=V[%s]\n", i, VertexShaderDeclRegister[reg]);*/ - p[i] = &input->V[reg]; - break; - case D3DSPR_CONST: - if (pToken[i] & D3DVS_ADDRMODE_RELATIVE) { - p[i] = &vshader->data->C[(DWORD) A[0].x + reg]; - } else { - p[i] = &vshader->data->C[reg]; - } - break; - case D3DSPR_ADDR: /*case D3DSPR_TEXTURE:*/ - if (0 != reg) { - ERR("cannot handle address registers != a0, forcing use of a0\n"); - reg = 0; - } - /*TRACE("p[%d]=A[%d]\n", i, reg);*/ - p[i] = &A[reg]; - break; - case D3DSPR_RASTOUT: - switch (reg) { - case D3DSRO_POSITION: - p[i] = &output->oPos; - break; - case D3DSRO_FOG: - p[i] = &output->oFog; - break; - case D3DSRO_POINT_SIZE: - p[i] = &output->oPts; - break; - } - break; - case D3DSPR_ATTROUT: - /*TRACE("p[%d]=oD[%d]\n", i, reg);*/ - p[i] = &output->oD[reg]; - break; - case D3DSPR_TEXCRDOUT: - /*TRACE("p[%d]=oT[%d]\n", i, reg);*/ - p[i] = &output->oT[reg]; - break; - default: - break; - } - - if (i > 0) { /* input reg */ - DWORD swizzle = (pToken[i] & D3DVS_SWIZZLE_MASK) >> D3DVS_SWIZZLE_SHIFT; - UINT isNegative = ((pToken[i] & D3DSP_SRCMOD_MASK) == D3DSPSM_NEG); - - if (!isNegative && (D3DVS_NOSWIZZLE >> D3DVS_SWIZZLE_SHIFT) == swizzle) { - /*TRACE("p[%d] not swizzled\n", i);*/ - p_send[i] = p[i]; - } else { - DWORD swizzle_x = swizzle & 0x03; - DWORD swizzle_y = (swizzle >> 2) & 0x03; - DWORD swizzle_z = (swizzle >> 4) & 0x03; - DWORD swizzle_w = (swizzle >> 6) & 0x03; - /*TRACE("p[%d] swizzled\n", i);*/ - float* tt = (float*) p[i]; - s[i].x = (isNegative) ? -tt[swizzle_x] : tt[swizzle_x]; - s[i].y = (isNegative) ? -tt[swizzle_y] : tt[swizzle_y]; - s[i].z = (isNegative) ? -tt[swizzle_z] : tt[swizzle_z]; - s[i].w = (isNegative) ? -tt[swizzle_w] : tt[swizzle_w]; - p_send[i] = &s[i]; - } - } else { /* output reg */ - if ((pToken[i] & D3DSP_WRITEMASK_ALL) == D3DSP_WRITEMASK_ALL) { - p_send[i] = p[i]; - } else { - p_send[i] = &d; /* to be post-processed for modifiers management */ - } - } - } - } - - switch (curOpcode->num_params) { - case 0: - curOpcode->soft_fct(); - break; - case 1: - curOpcode->soft_fct(p_send[0]); - break; - case 2: - curOpcode->soft_fct(p_send[0], p_send[1]); - break; - case 3: - curOpcode->soft_fct(p_send[0], p_send[1], p_send[2]); - break; - case 4: - curOpcode->soft_fct(p_send[0], p_send[1], p_send[2], p_send[3]); - break; - case 5: - curOpcode->soft_fct(p_send[0], p_send[1], p_send[2], p_send[3], p_send[4]); - break; - default: - ERR("%s too many params: %u\n", curOpcode->name, curOpcode->num_params); - } - - /* check if output reg modifier post-process */ - if (curOpcode->num_params > 0 && (pToken[0] & D3DSP_WRITEMASK_ALL) != D3DSP_WRITEMASK_ALL) { - if (pToken[0] & D3DSP_WRITEMASK_0) p[0]->x = d.x; - if (pToken[0] & D3DSP_WRITEMASK_1) p[0]->y = d.y; - if (pToken[0] & D3DSP_WRITEMASK_2) p[0]->z = d.z; - if (pToken[0] & D3DSP_WRITEMASK_3) p[0]->w = d.w; - } - -#if 0 - TRACE_VSVECTOR(output->oPos); - TRACE_VSVECTOR(output->oD[0]); - TRACE_VSVECTOR(output->oD[1]); - TRACE_VSVECTOR(output->oT[0]); - TRACE_VSVECTOR(output->oT[1]); - TRACE_VSVECTOR(R[0]); - TRACE_VSVECTOR(R[1]); - TRACE_VSVECTOR(R[2]); - TRACE_VSVECTOR(R[3]); - TRACE_VSVECTOR(R[4]); - TRACE_VSVECTOR(R[5]); -#endif - - /* to next opcode token */ - pToken += curOpcode->num_params; - } -#if 0 - TRACE("End of current instruction:\n"); - TRACE_VSVECTOR(output->oPos); - TRACE_VSVECTOR(output->oD[0]); - TRACE_VSVECTOR(output->oD[1]); - TRACE_VSVECTOR(output->oT[0]); - TRACE_VSVECTOR(output->oT[1]); - TRACE_VSVECTOR(R[0]); - TRACE_VSVECTOR(R[1]); - TRACE_VSVECTOR(R[2]); - TRACE_VSVECTOR(R[3]); - TRACE_VSVECTOR(R[4]); - TRACE_VSVECTOR(R[5]); -#endif - } -#if 0 /* Must not be 1 in cvs */ - TRACE("Output:\n"); - TRACE_VSVECTOR(output->oPos); - TRACE_VSVECTOR(output->oD[0]); - TRACE_VSVECTOR(output->oD[1]); - TRACE_VSVECTOR(output->oT[0]); - TRACE_VSVECTOR(output->oT[1]); -#endif - return D3D_OK; -} - -HRESULT WINAPI IDirect3DVertexShaderImpl_GetFunction(IDirect3DVertexShaderImpl* This, VOID* pData, UINT* pSizeOfData) { - if (NULL == pData) { - *pSizeOfData = This->functionLength; - return D3D_OK; - } - if (*pSizeOfData < This->functionLength) { - *pSizeOfData = This->functionLength; - return D3DERR_MOREDATA; - } - if (NULL == This->function) { /* no function defined */ - TRACE("(%p) : GetFunction no User Function defined using NULL to %p\n", This, pData); - (*(DWORD **) pData) = NULL; - } else { - TRACE("(%p) : GetFunction copying to %p\n", This, pData); - memcpy(pData, This->function, This->functionLength); - } - return D3D_OK; -} - -HRESULT WINAPI IDirect3DVertexShaderImpl_SetConstantF(IDirect3DVertexShaderImpl* This, UINT StartRegister, CONST FLOAT* pConstantData, UINT Vector4fCount) { - if (StartRegister + Vector4fCount > D3D8_VSHADER_MAX_CONSTANTS) { - return D3DERR_INVALIDCALL; - } - if (NULL == This->data) { /* temporary while datas not supported */ - FIXME("(%p) : VertexShader_SetConstant not fully supported yet\n", This); - return D3DERR_INVALIDCALL; - } - memcpy(&This->data->C[StartRegister], pConstantData, Vector4fCount * 4 * sizeof(FLOAT)); - return D3D_OK; -} - -HRESULT WINAPI IDirect3DVertexShaderImpl_GetConstantF(IDirect3DVertexShaderImpl* This, UINT StartRegister, FLOAT* pConstantData, UINT Vector4fCount) { - if (StartRegister + Vector4fCount > D3D8_VSHADER_MAX_CONSTANTS) { - return D3DERR_INVALIDCALL; - } - if (NULL == This->data) { /* temporary while datas not supported */ - return D3DERR_INVALIDCALL; - } - memcpy(pConstantData, &This->data->C[StartRegister], Vector4fCount * 4 * sizeof(FLOAT)); - return D3D_OK; -} - - -/********************************************************************************************************************************************** - ********************************************************************************************************************************************** - ********************************************************************************************************************************************** - ********************************************************************************************************************************************** - **********************************************************************************************************************************************/ - -void pshader_texcoord(D3DSHADERVECTOR* d) { -} - -void pshader_texkill(D3DSHADERVECTOR* d) { -} - -void pshader_tex(D3DSHADERVECTOR* d) { -} - -void pshader_texbem(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) { -} - -void pshader_texbeml(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) { -} - -void pshader_texreg2ar(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) { -} - -void pshader_texreg2gb(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) { -} - -void pshader_texm3x2pad(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) { -} - -void pshader_texm3x2tex(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) { -} - -void pshader_texm3x3pad(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) { -} - -void pshader_texm3x3tex(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) { -} - -void pshader_texm3x3diff(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) { -} - -void pshader_texm3x3spec(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1) { -} - -void pshader_texm3x3vspec(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) { -} - -void pshader_cnd(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1, D3DSHADERVECTOR* s2) { -} - -void pshader_def(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1, D3DSHADERVECTOR* s2, D3DSHADERVECTOR* s3) { -} - -void pshader_texreg2rgb(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) { -} - -void pshader_texdp3tex(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) { -} - -void pshader_texm3x2depth(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) { -} - -void pshader_texdp3(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) { -} - -void pshader_texm3x3(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) { -} - -void pshader_texdepth(D3DSHADERVECTOR* d) { -} - -void pshader_cmp(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1, D3DSHADERVECTOR* s2) { -} - -void pshader_bem(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1) { -} - -static CONST SHADER_OPCODE pshader_ins [] = { - {D3DSIO_NOP, "nop", 0, vshader_nop, 0, 0}, - {D3DSIO_MOV, "mov", 2, vshader_mov, 0, 0}, - {D3DSIO_ADD, "add", 3, vshader_add, 0, 0}, - {D3DSIO_SUB, "sub", 3, vshader_sub, 0, 0}, - {D3DSIO_MAD, "mad", 4, vshader_mad, 0, 0}, - {D3DSIO_MUL, "mul", 3, vshader_mul, 0, 0}, - {D3DSIO_RCP, "rcp", 2, vshader_rcp, 0, 0}, - {D3DSIO_RSQ, "rsq", 2, vshader_rsq, 0, 0}, - {D3DSIO_DP3, "dp3", 3, vshader_dp3, 0, 0}, - {D3DSIO_DP4, "dp4", 3, vshader_dp4, 0, 0}, - {D3DSIO_MIN, "min", 3, vshader_min, 0, 0}, - {D3DSIO_MAX, "max", 3, vshader_max, 0, 0}, - {D3DSIO_SLT, "slt", 3, vshader_slt, 0, 0}, - {D3DSIO_SGE, "sge", 3, vshader_sge, 0, 0}, - {D3DSIO_EXP, "exp", 2, vshader_exp, 0, 0}, - {D3DSIO_LOG, "log", 2, vshader_log, 0, 0}, - {D3DSIO_LIT, "lit", 2, vshader_lit, 0, 0}, - {D3DSIO_DST, "dst", 3, vshader_dst, 0, 0}, - {D3DSIO_LRP, "lrp", 4, vshader_lrp, 0, 0}, - {D3DSIO_FRC, "frc", 2, vshader_frc, 0, 0}, - {D3DSIO_M4x4, "m4x4", 3, vshader_m4x4, 0, 0}, - {D3DSIO_M4x3, "m4x3", 3, vshader_m4x3, 0, 0}, - {D3DSIO_M3x4, "m3x4", 3, vshader_m3x4, 0, 0}, - {D3DSIO_M3x3, "m3x3", 3, vshader_m3x3, 0, 0}, - {D3DSIO_M3x2, "m3x2", 3, vshader_m3x2, 0, 0}, - - {D3DSIO_TEXCOORD, "texcoord", 1, pshader_texcoord, D3DPS_VERSION(1,0), D3DPS_VERSION(1,3)}, - {D3DSIO_TEXCOORD, "texcrd", 2, pshader_texcoord, D3DPS_VERSION(1,4), D3DPS_VERSION(1,4)}, - {D3DSIO_TEXKILL, "texkill", 1, pshader_texkill, D3DPS_VERSION(1,0), D3DPS_VERSION(1,4)}, - {D3DSIO_TEX, "tex", 1, pshader_tex, D3DPS_VERSION(1,0), D3DPS_VERSION(1,3)}, - {D3DSIO_TEX, "texld", 2, pshader_tex, D3DPS_VERSION(1,4), D3DPS_VERSION(1,4)}, - {D3DSIO_TEXBEM, "texbem", 2, pshader_texbem, D3DPS_VERSION(1,0), D3DPS_VERSION(1,3)}, - {D3DSIO_TEXBEML, "texbeml", 2, pshader_texbeml, D3DPS_VERSION(1,0), D3DPS_VERSION(1,3)}, - {D3DSIO_TEXREG2AR, "texreg2ar", 2, pshader_texreg2ar, D3DPS_VERSION(1,1), D3DPS_VERSION(1,3)}, - {D3DSIO_TEXREG2GB, "texreg2gb", 2, pshader_texreg2gb, D3DPS_VERSION(1,2), D3DPS_VERSION(1,3)}, - {D3DSIO_TEXM3x2PAD, "texm3x2pad", 2, pshader_texm3x2pad, D3DPS_VERSION(1,0), D3DPS_VERSION(1,3)}, - {D3DSIO_TEXM3x2TEX, "texm3x2tex", 2, pshader_texm3x2tex, D3DPS_VERSION(1,0), D3DPS_VERSION(1,3)}, - {D3DSIO_TEXM3x3PAD, "texm3x3pad", 2, pshader_texm3x3pad, D3DPS_VERSION(1,0), D3DPS_VERSION(1,3)}, - {D3DSIO_TEXM3x3TEX, "texm3x3tex", 2, pshader_texm3x3tex, D3DPS_VERSION(1,0), D3DPS_VERSION(1,3)}, - {D3DSIO_TEXM3x3DIFF, "texm3x3diff", 2, pshader_texm3x3diff, D3DPS_VERSION(0,0), D3DPS_VERSION(0,0)}, - {D3DSIO_TEXM3x3SPEC, "texm3x3spec", 3, pshader_texm3x3spec, D3DPS_VERSION(1,0), D3DPS_VERSION(1,3)}, - {D3DSIO_TEXM3x3VSPEC, "texm3x3vspec", 2, pshader_texm3x3vspec, D3DPS_VERSION(1,0), D3DPS_VERSION(1,3)}, - - {D3DSIO_EXPP, "expp", 2, vshader_expp, 0, 0}, - {D3DSIO_LOGP, "logp", 2, vshader_logp, 0, 0}, - - {D3DSIO_CND, "cnd", 4, pshader_cnd, D3DPS_VERSION(1,1), D3DPS_VERSION(1,4)}, - {D3DSIO_DEF, "def", 5, pshader_def, D3DPS_VERSION(1,0), D3DPS_VERSION(3,0)}, - {D3DSIO_TEXREG2RGB, "texbreg2rgb", 2, pshader_texreg2rgb, D3DPS_VERSION(1,2), D3DPS_VERSION(1,3)}, - - {D3DSIO_TEXDP3TEX, "texdp3tex", 2, pshader_texdp3tex, D3DPS_VERSION(1,2), D3DPS_VERSION(1,3)}, - {D3DSIO_TEXM3x2DEPTH, "texm3x2depth", 2, pshader_texm3x2depth, D3DPS_VERSION(1,3), D3DPS_VERSION(1,3)}, - {D3DSIO_TEXDP3, "texdp3", 2, pshader_texdp3, D3DPS_VERSION(1,2), D3DPS_VERSION(1,3)}, - {D3DSIO_TEXM3x3, "texm3x3", 2, pshader_texm3x3, D3DPS_VERSION(1,2), D3DPS_VERSION(1,3)}, - {D3DSIO_TEXDEPTH, "texdepth", 1, pshader_texdepth, D3DPS_VERSION(1,4), D3DPS_VERSION(1,4)}, - {D3DSIO_CMP, "cmp", 4, pshader_cmp, D3DPS_VERSION(1,1), D3DPS_VERSION(3,0)}, - {D3DSIO_BEM, "bem", 3, pshader_bem, D3DPS_VERSION(1,4), D3DPS_VERSION(1,4)}, - - {D3DSIO_PHASE, "phase", 0, vshader_nop, 0, 0}, - - {0, NULL, 0, NULL} -}; - -inline static const SHADER_OPCODE* pshader_program_get_opcode(const DWORD code, const int version) { - DWORD i = 0; - DWORD hex_version = D3DPS_VERSION(version/10, version%10); - /** TODO: use dichotomic search */ - while (NULL != pshader_ins[i].name) { - if ( ( (code & D3DSI_OPCODE_MASK) == pshader_ins[i].opcode) && - ( ( (hex_version >= pshader_ins[i].min_version) && (hex_version <= pshader_ins[i].max_version)) || - ( (pshader_ins[i].min_version == 0) && (pshader_ins[i].max_version == 0) ) ) ) { - return &pshader_ins[i]; - } - ++i; - } - return NULL; -} - -inline static BOOL pshader_is_version_token(DWORD token) { - return 0xFFFF0000 == (token & 0xFFFF0000); -} - -inline static BOOL pshader_is_comment_token(DWORD token) { - return D3DSIO_COMMENT == (token & D3DSI_OPCODE_MASK); -} - -inline static void pshader_program_dump_opcode(const SHADER_OPCODE* curOpcode, const DWORD code, const DWORD output) { - if (0 != (code & ~D3DSI_OPCODE_MASK)) { - DWORD mask = (code & ~D3DSI_OPCODE_MASK); - switch (mask) { - case 0x40000000: TRACE("+"); break; - default: - TRACE(" unhandled modifier(0x%08lx) ", mask); - } - } - TRACE("%s", curOpcode->name); - /** - * normally this is a destination reg modifier - * but in pixel shaders asm code its specified as: - * dp3_x4 t1.rgba, r1, c1 - * or - * dp3_x2_sat r0, t0_bx2, v0_bx2 - * so for better debbuging i use the same norm - */ - if (0 != (output & D3DSP_DSTSHIFT_MASK)) { - DWORD shift = (output & D3DSP_DSTSHIFT_MASK) >> D3DSP_DSTSHIFT_SHIFT; - if (shift < 8) { - TRACE("_x%u", 1 << shift); - } else { - TRACE("_d%u", 1 << (16-shift)); - } - } - if (0 != (output & D3DSP_DSTMOD_MASK)) { - DWORD mask = output & D3DSP_DSTMOD_MASK; - switch (mask) { - case D3DSPDM_SATURATE: TRACE("_sat"); break; - default: - TRACE("_unhandled_modifier(0x%08lx)", mask); - } - } - TRACE(" "); -} - -inline static void pshader_program_dump_param(const DWORD param, int input) { - static const char* rastout_reg_names[] = { "oC0", "oC1", "oC2", "oC3", "oDepth" }; - static const char swizzle_reg_chars[] = "rgba"; - - DWORD reg = param & 0x00001FFF; - DWORD regtype = ((param & D3DSP_REGTYPE_MASK) >> D3DSP_REGTYPE_SHIFT); - - if (input) { - if ( ((param & D3DSP_SRCMOD_MASK) == D3DSPSM_NEG) || - ((param & D3DSP_SRCMOD_MASK) == D3DSPSM_BIASNEG) || - ((param & D3DSP_SRCMOD_MASK) == D3DSPSM_SIGNNEG) || - ((param & D3DSP_SRCMOD_MASK) == D3DSPSM_X2NEG) ) - TRACE("-"); - else if ((param & D3DSP_SRCMOD_MASK) == D3DSPSM_COMP) - TRACE("1-"); - } - - switch (regtype << D3DSP_REGTYPE_SHIFT) { - case D3DSPR_TEMP: - TRACE("R[%lu]", reg); - break; - case D3DSPR_INPUT: - TRACE("V[%lu]", reg); - break; - case D3DSPR_CONST: - TRACE("C[%s%lu]", (param & D3DVS_ADDRMODE_RELATIVE) ? "a0.x + " : "", reg); - break; - case D3DSPR_TEXTURE: /* case D3DSPR_ADDR: */ - TRACE("t[%lu]", reg); - break; - case D3DSPR_RASTOUT: - TRACE("%s", rastout_reg_names[reg]); - break; - case D3DSPR_ATTROUT: - TRACE("oD[%lu]", reg); - break; - case D3DSPR_TEXCRDOUT: - TRACE("oT[%lu]", reg); - break; - default: - break; - } - - if (!input) { - /** operand output */ - /** - * for better debugging traces it's done into opcode dump code - * @see pshader_program_dump_opcode - if (0 != (param & D3DSP_DSTMOD_MASK)) { - DWORD mask = param & D3DSP_DSTMOD_MASK; - switch (mask) { - case D3DSPDM_SATURATE: TRACE("_sat"); break; - default: - TRACE("_unhandled_modifier(0x%08lx)", mask); - } - } - if (0 != (param & D3DSP_DSTSHIFT_MASK)) { - DWORD shift = (param & D3DSP_DSTSHIFT_MASK) >> D3DSP_DSTSHIFT_SHIFT; - if (shift > 0) { - TRACE("_x%u", 1 << shift); - } - } - */ - if ((param & D3DSP_WRITEMASK_ALL) != D3DSP_WRITEMASK_ALL) { - TRACE("."); - if (param & D3DSP_WRITEMASK_0) TRACE("r"); - if (param & D3DSP_WRITEMASK_1) TRACE("g"); - if (param & D3DSP_WRITEMASK_2) TRACE("b"); - if (param & D3DSP_WRITEMASK_3) TRACE("a"); - } - } else { - /** operand input */ - DWORD swizzle = (param & D3DSP_SWIZZLE_MASK) >> D3DSP_SWIZZLE_SHIFT; - DWORD swizzle_x = swizzle & 0x03; - DWORD swizzle_y = (swizzle >> 2) & 0x03; - DWORD swizzle_z = (swizzle >> 4) & 0x03; - DWORD swizzle_w = (swizzle >> 6) & 0x03; - - if (0 != (param & D3DSP_SRCMOD_MASK)) { - DWORD mask = param & D3DSP_SRCMOD_MASK; - /*TRACE("_modifier(0x%08lx) ", mask);*/ - switch (mask) { - case D3DSPSM_NONE: break; - case D3DSPSM_NEG: break; - case D3DSPSM_BIAS: TRACE("_bias"); break; - case D3DSPSM_BIASNEG: TRACE("_bias"); break; - case D3DSPSM_SIGN: TRACE("_bx2"); break; - case D3DSPSM_SIGNNEG: TRACE("_bx2"); break; - case D3DSPSM_COMP: break; - case D3DSPSM_X2: TRACE("_x2"); break; - case D3DSPSM_X2NEG: TRACE("_x2"); break; - case D3DSPSM_DZ: TRACE("_dz"); break; - case D3DSPSM_DW: TRACE("_dw"); break; - default: - TRACE("_unknown(0x%08lx)", mask); - } - } - - /** - * swizzle bits fields: - * WWZZYYXX - */ - if ((D3DSP_NOSWIZZLE >> D3DSP_SWIZZLE_SHIFT) != swizzle) { /* ! D3DVS_NOSWIZZLE == 0xE4 << D3DVS_SWIZZLE_SHIFT */ - if (swizzle_x == swizzle_y && - swizzle_x == swizzle_z && - swizzle_x == swizzle_w) { - TRACE(".%c", swizzle_reg_chars[swizzle_x]); - } else { - TRACE(".%c%c%c%c", - swizzle_reg_chars[swizzle_x], - swizzle_reg_chars[swizzle_y], - swizzle_reg_chars[swizzle_z], - swizzle_reg_chars[swizzle_w]); - } - } - } -} - -static int constants[D3D8_PSHADER_MAX_CONSTANTS]; - -inline static void get_register_name(const DWORD param, char* regstr) -{ - static const char* rastout_reg_names[] = { "oC0", "oC1", "oC2", "oC3", "oDepth" }; - - DWORD reg = param & 0x00001FFF; - DWORD regtype = ((param & D3DSP_REGTYPE_MASK) >> D3DSP_REGTYPE_SHIFT); - - switch (regtype << D3DSP_REGTYPE_SHIFT) { - case D3DSPR_TEMP: - sprintf(regstr, "R%lu", reg); - break; - case D3DSPR_INPUT: - if (reg==0) { - strcpy(regstr, "fragment.color.primary"); - } else { - strcpy(regstr, "fragment.color.secondary"); - } - break; - case D3DSPR_CONST: - if (constants[reg]) - sprintf(regstr, "C%lu", reg); - else - sprintf(regstr, "program.env[%lu]", reg); - break; - case D3DSPR_TEXTURE: /* case D3DSPR_ADDR: */ - sprintf(regstr,"T%lu", reg); - break; - case D3DSPR_RASTOUT: - sprintf(regstr, "%s", rastout_reg_names[reg]); - break; - case D3DSPR_ATTROUT: - sprintf(regstr, "oD[%lu]", reg); - break; - case D3DSPR_TEXCRDOUT: - sprintf(regstr, "oT[%lu]", reg); - break; - default: - break; - } -} - -inline static void addline(unsigned int* lineNum, char* pgm, char* line) -{ - ++(*lineNum); - TRACE_(d3d_hw_shader)("GL HW (%u, %u) : %s\n", *lineNum, strlen(pgm), line); - strcat(pgm, line); - strcat(pgm, "\n"); -} - -static const char* shift_tab[] = { - "dummy", /* 0 (none) */ - "coefmul.x", /* 1 (x2) */ - "coefmul.y", /* 2 (x4) */ - "coefmul.z", /* 3 (x8) */ - "coefmul.w", /* 4 (x16) */ - "dummy", /* 5 (x32) */ - "dummy", /* 6 (x64) */ - "dummy", /* 7 (x128) */ - "dummy", /* 8 (d256) */ - "dummy", /* 9 (d128) */ - "dummy", /* 10 (d64) */ - "dummy", /* 11 (d32) */ - "coefdiv.w", /* 12 (d16) */ - "coefdiv.z", /* 13 (d8) */ - "coefdiv.y", /* 14 (d4) */ - "coefdiv.x" /* 15 (d2) */ -}; - -inline static void get_write_mask(const DWORD output_reg, char* write_mask) -{ - *write_mask = 0; - if ((output_reg & D3DSP_WRITEMASK_ALL) != D3DSP_WRITEMASK_ALL) { - strcat(write_mask, "."); - if (output_reg & D3DSP_WRITEMASK_0) strcat(write_mask, "r"); - if (output_reg & D3DSP_WRITEMASK_1) strcat(write_mask, "g"); - if (output_reg & D3DSP_WRITEMASK_2) strcat(write_mask, "b"); - if (output_reg & D3DSP_WRITEMASK_3) strcat(write_mask, "a"); - } -} - -inline static void get_input_register_swizzle(const DWORD instr, char* swzstring) -{ - static const char swizzle_reg_chars[] = "rgba"; - DWORD swizzle = (instr & D3DSP_SWIZZLE_MASK) >> D3DSP_SWIZZLE_SHIFT; - DWORD swizzle_x = swizzle & 0x03; - DWORD swizzle_y = (swizzle >> 2) & 0x03; - DWORD swizzle_z = (swizzle >> 4) & 0x03; - DWORD swizzle_w = (swizzle >> 6) & 0x03; - /** - * swizzle bits fields: - * WWZZYYXX - */ - *swzstring = 0; - if ((D3DSP_NOSWIZZLE >> D3DSP_SWIZZLE_SHIFT) != swizzle) { /* ! D3DVS_NOSWIZZLE == 0xE4 << D3DVS_SWIZZLE_SHIFT */ - if (swizzle_x == swizzle_y && - swizzle_x == swizzle_z && - swizzle_x == swizzle_w) { - sprintf(swzstring, ".%c", swizzle_reg_chars[swizzle_x]); - } else { - sprintf(swzstring, ".%c%c%c%c", - swizzle_reg_chars[swizzle_x], - swizzle_reg_chars[swizzle_y], - swizzle_reg_chars[swizzle_z], - swizzle_reg_chars[swizzle_w]); - } - } -} - -inline static void gen_output_modifier_line(int saturate, char* write_mask, int shift, char *regstr, char* line) -{ - /* Generate a line that does the output modifier computation */ - sprintf(line, "MUL%s %s%s, %s, %s;", saturate ? "_SAT" : "", regstr, write_mask, regstr, shift_tab[shift]); -} - -inline static int gen_input_modifier_line(const DWORD instr, int tmpreg, char* outregstr, char* line) -{ - /* Generate a line that does the input modifier computation and return the input register to use */ - static char regstr[256]; - static char tmpline[256]; - int insert_line; - - /* Assume a new line will be added */ - insert_line = 1; - - /* Get register name */ - get_register_name(instr, regstr); - - switch (instr & D3DSP_SRCMOD_MASK) { - case D3DSPSM_NONE: - strcpy(outregstr, regstr); - insert_line = 0; - break; - case D3DSPSM_NEG: - sprintf(outregstr, "-%s", regstr); - insert_line = 0; - break; - case D3DSPSM_BIAS: - sprintf(line, "ADD T%c, %s, -coefdiv.x;", 'A' + tmpreg, regstr); - break; - case D3DSPSM_BIASNEG: - sprintf(line, "ADD T%c, -%s, coefdiv.x;", 'A' + tmpreg, regstr); - break; - case D3DSPSM_SIGN: - sprintf(line, "MAD T%c, %s, coefmul.x, -one.x;", 'A' + tmpreg, regstr); - break; - case D3DSPSM_SIGNNEG: - sprintf(line, "MAD T%c, %s, -coefmul.x, one.x;", 'A' + tmpreg, regstr); - break; - case D3DSPSM_COMP: - sprintf(line, "SUB T%c, one.x, %s;", 'A' + tmpreg, regstr); - break; - case D3DSPSM_X2: - sprintf(line, "ADD T%c, %s, %s;", 'A' + tmpreg, regstr, regstr); - break; - case D3DSPSM_X2NEG: - sprintf(line, "ADD T%c, -%s, -%s;", 'A' + tmpreg, regstr, regstr); - break; - case D3DSPSM_DZ: - sprintf(line, "RCP T%c, %s.z;", 'A' + tmpreg, regstr); - sprintf(tmpline, "MUL T%c, %s, T%c;", 'A' + tmpreg, regstr, 'A' + tmpreg); - strcat(line, "\n"); /* Hack */ - strcat(line, tmpline); - break; - case D3DSPSM_DW: - sprintf(line, "RCP T%c, %s;", 'A' + tmpreg, regstr); - sprintf(tmpline, "MUL T%c, %s, T%c;", 'A' + tmpreg, regstr, 'A' + tmpreg); - strcat(line, "\n"); /* Hack */ - strcat(line, tmpline); - break; - default: - strcpy(outregstr, regstr); - insert_line = 0; - } - - if (insert_line) { - /* Substitute the register name */ - sprintf(outregstr, "T%c", 'A' + tmpreg); - } - - return insert_line; -} - -/** - * Pixel Shaders - * - * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/Shaders/PixelShader1_X/modifiers/sourceregistermodifiers.asp - * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/Shaders/PixelShader2_0/Registers/Registers.asp - * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/d3d/interfaces/IDirect3DPixelShader9/_IDirect3DPixelShader9.asp - * - */ -inline static VOID IDirect3DPixelShaderImpl_GenerateProgramArbHW(IDirect3DPixelShaderImpl* pshader, CONST DWORD* pFunction) { - const DWORD* pToken = pFunction; - const SHADER_OPCODE* curOpcode = NULL; - const DWORD* pInstr; - DWORD code; - DWORD i; - int autoparam; - unsigned lineNum = 0; - char *pgmStr = NULL; - char tmpLine[255]; - BOOL saturate; - int row = 0; - DWORD tcw[2]; - IDirect3DDevice8Impl* This = pshader->device; - int version = 0; - - for(i = 0; i < D3D8_PSHADER_MAX_CONSTANTS; i++) - constants[i] = 0; - - pgmStr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 65535); /* 64kb should be enough */ - - if (NULL != pToken) { - while (D3DPS_END() != *pToken) { - if (pshader_is_version_token(*pToken)) { /** version */ - int numTemps; - int numConstants; - - /* Extract version *10 into integer value (ie. 1.0 == 10, 1.1==11 etc */ - version = (((*pToken >> 8) & 0x0F) * 10) + (*pToken & 0x0F); - - TRACE_(d3d_hw_shader)("ps.%lu.%lu;\n", (*pToken >> 8) & 0x0F, (*pToken & 0x0F)); - - /* Each release of pixel shaders has had different numbers of temp registers */ - switch (version) { - case 10: - case 11: - case 12: - case 13: - case 14: numTemps=12; - numConstants=8; - strcpy(tmpLine, "!!ARBfp1.0"); - break; - case 20: numTemps=12; - numConstants=8; - strcpy(tmpLine, "!!ARBfp2.0"); - FIXME_(d3d_hw_shader)("No work done yet to support ps2.0 in hw\n"); - break; - case 30: numTemps=32; - numConstants=8; - strcpy(tmpLine, "!!ARBfp3.0"); - FIXME_(d3d_hw_shader)("No work done yet to support ps3.0 in hw\n"); - break; - default: - numTemps=12; - numConstants=8; - strcpy(tmpLine, "!!ARBfp1.0"); - FIXME_(d3d_hw_shader)("Unrecognized pixel shader version!\n"); - } - addline(&lineNum, pgmStr, tmpLine); - - for(i = 0; i < 6; i++) { - sprintf(tmpLine, "TEMP T%lu;", i); - addline(&lineNum, pgmStr, tmpLine); - } - for(i = 0; i < 6; i++) { - sprintf(tmpLine, "TEMP R%lu;", i); - addline(&lineNum, pgmStr, tmpLine); - } - - sprintf(tmpLine, "TEMP TMP;"); - addline(&lineNum, pgmStr, tmpLine); - sprintf(tmpLine, "TEMP TMP2;"); - addline(&lineNum, pgmStr, tmpLine); - sprintf(tmpLine, "TEMP TA;"); - addline(&lineNum, pgmStr, tmpLine); - sprintf(tmpLine, "TEMP TB;"); - addline(&lineNum, pgmStr, tmpLine); - sprintf(tmpLine, "TEMP TC;"); - addline(&lineNum, pgmStr, tmpLine); - - strcpy(tmpLine, "PARAM coefdiv = { 0.5, 0.25, 0.125, 0.0625 };"); - addline(&lineNum, pgmStr, tmpLine); - strcpy(tmpLine, "PARAM coefmul = { 2, 4, 8, 16 };"); - addline(&lineNum, pgmStr, tmpLine); - strcpy(tmpLine, "PARAM one = { 1.0, 1.0, 1.0, 1.0 };"); - addline(&lineNum, pgmStr, tmpLine); - - for(i = 0; i < 4; i++) { - sprintf(tmpLine, "MOV T%lu, fragment.texcoord[%lu];", i, i); - addline(&lineNum, pgmStr, tmpLine); - } - - ++pToken; - continue; - } - if (pshader_is_comment_token(*pToken)) { /** comment */ - DWORD comment_len = (*pToken & D3DSI_COMMENTSIZE_MASK) >> D3DSI_COMMENTSIZE_SHIFT; - ++pToken; - /*TRACE("comment[%ld] ;%s\n", comment_len, (char*)pToken);*/ - pToken += comment_len; - continue; - } - code = *pToken; - pInstr = pToken; - curOpcode = pshader_program_get_opcode(code, version); - ++pToken; - if (NULL == curOpcode) { - /* unknown current opcode ... */ - while (*pToken & 0x80000000) { - TRACE("unrecognized opcode: %08lx\n", *pToken); - ++pToken; - } - } else { - autoparam = 1; - saturate = FALSE; - /* Build opcode for GL vertex_program */ - switch (curOpcode->opcode) { - case D3DSIO_NOP: - case D3DSIO_PHASE: - continue; - case D3DSIO_DEF: - { - DWORD reg = *pToken & 0x00001FFF; - sprintf(tmpLine, "PARAM C%lu = { %f, %f, %f, %f };", reg, - *((const float*)(pToken+1)), - *((const float*)(pToken+2)), - *((const float*)(pToken+3)), - *((const float*)(pToken+4)) ); - addline(&lineNum, pgmStr, tmpLine); - constants[reg] = 1; - autoparam = 0; - pToken+=5; - } - break; - case D3DSIO_TEXKILL: - strcpy(tmpLine, "KIL"); - break; - case D3DSIO_TEX: - { - char tmp[20]; - get_write_mask(*pToken, tmp); - if (version != 14) { - DWORD reg = *pToken & 0x00001FFF; - sprintf(tmpLine,"TEX T%lu%s, T%lu, texture[%lu], 2D;", reg, tmp, reg, reg); - addline(&lineNum, pgmStr, tmpLine); - autoparam = 0; - pToken++; - } else { - char line[256]; - char reg[20]; - DWORD reg1 = *pToken & 0x00001FFF; - DWORD reg2 = *(pToken+1) & 0x00001FFF; - if (gen_input_modifier_line(*(pToken+1), 0, reg, line)) - addline(&lineNum, pgmStr, line); - sprintf(tmpLine,"TEX R%lu%s, %s, texture[%lu], 2D;", reg1, tmp, reg, reg2); - addline(&lineNum, pgmStr, tmpLine); - autoparam = 0; - pToken += 2; - } - } - break; - case D3DSIO_TEXCOORD: - { - char tmp[20]; - get_write_mask(*pToken, tmp); - if (version != 14) { - DWORD reg = *pToken & 0x00001FFF; - sprintf(tmpLine, "MOV T%lu%s, fragment.texcoord[%lu];", reg, tmp, reg); - addline(&lineNum, pgmStr, tmpLine); - autoparam = 0; - pToken++; - } else { - DWORD reg1 = *pToken & 0x00001FFF; - DWORD reg2 = *(pToken+1) & 0x00001FFF; - sprintf(tmpLine, "MOV R%lu%s, fragment.texcoord[%lu];", reg1, tmp, reg2); - addline(&lineNum, pgmStr, tmpLine); - autoparam = 0; - pToken += 2; - } - } - break; - case D3DSIO_TEXM3x2PAD: - { - DWORD reg = *pToken & 0x00001FFF; - char buf[50]; - if (gen_input_modifier_line(*(pToken+1), 0, buf, tmpLine)) - addline(&lineNum, pgmStr, tmpLine); - sprintf(tmpLine, "DP3 TMP.x, T%lu, %s;", reg, buf); - addline(&lineNum, pgmStr, tmpLine); - autoparam = 0; - pToken += 2; - } - break; - case D3DSIO_TEXM3x2TEX: - { - DWORD reg = *pToken & 0x00001FFF; - char buf[50]; - if (gen_input_modifier_line(*(pToken+1), 0, buf, tmpLine)) - addline(&lineNum, pgmStr, tmpLine); - sprintf(tmpLine, "DP3 TMP.y, T%lu, %s;", reg, buf); - addline(&lineNum, pgmStr, tmpLine); - sprintf(tmpLine, "TEX T%lu, TMP, texture[%lu], 2D;", reg, reg); - addline(&lineNum, pgmStr, tmpLine); - autoparam = 0; - pToken += 2; - } - break; - case D3DSIO_TEXREG2AR: - { - DWORD reg1 = *pToken & 0x00001FFF; - DWORD reg2 = *(pToken+1) & 0x00001FFF; - sprintf(tmpLine, "MOV TMP.r, T%lu.a;", reg2); - addline(&lineNum, pgmStr, tmpLine); - sprintf(tmpLine, "MOV TMP.g, T%lu.r;", reg2); - addline(&lineNum, pgmStr, tmpLine); - sprintf(tmpLine, "TEX T%lu, TMP, texture[%lu], 2D;", reg1, reg1); - addline(&lineNum, pgmStr, tmpLine); - autoparam = 0; - pToken+=2; - } - break; - case D3DSIO_TEXREG2GB: - { - DWORD reg1 = *pToken & 0x00001FFF; - DWORD reg2 = *(pToken+1) & 0x00001FFF; - sprintf(tmpLine, "MOV TMP.r, T%lu.g;", reg2); - addline(&lineNum, pgmStr, tmpLine); - sprintf(tmpLine, "MOV TMP.g, T%lu.b;", reg2); - addline(&lineNum, pgmStr, tmpLine); - sprintf(tmpLine, "TEX T%lu, TMP, texture[%lu], 2D;", reg1, reg1); - addline(&lineNum, pgmStr, tmpLine); - autoparam = 0; - pToken+=2; - } - break; - case D3DSIO_TEXBEM: - { - DWORD reg1 = *pToken & 0x00001FFF; - DWORD reg2 = *(pToken+1) & 0x00001FFF; - /* FIXME: Should apply the BUMPMAPENV matrix */ - sprintf(tmpLine, "ADD TMP.rg, fragment.texcoord[%lu], T%lu;", reg1, reg2); - addline(&lineNum, pgmStr, tmpLine); - sprintf(tmpLine, "TEX T%lu, TMP, texture[%lu], 2D;", reg1, reg1); - addline(&lineNum, pgmStr, tmpLine); - autoparam = 0; - pToken+=2; - } - break; - case D3DSIO_TEXM3x3PAD: - { - DWORD reg = *pToken & 0x00001FFF; - char buf[50]; - if (gen_input_modifier_line(*(pToken+1), 0, buf, tmpLine)) - addline(&lineNum, pgmStr, tmpLine); - sprintf(tmpLine, "DP3 TMP.%c, T%lu, %s;", 'x'+row, reg, buf); - addline(&lineNum, pgmStr, tmpLine); - tcw[row++] = reg; - autoparam = 0; - pToken += 2; - } - break; - case D3DSIO_TEXM3x3TEX: - { - DWORD reg = *pToken & 0x00001FFF; - char buf[50]; - if (gen_input_modifier_line(*(pToken+1), 0, buf, tmpLine)) - addline(&lineNum, pgmStr, tmpLine); - sprintf(tmpLine, "DP3 TMP.z, T%lu, %s;", reg, buf); - addline(&lineNum, pgmStr, tmpLine); - /* Cubemap textures will be more used than 3D ones. */ - sprintf(tmpLine, "TEX T%lu, TMP, texture[%lu], CUBE;", reg, reg); - addline(&lineNum, pgmStr, tmpLine); - row = 0; - autoparam = 0; - pToken += 2; - } - case D3DSIO_TEXM3x3VSPEC: - { - DWORD reg = *pToken & 0x00001FFF; - char buf[50]; - if (gen_input_modifier_line(*(pToken+1), 0, buf, tmpLine)) - addline(&lineNum, pgmStr, tmpLine); - sprintf(tmpLine, "DP3 TMP.z, T%lu, %s;", reg, buf); - addline(&lineNum, pgmStr, tmpLine); - /* Construct the eye-ray vector from w coordinates */ - sprintf(tmpLine, "MOV TMP2.x, fragment.texcoord[%lu].w;", tcw[0]); - addline(&lineNum, pgmStr, tmpLine); - sprintf(tmpLine, "MOV TMP2.y, fragment.texcoord[%lu].w;", tcw[1]); - addline(&lineNum, pgmStr, tmpLine); - sprintf(tmpLine, "MOV TMP2.z, fragment.texcoord[%lu].w;", reg); - addline(&lineNum, pgmStr, tmpLine); - /* Calculate reflection vector (Assume normal is normalized): RF = 2*(N.E)*N -E */ - sprintf(tmpLine, "DP3 TMP.w, TMP, TMP2;"); - addline(&lineNum, pgmStr, tmpLine); - sprintf(tmpLine, "MUL TMP, TMP.w, TMP;"); - addline(&lineNum, pgmStr, tmpLine); - sprintf(tmpLine, "MAD TMP, coefmul.x, TMP, -TMP2;"); - addline(&lineNum, pgmStr, tmpLine); - /* Cubemap textures will be more used than 3D ones. */ - sprintf(tmpLine, "TEX T%lu, TMP, texture[%lu], CUBE;", reg, reg); - addline(&lineNum, pgmStr, tmpLine); - row = 0; - autoparam = 0; - pToken += 2; - } - break; - case D3DSIO_TEXM3x3SPEC: - { - DWORD reg = *pToken & 0x00001FFF; - DWORD reg3 = *(pToken+2) & 0x00001FFF; - char buf[50]; - if (gen_input_modifier_line(*(pToken+1), 0, buf, tmpLine)) - addline(&lineNum, pgmStr, tmpLine); - sprintf(tmpLine, "DP3 TMP.z, T%lu, %s;", reg, buf); - addline(&lineNum, pgmStr, tmpLine); - /* Calculate reflection vector (Assume normal is normalized): RF = 2*(N.E)*N -E */ - sprintf(tmpLine, "DP3 TMP.w, TMP, C[%lu];", reg3); - addline(&lineNum, pgmStr, tmpLine); - sprintf(tmpLine, "MUL TMP, TMP.w, TMP;"); - addline(&lineNum, pgmStr, tmpLine); - sprintf(tmpLine, "MAD TMP, coefmul.x, TMP, -C[%lu];", reg3); - addline(&lineNum, pgmStr, tmpLine); - /* Cubemap textures will be more used than 3D ones. */ - sprintf(tmpLine, "TEX T%lu, TMP, texture[%lu], CUBE;", reg, reg); - addline(&lineNum, pgmStr, tmpLine); - row = 0; - autoparam = 0; - pToken += 3; - } - break; - case D3DSIO_CND: - break; - case D3DSIO_CMP: - break; - case D3DSIO_MOV: - strcpy(tmpLine, "MOV"); - break; - case D3DSIO_MUL: - strcpy(tmpLine, "MUL"); - break; - case D3DSIO_DP3: - strcpy(tmpLine, "DP3"); - break; - case D3DSIO_MAD: - strcpy(tmpLine, "MAD"); - break; - case D3DSIO_ADD: - strcpy(tmpLine, "ADD"); - break; - case D3DSIO_SUB: - strcpy(tmpLine, "SUB"); - break; - case D3DSIO_LRP: - strcpy(tmpLine, "LRP"); - break; - default: - FIXME_(d3d_hw_shader)("Can't handle opcode %s in hwShader\n", curOpcode->name); - } - if (0 != (*pToken & D3DSP_DSTMOD_MASK)) { - DWORD mask = *pToken & D3DSP_DSTMOD_MASK; - switch (mask) { - case D3DSPDM_SATURATE: saturate = TRUE; break; - default: - TRACE("_unhandled_modifier(0x%08lx)", mask); - } - } - if (autoparam && (curOpcode->num_params > 0)) { - char regs[3][50]; - char operands[4][100]; - char tmp[256]; - char swzstring[20]; - int saturate = 0; - /* Generate lines that handle input modifier computation */ - for (i = 1; i < curOpcode->num_params; i++) { - if (gen_input_modifier_line(*(pToken+i), i-1, regs[i-1], tmp)) - addline(&lineNum, pgmStr, tmp); - } - /* Handle saturation only when no shift is present in the output modifier */ - if ((*pToken & D3DSPDM_SATURATE) && (0 == (*pToken & D3DSP_DSTSHIFT_MASK))) - saturate = 1; - /* Handle output register */ - get_register_name(*pToken, tmp); - strcpy(operands[0], tmp); - get_write_mask(*pToken, tmp); - strcat(operands[0], tmp); - /* Handle input registers */ - for (i = 1; i < curOpcode->num_params; i++) { - strcpy(operands[i], regs[i-1]); - get_input_register_swizzle(*(pToken+i), swzstring); - strcat(operands[i], swzstring); - } - if (curOpcode->opcode == D3DSIO_CMP) { - sprintf(tmpLine, "CMP%s %s, %s, %s, %s;", (saturate ? "_SAT" : ""), operands[0], operands[1], operands[3], operands[2]); - } else if (curOpcode->opcode == D3DSIO_CND) { - sprintf(tmpLine, "ADD TMP, -%s, coefdiv.x;", operands[1]); - addline(&lineNum, pgmStr, tmpLine); - sprintf(tmpLine, "CMP%s %s, TMP, %s, %s;", (saturate ? "_SAT" : ""), operands[0], operands[2], operands[3]); - } else { - if (saturate) - strcat(tmpLine, "_SAT"); - strcat(tmpLine, " "); - strcat(tmpLine, operands[0]); - for (i = 1; i < curOpcode->num_params; i++) { - strcat(tmpLine, ", "); - strcat(tmpLine, operands[i]); - } - strcat(tmpLine,";"); - } - addline(&lineNum, pgmStr, tmpLine); - pToken += curOpcode->num_params; - } - if (curOpcode->num_params > 0) { - DWORD param = *(pInstr+1); - if (0 != (param & D3DSP_DSTSHIFT_MASK)) { - /* Generate a line that handle the output modifier computation */ - char regstr[100]; - char write_mask[20]; - DWORD shift = (param & D3DSP_DSTSHIFT_MASK) >> D3DSP_DSTSHIFT_SHIFT; - get_register_name(param, regstr); - get_write_mask(param, write_mask); - gen_output_modifier_line(saturate, write_mask, shift, regstr, tmpLine); - addline(&lineNum, pgmStr, tmpLine); - } - } - } - } - strcpy(tmpLine, "MOV result.color, R0;"); - addline(&lineNum, pgmStr, tmpLine); - - strcpy(tmpLine, "END"); - addline(&lineNum, pgmStr, tmpLine); - } - - /* Create the hw shader */ - GL_EXTCALL(glGenProgramsARB(1, &pshader->prgId)); - TRACE_(d3d_hw_shader)("Creating a hw pixel shader, prg=%d\n", pshader->prgId); - - GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, pshader->prgId)); - - /* Create the program and check for errors */ - GL_EXTCALL(glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, strlen(pgmStr), pgmStr)); - if (glGetError() == GL_INVALID_OPERATION) { - GLint errPos; - glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errPos); - FIXME_(d3d_hw_shader)("HW PixelShader Error at position: %d\n%s\n", errPos, glGetString(GL_PROGRAM_ERROR_STRING_ARB)); - pshader->prgId = -1; - } - - HeapFree(GetProcessHeap(), 0, pgmStr); -} - -inline static VOID IDirect3DPixelShaderImpl_ParseProgram(IDirect3DPixelShaderImpl* pshader, CONST DWORD* pFunction) { - const DWORD* pToken = pFunction; - const SHADER_OPCODE* curOpcode = NULL; - DWORD code; - DWORD len = 0; - DWORD i; - int version = 0; - - if (NULL != pToken) { - while (D3DPS_END() != *pToken) { - if (pshader_is_version_token(*pToken)) { /** version */ - TRACE("ps.%lu.%lu\n", (*pToken >> 8) & 0x0F, (*pToken & 0x0F)); - version = (((*pToken >> 8) & 0x0F) * 10) + (*pToken & 0x0F); - ++pToken; - ++len; - continue; - } - if (pshader_is_comment_token(*pToken)) { /** comment */ - DWORD comment_len = (*pToken & D3DSI_COMMENTSIZE_MASK) >> D3DSI_COMMENTSIZE_SHIFT; - ++pToken; - /*TRACE("comment[%ld] ;%s\n", comment_len, (char*)pToken);*/ - pToken += comment_len; - len += comment_len + 1; - continue; - } - code = *pToken; - curOpcode = pshader_program_get_opcode(code, version); - ++pToken; - ++len; - if (NULL == curOpcode) { - /* unknown current opcode ... */ - while (*pToken & 0x80000000) { - TRACE("unrecognized opcode: %08lx\n", *pToken); - ++pToken; - ++len; - } - } else { - TRACE(" "); - pshader_program_dump_opcode(curOpcode, code, *pToken); - if (curOpcode->num_params > 0) { - pshader_program_dump_param(*pToken, 0); - ++pToken; - ++len; - for (i = 1; i < curOpcode->num_params; ++i) { - TRACE(", "); - if (D3DSIO_DEF != code) { - pshader_program_dump_param(*pToken, 1); - } else { - TRACE("%f", *((const float*) pToken)); - } - ++pToken; - ++len; - } - } - TRACE("\n"); - } - pshader->functionLength = (len + 1) * sizeof(DWORD); - } - } else { - pshader->functionLength = 1; /* no Function defined use fixed function vertex processing */ - } - - if (NULL != pFunction) { - IDirect3DPixelShaderImpl_GenerateProgramArbHW(pshader, pFunction); - } - - if (NULL != pFunction) { - pshader->function = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, pshader->functionLength); - memcpy(pshader->function, pFunction, pshader->functionLength); - } else { - pshader->function = NULL; - } -} - -HRESULT WINAPI IDirect3DDeviceImpl_CreatePixelShader(IDirect3DDevice8Impl* This, CONST DWORD* pFunction, IDirect3DPixelShaderImpl** ppPixelShader) { - IDirect3DPixelShaderImpl* object; - - object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DPixelShaderImpl)); - if (NULL == object) { - *ppPixelShader = NULL; - return D3DERR_OUTOFVIDEOMEMORY; - } - /*object->lpVtbl = &Direct3DPixelShader9_Vtbl;*/ - object->device = This; - object->ref = 1; - - object->data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PSHADERDATA8)); - - IDirect3DPixelShaderImpl_ParseProgram(object, pFunction); - - *ppPixelShader = object; - return D3D_OK; -} - -HRESULT WINAPI IDirect3DPixelShaderImpl_GetFunction(IDirect3DPixelShaderImpl* This, VOID* pData, UINT* pSizeOfData) { - if (NULL == pData) { - *pSizeOfData = This->functionLength; - return D3D_OK; - } - if (*pSizeOfData < This->functionLength) { - *pSizeOfData = This->functionLength; - return D3DERR_MOREDATA; - } - if (NULL == This->function) { /* no function defined */ - TRACE("(%p) : GetFunction no User Function defined using NULL to %p\n", This, pData); - (*(DWORD **) pData) = NULL; - } else { - TRACE("(%p) : GetFunction copying to %p\n", This, pData); - memcpy(pData, This->function, This->functionLength); - } - return D3D_OK; -} - -HRESULT WINAPI IDirect3DPixelShaderImpl_SetConstantF(IDirect3DPixelShaderImpl* This, UINT StartRegister, CONST FLOAT* pConstantData, UINT Vector4fCount) { - if (StartRegister + Vector4fCount > D3D8_VSHADER_MAX_CONSTANTS) { - return D3DERR_INVALIDCALL; - } - if (NULL == This->data) { /* temporary while datas not supported */ - FIXME("(%p) : PixelShader_SetConstant not fully supported yet\n", This); - return D3DERR_INVALIDCALL; - } - memcpy(&This->data->C[StartRegister], pConstantData, Vector4fCount * 4 * sizeof(FLOAT)); - return D3D_OK; -} - -HRESULT WINAPI IDirect3DPixelShaderImpl_GetConstantF(IDirect3DPixelShaderImpl* This, UINT StartRegister, FLOAT* pConstantData, UINT Vector4fCount) { - if (StartRegister + Vector4fCount > D3D8_VSHADER_MAX_CONSTANTS) { - return D3DERR_INVALIDCALL; - } - if (NULL == This->data) { /* temporary while datas not supported */ - return D3DERR_INVALIDCALL; - } - memcpy(pConstantData, &This->data->C[StartRegister], Vector4fCount * 4 * sizeof(FLOAT)); - return D3D_OK; -} - - -/********************************************************************************************************************************************** - ********************************************************************************************************************************************** - ********************************************************************************************************************************************** - ********************************************************************************************************************************************** - **********************************************************************************************************************************************/ - -/*********************************************************************** - * ValidateVertexShader (D3D8.@) - * - * PARAMS - * toto result? - */ -BOOL WINAPI ValidateVertexShader(LPVOID pFunction, int param1, int param2, LPVOID toto) -{ - FIXME("(void): stub: pFunction %p, param1 %d, param2 %d, result? %p\n", pFunction, param1, param2, toto); - return 0; -} - -/*********************************************************************** - * ValidatePixelShader (D3D8.@) - * - * PARAMS - * toto result? - */ -BOOL WINAPI ValidatePixelShader(LPVOID pFunction, int param1, int param2, LPVOID toto) -{ - FIXME("(void): stub: pFunction %p, param1 %d, param2 %d, result? %p\n", pFunction, param1, param2, toto); - return TRUE; -} diff --git a/dlls/d3d8/stateblock.c b/dlls/d3d8/stateblock.c index c48794ecce0..1ccdd455575 100644 --- a/dlls/d3d8/stateblock.c +++ b/dlls/d3d8/stateblock.c @@ -1,7 +1,9 @@ /* - * state block implementation + * IDirect3DStateBlock8 implementation * - * Copyright 2002 Raphael Junqueira + * Copyright 2002-2003 Raphael Junqueira + * Copyright 2002-2003 Jason Edmeades + * Copyright 2005 Oliver Stieber * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -19,821 +21,75 @@ */ #include "config.h" - -#include -#include - -#include "windef.h" -#include "winbase.h" -#include "winuser.h" -#include "wingdi.h" -#include "wine/debug.h" - #include "d3d8_private.h" -WINE_DEFAULT_DEBUG_CHANNEL(d3d); +WINE_DEFAULT_DEBUG_CHANNEL(d3d8); -/* Used for CreateStateBlock */ -#define NUM_SAVEDPIXELSTATES_R 38 -#define NUM_SAVEDPIXELSTATES_T 27 -#define NUM_SAVEDVERTEXSTATES_R 33 -#define NUM_SAVEDVERTEXSTATES_T 2 +/* NOTE: DirectX8 doesn't export a IDirect3DStateBlock8, the interface is used internally to keep d3d8 and d3d9 as simila as possible */ +/* IDirect3DStateBlock8 IUnknown parts follow: */ +HRESULT WINAPI IDirect3DStateBlock8Impl_QueryInterface(IDirect3DStateBlock8 *iface, REFIID riid, LPVOID *ppobj) { + IDirect3DStateBlock8Impl *This = (IDirect3DStateBlock8Impl *)iface; -/* - * Globals - */ -extern DWORD SavedPixelStates_R[NUM_SAVEDPIXELSTATES_R]; -extern DWORD SavedPixelStates_T[NUM_SAVEDPIXELSTATES_T]; -extern DWORD SavedVertexStates_R[NUM_SAVEDVERTEXSTATES_R]; -extern DWORD SavedVertexStates_T[NUM_SAVEDVERTEXSTATES_T]; -static const float idmatrix[16] = { - 1.0, 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0 -}; - -HRESULT WINAPI IDirect3DDeviceImpl_InitStartupStateBlock(IDirect3DDevice8Impl* This) { - union { - D3DLINEPATTERN lp; - DWORD d; - } lp; - union { - float f; - DWORD d; - } tmpfloat; - unsigned int i; - int j; - LPDIRECT3DDEVICE8 iface = (LPDIRECT3DDEVICE8) This; - - /* Note this may have a large overhead but it should only be executed - once, in order to initialize the complete state of the device and - all opengl equivalents */ - TRACE("-----------------------> Setting up device defaults...\n"); - This->StateBlock->blockType = D3DSBT_ALL; - - /* FIXME: Set some of the defaults for lights, transforms etc */ - memcpy(&This->StateBlock->transforms[D3DTS_PROJECTION], &idmatrix, sizeof(idmatrix)); - memcpy(&This->StateBlock->transforms[D3DTS_VIEW], &idmatrix, sizeof(idmatrix)); - for (i = 0; i < 256; ++i) { - memcpy(&This->StateBlock->transforms[D3DTS_WORLDMATRIX(i)], &idmatrix, sizeof(idmatrix)); - } - - /* Render states: */ - if (This->PresentParms.EnableAutoDepthStencil) { - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZENABLE, D3DZB_TRUE); - } else { - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZENABLE, D3DZB_FALSE); - } - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FILLMODE, D3DFILL_SOLID); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SHADEMODE, D3DSHADE_GOURAUD); - - lp.lp.wRepeatFactor = 0; lp.lp.wLinePattern = 0; - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_LINEPATTERN, lp.d); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZWRITEENABLE, TRUE); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ALPHATESTENABLE, FALSE); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_LASTPIXEL, TRUE); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SRCBLEND, D3DBLEND_ONE); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_DESTBLEND, D3DBLEND_ZERO); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_CULLMODE, D3DCULL_CCW); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZFUNC, D3DCMP_LESSEQUAL); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ALPHAFUNC, D3DCMP_ALWAYS); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ALPHAREF, 0xff); /*??*/ - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_DITHERENABLE, FALSE); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ALPHABLENDENABLE, FALSE); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGENABLE, FALSE); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SPECULARENABLE, FALSE); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZVISIBLE, 0); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGCOLOR, 0); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGTABLEMODE, D3DFOG_NONE); - tmpfloat.f = 0.0f; - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGSTART, tmpfloat.d); - tmpfloat.f = 1.0f; - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGEND, tmpfloat.d); - tmpfloat.f = 1.0f; - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGDENSITY, tmpfloat.d); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_EDGEANTIALIAS, FALSE); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZBIAS, 0); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_RANGEFOGENABLE, FALSE); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILENABLE, FALSE); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP); - - /* Setting stencil func also uses values for stencil ref/mask, so manually set defaults - * so only a single call performed (and ensure defaults initialized before making that call) - * - * IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILREF, 0); - * IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILMASK, 0xFFFFFFFF); - */ - This->StateBlock->renderstate[D3DRS_STENCILREF] = 0; - This->StateBlock->renderstate[D3DRS_STENCILMASK] = 0xFFFFFFFF; - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILFUNC, D3DCMP_ALWAYS); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILWRITEMASK, 0xFFFFFFFF); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_TEXTUREFACTOR, 0xFFFFFFFF); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP0, 0); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP1, 0); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP2, 0); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP3, 0); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP4, 0); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP5, 0); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP6, 0); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP7, 0); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_CLIPPING, TRUE); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_LIGHTING, TRUE); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_AMBIENT, 0); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGVERTEXMODE, D3DFOG_NONE); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_COLORVERTEX, TRUE); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_LOCALVIEWER, TRUE); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_NORMALIZENORMALS, FALSE); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_COLOR2); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_VERTEXBLEND, D3DVBF_DISABLE); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_CLIPPLANEENABLE, 0); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SOFTWAREVERTEXPROCESSING, FALSE); - tmpfloat.f = 1.0f; - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSIZE, tmpfloat.d); - tmpfloat.f = 0.0f; - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSIZE_MIN, tmpfloat.d); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSPRITEENABLE, FALSE); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSCALEENABLE, FALSE); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSCALE_A, TRUE); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSCALE_B, TRUE); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSCALE_C, TRUE); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_MULTISAMPLEANTIALIAS, TRUE); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_PATCHEDGESTYLE, D3DPATCHEDGE_DISCRETE); - tmpfloat.f = 1.0f; - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_PATCHSEGMENTS, tmpfloat.d); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_DEBUGMONITORTOKEN, D3DDMT_DISABLE); - tmpfloat.f = 64.0f; - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSIZE_MAX, tmpfloat.d); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_COLORWRITEENABLE, 0x0000000F); - tmpfloat.f = 0.0f; - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_TWEENFACTOR, tmpfloat.d); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_BLENDOP, D3DBLENDOP_ADD); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POSITIONORDER, D3DORDER_CUBIC); - IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_NORMALORDER, D3DORDER_LINEAR); - - /** clipping status */ - This->StateBlock->clip_status.ClipUnion = 0; - This->StateBlock->clip_status.ClipIntersection = 0xFFFFFFFF; - - /* Texture Stage States - Put directly into state block, we will call function below */ - for (i = 0; i < GL_LIMITS(textures); i++) { - memcpy(&This->StateBlock->transforms[D3DTS_TEXTURE0 + i], &idmatrix, sizeof(idmatrix)); - This->StateBlock->texture_state[i][D3DTSS_COLOROP ] = (i==0)? D3DTOP_MODULATE : D3DTOP_DISABLE; - This->StateBlock->texture_state[i][D3DTSS_COLORARG1 ] = D3DTA_TEXTURE; - This->StateBlock->texture_state[i][D3DTSS_COLORARG2 ] = D3DTA_CURRENT; - This->StateBlock->texture_state[i][D3DTSS_ALPHAOP ] = (i==0)? D3DTOP_SELECTARG1 : D3DTOP_DISABLE; - This->StateBlock->texture_state[i][D3DTSS_ALPHAARG1 ] = D3DTA_TEXTURE; - This->StateBlock->texture_state[i][D3DTSS_ALPHAARG2 ] = D3DTA_CURRENT; - This->StateBlock->texture_state[i][D3DTSS_BUMPENVMAT00 ] = (DWORD) 0.0; - This->StateBlock->texture_state[i][D3DTSS_BUMPENVMAT01 ] = (DWORD) 0.0; - This->StateBlock->texture_state[i][D3DTSS_BUMPENVMAT10 ] = (DWORD) 0.0; - This->StateBlock->texture_state[i][D3DTSS_BUMPENVMAT11 ] = (DWORD) 0.0; - This->StateBlock->texture_state[i][D3DTSS_TEXCOORDINDEX ] = i; - This->StateBlock->texture_state[i][D3DTSS_ADDRESSU ] = D3DTADDRESS_WRAP; - This->StateBlock->texture_state[i][D3DTSS_ADDRESSV ] = D3DTADDRESS_WRAP; - This->StateBlock->texture_state[i][D3DTSS_BORDERCOLOR ] = 0x00; - This->StateBlock->texture_state[i][D3DTSS_MAGFILTER ] = D3DTEXF_POINT; - This->StateBlock->texture_state[i][D3DTSS_MINFILTER ] = D3DTEXF_POINT; - This->StateBlock->texture_state[i][D3DTSS_MIPFILTER ] = D3DTEXF_NONE; - This->StateBlock->texture_state[i][D3DTSS_MIPMAPLODBIAS ] = 0; - This->StateBlock->texture_state[i][D3DTSS_MAXMIPLEVEL ] = 0; - This->StateBlock->texture_state[i][D3DTSS_MAXANISOTROPY ] = 1; - This->StateBlock->texture_state[i][D3DTSS_BUMPENVLSCALE ] = (DWORD) 0.0; - This->StateBlock->texture_state[i][D3DTSS_BUMPENVLOFFSET ] = (DWORD) 0.0; - This->StateBlock->texture_state[i][D3DTSS_TEXTURETRANSFORMFLAGS ] = D3DTTFF_DISABLE; - This->StateBlock->texture_state[i][D3DTSS_ADDRESSW ] = D3DTADDRESS_WRAP; - This->StateBlock->texture_state[i][D3DTSS_COLORARG0 ] = D3DTA_CURRENT; - This->StateBlock->texture_state[i][D3DTSS_ALPHAARG0 ] = D3DTA_CURRENT; - This->StateBlock->texture_state[i][D3DTSS_RESULTARG ] = D3DTA_CURRENT; - } - - /* Under DirectX you can have texture stage operations even if no texture is - bound, whereas opengl will only do texture operations when a valid texture is - bound. We emulate this by creating dummy textures and binding them to each - texture stage, but disable all stages by default. Hence if a stage is enabled - then the default texture will kick in until replaced by a SetTexture call */ - - ENTER_GL(); - - for (i = 0; i < GL_LIMITS(textures); i++) { - GLubyte white = 255; - - /* Note this avoids calling settexture, so pretend it has been called */ - This->StateBlock->Set.textures[i] = TRUE; - This->StateBlock->Changed.textures[i] = TRUE; - This->StateBlock->textures[i] = NULL; - - /* Make appropriate texture active */ - if (GL_SUPPORT(ARB_MULTITEXTURE)) { -#if defined(GL_VERSION_1_3) - glActiveTexture(GL_TEXTURE0 + i); -#else - glActiveTextureARB(GL_TEXTURE0_ARB + i); -#endif - checkGLcall("glActiveTextureARB"); - } else if (i > 0) { - FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n"); - } - - /* Generate an opengl texture name */ - glGenTextures(1, &This->dummyTextureName[i]); - checkGLcall("glGenTextures"); - TRACE("Dummy Texture %d given name %d\n", i, This->dummyTextureName[i]); - - /* Generate a dummy 1d texture */ - This->StateBlock->textureDimensions[i] = GL_TEXTURE_1D; - glBindTexture(GL_TEXTURE_1D, This->dummyTextureName[i]); - checkGLcall("glBindTexture"); - - glTexImage1D(GL_TEXTURE_1D, 0, GL_LUMINANCE, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, &white); - checkGLcall("glTexImage1D"); - - /* Reapply all the texture state information to this texture */ - setupTextureStates(iface, i, REAPPLY_ALL); - } - - LEAVE_GL(); - - /* defaulting palettes */ - for (i = 0; i < MAX_PALETTES; ++i) { - for (j = 0; j < 256; ++j) { - This->palettes[i][j].peRed = 0xFF; - This->palettes[i][j].peGreen = 0xFF; - This->palettes[i][j].peBlue = 0xFF; - This->palettes[i][j].peFlags = 0xFF; - } - } - This->currentPalette = 0; - - TRACE("-----------------------> Device defaults now set up...\n"); - - return D3D_OK; -} - - - -HRESULT WINAPI IDirect3DDeviceImpl_CreateStateBlock(IDirect3DDevice8Impl* This, D3DSTATEBLOCKTYPE Type, IDirect3DStateBlockImpl** ppStateBlock) { - IDirect3DStateBlockImpl* object; - UINT i, j; - - TRACE("(%p) : Type(%d)\n", This, Type); - - /* Allocate Storage */ - object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DStateBlockImpl)); - if (object) { - if (NULL == This->StateBlock) { /** if it the main stateblock only do init and returns */ - /*object->lpVtbl = &Direct3DStateBlock9_Vtbl;*/ - object->device = This; - object->ref = 1; - object->blockType = Type; - This->StateBlock = object; - /* don't forget to init it calling InitStartupStateBlock */ - return D3D_OK; - } - memcpy(object, This->StateBlock, sizeof(IDirect3DStateBlockImpl)); - } else { - *ppStateBlock = (IDirect3DStateBlockImpl*) 0xFFFFFFFF; - return E_OUTOFMEMORY; - } - /*object->lpVtbl = &Direct3DStateBlock9_Vtbl;*/ - object->device = This; - object->ref = 1; - object->blockType = Type; - - TRACE("Updating changed flags appropriate for type %d\n", Type); - - if (Type == D3DSBT_ALL) { - TRACE("ALL => Pretend everything has changed\n"); - memset(&object->Changed, TRUE, sizeof(This->StateBlock->Changed)); - - } else if (Type == D3DSBT_PIXELSTATE) { - - memset(&object->Changed, FALSE, sizeof(This->StateBlock->Changed)); - - /* TODO: Pixel Shader Constants */ - object->Changed.pixelShader = TRUE; - for (i = 0; i < NUM_SAVEDPIXELSTATES_R; i++) { - object->Changed.renderstate[SavedPixelStates_R[i]] = TRUE; - } - for (j = 0; j < GL_LIMITS(textures); i++) { - for (i = 0; i < NUM_SAVEDPIXELSTATES_T; i++) { - object->Changed.texture_state[j][SavedPixelStates_T[i]] = TRUE; - } - } - - } else if (Type == D3DSBT_VERTEXSTATE) { - - memset(&object->Changed, FALSE, sizeof(This->StateBlock->Changed)); - - /* TODO: Vertex Shader Constants */ - object->Changed.vertexShader = TRUE; - for (i = 0; i < NUM_SAVEDVERTEXSTATES_R; i++) { - object->Changed.renderstate[SavedVertexStates_R[i]] = TRUE; - } - for (j = 0; j < GL_LIMITS(textures); i++) { - for (i = 0; i < NUM_SAVEDVERTEXSTATES_T; i++) { - object->Changed.texture_state[j][SavedVertexStates_T[i]] = TRUE; - } - } - - /* Duplicate light chain */ - { - PLIGHTINFOEL *src = NULL; - PLIGHTINFOEL *dst = NULL; - PLIGHTINFOEL *newEl = NULL; - - src = This->StateBlock->lights; - object->lights = NULL; - - while (src) { - newEl = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PLIGHTINFOEL)); - if (newEl == NULL) return D3DERR_OUTOFVIDEOMEMORY; - memcpy(newEl, src, sizeof(PLIGHTINFOEL)); - newEl->prev = dst; - newEl->changed = TRUE; - newEl->enabledChanged = TRUE; - if (dst == NULL) { - object->lights = newEl; - } else { - dst->next = newEl; - } - dst = newEl; - src = src->next; - } - } - - } else { - FIXME("Unrecognized state block type %d\n", Type); - } - TRACE("(%p) returning token (ptr to stateblock) of %p\n", This, object); - - *ppStateBlock = object; - return D3D_OK; -} - -/** yakkk temporary waiting for Release */ -HRESULT WINAPI IDirect3DDeviceImpl_DeleteStateBlock(IDirect3DDevice8Impl* This, IDirect3DStateBlockImpl* pSB) { - PLIGHTINFOEL *tmp; - - TRACE("(%p) : freeing StateBlock %p\n", This, pSB); - tmp = pSB->lights; - if (tmp) tmp = tmp->next; - while (tmp != NULL) { - HeapFree(GetProcessHeap(), 0, (void *)(tmp->prev)); - tmp = tmp->next; - } - HeapFree(GetProcessHeap(), 0, (void *)tmp); - HeapFree(GetProcessHeap(), 0, (void *)pSB); - return D3D_OK; -} - -HRESULT WINAPI IDirect3DDeviceImpl_BeginStateBlock(IDirect3DDevice8Impl* This) { - IDirect3DStateBlockImpl* object; - - TRACE("(%p)\n", This); - - if (This->isRecordingState) { - TRACE("(%p) already recording! returning error\n", This); - return D3DERR_INVALIDCALL; - } - - /* Allocate Storage */ - object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DStateBlockImpl)); - if (object) { - } else { - return E_OUTOFMEMORY; - } - /*object->lpVtbl = &Direct3DVextexShaderDeclaration8_Vtbl;*/ - object->device = This; - object->ref = 1; - - This->isRecordingState = TRUE; - This->UpdateStateBlock = object; - - return D3D_OK; -} - -HRESULT WINAPI IDirect3DDeviceImpl_EndStateBlock(IDirect3DDevice8Impl* This, IDirect3DStateBlockImpl** ppStateBlock) { - TRACE("(%p)\n", This); - - if (!This->isRecordingState) { - TRACE("(%p) not recording! returning error\n", This); - *ppStateBlock = NULL; - return D3DERR_INVALIDCALL; - } - - This->UpdateStateBlock->blockType = D3DSBT_RECORDED; - *ppStateBlock = This->UpdateStateBlock; /* FIXME: AddRef() */ - This->isRecordingState = FALSE; - This->UpdateStateBlock = This->StateBlock; - - TRACE("(%p) returning token (ptr to stateblock) of %p\n", This, *ppStateBlock); - return D3D_OK; -} - -HRESULT WINAPI IDirect3DDeviceImpl_ApplyStateBlock(IDirect3DDevice8Impl* This, IDirect3DStateBlockImpl* pSB) { - UINT i; - UINT j; - LPDIRECT3DDEVICE8 iface = (LPDIRECT3DDEVICE8) This; - - TRACE("(%p) : Applying state block %p ------------------v\n", This, pSB); - - /* FIXME: Only apply applicable states not all states */ - - if (pSB->blockType == D3DSBT_RECORDED || pSB->blockType == D3DSBT_ALL || pSB->blockType == D3DSBT_VERTEXSTATE) { - - PLIGHTINFOEL *toDo = pSB->lights; - while (toDo != NULL) { - if (toDo->changed) - IDirect3DDevice8Impl_SetLight(iface, toDo->OriginalIndex, &toDo->OriginalParms); - if (toDo->enabledChanged) - IDirect3DDevice8Impl_LightEnable(iface, toDo->OriginalIndex, toDo->lightEnabled); - toDo = toDo->next; - } - - if (pSB->Set.vertexShader && pSB->Changed.vertexShader) - IDirect3DDevice8Impl_SetVertexShader(iface, pSB->VertexShader); - - /* TODO: Vertex Shader Constants */ - } - - if (pSB->blockType == D3DSBT_RECORDED || pSB->blockType == D3DSBT_ALL || pSB->blockType == D3DSBT_PIXELSTATE) { - - if (pSB->Set.pixelShader && pSB->Changed.pixelShader) - IDirect3DDevice8Impl_SetPixelShader(iface, pSB->PixelShader); - - /* TODO: Pixel Shader Constants */ - } - - /* Others + Render & Texture */ - if (pSB->blockType == D3DSBT_RECORDED || pSB->blockType == D3DSBT_ALL) { - for (i = 0; i < HIGHEST_TRANSFORMSTATE; i++) { - if (pSB->Set.transform[i] && pSB->Changed.transform[i]) - IDirect3DDevice8Impl_SetTransform(iface, i, &pSB->transforms[i]); - } - - if (pSB->Set.Indices && pSB->Changed.Indices) - IDirect3DDevice8Impl_SetIndices(iface, pSB->pIndexData, pSB->baseVertexIndex); - - if (pSB->Set.material && pSB->Changed.material) - IDirect3DDevice8Impl_SetMaterial(iface, &pSB->material); - - if (pSB->Set.viewport && pSB->Changed.viewport) - IDirect3DDevice8Impl_SetViewport(iface, &pSB->viewport); - - for (i=0; iSet.stream_source[i] && pSB->Changed.stream_source[i]) - IDirect3DDevice8Impl_SetStreamSource(iface, i, pSB->stream_source[i], pSB->stream_stride[i]); - } - - for (i = 0; i < GL_LIMITS(clipplanes); i++) { - if (pSB->Set.clipplane[i] && pSB->Changed.clipplane[i]) { - float clip[4]; - - clip[0] = pSB->clipplane[i][0]; - clip[1] = pSB->clipplane[i][1]; - clip[2] = pSB->clipplane[i][2]; - clip[3] = pSB->clipplane[i][3]; - IDirect3DDevice8Impl_SetClipPlane(iface, i, clip); - } - } - - /* Render */ - for (i = 0; i < HIGHEST_RENDER_STATE; i++) { - if (pSB->Set.renderstate[i] && pSB->Changed.renderstate[i]) - IDirect3DDevice8Impl_SetRenderState(iface, i, pSB->renderstate[i]); - } - - /* Texture */ - for (j = 0; j < GL_LIMITS(textures); j++) { - for (i = 0; i < HIGHEST_TEXTURE_STATE; i++) { - if (pSB->Set.texture_state[j][i] && pSB->Changed.texture_state[j][i]) { - IDirect3DDevice8Impl_SetTextureStageState(iface, j, i, pSB->texture_state[j][i]); - } - } - if (pSB->Set.textures[j] && pSB->Changed.textures[j]) { - IDirect3DDevice8Impl_SetTexture(iface, j, pSB->textures[j]); - } - } - - - } else if (pSB->blockType == D3DSBT_PIXELSTATE) { - - for (i = 0; i < NUM_SAVEDPIXELSTATES_R; i++) { - if (pSB->Set.renderstate[SavedPixelStates_R[i]] && pSB->Changed.renderstate[SavedPixelStates_R[i]]) - IDirect3DDevice8Impl_SetRenderState(iface, SavedPixelStates_R[i], pSB->renderstate[SavedPixelStates_R[i]]); - - } - - for (j = 0; j < GL_LIMITS(textures); i++) { - for (i = 0; i < NUM_SAVEDPIXELSTATES_T; i++) { - if (pSB->Set.texture_state[j][SavedPixelStates_T[i]] && - pSB->Changed.texture_state[j][SavedPixelStates_T[i]]) - IDirect3DDevice8Impl_SetTextureStageState(iface, j, SavedPixelStates_T[i], pSB->texture_state[j][SavedPixelStates_T[i]]); - } - } - - } else if (pSB->blockType == D3DSBT_VERTEXSTATE) { - - for (i = 0; i < NUM_SAVEDVERTEXSTATES_R; i++) { - if (pSB->Set.renderstate[SavedVertexStates_R[i]] && pSB->Changed.renderstate[SavedVertexStates_R[i]]) - IDirect3DDevice8Impl_SetRenderState(iface, SavedVertexStates_R[i], pSB->renderstate[SavedVertexStates_R[i]]); - } - - for (j = 0; j < GL_LIMITS(textures); i++) { - for (i = 0; i < NUM_SAVEDVERTEXSTATES_T; i++) { - if (pSB->Set.texture_state[j][SavedVertexStates_T[i]] && - pSB->Changed.texture_state[j][SavedVertexStates_T[i]]) - IDirect3DDevice8Impl_SetTextureStageState(iface, j, SavedVertexStates_T[i], pSB->texture_state[j][SavedVertexStates_T[i]]); - } - } - - - } else { - FIXME("Unrecognized state block type %d\n", pSB->blockType); - } - memcpy(&This->StateBlock->Changed, &pSB->Changed, sizeof(This->StateBlock->Changed)); - TRACE("(%p) : Applied state block %p ------------------^\n", This, pSB); - - return D3D_OK; -} - -HRESULT WINAPI IDirect3DDeviceImpl_CaptureStateBlock(IDirect3DDevice8Impl* This, IDirect3DStateBlockImpl* updateBlock) { - LPDIRECT3DDEVICE8 iface = (LPDIRECT3DDEVICE8) This; - PLIGHTINFOEL *tmp; - - TRACE("(%p) : Updating state block %p ------------------v\n", This, updateBlock); - - /* If not recorded, then update can just recapture */ - if (updateBlock->blockType != D3DSBT_RECORDED) { - IDirect3DStateBlockImpl* tmpBlock; - IDirect3DDeviceImpl_CreateStateBlock(This, updateBlock->blockType, &tmpBlock); - - /* Note just swap the light chains over so when deleting, the old one goes */ - tmp = updateBlock->lights; - memcpy(updateBlock, tmpBlock, sizeof(IDirect3DStateBlockImpl)); - tmpBlock->lights = tmp; - - /* Delete the temporary one (which points to the old light chain though */ - IDirect3DDeviceImpl_DeleteStateBlock(This, tmpBlock); - - } else { - unsigned int i, j; - PLIGHTINFOEL *src; - - /* Recorded => Only update 'changed' values */ - if (updateBlock->Set.vertexShader && updateBlock->VertexShader != This->StateBlock->VertexShader) { - updateBlock->VertexShader = This->StateBlock->VertexShader; - TRACE("Updating vertex shader to %ld\n", This->StateBlock->VertexShader); - } - - /* TODO: Vertex Shader Constants */ - - /* Lights... For a recorded state block, we just had a chain of actions to perform, - so we need to walk that chain and update any actions which differ */ - src = updateBlock->lights; - while (src != NULL) { - PLIGHTINFOEL *realLight = NULL; - - /* Locate the light in the live lights */ - realLight = This->StateBlock->lights; - while (realLight != NULL && realLight->OriginalIndex != src->OriginalIndex) realLight = realLight->next; - - if (realLight == NULL) { - FIXME("A captured light no longer exists...?\n"); - } else { - - /* If 'changed' then its a SetLight command. Rather than comparing to see - if the OriginalParms have changed and then copy them (twice through - memory) just do the copy */ - if (src->changed) { - TRACE("Updating lights for light %ld\n", src->OriginalIndex); - memcpy(&src->OriginalParms, &realLight->OriginalParms, sizeof(PLIGHTINFOEL)); - } - - /* If 'enabledChanged' then its a LightEnable command */ - if (src->enabledChanged) { - TRACE("Updating lightEnabled for light %ld\n", src->OriginalIndex); - src->lightEnabled = realLight->lightEnabled; - } - - } - - src = src->next; - } - - - if (updateBlock->Set.pixelShader && updateBlock->PixelShader != This->StateBlock->PixelShader) { - TRACE("Updating pixel shader to %ld\n", This->StateBlock->PixelShader); - IDirect3DDevice8Impl_SetVertexShader(iface, updateBlock->PixelShader); - } - - /* TODO: Pixel Shader Constants */ - - /* Others + Render & Texture */ - for (i = 0; i < HIGHEST_TRANSFORMSTATE; i++) { - if (updateBlock->Set.transform[i] && memcmp(&This->StateBlock->transforms[i], - &updateBlock->transforms[i], - sizeof(D3DMATRIX)) != 0) { - TRACE("Updating transform %d\n", i); - memcpy(&updateBlock->transforms[i], &This->StateBlock->transforms[i], sizeof(D3DMATRIX)); - } - } - - if (updateBlock->Set.Indices && ((updateBlock->pIndexData != This->StateBlock->pIndexData) - || (updateBlock->baseVertexIndex != This->StateBlock->baseVertexIndex))) { - TRACE("Updating pindexData to %p, baseVertexIndex to %d\n", - This->StateBlock->pIndexData, This->StateBlock->baseVertexIndex); - updateBlock->pIndexData = This->StateBlock->pIndexData; - updateBlock->baseVertexIndex = This->StateBlock->baseVertexIndex; - } - - if (updateBlock->Set.material && memcmp(&This->StateBlock->material, - &updateBlock->material, - sizeof(D3DMATERIAL8)) != 0) { - TRACE("Updating material\n"); - memcpy(&updateBlock->material, &This->StateBlock->material, sizeof(D3DMATERIAL8)); - } - - if (updateBlock->Set.viewport && memcmp(&This->StateBlock->viewport, - &updateBlock->viewport, - sizeof(D3DVIEWPORT8)) != 0) { - TRACE("Updating viewport\n"); - memcpy(&updateBlock->viewport, &This->StateBlock->viewport, sizeof(D3DVIEWPORT8)); - } - - for (i = 0; i < MAX_STREAMS; i++) { - if (updateBlock->Set.stream_source[i] && - ((updateBlock->stream_stride[i] != This->StateBlock->stream_stride[i]) || - (updateBlock->stream_source[i] != This->StateBlock->stream_source[i]))) { - TRACE("Updating stream source %d to %p, stride to %d\n", i, This->StateBlock->stream_source[i], - This->StateBlock->stream_stride[i]); - updateBlock->stream_stride[i] = This->StateBlock->stream_stride[i]; - updateBlock->stream_source[i] = This->StateBlock->stream_source[i]; - } - } - - for (i = 0; i < GL_LIMITS(clipplanes); i++) { - if (updateBlock->Set.clipplane[i] && memcmp(&This->StateBlock->clipplane[i], - &updateBlock->clipplane[i], - sizeof(updateBlock->clipplane)) != 0) { - - TRACE("Updating clipplane %d\n", i); - memcpy(&updateBlock->clipplane[i], &This->StateBlock->clipplane[i], - sizeof(updateBlock->clipplane)); - } - } - - /* Render */ - for (i = 0; i < HIGHEST_RENDER_STATE; i++) { - - if (updateBlock->Set.renderstate[i] && (updateBlock->renderstate[i] != - This->StateBlock->renderstate[i])) { - TRACE("Updating renderstate %d to %ld\n", i, This->StateBlock->renderstate[i]); - updateBlock->renderstate[i] = This->StateBlock->renderstate[i]; - } - } - - /* Texture */ - for (j = 0; j < GL_LIMITS(textures); j++) { - for (i = 0; i < HIGHEST_TEXTURE_STATE; i++) { - - if (updateBlock->Set.texture_state[j][i] && (updateBlock->texture_state[j][i] != - This->StateBlock->texture_state[j][i])) { - TRACE("Updating texturestagestate %d,%d to %ld (was %ld)\n", j,i, This->StateBlock->texture_state[j][i], - updateBlock->texture_state[j][i]); - updateBlock->texture_state[j][i] = This->StateBlock->texture_state[j][i]; - } - - if (updateBlock->Set.textures[j] && (updateBlock->textures[j] != This->StateBlock->textures[j])) { - TRACE("Updating texture %d to %p (was %p)\n", j, This->StateBlock->textures[j], updateBlock->textures[j]); - updateBlock->textures[j] = This->StateBlock->textures[j]; - } - } - - } - } - - TRACE("(%p) : Updated state block %p ------------------^\n", This, updateBlock); - - return D3D_OK; -} - -DWORD SavedPixelStates_R[NUM_SAVEDPIXELSTATES_R] = { - D3DRS_ALPHABLENDENABLE , - D3DRS_ALPHAFUNC , - D3DRS_ALPHAREF , - D3DRS_ALPHATESTENABLE , - D3DRS_BLENDOP , - D3DRS_COLORWRITEENABLE , - D3DRS_DESTBLEND , - D3DRS_DITHERENABLE , - D3DRS_EDGEANTIALIAS , - D3DRS_FILLMODE , - D3DRS_FOGDENSITY , - D3DRS_FOGEND , - D3DRS_FOGSTART , - D3DRS_LASTPIXEL , - D3DRS_LINEPATTERN , - D3DRS_SHADEMODE , - D3DRS_SRCBLEND , - D3DRS_STENCILENABLE , - D3DRS_STENCILFAIL , - D3DRS_STENCILFUNC , - D3DRS_STENCILMASK , - D3DRS_STENCILPASS , - D3DRS_STENCILREF , - D3DRS_STENCILWRITEMASK , - D3DRS_STENCILZFAIL , - D3DRS_TEXTUREFACTOR , - D3DRS_WRAP0 , - D3DRS_WRAP1 , - D3DRS_WRAP2 , - D3DRS_WRAP3 , - D3DRS_WRAP4 , - D3DRS_WRAP5 , - D3DRS_WRAP6 , - D3DRS_WRAP7 , - D3DRS_ZBIAS , - D3DRS_ZENABLE , - D3DRS_ZFUNC , - D3DRS_ZWRITEENABLE -}; - -DWORD SavedPixelStates_T[NUM_SAVEDPIXELSTATES_T] = { - D3DTSS_ADDRESSU , - D3DTSS_ADDRESSV , - D3DTSS_ADDRESSW , - D3DTSS_ALPHAARG0 , - D3DTSS_ALPHAARG1 , - D3DTSS_ALPHAARG2 , - D3DTSS_ALPHAOP , - D3DTSS_BORDERCOLOR , - D3DTSS_BUMPENVLOFFSET , - D3DTSS_BUMPENVLSCALE , - D3DTSS_BUMPENVMAT00 , - D3DTSS_BUMPENVMAT01 , - D3DTSS_BUMPENVMAT10 , - D3DTSS_BUMPENVMAT11 , - D3DTSS_COLORARG0 , - D3DTSS_COLORARG1 , - D3DTSS_COLORARG2 , - D3DTSS_COLOROP , - D3DTSS_MAGFILTER , - D3DTSS_MAXANISOTROPY , - D3DTSS_MAXMIPLEVEL , - D3DTSS_MINFILTER , - D3DTSS_MIPFILTER , - D3DTSS_MIPMAPLODBIAS , - D3DTSS_RESULTARG , - D3DTSS_TEXCOORDINDEX , - D3DTSS_TEXTURETRANSFORMFLAGS -}; - -DWORD SavedVertexStates_R[NUM_SAVEDVERTEXSTATES_R] = { - D3DRS_AMBIENT , - D3DRS_AMBIENTMATERIALSOURCE , - D3DRS_CLIPPING , - D3DRS_CLIPPLANEENABLE , - D3DRS_COLORVERTEX , - D3DRS_DIFFUSEMATERIALSOURCE , - D3DRS_EMISSIVEMATERIALSOURCE , - D3DRS_FOGDENSITY , - D3DRS_FOGEND , - D3DRS_FOGSTART , - D3DRS_FOGTABLEMODE , - D3DRS_FOGVERTEXMODE , - D3DRS_INDEXEDVERTEXBLENDENABLE , - D3DRS_LIGHTING , - D3DRS_LOCALVIEWER , - D3DRS_MULTISAMPLEANTIALIAS , - D3DRS_MULTISAMPLEMASK , - D3DRS_NORMALIZENORMALS , - D3DRS_PATCHEDGESTYLE , - D3DRS_PATCHSEGMENTS , - D3DRS_POINTSCALE_A , - D3DRS_POINTSCALE_B , - D3DRS_POINTSCALE_C , - D3DRS_POINTSCALEENABLE , - D3DRS_POINTSIZE , - D3DRS_POINTSIZE_MAX , - D3DRS_POINTSIZE_MIN , - D3DRS_POINTSPRITEENABLE , - D3DRS_RANGEFOGENABLE , - D3DRS_SOFTWAREVERTEXPROCESSING , - D3DRS_SPECULARMATERIALSOURCE , - D3DRS_TWEENFACTOR , - D3DRS_VERTEXBLEND -}; - -DWORD SavedVertexStates_T[NUM_SAVEDVERTEXSTATES_T] = { - D3DTSS_TEXCOORDINDEX , - D3DTSS_TEXTURETRANSFORMFLAGS + if (IsEqualGUID(riid, &IID_IUnknown) + || IsEqualGUID(riid, &IID_IDirect3DStateBlock8)) { + IUnknown_AddRef(iface); + *ppobj = This; + return D3D_OK; + } + + WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj); + return E_NOINTERFACE; +} + +ULONG WINAPI IDirect3DStateBlock8Impl_AddRef(IDirect3DStateBlock8 *iface) { + IDirect3DStateBlock8Impl *This = (IDirect3DStateBlock8Impl *)iface; + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) : AddRef from %ld\n", This, ref - 1); + + return ref; +} + +ULONG WINAPI IDirect3DStateBlock8Impl_Release(IDirect3DStateBlock8 *iface) { + IDirect3DStateBlock8Impl *This = (IDirect3DStateBlock8Impl *)iface; + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) : ReleaseRef to %ld\n", This, ref); + + if (ref == 0) { + IWineD3DStateBlock_Release(This->wineD3DStateBlock); + HeapFree(GetProcessHeap(), 0, This); + } + return ref; +} + +/* IDirect3DStateBlock8 Interface follow: */ +HRESULT WINAPI IDirect3DStateBlock8Impl_GetDevice(IDirect3DStateBlock8 *iface, IDirect3DDevice8 **ppDevice) { + IDirect3DStateBlock8Impl *This = (IDirect3DStateBlock8Impl *)iface; + TRACE("(%p) Relay\n", This); + return IDirect3DResource8Impl_GetDevice((LPDIRECT3DRESOURCE8) This, ppDevice); +} + +HRESULT WINAPI IDirect3DStateBlock8Impl_Capture(IDirect3DStateBlock8 *iface) { + IDirect3DStateBlock8Impl *This = (IDirect3DStateBlock8Impl *)iface; + TRACE("(%p) Relay\n", This); + return IWineD3DStateBlock_Capture(This->wineD3DStateBlock); +} + +HRESULT WINAPI IDirect3DStateBlock8Impl_Apply(IDirect3DStateBlock8 *iface) { + IDirect3DStateBlock8Impl *This = (IDirect3DStateBlock8Impl *)iface; + TRACE("(%p) Relay\n", This); + return IWineD3DStateBlock_Apply(This->wineD3DStateBlock); +} + +const IDirect3DStateBlock8Vtbl Direct3DStateBlock8_Vtbl = +{ + /* IUnknown */ + IDirect3DStateBlock8Impl_QueryInterface, + IDirect3DStateBlock8Impl_AddRef, + IDirect3DStateBlock8Impl_Release, + /* IDirect3DStateBlock8 */ + IDirect3DStateBlock8Impl_GetDevice, + IDirect3DStateBlock8Impl_Capture, + IDirect3DStateBlock8Impl_Apply }; diff --git a/dlls/d3d8/swapchain.c b/dlls/d3d8/swapchain.c index 51e8df9513b..10389968a76 100644 --- a/dlls/d3d8/swapchain.c +++ b/dlls/d3d8/swapchain.c @@ -1,7 +1,7 @@ /* * IDirect3DSwapChain8 implementation * - * Copyright 2002 Jason Edmeades + * Copyright 2005 Oliver Stieber * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -19,32 +19,23 @@ */ #include "config.h" - -#include - -#include "windef.h" -#include "winbase.h" -#include "winuser.h" -#include "wingdi.h" -#include "wine/debug.h" - #include "d3d8_private.h" -WINE_DEFAULT_DEBUG_CHANNEL(d3d); +WINE_DEFAULT_DEBUG_CHANNEL(d3d8); /* IDirect3DSwapChain IUnknown parts follow: */ -HRESULT WINAPI IDirect3DSwapChain8Impl_QueryInterface(LPDIRECT3DSWAPCHAIN8 iface,REFIID riid,LPVOID *ppobj) +HRESULT WINAPI IDirect3DSwapChain8Impl_QueryInterface(LPDIRECT3DSWAPCHAIN8 iface, REFIID riid, LPVOID* ppobj) { IDirect3DSwapChain8Impl *This = (IDirect3DSwapChain8Impl *)iface; if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IDirect3DSwapChain8)) { - IDirect3DSwapChain8Impl_AddRef(iface); + IUnknown_AddRef(iface); *ppobj = This; return D3D_OK; } - WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj); + WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj); return E_NOINTERFACE; } @@ -64,31 +55,32 @@ ULONG WINAPI IDirect3DSwapChain8Impl_Release(LPDIRECT3DSWAPCHAIN8 iface) { TRACE("(%p) : ReleaseRef to %ld\n", This, ref); if (ref == 0) { + IWineD3DSwapChain_Release(This->wineD3DSwapChain); HeapFree(GetProcessHeap(), 0, This); } return ref; } -/* IDirect3DSwapChain parts follow: */ -HRESULT WINAPI IDirect3DSwapChain8Impl_Present(LPDIRECT3DSWAPCHAIN8 iface, CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion) { +/* IDirect3DSwapChain8 parts follow: */ +HRESULT WINAPI IDirect3DSwapChain8Impl_Present(LPDIRECT3DSWAPCHAIN8 iface, CONST RECT *pSourceRect, CONST RECT *pDestRect, HWND hDestWindowOverride, CONST RGNDATA *pDirtyRegion) { IDirect3DSwapChain8Impl *This = (IDirect3DSwapChain8Impl *)iface; - FIXME("(%p) : stub\n", This); - return D3D_OK; + TRACE("(%p) Relay\n", This); + return IWineD3DSwapChain_Present(This->wineD3DSwapChain, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion, 0); } -HRESULT WINAPI IDirect3DSwapChain8Impl_GetBackBuffer(LPDIRECT3DSWAPCHAIN8 iface, UINT BackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface8** ppBackBuffer) { +HRESULT WINAPI IDirect3DSwapChain8Impl_GetBackBuffer(LPDIRECT3DSWAPCHAIN8 iface, UINT iBackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface8** ppBackBuffer) { IDirect3DSwapChain8Impl *This = (IDirect3DSwapChain8Impl *)iface; - *ppBackBuffer = (LPDIRECT3DSURFACE8) This->backBuffer; - TRACE("(%p) : BackBuf %d Type %d returning %p\n", This, BackBuffer, Type, *ppBackBuffer); + HRESULT hrc = D3D_OK; + IWineD3DSurface *mySurface = NULL; - if (BackBuffer > This->PresentParms.BackBufferCount - 1) { - FIXME("Only one backBuffer currently supported\n"); - return D3DERR_INVALIDCALL; + TRACE("(%p) Relay\n", This); + + hrc = IWineD3DSwapChain_GetBackBuffer(This->wineD3DSwapChain, iBackBuffer, Type, &mySurface); + if (hrc == D3D_OK && NULL != mySurface) { + IWineD3DSurface_GetParent(mySurface, (IUnknown **)ppBackBuffer); + IWineD3DSurface_Release(mySurface); } - - /* Note inc ref on returned surface */ - IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppBackBuffer); - return D3D_OK; + return hrc; } const IDirect3DSwapChain8Vtbl Direct3DSwapChain8_Vtbl = diff --git a/dlls/d3d8/texture.c b/dlls/d3d8/texture.c index 769f645a43c..fa6927839f4 100644 --- a/dlls/d3d8/texture.c +++ b/dlls/d3d8/texture.c @@ -23,10 +23,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d8); -#define D3D8_TEXTURE(a) ((IWineD3DTextureImpl*)(a->wineD3DTexture)) -#define D3D8_TEXTURE_GET_SURFACE(a) ((IWineD3DSurfaceImpl*)(D3D8_TEXTURE(a)->surfaces[i])) -#define D3D8_BASETEXTURE(a) (((IWineD3DTextureImpl*)(a->wineD3DTexture))->baseTexture) - /* IDirect3DTexture8 IUnknown parts follow: */ HRESULT WINAPI IDirect3DTexture8Impl_QueryInterface(LPDIRECT3DTEXTURE8 iface, REFIID riid, LPVOID *ppobj) { IDirect3DTexture8Impl *This = (IDirect3DTexture8Impl *)iface; @@ -103,50 +99,10 @@ DWORD WINAPI IDirect3DTexture8Impl_GetPriority(LPDIRECT3DTEXTURE8 iface) { return IWineD3DTexture_GetPriority(This->wineD3DTexture); } -void WINAPI IDirect3DTexture8Impl_PreLoad(LPDIRECT3DTEXTURE8 iface) { - unsigned int i; +void WINAPI IDirect3DTexture8Impl_PreLoad(LPDIRECT3DTEXTURE8 iface) { IDirect3DTexture8Impl *This = (IDirect3DTexture8Impl *)iface; - TRACE("(%p) : About to load texture\n", This); - - ENTER_GL(); - - for (i = 0; i < D3D8_BASETEXTURE(This).levels; i++) { - if (i == 0 && D3D8_TEXTURE_GET_SURFACE(This)->textureName != 0 && D3D8_BASETEXTURE(This).dirty == FALSE) { - glBindTexture(GL_TEXTURE_2D, D3D8_TEXTURE_GET_SURFACE(This)->textureName); - checkGLcall("glBindTexture"); - TRACE("Texture %p (level %d) given name %d\n", D3D8_TEXTURE_GET_SURFACE(This), i, D3D8_TEXTURE_GET_SURFACE(This)->textureName); - /* No need to walk through all mip-map levels, since already all assigned */ - i = D3D8_BASETEXTURE(This).levels; - - } else { - if (i == 0) { - if (D3D8_TEXTURE_GET_SURFACE(This)->textureName == 0) { - glGenTextures(1, &(D3D8_TEXTURE_GET_SURFACE(This)->textureName)); - checkGLcall("glGenTextures"); - TRACE("Texture %p (level %d) given name %d\n", D3D8_TEXTURE_GET_SURFACE(This), i, D3D8_TEXTURE_GET_SURFACE(This)->textureName); - } - - glBindTexture(GL_TEXTURE_2D, D3D8_TEXTURE_GET_SURFACE(This)->textureName); - checkGLcall("glBindTexture"); - } - IWineD3DSurface_LoadTexture((IWineD3DSurface*)D3D8_TEXTURE_GET_SURFACE(This)); -/* IDirect3DSurface8Impl_LoadTexture((LPDIRECT3DSURFACE8) D3D8_TEXTURE_GET_SURFACE(This), GL_TEXTURE_2D, i); */ - } - } - - /* No longer dirty */ - D3D8_BASETEXTURE(This).dirty = FALSE; - - /* Always need to reset the number of mipmap levels when rebinding as it is - a property of the active texture unit, and another texture may have set it - to a different value */ - TRACE("Setting GL_TEXTURE_MAX_LEVEL to %d\n", D3D8_BASETEXTURE(This).levels - 1); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, D3D8_BASETEXTURE(This).levels - 1); - checkGLcall("glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, This->levels)"); - - LEAVE_GL(); - - return ; + TRACE("(%p) Relay\n", This); + return IWineD3DTexture_PreLoad(This->wineD3DTexture); } D3DRESOURCETYPE WINAPI IDirect3DTexture8Impl_GetType(LPDIRECT3DTEXTURE8 iface) { diff --git a/dlls/d3d8/utils.c b/dlls/d3d8/utils.c deleted file mode 100644 index 8cd8766607b..00000000000 --- a/dlls/d3d8/utils.c +++ /dev/null @@ -1,1845 +0,0 @@ -/* - * D3D8 utils - * - * Copyright 2002-2003 Jason Edmeades - * Raphael Junqueira - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "config.h" - -#include -#include - -#define NONAMELESSUNION -#define NONAMELESSSTRUCT -#include "windef.h" -#include "winbase.h" -#include "winuser.h" -#include "wingdi.h" -#include "wine/debug.h" - -#include "d3d8_private.h" - -WINE_DEFAULT_DEBUG_CHANNEL(d3d); - -const char* debug_d3ddevicetype(D3DDEVTYPE devtype) { - switch (devtype) { -#define DEVTYPE_TO_STR(dev) case dev: return #dev - DEVTYPE_TO_STR(D3DDEVTYPE_HAL); - DEVTYPE_TO_STR(D3DDEVTYPE_REF); - DEVTYPE_TO_STR(D3DDEVTYPE_SW); -#undef DEVTYPE_TO_STR - default: - FIXME("Unrecognized %u D3DDEVTYPE!\n", devtype); - return "unrecognized"; - } -} - -const char* debug_d3dusage(DWORD usage) { - switch (usage) { -#define D3DUSAGE_TO_STR(u) case u: return #u - D3DUSAGE_TO_STR(D3DUSAGE_RENDERTARGET); - D3DUSAGE_TO_STR(D3DUSAGE_DEPTHSTENCIL); - D3DUSAGE_TO_STR(D3DUSAGE_WRITEONLY); - D3DUSAGE_TO_STR(D3DUSAGE_SOFTWAREPROCESSING); - D3DUSAGE_TO_STR(D3DUSAGE_DONOTCLIP); - D3DUSAGE_TO_STR(D3DUSAGE_POINTS); - D3DUSAGE_TO_STR(D3DUSAGE_RTPATCHES); - D3DUSAGE_TO_STR(D3DUSAGE_NPATCHES); - D3DUSAGE_TO_STR(D3DUSAGE_DYNAMIC); -#undef D3DUSAGE_TO_STR - case 0: return "none"; - default: - FIXME("Unrecognized %lu Usage!\n", usage); - return "unrecognized"; - } -} - -const char* debug_d3dformat(D3DFORMAT fmt) { - switch (fmt) { -#define FMT_TO_STR(fmt) case fmt: return #fmt - FMT_TO_STR(D3DFMT_UNKNOWN); - FMT_TO_STR(D3DFMT_R8G8B8); - FMT_TO_STR(D3DFMT_A8R8G8B8); - FMT_TO_STR(D3DFMT_X8R8G8B8); - FMT_TO_STR(D3DFMT_R5G6B5); - FMT_TO_STR(D3DFMT_X1R5G5B5); - FMT_TO_STR(D3DFMT_A1R5G5B5); - FMT_TO_STR(D3DFMT_A4R4G4B4); - FMT_TO_STR(D3DFMT_R3G3B2); - FMT_TO_STR(D3DFMT_A8); - FMT_TO_STR(D3DFMT_A8R3G3B2); - FMT_TO_STR(D3DFMT_X4R4G4B4); - FMT_TO_STR(D3DFMT_A8P8); - FMT_TO_STR(D3DFMT_P8); - FMT_TO_STR(D3DFMT_L8); - FMT_TO_STR(D3DFMT_A8L8); - FMT_TO_STR(D3DFMT_A4L4); - FMT_TO_STR(D3DFMT_V8U8); - FMT_TO_STR(D3DFMT_L6V5U5); - FMT_TO_STR(D3DFMT_X8L8V8U8); - FMT_TO_STR(D3DFMT_Q8W8V8U8); - FMT_TO_STR(D3DFMT_V16U16); - FMT_TO_STR(D3DFMT_W11V11U10); - FMT_TO_STR(D3DFMT_UYVY); - FMT_TO_STR(D3DFMT_YUY2); - FMT_TO_STR(D3DFMT_DXT1); - FMT_TO_STR(D3DFMT_DXT2); - FMT_TO_STR(D3DFMT_DXT3); - FMT_TO_STR(D3DFMT_DXT4); - FMT_TO_STR(D3DFMT_DXT5); - FMT_TO_STR(D3DFMT_D16_LOCKABLE); - FMT_TO_STR(D3DFMT_D32); - FMT_TO_STR(D3DFMT_D15S1); - FMT_TO_STR(D3DFMT_D24S8); - FMT_TO_STR(D3DFMT_D16); - FMT_TO_STR(D3DFMT_D24X8); - FMT_TO_STR(D3DFMT_D24X4S4); - FMT_TO_STR(D3DFMT_VERTEXDATA); - FMT_TO_STR(D3DFMT_INDEX16); - FMT_TO_STR(D3DFMT_INDEX32); -#undef FMT_TO_STR - default: - FIXME("Unrecognized %u D3DFORMAT!\n", fmt); - return "unrecognized"; - } -} - -const char* debug_d3dressourcetype(D3DRESOURCETYPE res) { - switch (res) { -#define RES_TO_STR(res) case res: return #res; - RES_TO_STR(D3DRTYPE_SURFACE); - RES_TO_STR(D3DRTYPE_VOLUME); - RES_TO_STR(D3DRTYPE_TEXTURE); - RES_TO_STR(D3DRTYPE_VOLUMETEXTURE); - RES_TO_STR(D3DRTYPE_CUBETEXTURE); - RES_TO_STR(D3DRTYPE_VERTEXBUFFER); - RES_TO_STR(D3DRTYPE_INDEXBUFFER); -#undef RES_TO_STR - default: - FIXME("Unrecognized %u D3DRESOURCETYPE!\n", res); - return "unrecognized"; - } -} - -const char* debug_d3dprimitivetype(D3DPRIMITIVETYPE PrimitiveType) { - switch (PrimitiveType) { -#define PRIM_TO_STR(prim) case prim: return #prim; - PRIM_TO_STR(D3DPT_POINTLIST); - PRIM_TO_STR(D3DPT_LINELIST); - PRIM_TO_STR(D3DPT_LINESTRIP); - PRIM_TO_STR(D3DPT_TRIANGLELIST); - PRIM_TO_STR(D3DPT_TRIANGLESTRIP); - PRIM_TO_STR(D3DPT_TRIANGLEFAN); -#undef PRIM_TO_STR - default: - FIXME("Unrecognized %u D3DPRIMITIVETYPE!\n", PrimitiveType); - return "unrecognized"; - } -} - -const char* debug_d3dpool(D3DPOOL Pool) { - switch (Pool) { -#define POOL_TO_STR(p) case p: return #p; - POOL_TO_STR(D3DPOOL_DEFAULT); - POOL_TO_STR(D3DPOOL_MANAGED); - POOL_TO_STR(D3DPOOL_SYSTEMMEM); - POOL_TO_STR(D3DPOOL_SCRATCH); -#undef POOL_TO_STR - default: - FIXME("Unrecognized %u D3DPOOL!\n", Pool); - return "unrecognized"; - } -} - -const char* debug_d3drenderstate(DWORD state) { - switch (state) { -#define D3DSTATE_TO_STR(u) case u: return #u - D3DSTATE_TO_STR(D3DRS_ZENABLE ); - D3DSTATE_TO_STR(D3DRS_FILLMODE ); - D3DSTATE_TO_STR(D3DRS_SHADEMODE ); - D3DSTATE_TO_STR(D3DRS_LINEPATTERN ); - D3DSTATE_TO_STR(D3DRS_ZWRITEENABLE ); - D3DSTATE_TO_STR(D3DRS_ALPHATESTENABLE ); - D3DSTATE_TO_STR(D3DRS_LASTPIXEL ); - D3DSTATE_TO_STR(D3DRS_SRCBLEND ); - D3DSTATE_TO_STR(D3DRS_DESTBLEND ); - D3DSTATE_TO_STR(D3DRS_CULLMODE ); - D3DSTATE_TO_STR(D3DRS_ZFUNC ); - D3DSTATE_TO_STR(D3DRS_ALPHAREF ); - D3DSTATE_TO_STR(D3DRS_ALPHAFUNC ); - D3DSTATE_TO_STR(D3DRS_DITHERENABLE ); - D3DSTATE_TO_STR(D3DRS_ALPHABLENDENABLE ); - D3DSTATE_TO_STR(D3DRS_FOGENABLE ); - D3DSTATE_TO_STR(D3DRS_SPECULARENABLE ); - D3DSTATE_TO_STR(D3DRS_ZVISIBLE ); - D3DSTATE_TO_STR(D3DRS_FOGCOLOR ); - D3DSTATE_TO_STR(D3DRS_FOGTABLEMODE ); - D3DSTATE_TO_STR(D3DRS_FOGSTART ); - D3DSTATE_TO_STR(D3DRS_FOGEND ); - D3DSTATE_TO_STR(D3DRS_FOGDENSITY ); - D3DSTATE_TO_STR(D3DRS_EDGEANTIALIAS ); - D3DSTATE_TO_STR(D3DRS_ZBIAS ); - D3DSTATE_TO_STR(D3DRS_RANGEFOGENABLE ); - D3DSTATE_TO_STR(D3DRS_STENCILENABLE ); - D3DSTATE_TO_STR(D3DRS_STENCILFAIL ); - D3DSTATE_TO_STR(D3DRS_STENCILZFAIL ); - D3DSTATE_TO_STR(D3DRS_STENCILPASS ); - D3DSTATE_TO_STR(D3DRS_STENCILFUNC ); - D3DSTATE_TO_STR(D3DRS_STENCILREF ); - D3DSTATE_TO_STR(D3DRS_STENCILMASK ); - D3DSTATE_TO_STR(D3DRS_STENCILWRITEMASK ); - D3DSTATE_TO_STR(D3DRS_TEXTUREFACTOR ); - D3DSTATE_TO_STR(D3DRS_WRAP0 ); - D3DSTATE_TO_STR(D3DRS_WRAP1 ); - D3DSTATE_TO_STR(D3DRS_WRAP2 ); - D3DSTATE_TO_STR(D3DRS_WRAP3 ); - D3DSTATE_TO_STR(D3DRS_WRAP4 ); - D3DSTATE_TO_STR(D3DRS_WRAP5 ); - D3DSTATE_TO_STR(D3DRS_WRAP6 ); - D3DSTATE_TO_STR(D3DRS_WRAP7 ); - D3DSTATE_TO_STR(D3DRS_CLIPPING ); - D3DSTATE_TO_STR(D3DRS_LIGHTING ); - D3DSTATE_TO_STR(D3DRS_AMBIENT ); - D3DSTATE_TO_STR(D3DRS_FOGVERTEXMODE ); - D3DSTATE_TO_STR(D3DRS_COLORVERTEX ); - D3DSTATE_TO_STR(D3DRS_LOCALVIEWER ); - D3DSTATE_TO_STR(D3DRS_NORMALIZENORMALS ); - D3DSTATE_TO_STR(D3DRS_DIFFUSEMATERIALSOURCE ); - D3DSTATE_TO_STR(D3DRS_SPECULARMATERIALSOURCE ); - D3DSTATE_TO_STR(D3DRS_AMBIENTMATERIALSOURCE ); - D3DSTATE_TO_STR(D3DRS_EMISSIVEMATERIALSOURCE ); - D3DSTATE_TO_STR(D3DRS_VERTEXBLEND ); - D3DSTATE_TO_STR(D3DRS_CLIPPLANEENABLE ); - D3DSTATE_TO_STR(D3DRS_SOFTWAREVERTEXPROCESSING ); - D3DSTATE_TO_STR(D3DRS_POINTSIZE ); - D3DSTATE_TO_STR(D3DRS_POINTSIZE_MIN ); - D3DSTATE_TO_STR(D3DRS_POINTSPRITEENABLE ); - D3DSTATE_TO_STR(D3DRS_POINTSCALEENABLE ); - D3DSTATE_TO_STR(D3DRS_POINTSCALE_A ); - D3DSTATE_TO_STR(D3DRS_POINTSCALE_B ); - D3DSTATE_TO_STR(D3DRS_POINTSCALE_C ); - D3DSTATE_TO_STR(D3DRS_MULTISAMPLEANTIALIAS ); - D3DSTATE_TO_STR(D3DRS_MULTISAMPLEMASK ); - D3DSTATE_TO_STR(D3DRS_PATCHEDGESTYLE ); - D3DSTATE_TO_STR(D3DRS_PATCHSEGMENTS ); - D3DSTATE_TO_STR(D3DRS_DEBUGMONITORTOKEN ); - D3DSTATE_TO_STR(D3DRS_POINTSIZE_MAX ); - D3DSTATE_TO_STR(D3DRS_INDEXEDVERTEXBLENDENABLE ); - D3DSTATE_TO_STR(D3DRS_COLORWRITEENABLE ); - D3DSTATE_TO_STR(D3DRS_TWEENFACTOR ); - D3DSTATE_TO_STR(D3DRS_BLENDOP ); - D3DSTATE_TO_STR(D3DRS_POSITIONORDER ); - D3DSTATE_TO_STR(D3DRS_NORMALORDER ); -#undef D3DSTATE_TO_STR - default: - FIXME("Unrecognized %lu render state!\n", state); - return "unrecognized"; - } -} - -const char* debug_d3dtexturestate(DWORD state) { - switch (state) { -#define D3DSTATE_TO_STR(u) case u: return #u - D3DSTATE_TO_STR(D3DTSS_COLOROP ); - D3DSTATE_TO_STR(D3DTSS_COLORARG1 ); - D3DSTATE_TO_STR(D3DTSS_COLORARG2 ); - D3DSTATE_TO_STR(D3DTSS_ALPHAOP ); - D3DSTATE_TO_STR(D3DTSS_ALPHAARG1 ); - D3DSTATE_TO_STR(D3DTSS_ALPHAARG2 ); - D3DSTATE_TO_STR(D3DTSS_BUMPENVMAT00 ); - D3DSTATE_TO_STR(D3DTSS_BUMPENVMAT01 ); - D3DSTATE_TO_STR(D3DTSS_BUMPENVMAT10 ); - D3DSTATE_TO_STR(D3DTSS_BUMPENVMAT11 ); - D3DSTATE_TO_STR(D3DTSS_TEXCOORDINDEX ); - D3DSTATE_TO_STR(D3DTSS_ADDRESSU ); - D3DSTATE_TO_STR(D3DTSS_ADDRESSV ); - D3DSTATE_TO_STR(D3DTSS_BORDERCOLOR ); - D3DSTATE_TO_STR(D3DTSS_MAGFILTER ); - D3DSTATE_TO_STR(D3DTSS_MINFILTER ); - D3DSTATE_TO_STR(D3DTSS_MIPFILTER ); - D3DSTATE_TO_STR(D3DTSS_MIPMAPLODBIAS ); - D3DSTATE_TO_STR(D3DTSS_MAXMIPLEVEL ); - D3DSTATE_TO_STR(D3DTSS_MAXANISOTROPY ); - D3DSTATE_TO_STR(D3DTSS_BUMPENVLSCALE ); - D3DSTATE_TO_STR(D3DTSS_BUMPENVLOFFSET ); - D3DSTATE_TO_STR(D3DTSS_TEXTURETRANSFORMFLAGS ); - D3DSTATE_TO_STR(D3DTSS_ADDRESSW ); - D3DSTATE_TO_STR(D3DTSS_COLORARG0 ); - D3DSTATE_TO_STR(D3DTSS_ALPHAARG0 ); - D3DSTATE_TO_STR(D3DTSS_RESULTARG ); -#undef D3DSTATE_TO_STR - case 12: - /* Note D3DTSS are not consecutive, so skip these */ - return "unused"; - default: - FIXME("Unrecognized %lu texture state!\n", state); - return "unrecognized"; - } -} - -/* - * Simple utility routines used for dx -> gl mapping of byte formats - */ -int D3DPrimitiveListGetVertexSize(D3DPRIMITIVETYPE PrimitiveType, int iNumPrim) { - switch (PrimitiveType) { - case D3DPT_POINTLIST: return iNumPrim; - case D3DPT_LINELIST: return iNumPrim * 2; - case D3DPT_LINESTRIP: return iNumPrim + 1; - case D3DPT_TRIANGLELIST: return iNumPrim * 3; - case D3DPT_TRIANGLESTRIP: return iNumPrim + 2; - case D3DPT_TRIANGLEFAN: return iNumPrim + 2; - default: - FIXME("Unrecognized %u D3DPRIMITIVETYPE!\n", PrimitiveType); - return 0; - } -} - -int D3DPrimitive2GLenum(D3DPRIMITIVETYPE PrimitiveType) { - switch (PrimitiveType) { - case D3DPT_POINTLIST: return GL_POINTS; - case D3DPT_LINELIST: return GL_LINES; - case D3DPT_LINESTRIP: return GL_LINE_STRIP; - case D3DPT_TRIANGLELIST: return GL_TRIANGLES; - case D3DPT_TRIANGLESTRIP: return GL_TRIANGLE_STRIP; - case D3DPT_TRIANGLEFAN: return GL_TRIANGLE_FAN; - default: - FIXME("Unrecognized %u D3DPRIMITIVETYPE!\n", PrimitiveType); - return GL_POLYGON; - } -} - -int D3DFVFGetSize(D3DFORMAT fvf) { - int ret = 0; - if (fvf & D3DFVF_XYZ) ret += 3 * sizeof(float); - else if (fvf & D3DFVF_XYZRHW) ret += 4 * sizeof(float); - if (fvf & D3DFVF_NORMAL) ret += 3 * sizeof(float); - if (fvf & D3DFVF_PSIZE) ret += sizeof(float); - if (fvf & D3DFVF_DIFFUSE) ret += sizeof(DWORD); - if (fvf & D3DFVF_SPECULAR) ret += sizeof(DWORD); - /*if (fvf & D3DFVF_TEX1) ret += 1;*/ - return ret; -} - -GLenum D3DFmt2GLDepthFmt(D3DFORMAT fmt) { - switch (fmt) { - /* depth/stencil buffer */ - case D3DFMT_D16_LOCKABLE: - case D3DFMT_D16: - case D3DFMT_D15S1: - case D3DFMT_D24X4S4: - case D3DFMT_D24S8: - case D3DFMT_D24X8: - case D3DFMT_D32: - return GL_DEPTH_COMPONENT; - default: - FIXME("Unhandled fmt(%u,%s)\n", fmt, debug_d3dformat(fmt)); - } - return 0; -} - -GLenum D3DFmt2GLDepthType(D3DFORMAT fmt) { - switch (fmt) { - /* depth/stencil buffer */ - case D3DFMT_D15S1: - case D3DFMT_D16_LOCKABLE: - case D3DFMT_D16: - return GL_UNSIGNED_SHORT; - case D3DFMT_D24X4S4: - case D3DFMT_D24S8: - case D3DFMT_D24X8: - case D3DFMT_D32: - return GL_UNSIGNED_INT; - default: - FIXME("Unhandled fmt(%u,%s)\n", fmt, debug_d3dformat(fmt)); - } - return 0; -} - -SHORT D3DFmtGetBpp(IDirect3DDevice8Impl* This, D3DFORMAT fmt) { - SHORT retVal; - - switch (fmt) { - /* color buffer */ - case D3DFMT_R3G3B2: retVal = 1; break; - case D3DFMT_R5G6B5: retVal = 2; break; - case D3DFMT_R8G8B8: retVal = 3; break; - case D3DFMT_A1R5G5B5: retVal = 2; break; - case D3DFMT_X1R5G5B5: retVal = 2; break; - case D3DFMT_A4R4G4B4: retVal = 2; break; - case D3DFMT_X4R4G4B4: retVal = 2; break; - case D3DFMT_A8R8G8B8: retVal = 4; break; - case D3DFMT_X8R8G8B8: retVal = 4; break; - /* Paletted */ - case D3DFMT_P8: retVal = 1; break; - case D3DFMT_A8P8: retVal = 2; break; - /* depth/stencil buffer */ - case D3DFMT_D16_LOCKABLE: retVal = 2; break; - case D3DFMT_D16: retVal = 2; break; - case D3DFMT_D32: retVal = 4; break; - case D3DFMT_D15S1: retVal = 2; break; - case D3DFMT_D24X4S4: retVal = 4; break; - case D3DFMT_D24S8: retVal = 4; break; - case D3DFMT_D24X8: retVal = 4; break; - /* Luminance */ - case D3DFMT_L8: retVal = 1; break; - case D3DFMT_A4L4: retVal = 1; break; - case D3DFMT_A8L8: retVal = 2; break; - /* Bump */ - case D3DFMT_V8U8: retVal = 2; break; - case D3DFMT_L6V5U5: retVal = 2; break; - case D3DFMT_V16U16: retVal = 4; break; - case D3DFMT_X8L8V8U8: retVal = 4; break; - /* Compressed */ - case D3DFMT_DXT1: retVal = 1; break; /* Actually 8 bytes per 16 pixels - Special cased later */ - case D3DFMT_DXT2: retVal = 1; break; /* Actually 16 bytes per 16 pixels */ - case D3DFMT_DXT3: retVal = 1; break; /* Actually 16 bytes per 16 pixels */ - case D3DFMT_DXT4: retVal = 1; break; /* Actually 16 bytes per 16 pixels */ - case D3DFMT_DXT5: retVal = 1; break; /* Actually 16 bytes per 16 pixels */ - /* to see */ - case D3DFMT_A8: retVal = 1; break; - /* unknown */ - case D3DFMT_UNKNOWN: - /* Guess at the highest value of the above */ - TRACE("D3DFMT_UNKNOWN - Guessing at 4 bytes/pixel %u\n", fmt); - retVal = 4; - break; - - default: - FIXME("Unhandled fmt(%u,%s)\n", fmt, debug_d3dformat(fmt)); - retVal = 4; - } - TRACE("bytes/Pxl for fmt(%u,%s) = %d\n", fmt, debug_d3dformat(fmt), retVal); - return retVal; -} - -GLint D3DFmt2GLIntFmt(IDirect3DDevice8Impl* This, D3DFORMAT fmt) { - GLint retVal = 0; - - if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) { - switch (fmt) { - case D3DFMT_DXT1: retVal = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; break; - case D3DFMT_DXT2: retVal = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; break; - case D3DFMT_DXT3: retVal = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; break; - case D3DFMT_DXT4: retVal = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break; - case D3DFMT_DXT5: retVal = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break; - default: - /* stupid compiler */ - break; - } - } - - if (retVal == 0) { - switch (fmt) { - /* Paletted */ - case D3DFMT_P8: retVal = GL_COLOR_INDEX8_EXT; break; - case D3DFMT_A8P8: retVal = GL_COLOR_INDEX8_EXT; break; - /* Luminance */ - case D3DFMT_L8: retVal = GL_LUMINANCE8; break; - case D3DFMT_A8L8: retVal = GL_LUMINANCE8_ALPHA8; break; - case D3DFMT_A4L4: retVal = GL_LUMINANCE4_ALPHA4; break; - /* Bump */ - case D3DFMT_V8U8: retVal = GL_COLOR_INDEX8_EXT; break; - case D3DFMT_V16U16: retVal = GL_COLOR_INDEX; break; - case D3DFMT_L6V5U5: retVal = GL_COLOR_INDEX8_EXT; break; - case D3DFMT_X8L8V8U8: retVal = GL_COLOR_INDEX; break; - /* color buffer */ - case D3DFMT_R3G3B2: retVal = GL_R3_G3_B2; break; - case D3DFMT_R5G6B5: retVal = GL_RGB5; break; /* fixme: internal format 6 for g? */ - case D3DFMT_R8G8B8: retVal = GL_RGB8; break; - case D3DFMT_A1R5G5B5: retVal = GL_RGB5_A1; break; - case D3DFMT_X1R5G5B5: retVal = GL_RGB5_A1; break; - case D3DFMT_A4R4G4B4: retVal = GL_RGBA4; break; - case D3DFMT_X4R4G4B4: retVal = GL_RGBA4; break; - case D3DFMT_A8R8G8B8: retVal = GL_RGBA8; break; - case D3DFMT_X8R8G8B8: retVal = GL_RGBA8; break; - /* to see */ - case D3DFMT_A8: retVal = GL_ALPHA8; break; - default: - FIXME("Unhandled fmt(%u,%s)\n", fmt, debug_d3dformat(fmt)); - retVal = GL_RGB8; - } - } - TRACE("fmt2glintFmt for fmt(%u,%s) = %x\n", fmt, debug_d3dformat(fmt), retVal); - return retVal; -} - -GLenum D3DFmt2GLFmt(IDirect3DDevice8Impl* This, D3DFORMAT fmt) { - GLenum retVal = 0; - - if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) { - switch (fmt) { - case D3DFMT_DXT1: retVal = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; break; - case D3DFMT_DXT2: retVal = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; break; - case D3DFMT_DXT3: retVal = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; break; - case D3DFMT_DXT4: retVal = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break; - case D3DFMT_DXT5: retVal = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break; - default: - /* stupid compiler */ - break; - } - } - - if (retVal == 0) { - switch (fmt) { - /* Paletted */ - case D3DFMT_P8: retVal = GL_COLOR_INDEX; break; - case D3DFMT_A8P8: retVal = GL_COLOR_INDEX; break; - /* Luminance */ - case D3DFMT_L8: retVal = GL_LUMINANCE; break; - case D3DFMT_A8L8: retVal = GL_LUMINANCE_ALPHA; break; - case D3DFMT_A4L4: retVal = GL_LUMINANCE_ALPHA; break; - /* Bump */ - case D3DFMT_V8U8: retVal = GL_COLOR_INDEX; break; - case D3DFMT_V16U16: retVal = GL_COLOR_INDEX; break; - case D3DFMT_L6V5U5: retVal = GL_COLOR_INDEX; break; - case D3DFMT_X8L8V8U8: retVal = GL_COLOR_INDEX; break; - /* color buffer */ - case D3DFMT_R3G3B2: retVal = GL_BGR; break; - case D3DFMT_R5G6B5: retVal = GL_RGB; break; - case D3DFMT_R8G8B8: retVal = GL_RGB; break; - case D3DFMT_A1R5G5B5: retVal = GL_BGRA; break; - case D3DFMT_X1R5G5B5: retVal = GL_BGRA; break; - case D3DFMT_A4R4G4B4: retVal = GL_BGRA; break; - case D3DFMT_X4R4G4B4: retVal = GL_BGRA; break; - case D3DFMT_A8R8G8B8: retVal = GL_BGRA; break; - case D3DFMT_X8R8G8B8: retVal = GL_BGRA; break; - /* to see */ - case D3DFMT_A8: retVal = GL_ALPHA; break; - default: - FIXME("Unhandled fmt(%u,%s)\n", fmt, debug_d3dformat(fmt)); - retVal = GL_BGR; - } - } - - TRACE("fmt2glFmt for fmt(%u,%s) = %x\n", fmt, debug_d3dformat(fmt), retVal); - return retVal; -} - -GLenum D3DFmt2GLType(IDirect3DDevice8Impl* This, D3DFORMAT fmt) { - GLenum retVal = 0; - - if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) { - switch (fmt) { - case D3DFMT_DXT1: retVal = 0; break; - case D3DFMT_DXT2: retVal = 0; break; - case D3DFMT_DXT3: retVal = 0; break; - case D3DFMT_DXT4: retVal = 0; break; - case D3DFMT_DXT5: retVal = 0; break; - default: - /* stupid compiler */ - break; - } - } - - if (retVal == 0) { - switch (fmt) { - /* Paletted */ - case D3DFMT_P8: retVal = GL_UNSIGNED_BYTE; break; - case D3DFMT_A8P8: retVal = GL_UNSIGNED_BYTE; break; - /* Luminance */ - case D3DFMT_L8: retVal = GL_UNSIGNED_BYTE; break; - case D3DFMT_A8L8: retVal = GL_UNSIGNED_BYTE; break; - case D3DFMT_A4L4: retVal = GL_UNSIGNED_BYTE; break; - /* Bump */ - case D3DFMT_V8U8: retVal = GL_UNSIGNED_BYTE; break; - case D3DFMT_V16U16: retVal = GL_UNSIGNED_SHORT; break; - case D3DFMT_L6V5U5: retVal = GL_UNSIGNED_SHORT_5_5_5_1; break; - case D3DFMT_X8L8V8U8: retVal = GL_UNSIGNED_BYTE; break; - /* Color buffer */ - case D3DFMT_R3G3B2: retVal = GL_UNSIGNED_BYTE_2_3_3_REV; break; - case D3DFMT_R5G6B5: retVal = GL_UNSIGNED_SHORT_5_6_5; break; - case D3DFMT_R8G8B8: retVal = GL_UNSIGNED_BYTE; break; - case D3DFMT_A1R5G5B5: retVal = GL_UNSIGNED_SHORT_1_5_5_5_REV; break; - case D3DFMT_X1R5G5B5: retVal = GL_UNSIGNED_SHORT_1_5_5_5_REV; break; - case D3DFMT_A4R4G4B4: retVal = GL_UNSIGNED_SHORT_4_4_4_4_REV; break; - case D3DFMT_X4R4G4B4: retVal = GL_UNSIGNED_SHORT_4_4_4_4_REV; break; - case D3DFMT_A8R8G8B8: retVal = GL_UNSIGNED_INT_8_8_8_8_REV; break; - case D3DFMT_X8R8G8B8: retVal = GL_UNSIGNED_INT_8_8_8_8_REV; break; - /* to see */ - case D3DFMT_A8: retVal = GL_ALPHA; break; - default: - FIXME("Unhandled fmt(%u,%s)\n", fmt, debug_d3dformat(fmt)); - retVal = GL_UNSIGNED_BYTE; - } - } - - TRACE("fmt2glType for fmt(%u,%s) = %x\n", fmt, debug_d3dformat(fmt), retVal); - return retVal; -} - -int SOURCEx_RGB_EXT(DWORD arg) { - switch(arg) { - case D3DTSS_COLORARG0: return GL_SOURCE2_RGB_EXT; - case D3DTSS_COLORARG1: return GL_SOURCE0_RGB_EXT; - case D3DTSS_COLORARG2: return GL_SOURCE1_RGB_EXT; - case D3DTSS_ALPHAARG0: - case D3DTSS_ALPHAARG1: - case D3DTSS_ALPHAARG2: - default: - FIXME("Invalid arg %ld\n", arg); - return GL_SOURCE0_RGB_EXT; - } -} - -int OPERANDx_RGB_EXT(DWORD arg) { - switch(arg) { - case D3DTSS_COLORARG0: return GL_OPERAND2_RGB_EXT; - case D3DTSS_COLORARG1: return GL_OPERAND0_RGB_EXT; - case D3DTSS_COLORARG2: return GL_OPERAND1_RGB_EXT; - case D3DTSS_ALPHAARG0: - case D3DTSS_ALPHAARG1: - case D3DTSS_ALPHAARG2: - default: - FIXME("Invalid arg %ld\n", arg); - return GL_OPERAND0_RGB_EXT; - } -} - -int SOURCEx_ALPHA_EXT(DWORD arg) { - switch(arg) { - case D3DTSS_ALPHAARG0: return GL_SOURCE2_ALPHA_EXT; - case D3DTSS_ALPHAARG1: return GL_SOURCE0_ALPHA_EXT; - case D3DTSS_ALPHAARG2: return GL_SOURCE1_ALPHA_EXT; - case D3DTSS_COLORARG0: - case D3DTSS_COLORARG1: - case D3DTSS_COLORARG2: - default: - FIXME("Invalid arg %ld\n", arg); - return GL_SOURCE0_ALPHA_EXT; - } -} - -int OPERANDx_ALPHA_EXT(DWORD arg) { - switch(arg) { - case D3DTSS_ALPHAARG0: return GL_OPERAND2_ALPHA_EXT; - case D3DTSS_ALPHAARG1: return GL_OPERAND0_ALPHA_EXT; - case D3DTSS_ALPHAARG2: return GL_OPERAND1_ALPHA_EXT; - case D3DTSS_COLORARG0: - case D3DTSS_COLORARG1: - case D3DTSS_COLORARG2: - default: - FIXME("Invalid arg %ld\n", arg); - return GL_OPERAND0_ALPHA_EXT; - } -} - -GLenum StencilOp(DWORD op) { - switch(op) { - case D3DSTENCILOP_KEEP : return GL_KEEP; - case D3DSTENCILOP_ZERO : return GL_ZERO; - case D3DSTENCILOP_REPLACE : return GL_REPLACE; - case D3DSTENCILOP_INCRSAT : return GL_INCR; - case D3DSTENCILOP_DECRSAT : return GL_DECR; - case D3DSTENCILOP_INVERT : return GL_INVERT; - case D3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT; - case D3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT; - default: - FIXME("Invalid stencil op %ld\n", op); - return GL_ALWAYS; - } -} - -/** - * @nodoc: todo - */ -void GetSrcAndOpFromValue(DWORD iValue, BOOL isAlphaArg, GLenum* source, GLenum* operand) -{ - BOOL isAlphaReplicate = FALSE; - BOOL isComplement = FALSE; - - *operand = GL_SRC_COLOR; - *source = GL_TEXTURE; - - /* Catch alpha replicate */ - if (iValue & D3DTA_ALPHAREPLICATE) { - iValue = iValue & ~D3DTA_ALPHAREPLICATE; - isAlphaReplicate = TRUE; - } - - /* Catch Complement */ - if (iValue & D3DTA_COMPLEMENT) { - iValue = iValue & ~D3DTA_COMPLEMENT; - isComplement = TRUE; - } - - /* Calculate the operand */ - if (isAlphaReplicate && !isComplement) { - *operand = GL_SRC_ALPHA; - } else if (isAlphaReplicate && isComplement) { - *operand = GL_ONE_MINUS_SRC_ALPHA; - } else if (isComplement) { - if (isAlphaArg) { - *operand = GL_ONE_MINUS_SRC_ALPHA; - } else { - *operand = GL_ONE_MINUS_SRC_COLOR; - } - } else { - if (isAlphaArg) { - *operand = GL_SRC_ALPHA; - } else { - *operand = GL_SRC_COLOR; - } - } - - /* Calculate the source */ - switch (iValue & D3DTA_SELECTMASK) { - case D3DTA_CURRENT: *source = GL_PREVIOUS_EXT; - break; - case D3DTA_DIFFUSE: *source = GL_PRIMARY_COLOR_EXT; - break; - case D3DTA_TEXTURE: *source = GL_TEXTURE; - break; - case D3DTA_TFACTOR: *source = GL_CONSTANT_EXT; - break; - case D3DTA_SPECULAR: - /* - * According to the GL_ARB_texture_env_combine specs, SPECULAR is - * 'Secondary color' and isn't supported until base GL supports it - * There is no concept of temp registers as far as I can tell - */ - FIXME("Unhandled texture arg D3DTA_SPECULAR\n"); - *source = GL_TEXTURE; - break; - - default: - FIXME("Unrecognized texture arg %ld\n", iValue); - *source = GL_TEXTURE; - } -} - - -/* Set texture operations up - The following avoids lots of ifdefs in this routine!*/ -#if defined (GL_VERSION_1_3) -# define useext(A) A -# define combine_ext 1 -#elif defined (GL_EXT_texture_env_combine) -# define useext(A) A##_EXT -# define combine_ext 1 -#elif defined (GL_ARB_texture_env_combine) -# define useext(A) A##_ARB -# define combine_ext 1 -#else -# undef combine_ext -#endif - -#if !defined(combine_ext) -void set_tex_op(LPDIRECT3DDEVICE8 iface, BOOL isAlpha, int Stage, D3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) -{ - FIXME("Requires opengl combine extensions to work\n"); - return; -} -#else -/* Setup the texture operations texture stage states */ -void set_tex_op(LPDIRECT3DDEVICE8 iface, BOOL isAlpha, int Stage, D3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) -{ - GLenum src1, src2, src3; - GLenum opr1, opr2, opr3; - GLenum comb_target; - GLenum src0_target, src1_target, src2_target; - GLenum opr0_target, opr1_target, opr2_target; - GLenum scal_target; - GLenum opr=0, invopr, src3_target, opr3_target; - BOOL Handled = FALSE; - IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - - TRACE("Alpha?(%d), Stage:%d Op(%d), a1(%ld), a2(%ld), a3(%ld)\n", isAlpha, Stage, op, arg1, arg2, arg3); - - ENTER_GL(); - - /* Note: Operations usually involve two ars, src0 and src1 and are operations of - the form (a1 a2). However, some of the more complex operations - take 3 parameters. Instead of the (sensible) addition of a3, Microsoft added - in a third parameter called a0. Therefore these are operations of the form - a0 a1 a2, ie the new parameter goes to the front. - - However, below we treat the new (a0) parameter as src2/opr2, so in the actual - functions below, expect their syntax to differ slightly to those listed in the - manuals, ie replace arg1 with arg3, arg2 with arg1 and arg3 with arg2 - This affects D3DTOP_MULTIPLYADD and D3DTOP_LERP */ - - if (isAlpha) { - comb_target = useext(GL_COMBINE_ALPHA); - src0_target = useext(GL_SOURCE0_ALPHA); - src1_target = useext(GL_SOURCE1_ALPHA); - src2_target = useext(GL_SOURCE2_ALPHA); - opr0_target = useext(GL_OPERAND0_ALPHA); - opr1_target = useext(GL_OPERAND1_ALPHA); - opr2_target = useext(GL_OPERAND2_ALPHA); - scal_target = GL_ALPHA_SCALE; - } - else { - comb_target = useext(GL_COMBINE_RGB); - src0_target = useext(GL_SOURCE0_RGB); - src1_target = useext(GL_SOURCE1_RGB); - src2_target = useext(GL_SOURCE2_RGB); - opr0_target = useext(GL_OPERAND0_RGB); - opr1_target = useext(GL_OPERAND1_RGB); - opr2_target = useext(GL_OPERAND2_RGB); - scal_target = useext(GL_RGB_SCALE); - } - - /* From MSDN (D3DTSS_ALPHAARG1) : - The default argument is D3DTA_TEXTURE. If no texture is set for this stage, - then the default argument is D3DTA_DIFFUSE. - FIXME? If texture added/removed, may need to reset back as well? */ - if (isAlpha && This->StateBlock->textures[Stage] == NULL && arg1 == D3DTA_TEXTURE) { - GetSrcAndOpFromValue(D3DTA_DIFFUSE, isAlpha, &src1, &opr1); - } else { - GetSrcAndOpFromValue(arg1, isAlpha, &src1, &opr1); - } - GetSrcAndOpFromValue(arg2, isAlpha, &src2, &opr2); - GetSrcAndOpFromValue(arg3, isAlpha, &src3, &opr3); - - TRACE("ct(%x), 1:(%x,%x), 2:(%x,%x), 3:(%x,%x)\n", comb_target, src1, opr1, src2, opr2, src3, opr3); - - Handled = TRUE; /* Assume will be handled */ - - /* Other texture operations require special extensions: */ - if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) { - if (isAlpha) { - opr = GL_SRC_ALPHA; - invopr = GL_ONE_MINUS_SRC_ALPHA; - src3_target = GL_SOURCE3_ALPHA_NV; - opr3_target = GL_OPERAND3_ALPHA_NV; - } else { - opr = GL_SRC_COLOR; - invopr = GL_ONE_MINUS_SRC_COLOR; - src3_target = GL_SOURCE3_RGB_NV; - opr3_target = GL_OPERAND3_RGB_NV; - } - switch (op) { - case D3DTOP_DISABLE: /* Only for alpha */ - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr3_target, opr"); - break; - case D3DTOP_SELECTARG1: /* = a1 * 1 + 0 * 0 */ - case D3DTOP_SELECTARG2: /* = a2 * 1 + 0 * 0 */ - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); - if (op == D3DTOP_SELECTARG1) { - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - } else { - glTexEnvi(GL_TEXTURE_ENV, src0_target, src2); - checkGLcall("GL_TEXTURE_ENV, src0_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2"); - } - glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr3_target, opr"); - break; - - case D3DTOP_MODULATE: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */ - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case D3DTOP_MODULATE2X: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */ - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 2); - checkGLcall("GL_TEXTURE_ENV, scal_target, 2"); - break; - case D3DTOP_MODULATE4X: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */ - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 4); - checkGLcall("GL_TEXTURE_ENV, scal_target, 4"); - break; - - case D3DTOP_ADD: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - - case D3DTOP_ADDSIGNED: - glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)); - checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - - case D3DTOP_ADDSIGNED2X: - glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)); - checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 2); - checkGLcall("GL_TEXTURE_ENV, scal_target, 2"); - break; - - case D3DTOP_ADDSMOOTH: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, src1); - checkGLcall("GL_TEXTURE_ENV, src3_target, src1"); - switch (opr1) { - case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break; - case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break; - case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break; - } - glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr3_target, opr"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - - case D3DTOP_BLENDDIFFUSEALPHA: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, useext(GL_PRIMARY_COLOR)); - checkGLcall("GL_TEXTURE_ENV, src1_target, useext(GL_PRIMARY_COLOR)"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, useext(GL_PRIMARY_COLOR)); - checkGLcall("GL_TEXTURE_ENV, src3_target, useext(GL_PRIMARY_COLOR)"); - glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA); - checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case D3DTOP_BLENDTEXTUREALPHA: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_TEXTURE); - checkGLcall("GL_TEXTURE_ENV, src1_target, GL_TEXTURE"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE); - checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE"); - glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA); - checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case D3DTOP_BLENDFACTORALPHA: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, useext(GL_CONSTANT)); - checkGLcall("GL_TEXTURE_ENV, src1_target, useext(GL_CONSTANT)"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, useext(GL_CONSTANT)); - checkGLcall("GL_TEXTURE_ENV, src3_target, useext(GL_CONSTANT)"); - glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA); - checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case D3DTOP_BLENDTEXTUREALPHAPM: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE); - checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE"); - glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA); - checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case D3DTOP_MODULATEALPHA_ADDCOLOR: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */ - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); /* a0 = src1/opr1 */ - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); /* a1 = 1 (see docs) */ - glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); /* a2 = arg2 */ - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); /* a3 = src1 alpha */ - glTexEnvi(GL_TEXTURE_ENV, src3_target, src1); - checkGLcall("GL_TEXTURE_ENV, src3_target, src1"); - switch (opr) { - case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break; - } - glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr3_target, opr"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case D3DTOP_MODULATECOLOR_ADDALPHA: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src1); - checkGLcall("GL_TEXTURE_ENV, src2_target, src1"); - switch (opr1) { - case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break; - } - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case D3DTOP_MODULATEINVALPHA_ADDCOLOR: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, src1); - checkGLcall("GL_TEXTURE_ENV, src3_target, src1"); - switch (opr1) { - case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break; - case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break; - } - glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr3_target, opr"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case D3DTOP_MODULATEINVCOLOR_ADDALPHA: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - switch (opr1) { - case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break; - case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break; - case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break; - } - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src1); - checkGLcall("GL_TEXTURE_ENV, src2_target, src1"); - switch (opr1) { - case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break; - } - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case D3DTOP_MULTIPLYADD: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src3); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src1); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, src2); - checkGLcall("GL_TEXTURE_ENV, src3_target, src3"); - glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr3_target, opr3"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - - case D3DTOP_BUMPENVMAP: - { - if (GL_SUPPORT(NV_TEXTURE_SHADER)) { - /* - texture unit 0: GL_TEXTURE_2D - texture unit 1: GL_DOT_PRODUCT_NV - texture unit 2: GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV - texture unit 3: GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV - */ - float m[2][2]; - - union { - float f; - DWORD d; - } tmpvalue; - - tmpvalue.d = This->StateBlock->texture_state[Stage][D3DTSS_BUMPENVMAT00]; - m[0][0] = tmpvalue.f; - tmpvalue.d = This->StateBlock->texture_state[Stage][D3DTSS_BUMPENVMAT01]; - m[0][1] = tmpvalue.f; - tmpvalue.d = This->StateBlock->texture_state[Stage][D3DTSS_BUMPENVMAT10]; - m[1][0] = tmpvalue.f; - tmpvalue.d = This->StateBlock->texture_state[Stage][D3DTSS_BUMPENVMAT11]; - m[1][1] = tmpvalue.f; - - /*FIXME("Stage %d matrix is (%.2f,%.2f),(%.2f,%.2f)\n", Stage, m[0][0], m[0][1], m[1][0], m[1][0]);*/ - - if (FALSE == This->texture_shader_active) { - This->texture_shader_active = TRUE; - glEnable(GL_TEXTURE_SHADER_NV); - } - - /* - glEnable(GL_REGISTER_COMBINERS_NV); - glCombinerParameteriNV (GL_NUM_GENERAL_COMBINERS_NV, 1); - glCombinerInputNV (GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_A_NV, GL_TEXTURE0_ARB, GL_SIGNED_IDENTITY_NV, GL_RGB); - glCombinerInputNV (GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_B_NV, GL_NONE, GL_UNSIGNED_INVERT_NV, GL_RGB); - glCombinerInputNV (GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_C_NV, GL_TEXTURE2_ARB, GL_SIGNED_IDENTITY_NV, GL_RGB); - glCombinerInputNV (GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_D_NV, GL_NONE, GL_UNSIGNED_INVERT_NV, GL_RGB); - glCombinerOutputNV (GL_COMBINER0_NV, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, GL_PRIMARY_COLOR_NV, 0, 0, 0, 0, 0); - glCombinerInputNV (GL_COMBINER0_NV, GL_ALPHA, GL_VARIABLE_A_NV, GL_TEXTURE0_ARB, GL_SIGNED_IDENTITY_NV, GL_ALPHA); - glCombinerInputNV (GL_COMBINER0_NV, GL_ALPHA, GL_VARIABLE_B_NV, GL_NONE, GL_UNSIGNED_INVERT_NV, GL_ALPHA); - glCombinerInputNV (GL_COMBINER0_NV, GL_ALPHA, GL_VARIABLE_C_NV, GL_TEXTURE2_ARB, GL_SIGNED_IDENTITY_NV, GL_ALPHA); - glCombinerInputNV (GL_COMBINER0_NV, GL_ALPHA, GL_VARIABLE_D_NV, GL_NONE, GL_UNSIGNED_INVERT_NV, GL_ALPHA); - glCombinerOutputNV (GL_COMBINER0_NV, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, GL_PRIMARY_COLOR_NV, 0, 0, 0, 0, 0); - glDisable (GL_PER_STAGE_CONSTANTS_NV); - glCombinerParameteriNV (GL_COLOR_SUM_CLAMP_NV, 0); - glFinalCombinerInputNV (GL_VARIABLE_A_NV, 0, GL_UNSIGNED_IDENTITY_NV, GL_RGB); - glFinalCombinerInputNV (GL_VARIABLE_B_NV, 0, GL_UNSIGNED_IDENTITY_NV, GL_RGB); - glFinalCombinerInputNV (GL_VARIABLE_C_NV, 0, GL_UNSIGNED_IDENTITY_NV, GL_RGB); - glFinalCombinerInputNV (GL_VARIABLE_D_NV, GL_PRIMARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB); - glFinalCombinerInputNV (GL_VARIABLE_E_NV, 0, GL_UNSIGNED_IDENTITY_NV, GL_RGB); - glFinalCombinerInputNV (GL_VARIABLE_F_NV, 0, GL_UNSIGNED_IDENTITY_NV, GL_RGB); - glFinalCombinerInputNV (GL_VARIABLE_G_NV, GL_PRIMARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA); - */ - /* - int i; - for (i = 0; i < Stage; i++) { - if (GL_SUPPORT(ARB_MULTITEXTURE)) { - glActiveTexture(GL_TEXTURE0 + i); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_2D); - checkGLcall("Activate texture.."); - } else if (i>0) { - FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n"); - } - } - */ - /* - glActiveTextureARB(GL_TEXTURE0_ARB + Stage - 1); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_2D); - */ - /* - glActiveTextureARB(GL_TEXTURE0_ARB + Stage); - checkGLcall("Activate texture.. to update const color"); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_OFFSET_TEXTURE_2D_NV); - checkGLcall("glTexEnv"); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + Stage - 1); - checkGLcall("glTexEnv"); - glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_MATRIX_NV, (float*)&m[0]); - checkGLcall("glTexEnv"); - */ - LEAVE_GL(); - return; - } - } - - case D3DTOP_BUMPENVMAPLUMINANCE: - - default: - Handled = FALSE; - } - if (Handled) { - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV); - checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV"); - - LEAVE_GL(); - return; - } - } /* GL_NV_texture_env_combine4 */ - - Handled = TRUE; /* Again, assume handled */ - switch (op) { - case D3DTOP_DISABLE: /* Only for alpha */ - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT); - checkGLcall("GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA); - checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case D3DTOP_SELECTARG1: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case D3DTOP_SELECTARG2: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src2); - checkGLcall("GL_TEXTURE_ENV, src0_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case D3DTOP_MODULATE: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case D3DTOP_MODULATE2X: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 2); - checkGLcall("GL_TEXTURE_ENV, scal_target, 2"); - break; - case D3DTOP_MODULATE4X: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 4); - checkGLcall("GL_TEXTURE_ENV, scal_target, 4"); - break; - case D3DTOP_ADD: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case D3DTOP_ADDSIGNED: - glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)); - checkGLcall("GL_TEXTURE_ENV, comb_target, useext((GL_ADD_SIGNED)"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case D3DTOP_ADDSIGNED2X: - glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)); - checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 2); - checkGLcall("GL_TEXTURE_ENV, scal_target, 2"); - break; - case D3DTOP_SUBTRACT: - if (GL_SUPPORT(ARB_TEXTURE_ENV_COMBINE)) { - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_SUBTRACT); - checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_SUBTRACT)"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - } else { - FIXME("This version of opengl does not support GL_SUBTRACT\n"); - } - break; - - case D3DTOP_BLENDDIFFUSEALPHA: - glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)); - checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PRIMARY_COLOR)); - checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA); - checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case D3DTOP_BLENDTEXTUREALPHA: - glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)); - checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_TEXTURE); - checkGLcall("GL_TEXTURE_ENV, src2_target, GL_TEXTURE"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA); - checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case D3DTOP_BLENDFACTORALPHA: - glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)); - checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_CONSTANT)); - checkGLcall("GL_TEXTURE_ENV, src2_target, GL_CONSTANT"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA); - checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case D3DTOP_BLENDCURRENTALPHA: - glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)); - checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PREVIOUS)); - checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PREVIOUS"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA); - checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case D3DTOP_DOTPRODUCT3: - if (GL_SUPPORT(ARB_TEXTURE_ENV_DOT3)) { - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB"); - } else if (GL_SUPPORT(EXT_TEXTURE_ENV_DOT3)) { - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT"); - } else { - FIXME("This version of opengl does not support GL_DOT3\n"); - } - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case D3DTOP_LERP: - glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)); - checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src3); - checkGLcall("GL_TEXTURE_ENV, src2_target, src3"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr3); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr3"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case D3DTOP_ADDSMOOTH: - if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) { - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - switch (opr1) { - case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break; - case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break; - case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break; - } - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src1); - checkGLcall("GL_TEXTURE_ENV, src1_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - } else - Handled = FALSE; - break; - case D3DTOP_BLENDTEXTUREALPHAPM: - if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) { - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_TEXTURE); - checkGLcall("GL_TEXTURE_ENV, src0_target, GL_TEXTURE"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_ALPHA); - checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_APHA"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src1); - checkGLcall("GL_TEXTURE_ENV, src1_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - } else - Handled = FALSE; - break; - case D3DTOP_MODULATEALPHA_ADDCOLOR: - if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) { - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - switch (opr1) { - case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break; - case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break; - } - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src1); - checkGLcall("GL_TEXTURE_ENV, src1_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - } else - Handled = FALSE; - break; - case D3DTOP_MODULATECOLOR_ADDALPHA: - if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) { - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src1); - checkGLcall("GL_TEXTURE_ENV, src1_target, src1"); - switch (opr1) { - case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break; - case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break; - } - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - } else - Handled = FALSE; - break; - case D3DTOP_MODULATEINVALPHA_ADDCOLOR: - if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) { - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - switch (opr1) { - case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break; - case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break; - } - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src1); - checkGLcall("GL_TEXTURE_ENV, src1_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - } else - Handled = FALSE; - break; - case D3DTOP_MODULATEINVCOLOR_ADDALPHA: - if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) { - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - switch (opr1) { - case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break; - case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break; - case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break; - } - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src1); - checkGLcall("GL_TEXTURE_ENV, src1_target, src1"); - switch (opr1) { - case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break; - case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break; - } - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - } else - Handled = FALSE; - break; - case D3DTOP_MULTIPLYADD: - if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) { - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src3); - checkGLcall("GL_TEXTURE_ENV, src0_target, src3"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr3"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src1); - checkGLcall("GL_TEXTURE_ENV, src1_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - } else - Handled = FALSE; - break; - default: - Handled = FALSE; - } - - if (Handled) { - BOOL combineOK = TRUE; - if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) { - DWORD op2; - - if (isAlpha) { - op2 = This->UpdateStateBlock->texture_state[Stage][D3DTSS_COLOROP]; - } else { - op2 = This->UpdateStateBlock->texture_state[Stage][D3DTSS_ALPHAOP]; - } - - /* Note: If COMBINE4 in effect can't go back to combine! */ - switch (op2) { - case D3DTOP_ADDSMOOTH: - case D3DTOP_BLENDTEXTUREALPHAPM: - case D3DTOP_MODULATEALPHA_ADDCOLOR: - case D3DTOP_MODULATECOLOR_ADDALPHA: - case D3DTOP_MODULATEINVALPHA_ADDCOLOR: - case D3DTOP_MODULATEINVCOLOR_ADDALPHA: - case D3DTOP_MULTIPLYADD: - /* Ignore those implemented in both cases */ - switch (op) { - case D3DTOP_SELECTARG1: - case D3DTOP_SELECTARG2: - combineOK = FALSE; - Handled = FALSE; - break; - default: - FIXME("Can't use COMBINE4 and COMBINE together, thisop=%d, otherop=%ld, isAlpha(%d)\n", op, op2, isAlpha); - LEAVE_GL(); - return; - } - } - } - - if (combineOK) { - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE)); - checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE)"); - - LEAVE_GL(); - return; - } - } - - LEAVE_GL(); - - /* After all the extensions, if still unhandled, report fixme */ - FIXME("Unhandled texture operation %d\n", op); -} -#endif diff --git a/dlls/d3d8/vertexbuffer.c b/dlls/d3d8/vertexbuffer.c index ec17376ba94..375a550ce73 100644 --- a/dlls/d3d8/vertexbuffer.c +++ b/dlls/d3d8/vertexbuffer.c @@ -1,7 +1,7 @@ /* - * IDirect3DResource8 implementation + * IDirect3DVertexBuffer8 implementation * - * Copyright 2002 Jason Edmeades + * Copyright 2005 Oliver Stieber * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -19,33 +19,24 @@ */ #include "config.h" - -#include - -#include "windef.h" -#include "winbase.h" -#include "winuser.h" -#include "wingdi.h" -#include "wine/debug.h" - #include "d3d8_private.h" -WINE_DEFAULT_DEBUG_CHANNEL(d3d); +WINE_DEFAULT_DEBUG_CHANNEL(d3d8); -/* IDirect3DResource IUnknown parts follow: */ -HRESULT WINAPI IDirect3DVertexBuffer8Impl_QueryInterface(LPDIRECT3DVERTEXBUFFER8 iface, REFIID riid, LPVOID *ppobj) -{ +/* IDirect3DVertexBuffer8 IUnknown parts follow: */ +HRESULT WINAPI IDirect3DVertexBuffer8Impl_QueryInterface(LPDIRECT3DVERTEXBUFFER8 iface, REFIID riid, LPVOID *ppobj) { IDirect3DVertexBuffer8Impl *This = (IDirect3DVertexBuffer8Impl *)iface; if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IDirect3DResource8) || IsEqualGUID(riid, &IID_IDirect3DVertexBuffer8)) { - IDirect3DVertexBuffer8Impl_AddRef(iface); + IUnknown_AddRef(iface); *ppobj = This; return D3D_OK; } - WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj); + WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj); + return E_NOINTERFACE; } @@ -64,109 +55,101 @@ ULONG WINAPI IDirect3DVertexBuffer8Impl_Release(LPDIRECT3DVERTEXBUFFER8 iface) { TRACE("(%p) : ReleaseRef to %ld\n", This, ref); - if (ref == 0 && 0 == This->refInt) { - HeapFree(GetProcessHeap(), 0, This->allocatedMemory); + if (ref == 0) { + IWineD3DVertexBuffer_Release(This->wineD3DVertexBuffer); HeapFree(GetProcessHeap(), 0, This); - } else if (0 == ref) { - WARN("(%p) : The application failed to set Stream source to NULL before releasing the vertex shader, leak\n", This); } return ref; } -ULONG WINAPI IDirect3DVertexBuffer8Impl_AddRefInt(LPDIRECT3DVERTEXBUFFER8 iface) { +/* IDirect3DVertexBuffer8 IDirect3DResource8 Interface follow: */ +HRESULT WINAPI IDirect3DVertexBuffer8Impl_GetDevice(LPDIRECT3DVERTEXBUFFER8 iface, IDirect3DDevice8 **ppDevice) { IDirect3DVertexBuffer8Impl *This = (IDirect3DVertexBuffer8Impl *)iface; - ULONG refInt = InterlockedIncrement(&This->refInt); + TRACE("(%p) Relay\n", This); - TRACE("(%p) : AddRefInt from %ld\n", This, refInt - 1); - - return refInt; + return IDirect3DResource8Impl_GetDevice((LPDIRECT3DRESOURCE8) This, ppDevice); } -ULONG WINAPI IDirect3DVertexBuffer8Impl_ReleaseInt(LPDIRECT3DVERTEXBUFFER8 iface) { +HRESULT WINAPI IDirect3DVertexBuffer8Impl_SetPrivateData(LPDIRECT3DVERTEXBUFFER8 iface, REFGUID refguid, CONST void *pData, DWORD SizeOfData, DWORD Flags) { IDirect3DVertexBuffer8Impl *This = (IDirect3DVertexBuffer8Impl *)iface; - ULONG refInt = InterlockedDecrement(&This->refInt); + TRACE("(%p) Relay\n", This); - TRACE("(%p) : ReleaseRefInt to %ld\n", This, refInt); - - if (0 == This->ref && 0 == refInt) { - WARN("(%p) : Cleaning up after the calling application failed to release the stream source properly\n", This); - HeapFree(GetProcessHeap(), 0, This->allocatedMemory); - HeapFree(GetProcessHeap(), 0, This); - } - - return refInt; + return IWineD3DVertexBuffer_SetPrivateData(This->wineD3DVertexBuffer, refguid, pData, SizeOfData, Flags); } -/* IDirect3DResource Interface follow: */ -HRESULT WINAPI IDirect3DVertexBuffer8Impl_GetDevice(LPDIRECT3DVERTEXBUFFER8 iface, IDirect3DDevice8** ppDevice) { +HRESULT WINAPI IDirect3DVertexBuffer8Impl_GetPrivateData(LPDIRECT3DVERTEXBUFFER8 iface, REFGUID refguid, void *pData, DWORD *pSizeOfData) { IDirect3DVertexBuffer8Impl *This = (IDirect3DVertexBuffer8Impl *)iface; - TRACE("(%p) : returning %p\n", This, This->Device); - *ppDevice = (LPDIRECT3DDEVICE8) This->Device; - IDirect3DDevice8Impl_AddRef(*ppDevice); - return D3D_OK; + TRACE("(%p) Relay\n", This); + + return IWineD3DVertexBuffer_GetPrivateData(This->wineD3DVertexBuffer, refguid, pData, pSizeOfData); } -HRESULT WINAPI IDirect3DVertexBuffer8Impl_SetPrivateData(LPDIRECT3DVERTEXBUFFER8 iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) { + +HRESULT WINAPI IDirect3DVertexBuffer8Impl_FreePrivateData(LPDIRECT3DVERTEXBUFFER8 iface, REFGUID refguid) { IDirect3DVertexBuffer8Impl *This = (IDirect3DVertexBuffer8Impl *)iface; - FIXME("(%p) : stub\n", This); return D3D_OK; + TRACE("(%p) Relay\n", This); + + return IWineD3DVertexBuffer_FreePrivateData(This->wineD3DVertexBuffer, refguid); } -HRESULT WINAPI IDirect3DVertexBuffer8Impl_GetPrivateData(LPDIRECT3DVERTEXBUFFER8 iface, REFGUID refguid, void* pData, DWORD* pSizeOfData) { + +DWORD WINAPI IDirect3DVertexBuffer8Impl_SetPriority(LPDIRECT3DVERTEXBUFFER8 iface, DWORD PriorityNew) { IDirect3DVertexBuffer8Impl *This = (IDirect3DVertexBuffer8Impl *)iface; - FIXME("(%p) : stub\n", This); return D3D_OK; + TRACE("(%p) Relay\n", This); + + return IWineD3DVertexBuffer_SetPriority(This->wineD3DVertexBuffer, PriorityNew); } -HRESULT WINAPI IDirect3DVertexBuffer8Impl_FreePrivateData(LPDIRECT3DVERTEXBUFFER8 iface, REFGUID refguid) { + +DWORD WINAPI IDirect3DVertexBuffer8Impl_GetPriority(LPDIRECT3DVERTEXBUFFER8 iface) { IDirect3DVertexBuffer8Impl *This = (IDirect3DVertexBuffer8Impl *)iface; - FIXME("(%p) : stub\n", This); return D3D_OK; + TRACE("(%p) Relay\n", This); + + return IWineD3DVertexBuffer_GetPriority(This->wineD3DVertexBuffer); } -DWORD WINAPI IDirect3DVertexBuffer8Impl_SetPriority(LPDIRECT3DVERTEXBUFFER8 iface, DWORD PriorityNew) { + +void WINAPI IDirect3DVertexBuffer8Impl_PreLoad(LPDIRECT3DVERTEXBUFFER8 iface) { IDirect3DVertexBuffer8Impl *This = (IDirect3DVertexBuffer8Impl *)iface; - FIXME("(%p) : stub\n", This); return D3D_OK; -} -DWORD WINAPI IDirect3DVertexBuffer8Impl_GetPriority(LPDIRECT3DVERTEXBUFFER8 iface) { - IDirect3DVertexBuffer8Impl *This = (IDirect3DVertexBuffer8Impl *)iface; - FIXME("(%p) : stub\n", This); return D3D_OK; -} -void WINAPI IDirect3DVertexBuffer8Impl_PreLoad(LPDIRECT3DVERTEXBUFFER8 iface) { - IDirect3DVertexBuffer8Impl *This = (IDirect3DVertexBuffer8Impl *)iface; - FIXME("(%p) : stub\n", This); + TRACE("(%p) Relay\n", This); + IWineD3DVertexBuffer_PreLoad(This->wineD3DVertexBuffer); + + return; } + D3DRESOURCETYPE WINAPI IDirect3DVertexBuffer8Impl_GetType(LPDIRECT3DVERTEXBUFFER8 iface) { IDirect3DVertexBuffer8Impl *This = (IDirect3DVertexBuffer8Impl *)iface; - TRACE("(%p) : returning %d\n", This, This->ResourceType); - return This->ResourceType; + TRACE("(%p) Relay\n", This); + + return IWineD3DVertexBuffer_GetType(This->wineD3DVertexBuffer); } -/* IDirect3DVertexBuffer8 */ -HRESULT WINAPI IDirect3DVertexBuffer8Impl_Lock(LPDIRECT3DVERTEXBUFFER8 iface, UINT OffsetToLock, UINT SizeToLock, BYTE** ppbData, DWORD Flags) { - IDirect3DVertexBuffer8Impl *This = (IDirect3DVertexBuffer8Impl *)iface; - TRACE("(%p) : returning memory of %p (base:%p,offset:%u)\n", This, This->allocatedMemory + OffsetToLock, This->allocatedMemory, OffsetToLock); - /* TODO: check Flags compatibility with This->currentDesc.Usage (see MSDN) */ - *ppbData = This->allocatedMemory + OffsetToLock; - return D3D_OK; -} -HRESULT WINAPI IDirect3DVertexBuffer8Impl_Unlock(LPDIRECT3DVERTEXBUFFER8 iface) { - IDirect3DVertexBuffer8Impl *This = (IDirect3DVertexBuffer8Impl *)iface; - TRACE("(%p) : stub\n", This); - return D3D_OK; -} -HRESULT WINAPI IDirect3DVertexBuffer8Impl_GetDesc(LPDIRECT3DVERTEXBUFFER8 iface, D3DVERTEXBUFFER_DESC *pDesc) { +/* IDirect3DVertexBuffer8 Interface follow: */ +HRESULT WINAPI IDirect3DVertexBuffer8Impl_Lock(LPDIRECT3DVERTEXBUFFER8 iface, UINT OffsetToLock, UINT SizeToLock, BYTE **ppbData, DWORD Flags) { IDirect3DVertexBuffer8Impl *This = (IDirect3DVertexBuffer8Impl *)iface; + TRACE("(%p) Relay\n", This); - TRACE("(%p)\n", This); - pDesc->Format = This->currentDesc.Format; - pDesc->Type = This->currentDesc.Type; - pDesc->Usage = This->currentDesc.Usage; - pDesc->Pool = This->currentDesc.Pool; - pDesc->Size = This->currentDesc.Size; - pDesc->FVF = This->currentDesc.FVF; - return D3D_OK; + return IWineD3DVertexBuffer_Lock(This->wineD3DVertexBuffer, OffsetToLock, SizeToLock, ppbData, Flags); +} + +HRESULT WINAPI IDirect3DVertexBuffer8Impl_Unlock(LPDIRECT3DVERTEXBUFFER8 iface) { + IDirect3DVertexBuffer8Impl *This = (IDirect3DVertexBuffer8Impl *)iface; + TRACE("(%p) Relay\n", This); + + return IWineD3DVertexBuffer_Unlock(This->wineD3DVertexBuffer); +} + +HRESULT WINAPI IDirect3DVertexBuffer8Impl_GetDesc(LPDIRECT3DVERTEXBUFFER8 iface, D3DVERTEXBUFFER_DESC *pDesc) { + IDirect3DVertexBuffer8Impl *This = (IDirect3DVertexBuffer8Impl *)iface; + TRACE("(%p) Relay\n", This); + + return IWineD3DVertexBuffer_GetDesc(This->wineD3DVertexBuffer, pDesc); } const IDirect3DVertexBuffer8Vtbl Direct3DVertexBuffer8_Vtbl = { + /* IUnknown */ IDirect3DVertexBuffer8Impl_QueryInterface, IDirect3DVertexBuffer8Impl_AddRef, IDirect3DVertexBuffer8Impl_Release, + /* IDirect3DResource8 */ IDirect3DVertexBuffer8Impl_GetDevice, IDirect3DVertexBuffer8Impl_SetPrivateData, IDirect3DVertexBuffer8Impl_GetPrivateData, @@ -175,6 +158,7 @@ const IDirect3DVertexBuffer8Vtbl Direct3DVertexBuffer8_Vtbl = IDirect3DVertexBuffer8Impl_GetPriority, IDirect3DVertexBuffer8Impl_PreLoad, IDirect3DVertexBuffer8Impl_GetType, + /* IDirect3DVertexBuffer8 */ IDirect3DVertexBuffer8Impl_Lock, IDirect3DVertexBuffer8Impl_Unlock, IDirect3DVertexBuffer8Impl_GetDesc diff --git a/dlls/d3d8/vertexshader.c b/dlls/d3d8/vertexshader.c new file mode 100644 index 00000000000..5bba7aafda0 --- /dev/null +++ b/dlls/d3d8/vertexshader.c @@ -0,0 +1,98 @@ +/* + * IDirect3DVertexShader8 implementation + * + * Copyright 2002-2003 Jason Edmeades + * Raphael Junqueira + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "config.h" +#include "d3d8_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3d8); + +/* IDirect3DVertexShader8 IUnknown parts follow: */ +HRESULT WINAPI IDirect3DVertexShader8Impl_QueryInterface(IDirect3DVertexShader8 *iface, REFIID riid, LPVOID* ppobj) { + IDirect3DVertexShader8Impl *This = (IDirect3DVertexShader8Impl *)iface; + + if (IsEqualGUID(riid, &IID_IUnknown) + || IsEqualGUID(riid, &IID_IDirect3DVertexShader8)) { + IUnknown_AddRef(iface); + *ppobj = This; + return D3D_OK; + } + + WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj); + return E_NOINTERFACE; +} + +ULONG WINAPI IDirect3DVertexShader8Impl_AddRef(IDirect3DVertexShader8 *iface) { + IDirect3DVertexShader8Impl *This = (IDirect3DVertexShader8Impl *)iface; + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) : AddRef from %ld\n", This, ref - 1); + + return ref; +} + +ULONG WINAPI IDirect3DVertexShader8Impl_Release(IDirect3DVertexShader8 *iface) { + IDirect3DVertexShader8Impl *This = (IDirect3DVertexShader8Impl *)iface; + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) : ReleaseRef to %ld\n", This, ref); + + if (ref == 0) { + IWineD3DVertexShader_Release(This->wineD3DVertexShader); + HeapFree(GetProcessHeap(), 0, This); + } + return ref; +} + +/* IDirect3DVertexShader8 Interface follow: */ +HRESULT WINAPI IDirect3DVertexShader8Impl_GetDevice(IDirect3DVertexShader8 *iface, IDirect3DDevice8** ppDevice) { + IDirect3DVertexShader8Impl *This = (IDirect3DVertexShader8Impl *)iface; + IWineD3DDevice *myDevice = NULL; + HRESULT hr = D3D_OK; + TRACE("(%p) : Relay\n", This); + + if (D3D_OK == (hr = IWineD3DVertexShader_GetDevice(This->wineD3DVertexShader, &myDevice) && myDevice != NULL)) { + hr = IWineD3DDevice_GetParent(myDevice, (IUnknown **)ppDevice); + IWineD3DDevice_Release(myDevice); + } else { + *ppDevice = NULL; + } + TRACE("(%p) returing (%p)", This, *ppDevice); + return hr; +} + +HRESULT WINAPI IDirect3DVertexShader8Impl_GetFunction(IDirect3DVertexShader8 *iface, VOID* pData, UINT* pSizeOfData) { + IDirect3DVertexShader8Impl *This = (IDirect3DVertexShader8Impl *)iface; + + TRACE("(%p) : Relay\n", This); + return IWineD3DVertexShader_GetFunction(This->wineD3DVertexShader, pData, pSizeOfData); +} + + +const IDirect3DVertexShader8Vtbl Direct3DVertexShader8_Vtbl = +{ + /* IUnknown */ + IDirect3DVertexShader8Impl_QueryInterface, + IDirect3DVertexShader8Impl_AddRef, + IDirect3DVertexShader8Impl_Release, + /* IDirect3DVertexShader8 */ + IDirect3DVertexShader8Impl_GetDevice, + IDirect3DVertexShader8Impl_GetFunction +}; diff --git a/dlls/d3d8/vshaderdeclaration.c b/dlls/d3d8/vshaderdeclaration.c deleted file mode 100644 index f41b6137547..00000000000 --- a/dlls/d3d8/vshaderdeclaration.c +++ /dev/null @@ -1,723 +0,0 @@ -/* - * vertex shaders declaration implementation - * - * Copyright 2002 Raphael Junqueira - * Copyright 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "config.h" - -#include -#include - -#include "windef.h" -#include "winbase.h" -#include "winuser.h" -#include "wingdi.h" -#include "wine/debug.h" - -#include "d3d8_private.h" - -WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader); - -/** - * DirectX9 SDK download - * http://msdn.microsoft.com/library/default.asp?url=/downloads/list/directx.asp - * - * Exploring D3DX - * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndrive/html/directx07162002.asp - * - * Using Vertex Shaders - * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndrive/html/directx02192001.asp - * - * Dx9 New - * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/whatsnew.asp - * - * Dx9 Shaders - * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/Shaders/VertexShader2_0/VertexShader2_0.asp - * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/Shaders/VertexShader2_0/Instructions/Instructions.asp - * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/programmingguide/GettingStarted/VertexDeclaration/VertexDeclaration.asp - * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/Shaders/VertexShader3_0/VertexShader3_0.asp - * - * Dx9 D3DX - * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/programmingguide/advancedtopics/VertexPipe/matrixstack/matrixstack.asp - * - * FVF - * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/programmingguide/GettingStarted/VertexFormats/vformats.asp - * - * NVIDIA: DX8 Vertex Shader to NV Vertex Program - * http://developer.nvidia.com/view.asp?IO=vstovp - * - * NVIDIA: Memory Management with VAR - * http://developer.nvidia.com/view.asp?IO=var_memory_management - */ - -/** Vertex Shader Declaration data types tokens */ -#define MAX_VSHADER_DECL_TYPES 8 -static CONST char* VertexShaderDeclDataTypes[] = { - "D3DVSDT_FLOAT1", - "D3DVSDT_FLOAT2", - "D3DVSDT_FLOAT3", - "D3DVSDT_FLOAT4", - "D3DVSDT_D3DCOLOR", - "D3DVSDT_UBYTE4", - "D3DVSDT_SHORT2", - "D3DVSDT_SHORT4", - NULL -}; - -static CONST char* VertexShaderDeclRegister[] = { - "D3DVSDE_POSITION", - "D3DVSDE_BLENDWEIGHT", - "D3DVSDE_BLENDINDICES", - "D3DVSDE_NORMAL", - "D3DVSDE_PSIZE", - "D3DVSDE_DIFFUSE", - "D3DVSDE_SPECULAR", - "D3DVSDE_TEXCOORD0", - "D3DVSDE_TEXCOORD1", - "D3DVSDE_TEXCOORD2", - "D3DVSDE_TEXCOORD3", - "D3DVSDE_TEXCOORD4", - "D3DVSDE_TEXCOORD5", - "D3DVSDE_TEXCOORD6", - "D3DVSDE_TEXCOORD7", - "D3DVSDE_POSITION2", - "D3DVSDE_NORMAL2", - NULL -}; - -/** todo check decl validity */ -/*inline static*/ DWORD Direct3DVextexShaderDeclarationImpl_ParseToken(const DWORD* pToken) { - const DWORD token = *pToken; - DWORD tokenlen = 1; - - switch ((token & D3DVSD_TOKENTYPEMASK) >> D3DVSD_TOKENTYPESHIFT) { /* maybe a macro to inverse ... */ - case D3DVSD_TOKEN_NOP: - TRACE(" 0x%08lx NOP()\n", token); - break; - case D3DVSD_TOKEN_STREAM: - if (token & D3DVSD_STREAMTESSMASK) { - TRACE(" 0x%08lx STREAM_TESS()\n", token); - } else { - TRACE(" 0x%08lx STREAM(%lu)\n", token, ((token & D3DVSD_STREAMNUMBERMASK) >> D3DVSD_STREAMNUMBERSHIFT)); - } - break; - case D3DVSD_TOKEN_STREAMDATA: - if (token & 0x10000000) { - TRACE(" 0x%08lx SKIP(%lu)\n", token, ((token & D3DVSD_SKIPCOUNTMASK) >> D3DVSD_SKIPCOUNTSHIFT)); - } else { - DWORD type = ((token & D3DVSD_DATATYPEMASK) >> D3DVSD_DATATYPESHIFT); - DWORD reg = ((token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT); - TRACE(" 0x%08lx REG(%s, %s)\n", token, VertexShaderDeclRegister[reg], VertexShaderDeclDataTypes[type]); - } - break; - case D3DVSD_TOKEN_TESSELLATOR: - if (token & 0x10000000) { - DWORD type = ((token & D3DVSD_DATATYPEMASK) >> D3DVSD_DATATYPESHIFT); - DWORD reg = ((token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT); - TRACE(" 0x%08lx TESSUV(%s) as %s\n", token, VertexShaderDeclRegister[reg], VertexShaderDeclDataTypes[type]); - } else { - DWORD type = ((token & D3DVSD_DATATYPEMASK) >> D3DVSD_DATATYPESHIFT); - DWORD regout = ((token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT); - DWORD regin = ((token & D3DVSD_VERTEXREGINMASK) >> D3DVSD_VERTEXREGINSHIFT); - TRACE(" 0x%08lx TESSNORMAL(%s, %s) as %s\n", token, VertexShaderDeclRegister[regin], VertexShaderDeclRegister[regout], VertexShaderDeclDataTypes[type]); - } - break; - case D3DVSD_TOKEN_CONSTMEM: - { - DWORD i; - DWORD count = ((token & D3DVSD_CONSTCOUNTMASK) >> D3DVSD_CONSTCOUNTSHIFT); - DWORD constaddress = ((token & D3DVSD_CONSTADDRESSMASK) >> D3DVSD_CONSTADDRESSSHIFT); - TRACE(" 0x%08lx CONST(%lu, %lu)\n", token, constaddress, count); - ++pToken; - for (i = 0; i < count; ++i) { -#if 0 - TRACE(" c[%lu] = (0x%08lx, 0x%08lx, 0x%08lx, 0x%08lx)\n", - constaddress, - *pToken, - *(pToken + 1), - *(pToken + 2), - *(pToken + 3)); -#endif - TRACE(" c[%lu] = (%8f, %8f, %8f, %8f)\n", - constaddress, - *(const float*) pToken, - *(const float*) (pToken + 1), - *(const float*) (pToken + 2), - *(const float*) (pToken + 3)); - pToken += 4; - ++constaddress; - } - tokenlen = (4 * count) + 1; - } - break; - case D3DVSD_TOKEN_EXT: - { - DWORD count = ((token & D3DVSD_CONSTCOUNTMASK) >> D3DVSD_CONSTCOUNTSHIFT); - DWORD extinfo = ((token & D3DVSD_EXTINFOMASK) >> D3DVSD_EXTINFOSHIFT); - TRACE(" 0x%08lx EXT(%lu, %lu)\n", token, count, extinfo); - /* todo ... print extension */ - tokenlen = count + 1; - } - break; - case D3DVSD_TOKEN_END: - TRACE(" 0x%08lx END()\n", token); - break; - default: - TRACE(" 0x%08lx UNKNOWN\n", token); - /* argg error */ - } - return tokenlen; -} - -HRESULT WINAPI IDirect3DDeviceImpl_CreateVertexShaderDeclaration8(IDirect3DDevice8Impl* This, CONST DWORD* pDeclaration8, IDirect3DVertexShaderDeclarationImpl** ppVertexShaderDecl) { - /** parser data */ - const DWORD* pToken = pDeclaration8; - DWORD fvf = 0; - DWORD len = 0; - DWORD stream = 0; - DWORD token; - DWORD tokenlen; - DWORD tokentype; - DWORD tex = D3DFVF_TEX0; - /** TRUE if declaration can be matched by a fvf */ - IDirect3DVertexShaderDeclarationImpl* object; - BOOL invalid_fvf = FALSE; - - TRACE("(%p) : pDeclaration8(%p)\n", This, pDeclaration8); - - object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVertexShaderDeclarationImpl)); - - /*object->lpVtbl = &Direct3DVextexShaderDeclaration8_Vtbl;*/ - object->device = This; /* FIXME: AddRef(This) */ - object->ref = 1; - object->allFVF = 0; - - while (D3DVSD_END() != *pToken) { - token = *pToken; - tokenlen = Direct3DVextexShaderDeclarationImpl_ParseToken(pToken); - tokentype = ((token & D3DVSD_TOKENTYPEMASK) >> D3DVSD_TOKENTYPESHIFT); - - /** FVF generation block */ - if (D3DVSD_TOKEN_STREAM == tokentype && 0 == (D3DVSD_STREAMTESSMASK & token)) { - /** - * how really works streams, - * in DolphinVS dx8 dsk sample they seems to decal reg numbers !!! - */ - DWORD oldStream = stream; - stream = ((token & D3DVSD_STREAMNUMBERMASK) >> D3DVSD_STREAMNUMBERSHIFT); - - /* copy fvf if valid */ - if (FALSE == invalid_fvf) { - fvf |= tex << D3DFVF_TEXCOUNT_SHIFT; - tex = 0; - object->fvf[oldStream] = fvf; - object->allFVF |= fvf; - } else { - object->fvf[oldStream] = 0; - tex = 0; - } - - /* reset valid/invalid fvf */ - fvf = 0; - invalid_fvf = FALSE; - - } else if (D3DVSD_TOKEN_STREAMDATA == tokentype && 0 == (0x10000000 & tokentype)) { - DWORD type = ((token & D3DVSD_DATATYPEMASK) >> D3DVSD_DATATYPESHIFT); - DWORD reg = ((token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT); - - switch (reg) { - case D3DVSDE_POSITION: - switch (type) { - case D3DVSDT_FLOAT3: fvf |= D3DFVF_XYZ; break; - case D3DVSDT_FLOAT4: fvf |= D3DFVF_XYZRHW; break; - default: - /** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */ - invalid_fvf = TRUE; - if (type >= MAX_VSHADER_DECL_TYPES) { - TRACE("Mismatched use in VertexShader declaration of D3DVSDE_POSITION register: unsupported and unrecognized type %08lx\n", type); - } else { - TRACE("Mismatched use in VertexShader declaration of D3DVSDE_POSITION register: unsupported type %s\n", VertexShaderDeclDataTypes[type]); - } - } - break; - - case D3DVSDE_BLENDWEIGHT: - switch (type) { - case D3DVSDT_FLOAT1: fvf |= D3DFVF_XYZB1; break; - case D3DVSDT_FLOAT2: fvf |= D3DFVF_XYZB2; break; - case D3DVSDT_FLOAT3: fvf |= D3DFVF_XYZB3; break; - case D3DVSDT_FLOAT4: fvf |= D3DFVF_XYZB4; break; - default: - /** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */ - invalid_fvf = TRUE; - TRACE("Mismatched use in VertexShader declaration of D3DVSDE_BLENDWEIGHT register: unsupported type %s\n", VertexShaderDeclDataTypes[type]); - } - break; - - case D3DVSDE_BLENDINDICES: /* seem to be B5 as said in MSDN Dx9SDK ?? */ - switch (type) { - case D3DVSDT_UBYTE4: fvf |= D3DFVF_LASTBETA_UBYTE4; break; - default: - /** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */ - invalid_fvf = TRUE; - TRACE("Mismatched use in VertexShader declaration of D3DVSDE_BLENDINDINCES register: unsupported type %s\n", VertexShaderDeclDataTypes[type]); - } - break; - - case D3DVSDE_NORMAL: /* TODO: only FLOAT3 supported ... another choice possible ? */ - switch (type) { - case D3DVSDT_FLOAT3: fvf |= D3DFVF_NORMAL; break; - default: - /** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */ - invalid_fvf = TRUE; - TRACE("Mismatched use in VertexShader declaration of D3DVSDE_NORMAL register: unsupported type %s\n", VertexShaderDeclDataTypes[type]); - } - break; - - case D3DVSDE_PSIZE: /* TODO: only FLOAT1 supported ... another choice possible ? */ - switch (type) { - case D3DVSDT_FLOAT1: fvf |= D3DFVF_PSIZE; break; - default: - /** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */ - invalid_fvf = TRUE; - TRACE("Mismatched use in VertexShader declaration of D3DVSDE_PSIZE register: unsupported type %s\n", VertexShaderDeclDataTypes[type]); - } - break; - - case D3DVSDE_DIFFUSE: /* TODO: only D3DCOLOR supported */ - switch (type) { - case D3DVSDT_D3DCOLOR: fvf |= D3DFVF_DIFFUSE; break; - default: - /** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */ - invalid_fvf = TRUE; - TRACE("Mismatched use in VertexShader declaration of D3DVSDE_DIFFUSE register: unsupported type %s\n", VertexShaderDeclDataTypes[type]); - } - break; - - case D3DVSDE_SPECULAR: /* TODO: only D3DCOLOR supported */ - switch (type) { - case D3DVSDT_D3DCOLOR: fvf |= D3DFVF_SPECULAR; break; - default: - /** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */ - invalid_fvf = TRUE; - TRACE("Mismatched use in VertexShader declaration of D3DVSDE_SPECULAR register: unsupported type %s\n", VertexShaderDeclDataTypes[type]); - } - break; - - case D3DVSDE_TEXCOORD0: - case D3DVSDE_TEXCOORD1: - case D3DVSDE_TEXCOORD2: - case D3DVSDE_TEXCOORD3: - case D3DVSDE_TEXCOORD4: - case D3DVSDE_TEXCOORD5: - case D3DVSDE_TEXCOORD6: - case D3DVSDE_TEXCOORD7: - /* Fixme? - assume all tex coords in same stream */ - { - int texNo = 1 + (reg - D3DVSDE_TEXCOORD0); - tex = max(tex, texNo); - switch (type) { - case D3DVSDT_FLOAT1: fvf |= D3DFVF_TEXCOORDSIZE1(texNo); break; - case D3DVSDT_FLOAT2: fvf |= D3DFVF_TEXCOORDSIZE2(texNo); break; - case D3DVSDT_FLOAT3: fvf |= D3DFVF_TEXCOORDSIZE3(texNo); break; - case D3DVSDT_FLOAT4: fvf |= D3DFVF_TEXCOORDSIZE4(texNo); break; - default: - /** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */ - invalid_fvf = TRUE; - TRACE("Mismatched use in VertexShader declaration of D3DVSDE_TEXCOORD? register: unsupported type %s\n", VertexShaderDeclDataTypes[type]); - } - } - break; - - case D3DVSDE_POSITION2: /* maybe D3DFVF_XYZRHW instead D3DFVF_XYZ (of D3DVDE_POSITION) ... to see */ - case D3DVSDE_NORMAL2: /* FIXME i don't know what to do here ;( */ - FIXME("[%lu] registers in VertexShader declaration not supported yet (token:0x%08lx)\n", reg, token); - break; - } - TRACE("VertexShader declaration define %lx as current FVF\n", fvf); - } - len += tokenlen; - pToken += tokenlen; - } - /* here D3DVSD_END() */ - len += Direct3DVextexShaderDeclarationImpl_ParseToken(pToken); - - /* copy fvf if valid */ - if (FALSE == invalid_fvf) { - fvf |= tex << D3DFVF_TEXCOUNT_SHIFT; - object->fvf[stream] = fvf; - object->allFVF |= fvf; - } else { - object->fvf[stream] = 0; - } - TRACE("Completed, allFVF = %lx\n", object->allFVF); - - /* compute size */ - object->declaration8Length = len * sizeof(DWORD); - /* copy the declaration */ - object->pDeclaration8 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->declaration8Length); - memcpy(object->pDeclaration8, pDeclaration8, object->declaration8Length); - /* returns */ - *ppVertexShaderDecl = object; - return D3D_OK; -} - -HRESULT WINAPI IDirect3DDeviceImpl_FillVertexShaderInputSW(IDirect3DDevice8Impl* This, - IDirect3DVertexShaderImpl* vshader, - DWORD SkipnStrides) { - /** parser data */ - const DWORD* pToken = This->UpdateStateBlock->vertexShaderDecl->pDeclaration8; - DWORD stream = 0; - DWORD token; - /*DWORD tokenlen;*/ - DWORD tokentype; - /** for input readers */ - const BYTE* curPos = NULL; - FLOAT x, y, z, w; - SHORT u, v, r, t; - DWORD dw; - - TRACE("(%p) - This:%p, skipstrides=%lu\n", vshader, This, SkipnStrides); - - while (D3DVSD_END() != *pToken) { - token = *pToken; - tokentype = ((token & D3DVSD_TOKENTYPEMASK) >> D3DVSD_TOKENTYPESHIFT); - - /** FVF generation block */ - if (D3DVSD_TOKEN_STREAM == tokentype && 0 == (D3DVSD_STREAMTESSMASK & token)) { - IDirect3DVertexBuffer8* pVB; - int skip = 0; - - ++pToken; - /** - * how really works streams, - * in DolphinVS dx8 dsk sample use it !!! - */ - stream = ((token & D3DVSD_STREAMNUMBERMASK) >> D3DVSD_STREAMNUMBERSHIFT); - skip = This->StateBlock->stream_stride[stream]; - pVB = This->StateBlock->stream_source[stream]; - - if (NULL == pVB) { - ERR("using unitialised stream[%lu]\n", stream); - return D3DERR_INVALIDCALL; - } else { - if (This->StateBlock->streamIsUP) { - curPos = (BYTE *)pVB + (SkipnStrides * skip); /* Not really a VB */ - } else { - curPos = ((IDirect3DVertexBuffer8Impl*) pVB)->allocatedMemory + (SkipnStrides * skip); - } - - TRACE(" using stream[%lu] with %p (%p + (Stride %d * skip %ld))\n", stream, curPos, - ((IDirect3DVertexBuffer8Impl*) pVB)->allocatedMemory, skip, SkipnStrides); - } - } else if (D3DVSD_TOKEN_CONSTMEM == tokentype) { - /** Const decl */ - DWORD i; - DWORD count = ((token & D3DVSD_CONSTCOUNTMASK) >> D3DVSD_CONSTCOUNTSHIFT); - DWORD constaddress = ((token & D3DVSD_CONSTADDRESSMASK) >> D3DVSD_CONSTADDRESSSHIFT); - ++pToken; - for (i = 0; i < count; ++i) { - vshader->data->C[constaddress + i].x = *(const float*)pToken; - vshader->data->C[constaddress + i].y = *(const float*)(pToken + 1); - vshader->data->C[constaddress + i].z = *(const float*)(pToken + 2); - vshader->data->C[constaddress + i].w = *(const float*)(pToken + 3); - pToken += 4; - } - - } else if (D3DVSD_TOKEN_STREAMDATA == tokentype && 0 != (0x10000000 & tokentype)) { - /** skip datas */ - DWORD skipCount = ((token & D3DVSD_SKIPCOUNTMASK) >> D3DVSD_SKIPCOUNTSHIFT); - TRACE(" skipping %ld dwords\n", skipCount); - curPos = curPos + skipCount * sizeof(DWORD); - ++pToken; - - } else if (D3DVSD_TOKEN_STREAMDATA == tokentype && 0 == (0x10000000 & tokentype)) { - DWORD type = ((token & D3DVSD_DATATYPEMASK) >> D3DVSD_DATATYPESHIFT); - DWORD reg = ((token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT); - ++pToken; - - TRACE(" type : %ld, reg = %ld\n", type, reg); - switch (type) { - case D3DVSDT_FLOAT1: - x = *(const float*) curPos; - curPos = curPos + sizeof(float); - /**/ - vshader->input.V[reg].x = x; - vshader->input.V[reg].y = 0.0f; - vshader->input.V[reg].z = 0.0f; - vshader->input.V[reg].w = 1.0f; - break; - - case D3DVSDT_FLOAT2: - x = *(const float*) curPos; - curPos = curPos + sizeof(float); - y = *(const float*) curPos; - curPos = curPos + sizeof(float); - /**/ - vshader->input.V[reg].x = x; - vshader->input.V[reg].y = y; - vshader->input.V[reg].z = 0.0f; - vshader->input.V[reg].w = 1.0f; - break; - - case D3DVSDT_FLOAT3: - x = *(const float*) curPos; - curPos = curPos + sizeof(float); - y = *(const float*) curPos; - curPos = curPos + sizeof(float); - z = *(const float*) curPos; - curPos = curPos + sizeof(float); - /**/ - vshader->input.V[reg].x = x; - vshader->input.V[reg].y = y; - vshader->input.V[reg].z = z; - vshader->input.V[reg].w = 1.0f; - break; - - case D3DVSDT_FLOAT4: - x = *(const float*) curPos; - curPos = curPos + sizeof(float); - y = *(const float*) curPos; - curPos = curPos + sizeof(float); - z = *(const float*) curPos; - curPos = curPos + sizeof(float); - w = *(const float*) curPos; - curPos = curPos + sizeof(float); - /**/ - vshader->input.V[reg].x = x; - vshader->input.V[reg].y = y; - vshader->input.V[reg].z = z; - vshader->input.V[reg].w = w; - break; - - case D3DVSDT_D3DCOLOR: - dw = *(const DWORD*) curPos; - curPos = curPos + sizeof(DWORD); - /**/ - vshader->input.V[reg].x = D3DCOLOR_R(dw); - vshader->input.V[reg].y = D3DCOLOR_G(dw); - vshader->input.V[reg].z = D3DCOLOR_B(dw); - vshader->input.V[reg].w = D3DCOLOR_A(dw); - break; - - case D3DVSDT_SHORT2: - u = *(const SHORT*) curPos; - curPos = curPos + sizeof(SHORT); - v = *(const SHORT*) curPos; - curPos = curPos + sizeof(SHORT); - /**/ - vshader->input.V[reg].x = (float) u; - vshader->input.V[reg].y = (float) v; - vshader->input.V[reg].z = 0.0f; - vshader->input.V[reg].w = 1.0f; - break; - - case D3DVSDT_SHORT4: - u = *(const SHORT*) curPos; - curPos = curPos + sizeof(SHORT); - v = *(const SHORT*) curPos; - curPos = curPos + sizeof(SHORT); - r = *(const SHORT*) curPos; - curPos = curPos + sizeof(SHORT); - t = *(const SHORT*) curPos; - curPos = curPos + sizeof(SHORT); - /**/ - vshader->input.V[reg].x = (float) u; - vshader->input.V[reg].y = (float) v; - vshader->input.V[reg].z = (float) r; - vshader->input.V[reg].w = (float) t; - break; - - case D3DVSDT_UBYTE4: - dw = *(const DWORD*) curPos; - curPos = curPos + sizeof(DWORD); - /**/ - vshader->input.V[reg].x = (float) ((dw & 0x000000FF) >> 0); - vshader->input.V[reg].y = (float) ((dw & 0x0000FF00) >> 8); - vshader->input.V[reg].z = (float) ((dw & 0x00FF0000) >> 16); - vshader->input.V[reg].w = (float) ((dw & 0xFF000000) >> 24); - break; - - default: /** errooooorr what to do ? */ - ERR("Error in VertexShader declaration of %s register: unsupported type %s\n", VertexShaderDeclRegister[reg], VertexShaderDeclDataTypes[type]); - } - } - - } - /* here D3DVSD_END() */ - return D3D_OK; -} - -HRESULT WINAPI IDirect3DDeviceImpl_FillVertexShaderInputArbHW(IDirect3DDevice8Impl* This, - IDirect3DVertexShaderImpl* vshader, - DWORD SkipnStrides) { - /** parser data */ - const DWORD* pToken = This->UpdateStateBlock->vertexShaderDecl->pDeclaration8; - DWORD stream = 0; - DWORD token; - /*DWORD tokenlen;*/ - DWORD tokentype; - /** for input readers */ - const BYTE* curPos = NULL; - int skip = 0; - - TRACE("(%p) - This:%p, skipstrides=%lu\n", vshader, This, SkipnStrides); - - while (D3DVSD_END() != *pToken) { - token = *pToken; - tokentype = ((token & D3DVSD_TOKENTYPEMASK) >> D3DVSD_TOKENTYPESHIFT); - - /** FVF generation block */ - if (D3DVSD_TOKEN_STREAM == tokentype && 0 == (D3DVSD_STREAMTESSMASK & token)) { - IDirect3DVertexBuffer8* pVB; - - ++pToken; - /** - * how really works streams, - * in DolphinVS dx8 dsk sample use it !!! - */ - stream = ((token & D3DVSD_STREAMNUMBERMASK) >> D3DVSD_STREAMNUMBERSHIFT); - skip = This->StateBlock->stream_stride[stream]; - pVB = This->StateBlock->stream_source[stream]; - - if (NULL == pVB) { - ERR("using unitialised stream[%lu]\n", stream); - return D3DERR_INVALIDCALL; - } else { - if (This->StateBlock->streamIsUP) { - curPos = ((BYTE *) pVB) + (SkipnStrides * skip); /* Not really a VB */ - } else { - curPos = ((IDirect3DVertexBuffer8Impl*) pVB)->allocatedMemory + (SkipnStrides * skip); - } - - TRACE(" using stream[%lu] with %p (%p + (Stride %d * skip %ld))\n", stream, curPos, - ((IDirect3DVertexBuffer8Impl*) pVB)->allocatedMemory, skip, SkipnStrides); - } - } else if (D3DVSD_TOKEN_CONSTMEM == tokentype) { - /** Const decl */ - DWORD i; - DWORD count = ((token & D3DVSD_CONSTCOUNTMASK) >> D3DVSD_CONSTCOUNTSHIFT); - DWORD constaddress = ((token & D3DVSD_CONSTADDRESSMASK) >> D3DVSD_CONSTADDRESSSHIFT); - - ++pToken; - for (i = 0; i < count; ++i) { - FIXME("Confirm this is correct handling of consts inside the hw vertex shader\n"); - GL_EXTCALL(glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, constaddress+i, (GLfloat *)pToken)); - vshader->data->C[constaddress + i].x = *(const float*)pToken; - vshader->data->C[constaddress + i].y = *(const float*)(pToken + 1); - vshader->data->C[constaddress + i].z = *(const float*)(pToken + 2); - vshader->data->C[constaddress + i].w = *(const float*)(pToken + 3); - pToken += 4; - } - - } else if (D3DVSD_TOKEN_STREAMDATA == tokentype && 0 != (0x10000000 & tokentype)) { - /** skip datas */ - DWORD skipCount = ((token & D3DVSD_SKIPCOUNTMASK) >> D3DVSD_SKIPCOUNTSHIFT); - TRACE(" skipping %ld dwords\n", skipCount); - curPos = curPos + skipCount * sizeof(DWORD); - ++pToken; - - } else if (D3DVSD_TOKEN_STREAMDATA == tokentype && 0 == (0x10000000 & tokentype)) { - DWORD type = ((token & D3DVSD_DATATYPEMASK) >> D3DVSD_DATATYPESHIFT); - DWORD reg = ((token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT); - ++pToken; - - TRACE(" type : %ld, reg = %ld\n", type, reg); - switch (type) { - case D3DVSDT_FLOAT1: - TRACE("HW VS glVertexAttribPointerARB(reg=%ld,num=%d,skip=%d,ptr=%p)\n", reg, 1, skip, curPos); - GL_EXTCALL(glVertexAttribPointerARB(reg, 1, GL_FLOAT, GL_FALSE, skip, curPos)); - GL_EXTCALL(glEnableVertexAttribArrayARB(reg)); - curPos = curPos + sizeof(float); - break; - - case D3DVSDT_FLOAT2: - TRACE("HW VS glVertexAttribPointerARB(reg=%ld,num=%d,skip=%d,ptr=%p)\n", reg, 2, skip, curPos); - GL_EXTCALL(glVertexAttribPointerARB(reg, 2, GL_FLOAT, GL_FALSE, skip, curPos)); - GL_EXTCALL(glEnableVertexAttribArrayARB(reg)); - curPos = curPos + 2*sizeof(float); - break; - - case D3DVSDT_FLOAT3: - TRACE("HW VS glVertexAttribPointerARB(reg=%ld,num=%d,skip=%d,ptr=%p)\n", reg, 3, skip, curPos); - GL_EXTCALL(glVertexAttribPointerARB(reg, 3, GL_FLOAT, GL_FALSE, skip, curPos)); - GL_EXTCALL(glEnableVertexAttribArrayARB(reg)); - curPos = curPos + 3*sizeof(float); - break; - - case D3DVSDT_FLOAT4: - TRACE("HW VS glVertexAttribPointerARB(reg=%ld,num=%d,skip=%d,ptr=%p)\n", reg, 4, skip, curPos); - GL_EXTCALL(glVertexAttribPointerARB(reg, 4, GL_FLOAT, GL_FALSE, skip, curPos)); - GL_EXTCALL(glEnableVertexAttribArrayARB(reg)); - curPos = curPos + 4*sizeof(float); - break; - - case D3DVSDT_D3DCOLOR: - TRACE("HW VS glVertexAttribPointerARB(reg=%ld,num=%d,skip=%d,ptr=%p)\n", reg, 4, skip, curPos); - FIXME("D3DVSDT_D3DCOLOR in hw shader - To confirm\n"); - GL_EXTCALL(glVertexAttribPointerARB(reg, 4, GL_UNSIGNED_BYTE, GL_TRUE, skip, curPos)); - GL_EXTCALL(glEnableVertexAttribArrayARB(reg)); - curPos = curPos + 4*sizeof(BYTE); - break; - - case D3DVSDT_SHORT2: - TRACE("HW VS glVertexAttribPointerARB(reg=%ld,num=%d,skip=%d,ptr=%p)\n", reg, 2, skip, curPos); - GL_EXTCALL(glVertexAttribPointerARB(reg, 2, GL_UNSIGNED_SHORT, GL_FALSE, skip, curPos)); - GL_EXTCALL(glEnableVertexAttribArrayARB(reg)); - curPos = curPos + 2*sizeof(short int); - break; - - case D3DVSDT_SHORT4: - TRACE("HW VS glVertexAttribPointerARB(reg=%ld,num=%d,skip=%d,ptr=%p)\n", reg, 1, skip, curPos); - GL_EXTCALL(glVertexAttribPointerARB(reg, 4, GL_UNSIGNED_SHORT, GL_FALSE, skip, curPos)); - GL_EXTCALL(glEnableVertexAttribArrayARB(reg)); - curPos = curPos + 4*sizeof(short int); - break; - - case D3DVSDT_UBYTE4: - FIXME("D3DVSDT_UBYTE4 in hw shader - To confirm\n"); - GL_EXTCALL(glVertexAttribPointerARB(reg, 4, GL_UNSIGNED_BYTE, GL_TRUE, skip, curPos)); - GL_EXTCALL(glEnableVertexAttribArrayARB(reg)); - curPos = curPos + 4*sizeof(BYTE); - break; - - default: /** errooooorr what to do ? */ - ERR("Error in VertexShader declaration of %s register: unsupported type %s\n", VertexShaderDeclRegister[reg], VertexShaderDeclDataTypes[type]); - } - } - - } - /* here D3DVSD_END() */ - return D3D_OK; -} - -HRESULT WINAPI IDirect3DVertexShaderDeclarationImpl_GetDeclaration8(IDirect3DVertexShaderDeclarationImpl* This, DWORD* pData, UINT* pSizeOfData) { - if (NULL == pData) { - *pSizeOfData = This->declaration8Length; - return D3D_OK; - } - if (*pSizeOfData < This->declaration8Length) { - *pSizeOfData = This->declaration8Length; - return D3DERR_MOREDATA; - } - TRACE("(%p) : GetVertexShaderDeclaration copying to %p\n", This, pData); - memcpy(pData, This->pDeclaration8, This->declaration8Length); - return D3D_OK; -} diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 04a2fe839c6..e458fa38672 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -362,7 +362,7 @@ ULONG WINAPI IWineD3DDeviceImpl_Release(IWineD3DDevice *iface) { if (!refCount) { /* TODO: Clean up all the surfaces and textures! */ /* FIXME: Create targets and state blocks in d3d8 */ - if (((IWineD3DImpl *)This->wineD3D)->dxVersion > 8) { /*We don't create a state block in d3d8 yet*/ + if (((IWineD3DImpl *)This->wineD3D)->dxVersion >= 8) { /*We don't create state blocks for d3d7 yet*/ /* NOTE: You must release the parent if the object was created via a callback ** ***************************/ /* TODO: this is exactly the same as required by _Reset.., so at some point we need to move the code so that is can be called by reset add release... */ diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index d14aa9be643..ca932ef4de8 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -1521,7 +1521,7 @@ HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter, D3DDEVT /* TODO: add support for NON-POW2 if avaialble */ - if (This->dxVersion > 8) { + if (This->dxVersion >= 8) { *pCaps->TextureCaps |= D3DPTEXTURECAPS_NONPOW2CONDITIONAL; } else { /* NONPOW2 isn't accessible by d3d8 yet */ @@ -1782,19 +1782,9 @@ HRESULT WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter, D3DDEV object->adapterNo = Adapter; object->devType = DeviceType; - /* Let D3D8 use WineD3D's capability detection code. We can't use the block of code after this call yet - / as D3D8 doesn't use WineD3D stateblocks / swapchains. - */ - if(This->dxVersion == 8) { - /* Setup some defaults for creating the implicit swapchain */ - ENTER_GL(); - IWineD3DImpl_FillGLCaps(&This->gl_info, IWineD3DImpl_GetAdapterDisplay(iface, Adapter)); - LEAVE_GL(); - } - - /* FIXME: Use for dx8 code eventually too! */ + /* FIXME: Use for dx7 code eventually too! */ /* Deliberately no indentation here, as this if will be removed when dx8 support merged in */ - if (This->dxVersion > 8) { + if (This->dxVersion >= 8) { TRACE("(%p) : Creating stateblock\n", This); /* Creating the startup stateBlock - Note Special Case: 0 => Don't fill in yet! */ if (D3D_OK != IWineD3DDevice_CreateStateBlock((IWineD3DDevice *)object,