[6/9] wined3d: Get rid of the vertexDeclaration field in IWineD3DVertexShaderImpl

H. Verbeet hverbeet at gmail.com
Tue Feb 13 16:12:29 CST 2007


This removes the vertexDeclaration field in IWineD3DVertexShaderImpl
and calls SetVertexDeclaration at the appropriate times instead. One
thing that needs to change a bit for this to work is setting the usage
and usage index properties of d3d8 vertex shaders, since it gets those
from the vertex declaration, but needs them before calling
IWineD3DVertexShader_SetFunction.

Changelog:
  - Get rid of the vertexDeclaration field in IWineD3DVertexShaderImpl
-------------- next part --------------
---

 dlls/d3d8/device.c                |    9 +++++++--
 dlls/wined3d/arb_program_shader.c |    4 +---
 dlls/wined3d/device.c             |   17 +++--------------
 dlls/wined3d/drawprim.c           |   11 +----------
 dlls/wined3d/glsl_shader.c        |    5 +----
 dlls/wined3d/state.c              |    4 +---
 dlls/wined3d/vertexshader.c       |   36 +++++++++++++++---------------------
 dlls/wined3d/wined3d_private.h    |    1 -
 include/wine/wined3d_interface.h  |    4 +++-
 9 files changed, 32 insertions(+), 59 deletions(-)

diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c
index d82919c..06eca32 100644
--- a/dlls/d3d8/device.c
+++ b/dlls/d3d8/device.c
@@ -1195,6 +1195,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexShader(LPDIRECT3DDEVICE8
     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
     HRESULT hrc = D3D_OK;
     IDirect3DVertexShader8Impl *object;
+    IWineD3DVertexDeclaration *wined3d_vertex_declaration;
 
     /* Setup a stub object for now */
     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
@@ -1215,9 +1216,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexShader(LPDIRECT3DDEVICE8
         *ppShader = 0;
         return D3DERR_INVALIDCALL;
     }
+    wined3d_vertex_declaration = ((IDirect3DVertexDeclaration8Impl *)object->vertex_declaration)->wined3d_vertex_declaration;
 
     /* Usage is missing ..*/
-    hrc = IWineD3DDevice_CreateVertexShader(This->WineD3DDevice, pDeclaration, pFunction, &object->wineD3DVertexShader, (IUnknown *)object);
+    hrc = IWineD3DDevice_CreateVertexShader(This->WineD3DDevice, wined3d_vertex_declaration, pFunction, &object->wineD3DVertexShader, (IUnknown *)object);
 
     if (FAILED(hrc)) {
         /* free up object */
@@ -1252,6 +1254,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShader(LPDIRECT3DDEVICE8 ifa
         IWineD3DDevice_SetFVF(This->WineD3DDevice, pShader);
 
 	/* Call SetVertexShader with a NULL shader to set the vertexshader in the stateblock to NULL. */
+        IWineD3DDevice_SetVertexDeclaration(This->WineD3DDevice, NULL);
         IWineD3DDevice_SetVertexShader(This->WineD3DDevice, NULL);
     } else {
         TRACE("Setting shader\n");
@@ -1260,7 +1263,9 @@ static HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShader(LPDIRECT3DDEVICE8 ifa
             hrc = D3DERR_INVALIDCALL;
         } else {
             IDirect3DVertexShader8Impl *shader = This->shader_handles[pShader - (VS_HIGHESTFIXEDFXF + 1)];
-            hrc =  IWineD3DDevice_SetVertexShader(This->WineD3DDevice, 0 == shader ? NULL : shader->wineD3DVertexShader);
+            IWineD3DDevice_SetVertexDeclaration(This->WineD3DDevice,
+                    shader ? ((IDirect3DVertexDeclaration8Impl *)shader->vertex_declaration)->wined3d_vertex_declaration : NULL);
+            hrc = IWineD3DDevice_SetVertexShader(This->WineD3DDevice, 0 == shader ? NULL : shader->wineD3DVertexShader);
         }
     }
     TRACE("(%p) : returning hr(%u)\n", This, hrc);
diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index e6f9510..6da40cc 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -113,9 +113,7 @@ void shader_arb_load_constants(
 
     if (useVertexShader) {
         IWineD3DBaseShaderImpl* vshader = (IWineD3DBaseShaderImpl*) stateBlock->vertexShader;
-        IWineD3DVertexShaderImpl* vshader_impl = (IWineD3DVertexShaderImpl*) stateBlock->vertexShader;
-        IWineD3DVertexDeclarationImpl* vertexDeclaration = 
-            (IWineD3DVertexDeclarationImpl*) vshader_impl->vertexDeclaration;
+        IWineD3DVertexDeclarationImpl* vertexDeclaration = (IWineD3DVertexDeclarationImpl*) stateBlock->vertexDecl;
 
         if (NULL != vertexDeclaration && NULL != vertexDeclaration->constants) {
             /* Load DirectX 8 float constants for vertex shader */
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 2315a45..60fe8da 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -1672,7 +1672,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexDeclaration(IWineD3DDevice*
 }
 
 /* http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/directx9_c/directx/graphics/programmingguide/programmable/vertexshaders/vscreate.asp */
-static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexShader(IWineD3DDevice *iface, CONST DWORD *pDeclaration, CONST DWORD *pFunction, IWineD3DVertexShader **ppVertexShader, IUnknown *parent) {
+static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexShader(IWineD3DDevice *iface, IWineD3DVertexDeclaration *vertex_declaration, CONST DWORD *pFunction, IWineD3DVertexShader **ppVertexShader, IUnknown *parent) {
     IWineD3DDeviceImpl       *This = (IWineD3DDeviceImpl *)iface;
     IWineD3DVertexShaderImpl *object;  /* NOTE: impl usage is ok, this is a create */
     HRESULT hr = WINED3D_OK;
@@ -1681,19 +1681,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexShader(IWineD3DDevice *ifac
 
     TRACE("(%p) : Created Vertex shader %p\n", This, *ppVertexShader);
 
-    /* If a vertex declaration has been passed, save it to the vertex shader, this affects d3d8 only. */
-    /* Further it needs to be set before calling SetFunction as SetFunction needs the declaration. */
-    if (pDeclaration != NULL) {
-        IWineD3DVertexDeclaration *vertexDeclaration;
-        hr = IWineD3DDevice_CreateVertexDeclaration(iface, pDeclaration, &vertexDeclaration ,NULL);
-        if (WINED3D_OK == hr) {
-            TRACE("(%p) : Setting vertex declaration to %p\n", This, vertexDeclaration);
-            object->vertexDeclaration = vertexDeclaration;
-        } else {
-            FIXME("(%p) : Failed to set the declaration, returning WINED3DERR_INVALIDCALL\n", iface);
-            IWineD3DVertexShader_Release(*ppVertexShader);
-            return WINED3DERR_INVALIDCALL;
-        }
+    if (vertex_declaration) {
+        IWineD3DVertexShader_FakeSemantics(*ppVertexShader, vertex_declaration);
     }
 
     hr = IWineD3DVertexShader_SetFunction(*ppVertexShader, pFunction);
diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c
index 94f24ed..329b5ee 100644
--- a/dlls/wined3d/drawprim.c
+++ b/dlls/wined3d/drawprim.c
@@ -150,7 +150,7 @@ void primitiveDeclarationConvertToStridedData(
 
     BYTE  *data    = NULL;
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    IWineD3DVertexDeclarationImpl* vertexDeclaration = NULL;
+    IWineD3DVertexDeclarationImpl* vertexDeclaration = (IWineD3DVertexDeclarationImpl *)This->stateBlock->vertexDecl;
     int i;
     WINED3DVERTEXELEMENT *element;
     DWORD stride;
@@ -160,15 +160,6 @@ void primitiveDeclarationConvertToStridedData(
 
     memset(isPreLoaded, 0, sizeof(isPreLoaded));
 
-    /* Locate the vertex declaration */
-    if (This->stateBlock->vertexShader && ((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->vertexDeclaration) {
-        TRACE("Using vertex declaration from shader\n");
-        vertexDeclaration = (IWineD3DVertexDeclarationImpl *)((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->vertexDeclaration;
-    } else {
-        TRACE("Using vertex declaration\n");
-        vertexDeclaration = (IWineD3DVertexDeclarationImpl *)This->stateBlock->vertexDecl;
-    }
-
     /* Translate the declaration into strided data */
     for (i = 0 ; i < vertexDeclaration->declarationWNumElements - 1; ++i) {
         GLint streamVBO = 0;
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index eea8cfc..1388c88 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -313,12 +313,9 @@ void shader_glsl_load_constants(
 
     if (useVertexShader) {
         IWineD3DBaseShaderImpl* vshader = (IWineD3DBaseShaderImpl*) stateBlock->vertexShader;
-        IWineD3DVertexShaderImpl* vshader_impl = (IWineD3DVertexShaderImpl*) vshader;
+        IWineD3DVertexDeclarationImpl* vertexDeclaration = (IWineD3DVertexDeclarationImpl*)stateBlock->vertexDecl;
         GLint pos;
 
-        IWineD3DVertexDeclarationImpl* vertexDeclaration =
-            (IWineD3DVertexDeclarationImpl*) vshader_impl->vertexDeclaration;
-
         constant_locations = stateBlock->glsl_program->vuniformF_locations;
         constant_list = &stateBlock->set_vconstantsF;
 
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index ef1d3a6..9893dcb 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -2583,9 +2583,7 @@ static inline void handleStreams(IWineD3DStateBlockImpl *stateblock, BOOL useVer
         TRACE("================ Vertex Declaration  ===================\n");
         memset(dataLocations, 0, sizeof(*dataLocations));
 
-        if (stateblock->vertexDecl != NULL ||
-            ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->vertexDeclaration != NULL) {
-
+        if (stateblock->vertexDecl) {
             primitiveDeclarationConvertToStridedData((IWineD3DDevice *) device, useVertexShaderFunction,
                 dataLocations, &fixup);
         }
diff --git a/dlls/wined3d/vertexshader.c b/dlls/wined3d/vertexshader.c
index 961f4f9..d9204e0 100644
--- a/dlls/wined3d/vertexshader.c
+++ b/dlls/wined3d/vertexshader.c
@@ -661,20 +661,12 @@ BOOL vshader_input_is_color(
 
     IWineD3DVertexShaderImpl* This = (IWineD3DVertexShaderImpl*) iface;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
+    IWineD3DVertexDeclarationImpl *vertexDeclaration = (IWineD3DVertexDeclarationImpl *)deviceImpl->stateBlock->vertexDecl;
 
     DWORD usage_token = This->semantics_in[regnum].usage;
     DWORD usage = (usage_token & WINED3DSP_DCL_USAGE_MASK) >> WINED3DSP_DCL_USAGE_SHIFT;
     DWORD usage_idx = (usage_token & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT;
 
-    IWineD3DVertexDeclarationImpl *vertexDeclaration = NULL;
-    if (This->vertexDeclaration) {
-        /* D3D8 declaration */
-        vertexDeclaration = (IWineD3DVertexDeclarationImpl *)This->vertexDeclaration;
-    } else {
-        /* D3D9 declaration */
-        vertexDeclaration = (IWineD3DVertexDeclarationImpl *) (deviceImpl->stateBlock->vertexDecl);
-    }
-
     if (vertexDeclaration) {
         int i;
         /* Find the declaration element that matches our register, then check
@@ -1111,7 +1103,6 @@ static ULONG WINAPI IWineD3DVertexShaderImpl_Release(IWineD3DVertexShader *iface
     TRACE("(%p) : Releasing from %d\n", This, This->ref);
     ref = InterlockedDecrement(&This->ref);
     if (ref == 0) {
-        if (This->vertexDeclaration) IWineD3DVertexDeclaration_Release(This->vertexDeclaration);
         if (This->baseShader.shader_mode == SHADER_GLSL && This->baseShader.prgId != 0) {
             /* If this shader is still attached to a program, GL will perform a lazy delete */
             TRACE("Deleting shader object %u\n", This->baseShader.prgId);
@@ -1195,16 +1186,6 @@ static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader
     list_init(&This->baseShader.constantsB);
     list_init(&This->baseShader.constantsI);
 
-    /* Preload semantics for d3d8 shaders */
-    if (This->vertexDeclaration) {
-       IWineD3DVertexDeclarationImpl* vdecl = (IWineD3DVertexDeclarationImpl*) This->vertexDeclaration;
-       int i;
-       for (i = 0; i < vdecl->declarationWNumElements - 1; ++i) {
-           WINED3DVERTEXELEMENT* element = vdecl->pDeclarationWine + i;
-           vshader_set_input(This, element->Reg, element->Usage, element->UsageIndex);
-       }
-    }
-
     /* Second pass: figure out registers used, semantics, etc.. */
     memset(reg_maps, 0, sizeof(shader_reg_maps));
     hr = shader_get_registers_used((IWineD3DBaseShader*) This, reg_maps,
@@ -1228,6 +1209,18 @@ static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader
     return WINED3D_OK;
 }
 
+/* Preload semantics for d3d8 shaders */
+static void WINAPI IWineD3DVertexShaderImpl_FakeSemantics(IWineD3DVertexShader *iface, IWineD3DVertexDeclaration *vertex_declaration) {
+    IWineD3DVertexShaderImpl *This =(IWineD3DVertexShaderImpl *)iface;
+    IWineD3DVertexDeclarationImpl* vdecl = (IWineD3DVertexDeclarationImpl*)vertex_declaration;
+
+    int i;
+    for (i = 0; i < vdecl->declarationWNumElements - 1; ++i) {
+        WINED3DVERTEXELEMENT* element = vdecl->pDeclarationWine + i;
+        vshader_set_input(This, element->Reg, element->Usage, element->UsageIndex);
+    }
+}
+
 static HRESULT WINAPI IWineD3DVertexShaderImpl_CompileShader(IWineD3DVertexShader *iface) {
     IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
     CONST DWORD *function = This->baseShader.function;
@@ -1265,5 +1258,6 @@ const IWineD3DVertexShaderVtbl IWineD3DVertexShader_Vtbl =
     IWineD3DVertexShaderImpl_CompileShader,
     /*** IWineD3DVertexShader methods ***/
     IWineD3DVertexShaderImpl_GetDevice,
-    IWineD3DVertexShaderImpl_GetFunction
+    IWineD3DVertexShaderImpl_GetFunction,
+    IWineD3DVertexShaderImpl_FakeSemantics
 };
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index c59764b..b23cdcd 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1811,7 +1811,6 @@ typedef struct IWineD3DVertexShaderImpl {
 
     /* run time datas...  */
     VSHADERDATA                *data;
-    IWineD3DVertexDeclaration  *vertexDeclaration;
 #if 0 /* needs reworking */
     /* run time datas */
     VSHADERINPUTDATA input;
diff --git a/include/wine/wined3d_interface.h b/include/wine/wined3d_interface.h
index b6bf26e..093e18f 100644
--- a/include/wine/wined3d_interface.h
+++ b/include/wine/wined3d_interface.h
@@ -357,7 +357,7 @@ DECLARE_INTERFACE_(IWineD3DDevice,IWineD3DBase)
     STDMETHOD(CreateQuery)(THIS_ WINED3DQUERYTYPE Type, struct IWineD3DQuery **ppQuery, IUnknown *pParent);
     STDMETHOD(CreateAdditionalSwapChain)(THIS_ WINED3DPRESENT_PARAMETERS *pPresentationParameters, struct IWineD3DSwapChain **pSwapChain, IUnknown *pParent, D3DCB_CREATERENDERTARGETFN pFn, D3DCB_CREATEDEPTHSTENCILSURFACEFN pFn2);
     STDMETHOD(CreateVertexDeclaration)(THIS_ CONST VOID* pDeclaration, struct IWineD3DVertexDeclaration** ppDecl, IUnknown* pParent) PURE;
-    STDMETHOD(CreateVertexShader)(THIS_ CONST DWORD *pDeclaration, CONST DWORD* pFunction, struct IWineD3DVertexShader** ppShader, IUnknown *pParent) PURE;
+    STDMETHOD(CreateVertexShader)(THIS_ struct IWineD3DVertexDeclaration *vertex_declaration, CONST DWORD* pFunction, struct IWineD3DVertexShader** ppShader, IUnknown *pParent) PURE;
     STDMETHOD(CreatePixelShader)(THIS_ CONST DWORD* pFunction, struct IWineD3DPixelShader** ppShader, IUnknown *pParent) PURE;
     STDMETHOD_(HRESULT,CreatePalette)(THIS_ DWORD Flags, PALETTEENTRY *PalEnt, struct IWineD3DPalette **Palette, IUnknown *Parent);
     STDMETHOD(Init3D)(THIS_ WINED3DPRESENT_PARAMETERS* pPresentationParameters, D3DCB_CREATEADDITIONALSWAPCHAIN D3DCB_CreateAdditionalSwapChain);
@@ -1449,6 +1449,7 @@ DECLARE_INTERFACE_(IWineD3DVertexShader,IWineD3DBaseShader)
     /*** IWineD3DVertexShader methods ***/
     STDMETHOD(GetDevice)(THIS_ IWineD3DDevice** ppDevice) PURE;
     STDMETHOD(GetFunction)(THIS_ VOID *pData, UINT *pSizeOfData) PURE;
+    STDMETHOD_(void, FakeSemantics)(THIS_ struct IWineD3DVertexDeclaration *vertex_declaration) PURE;
 };
 #undef INTERFACE
 
@@ -1465,6 +1466,7 @@ DECLARE_INTERFACE_(IWineD3DVertexShader,IWineD3DBaseShader)
 /*** IWineD3DVertexShader methods ***/
 #define IWineD3DVertexShader_GetDevice(p,a)            (p)->lpVtbl->GetDevice(p,a)
 #define IWineD3DVertexShader_GetFunction(p,a,b)        (p)->lpVtbl->GetFunction(p,a,b)
+#define IWineD3DVertexShader_FakeSemantics(p,a)        (p)->lpVtbl->FakeSemantics(p,a)
 #endif
 
 /*****************************************************************************


More information about the wine-patches mailing list