From 447d5ed048ff32b21aceeb945fece08bade252b5 Mon Sep 17 00:00:00 2001 From: Jason Edmeades Date: Thu, 21 Oct 2004 20:59:12 +0000 Subject: [PATCH] Implement the beginnings of the stateblock class, and a first method to use it. --- dlls/d3d9/device.c | 6 +-- dlls/wined3d/Makefile.in | 1 + dlls/wined3d/device.c | 55 +++++++++++++++++++++++- dlls/wined3d/directx.c | 17 +++----- dlls/wined3d/stateblock.c | 73 ++++++++++++++++++++++++++++++++ dlls/wined3d/wined3d_private.h | 45 ++++++++++++++++++-- include/wine/wined3d_interface.h | 34 ++++++++++++++- 7 files changed, 212 insertions(+), 19 deletions(-) create mode 100644 dlls/wined3d/stateblock.c diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c index f9c8c6ecb48..487972aeee5 100644 --- a/dlls/d3d9/device.c +++ b/dlls/d3d9/device.c @@ -597,14 +597,12 @@ HRESULT WINAPI IDirect3DDevice9Impl_ProcessVertices(LPDIRECT3DDEVICE9 iface, U HRESULT WINAPI IDirect3DDevice9Impl_SetFVF(LPDIRECT3DDEVICE9 iface, DWORD FVF) { IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface; - FIXME("(%p) : stub\n", This); - return D3D_OK; + return IWineD3DDevice_SetFVF(This->WineD3DDevice, FVF); } HRESULT WINAPI IDirect3DDevice9Impl_GetFVF(LPDIRECT3DDEVICE9 iface, DWORD* pFVF) { IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface; - FIXME("(%p) : stub\n", This); - return D3D_OK; + return IWineD3DDevice_GetFVF(This->WineD3DDevice, pFVF); } HRESULT WINAPI IDirect3DDevice9Impl_SetStreamSource(LPDIRECT3DDEVICE9 iface, UINT StreamNumber, IDirect3DVertexBuffer9* pStreamData, UINT OffsetInBytes, UINT Stride) { diff --git a/dlls/wined3d/Makefile.in b/dlls/wined3d/Makefile.in index 78a7a8892f3..8561f6479d1 100644 --- a/dlls/wined3d/Makefile.in +++ b/dlls/wined3d/Makefile.in @@ -11,6 +11,7 @@ C_SRCS = \ device.c \ directx.c \ resource.c \ + stateblock.c \ utils.c \ vertexbuffer.c \ vertexshader.c \ diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 1ee3463fc24..7a0c84c97d2 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -58,6 +58,56 @@ HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexBuffer(IWineD3DDevice *iface, UINT return D3D_OK; } +HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice* iface, D3DSTATEBLOCKTYPE Type, IWineD3DStateBlock** ppStateBlock) { + + IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; + IWineD3DStateBlockImpl *object; + + /* Allocate Storage for the state block */ + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IWineD3DStateBlockImpl)); + object->lpVtbl = &IWineD3DStateBlock_Vtbl; + object->wineD3DDevice = iface; + object->ref = 1; + object->blockType = Type; + *ppStateBlock = (IWineD3DStateBlock *)object; + + /* Special case - Used during initialization to produce a placeholder stateblock + so other functions called can update a state block */ + if (Type == (D3DSTATEBLOCKTYPE) 0) { + /* Dont bother increasing the reference count otherwise a device will never + be freed due to circular dependencies */ + return D3D_OK; + } + + /* Otherwise, might as well set the whole state block to the appropriate values */ + IWineD3DDevice_AddRef(iface); + memcpy(object, This->stateBlock, sizeof(IWineD3DStateBlockImpl)); + FIXME("unfinished - needs to set up changed and set attributes\n"); + return D3D_OK; +} + +/***** + * Get / Set FVF + *****/ +HRESULT WINAPI IWineD3DDeviceImpl_SetFVF(IWineD3DDevice *iface, DWORD fvf) { + IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; + + /* Update the current statte block */ + This->updateStateBlock->fvf = fvf; + This->updateStateBlock->changed.fvf = TRUE; + This->updateStateBlock->set.fvf = TRUE; + + TRACE("(%p) : FVF Shader FVF set to %lx\n", This, fvf); + + /* No difference if recording or not */ + return D3D_OK; +} +HRESULT WINAPI IWineD3DDeviceImpl_GetFVF(IWineD3DDevice *iface, DWORD *pfvf) { + IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; + TRACE("(%p) : GetFVF returning %lx\n", This, This->stateBlock->fvf); + *pfvf = This->stateBlock->fvf; + return D3D_OK; +} /********************************************************** * IUnknown parts follows @@ -95,5 +145,8 @@ IWineD3DDeviceVtbl IWineD3DDevice_Vtbl = IWineD3DDeviceImpl_QueryInterface, IWineD3DDeviceImpl_AddRef, IWineD3DDeviceImpl_Release, - IWineD3DDeviceImpl_CreateVertexBuffer + IWineD3DDeviceImpl_CreateVertexBuffer, + IWineD3DDeviceImpl_CreateStateBlock, + IWineD3DDeviceImpl_SetFVF, + IWineD3DDeviceImpl_GetFVF }; diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index c668c3d2d15..b0d9b491cb7 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -1465,12 +1465,11 @@ HRESULT WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter, D3DDEV object->presentParms.FullScreen_RefreshRateInHz = *(pPresentationParameters->FullScreen_RefreshRateInHz); object->presentParms.PresentationInterval = *(pPresentationParameters->PresentationInterval); -/* TODO: - * Creating the startup stateBlock * - object->StateBlock = NULL; - IWineD3DDevice_CreateStateBlock(object, D3DSBT_ALL, NULL); - object->UpdateStateBlock = object->StateBlock; -*/ + /* Creating the startup stateBlock - Note Special Case: 0 => Dont fill in yet! */ + IWineD3DDevice_CreateStateBlock((IWineD3DDevice *)object, + (D3DSTATEBLOCKTYPE) 0, + (IWineD3DStateBlock **)&object->stateBlock); + object->updateStateBlock = object->stateBlock; /* Setup surfaces for the backbuffer, frontbuffer and depthstencil buffer */ TRACE("Creating initial device surfaces\n"); @@ -1551,9 +1550,7 @@ HRESULT WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter, D3DDEV This->isGLInfoValid = IWineD3DImpl_FillGLCaps(&This->gl_info, object->display); /* Setup all the devices defaults */ -/* TODO: - IDirect3DDeviceImpl_InitStartupStateBlock(object); -*/ + IWineD3DStateBlock_InitStartupStateBlock((IWineD3DStateBlock *)object->stateBlock); LEAVE_GL(); @@ -1595,7 +1592,7 @@ HRESULT WINAPI IWineD3DImpl_QueryInterface(IWineD3D *iface,REFIID riid,LPVOID *p ULONG WINAPI IWineD3DImpl_AddRef(IWineD3D *iface) { IWineD3DImpl *This = (IWineD3DImpl *)iface; - FIXME("(%p) : AddRef increasing from %ld\n", This, This->ref); + TRACE("(%p) : AddRef increasing from %ld\n", This, This->ref); return InterlockedIncrement(&This->ref); } diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c new file mode 100644 index 00000000000..754e1f8babb --- /dev/null +++ b/dlls/wined3d/stateblock.c @@ -0,0 +1,73 @@ +/* + * state block implementation + * + * Copyright 2002 Raphael Junqueira + * 2004 Jason Edmeades + * + * 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 "wined3d_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3d); + +HRESULT WINAPI IWineD3DStateBlockImpl_InitStartupStateBlock(IWineD3DStateBlock* iface) { + IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface; + + /* 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->blockType = D3DSBT_ALL; + + TRACE("-----------------------> Device defaults now set up...\n"); + return D3D_OK; +} + +/********************************************************** + * IUnknown parts follows + **********************************************************/ +HRESULT WINAPI IWineD3DStateBlockImpl_QueryInterface(IWineD3DStateBlock *iface,REFIID riid,LPVOID *ppobj) +{ + return E_NOINTERFACE; +} + +ULONG WINAPI IWineD3DStateBlockImpl_AddRef(IWineD3DStateBlock *iface) { + IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface; + TRACE("(%p) : AddRef increasing from %ld\n", This, This->ref); + return InterlockedIncrement(&This->ref); +} + +ULONG WINAPI IWineD3DStateBlockImpl_Release(IWineD3DStateBlock *iface) { + IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface; + ULONG ref; + TRACE("(%p) : Releasing from %ld\n", This, This->ref); + ref = InterlockedDecrement(&This->ref); + if (ref == 0) HeapFree(GetProcessHeap(), 0, This); + return ref; +} + +/********************************************************** + * IWineD3DStateBlock VTbl follows + **********************************************************/ + +IWineD3DStateBlockVtbl IWineD3DStateBlock_Vtbl = +{ + IWineD3DStateBlockImpl_QueryInterface, + IWineD3DStateBlockImpl_AddRef, + IWineD3DStateBlockImpl_Release, + IWineD3DStateBlockImpl_InitStartupStateBlock +}; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 33dadf7ab38..977a510fa81 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -86,6 +86,8 @@ extern int num_lock; } \ } +typedef struct IWineD3DStateBlockImpl IWineD3DStateBlockImpl; + /***************************************************************************** * IWineD3D implementation structure */ @@ -133,6 +135,11 @@ typedef struct IWineD3DDeviceImpl BOOL view_ident; /* true iff view matrix is identity */ BOOL last_was_rhw; /* true iff last draw_primitive was in xyzrhw mode */ + /* State block related */ + BOOL isRecordingState; + IWineD3DStateBlockImpl *stateBlock; + IWineD3DStateBlockImpl *updateStateBlock; + /* Internal use fields */ D3DDEVICE_CREATION_PARAMETERS createParms; D3DPRESENT_PARAMETERS presentParms; @@ -184,14 +191,46 @@ typedef struct IWineD3DVertexBufferImpl extern IWineD3DVertexBufferVtbl IWineD3DVertexBuffer_Vtbl; -/* Utility function prototypes */ +/***************************************************************************** + * IWineD3DStateBlock implementation structure + */ + +/* Internal state Block for Begin/End/Capture/Create/Apply info */ +/* Note: Very long winded but gl Lists are not flexible enough */ +/* to resolve everything we need, so doing it manually for now */ +typedef struct SAVEDSTATES { + BOOL fvf; +} SAVEDSTATES; + +struct IWineD3DStateBlockImpl +{ + /* IUnknown fields */ + IWineD3DStateBlockVtbl *lpVtbl; + DWORD ref; /* Note: Ref counting not required */ + + /* IWineD3DStateBlock information */ + IWineD3DDevice *wineD3DDevice; + D3DSTATEBLOCKTYPE blockType; + + /* Array indicating whether things have been set or changed */ + SAVEDSTATES changed; + SAVEDSTATES set; + + /* Drawing - Vertex Shader or FVF related */ + DWORD fvf; + +}; + +extern IWineD3DStateBlockVtbl IWineD3DStateBlock_Vtbl; + +/***************************************************************************** + * Utility function prototypes + */ const char* debug_d3dformat(D3DFORMAT fmt); const char* debug_d3ddevicetype(D3DDEVTYPE devtype); const char* debug_d3dresourcetype(D3DRESOURCETYPE res); const char* debug_d3dusage(DWORD usage); - - #if 0 /* Needs fixing during rework */ /***************************************************************************** * IDirect3DVertexShaderDeclaration implementation structure diff --git a/include/wine/wined3d_interface.h b/include/wine/wined3d_interface.h index a3e2550c68a..60f38d66dea 100644 --- a/include/wine/wined3d_interface.h +++ b/include/wine/wined3d_interface.h @@ -37,7 +37,7 @@ /***************************************************************************** - * WineD3D Structures + * WineD3D Structures to be used when d3d8 and d3d9 are incompatible */ typedef struct _WINED3DADAPTER_IDENTIFIER { @@ -74,6 +74,7 @@ typedef struct IWineD3D IWineD3D; typedef struct IWineD3DDevice IWineD3DDevice; typedef struct IWineD3DResource IWineD3DResource; typedef struct IWineD3DVertexBuffer IWineD3DVertexBuffer; +typedef struct IWineD3DStateBlock IWineD3DStateBlock; /***************************************************************************** * WineD3D interface @@ -141,6 +142,9 @@ DECLARE_INTERFACE_(IWineD3DDevice,IUnknown) STDMETHOD_(ULONG,Release)(THIS) PURE; /*** IWineD3D methods ***/ STDMETHOD(CreateVertexBuffer)(THIS_ UINT Length,DWORD Usage,DWORD FVF,D3DPOOL Pool,IWineD3DVertexBuffer **ppVertexBuffer, HANDLE *sharedHandle) PURE; + STDMETHOD(CreateStateBlock)(THIS_ D3DSTATEBLOCKTYPE Type, IWineD3DStateBlock **ppStateBlock) PURE; + STDMETHOD(SetFVF)(THIS_ DWORD fvf) PURE; + STDMETHOD(GetFVF)(THIS_ DWORD * pfvf) PURE; }; #undef INTERFACE @@ -151,6 +155,9 @@ DECLARE_INTERFACE_(IWineD3DDevice,IUnknown) #define IWineD3DDevice_Release(p) (p)->lpVtbl->Release(p) /*** IWineD3DDevice methods ***/ #define IWineD3DDevice_CreateVertexBuffer(p,a,b,c,d,e,f) (p)->lpVtbl->CreateVertexBuffer(p,a,b,c,d,e,f) +#define IWineD3DDevice_CreateStateBlock(p,a,b) (p)->lpVtbl->CreateStateBlock(p,a,b) +#define IWineD3DDevice_SetFVF(p,a) (p)->lpVtbl->SetFVF(p,a) +#define IWineD3DDevice_GetFVF(p,a) (p)->lpVtbl->GetFVF(p,a) #endif /***************************************************************************** @@ -237,6 +244,31 @@ DECLARE_INTERFACE_(IWineD3DVertexBuffer,IDirect3DResource8) #define IWineD3DVertexBuffer_GetDesc(p,a) (p)->lpVtbl->GetDesc(p,a) #endif +/***************************************************************************** + * WineD3DStateBlock interface + */ +#define INTERFACE IWineD3DStateBlock +DECLARE_INTERFACE_(IWineD3DStateBlock,IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + /*** IWineD3DStateBlock methods ***/ + STDMETHOD(InitStartupStateBlock)(THIS) PURE; +}; +#undef INTERFACE + +#if !defined(__cplusplus) || defined(CINTERFACE) +/*** IUnknown methods ***/ +#define IWineD3DStateBlock_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IWineD3DStateBlock_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IWineD3DStateBlock_Release(p) (p)->lpVtbl->Release(p) +/*** IWineD3DStateBlock methods ***/ +#define IWineD3DStateBlock_InitStartupStateBlock(p) (p)->lpVtbl->InitStartupStateBlock(p) +#endif + + #if 0 /* FIXME: During porting in from d3d8 - the following will be used */ /***************************************************************** * Some defines