2 * vertex declaration implementation
4 * Copyright 2002-2005 Raphael Junqueira
5 * Copyright 2004 Jason Edmeades
6 * Copyright 2004 Christian Costa
7 * Copyright 2005 Oliver Stieber
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #include "wined3d_private.h"
27 WINE_DEFAULT_DEBUG_CHANNEL(d3d_decl
);
29 static void dump_wined3dvertexelement(const WINED3DVERTEXELEMENT
*element
) {
30 TRACE(" Stream: %d\n", element
->Stream
);
31 TRACE(" Offset: %d\n", element
->Offset
);
32 TRACE(" Type: %s (%#x)\n", debug_d3ddecltype(element
->Type
), element
->Type
);
33 TRACE(" Method: %s (%#x)\n", debug_d3ddeclmethod(element
->Method
), element
->Method
);
34 TRACE(" Usage: %s (%#x)\n", debug_d3ddeclusage(element
->Usage
), element
->Usage
);
35 TRACE("Usage index: %d\n", element
->UsageIndex
);
36 TRACE(" Register: %d\n", element
->Reg
);
39 /* *******************************************
40 IWineD3DVertexDeclaration IUnknown parts follow
41 ******************************************* */
42 static HRESULT WINAPI
IWineD3DVertexDeclarationImpl_QueryInterface(IWineD3DVertexDeclaration
*iface
, REFIID riid
, LPVOID
*ppobj
)
44 IWineD3DVertexDeclarationImpl
*This
= (IWineD3DVertexDeclarationImpl
*)iface
;
45 TRACE("(%p)->(%s,%p)\n",This
,debugstr_guid(riid
),ppobj
);
46 if (IsEqualGUID(riid
, &IID_IUnknown
)
47 || IsEqualGUID(riid
, &IID_IWineD3DBase
)
48 || IsEqualGUID(riid
, &IID_IWineD3DVertexDeclaration
)){
49 IUnknown_AddRef(iface
);
57 static ULONG WINAPI
IWineD3DVertexDeclarationImpl_AddRef(IWineD3DVertexDeclaration
*iface
) {
58 IWineD3DVertexDeclarationImpl
*This
= (IWineD3DVertexDeclarationImpl
*)iface
;
59 TRACE("(%p) : AddRef increasing from %d\n", This
, This
->ref
);
60 return InterlockedIncrement(&This
->ref
);
63 static ULONG WINAPI
IWineD3DVertexDeclarationImpl_Release(IWineD3DVertexDeclaration
*iface
) {
64 IWineD3DVertexDeclarationImpl
*This
= (IWineD3DVertexDeclarationImpl
*)iface
;
66 TRACE("(%p) : Releasing from %d\n", This
, This
->ref
);
67 ref
= InterlockedDecrement(&This
->ref
);
69 if(iface
== This
->wineD3DDevice
->stateBlock
->vertexDecl
) {
70 /* See comment in PixelShader::Release */
71 IWineD3DDeviceImpl_MarkStateDirty(This
->wineD3DDevice
, STATE_VDECL
);
74 HeapFree(GetProcessHeap(), 0, This
->pDeclarationWine
);
75 HeapFree(GetProcessHeap(), 0, This
);
80 /* *******************************************
81 IWineD3DVertexDeclaration parts follow
82 ******************************************* */
84 static HRESULT WINAPI
IWineD3DVertexDeclarationImpl_GetParent(IWineD3DVertexDeclaration
*iface
, IUnknown
** parent
){
85 IWineD3DVertexDeclarationImpl
*This
= (IWineD3DVertexDeclarationImpl
*)iface
;
87 *parent
= This
->parent
;
88 IUnknown_AddRef(*parent
);
89 TRACE("(%p) : returning %p\n", This
, *parent
);
93 static HRESULT WINAPI
IWineD3DVertexDeclarationImpl_GetDevice(IWineD3DVertexDeclaration
*iface
, IWineD3DDevice
** ppDevice
) {
94 IWineD3DVertexDeclarationImpl
*This
= (IWineD3DVertexDeclarationImpl
*)iface
;
95 TRACE("(%p) : returning %p\n", This
, This
->wineD3DDevice
);
97 *ppDevice
= (IWineD3DDevice
*) This
->wineD3DDevice
;
98 IWineD3DDevice_AddRef(*ppDevice
);
103 static HRESULT WINAPI
IWineD3DVertexDeclarationImpl_GetDeclaration(IWineD3DVertexDeclaration
*iface
,
104 WINED3DVERTEXELEMENT
*elements
, size_t *element_count
) {
105 IWineD3DVertexDeclarationImpl
*This
= (IWineD3DVertexDeclarationImpl
*)iface
;
106 HRESULT hr
= WINED3D_OK
;
108 TRACE("(%p) : d3d version %d, elements %p, element_count %p\n",
109 This
, ((IWineD3DImpl
*)This
->wineD3DDevice
->wineD3D
)->dxVersion
, elements
, element_count
);
111 *element_count
= This
->declarationWNumElements
;
113 CopyMemory(elements
, This
->pDeclarationWine
, This
->declarationWNumElements
* sizeof(WINED3DVERTEXELEMENT
));
119 static HRESULT WINAPI
IWineD3DVertexDeclarationImpl_SetDeclaration(IWineD3DVertexDeclaration
*iface
,
120 const WINED3DVERTEXELEMENT
*elements
, size_t element_count
) {
121 IWineD3DVertexDeclarationImpl
*This
= (IWineD3DVertexDeclarationImpl
*)iface
;
122 HRESULT hr
= WINED3D_OK
;
124 char isPreLoaded
[MAX_STREAMS
];
126 TRACE("(%p) : d3d version %d\n", This
, ((IWineD3DImpl
*)This
->wineD3DDevice
->wineD3D
)->dxVersion
);
127 memset(isPreLoaded
, 0, sizeof(isPreLoaded
));
129 if (TRACE_ON(d3d_decl
)) {
130 for (i
= 0; i
< element_count
; ++i
) {
131 dump_wined3dvertexelement(elements
+i
);
135 This
->declarationWNumElements
= element_count
;
136 This
->pDeclarationWine
= HeapAlloc(GetProcessHeap(), 0, sizeof(WINED3DVERTEXELEMENT
) * element_count
);
137 if (!This
->pDeclarationWine
) {
138 ERR("Memory allocation failed\n");
139 return WINED3DERR_OUTOFVIDEOMEMORY
;
141 CopyMemory(This
->pDeclarationWine
, elements
, sizeof(WINED3DVERTEXELEMENT
) * element_count
);
144 /* Do some static analysis on the elements to make reading the declaration more comfortable
145 * for the drawing code
147 This
->num_streams
= 0;
148 This
->position_transformed
= FALSE
;
149 for (i
= 0; i
< element_count
; ++i
) {
151 if(This
->pDeclarationWine
[i
].Usage
== WINED3DDECLUSAGE_POSITIONT
) {
152 This
->position_transformed
= TRUE
;
155 /* Find the Streams used in the declaration. The vertex buffers have to be loaded
156 * when drawing, but filter tesselation pseudo streams
158 if(This
->pDeclarationWine
[i
].Stream
>= MAX_STREAMS
) continue;
160 if(!isPreLoaded
[This
->pDeclarationWine
[i
].Stream
]) {
161 This
->streams
[This
->num_streams
] = This
->pDeclarationWine
[i
].Stream
;
163 isPreLoaded
[This
->pDeclarationWine
[i
].Stream
] = 1;
167 TRACE("Returning\n");
171 const IWineD3DVertexDeclarationVtbl IWineD3DVertexDeclaration_Vtbl
=
174 IWineD3DVertexDeclarationImpl_QueryInterface
,
175 IWineD3DVertexDeclarationImpl_AddRef
,
176 IWineD3DVertexDeclarationImpl_Release
,
177 /* IWineD3DVertexDeclaration */
178 IWineD3DVertexDeclarationImpl_GetParent
,
179 IWineD3DVertexDeclarationImpl_GetDevice
,
180 IWineD3DVertexDeclarationImpl_GetDeclaration
,
181 IWineD3DVertexDeclarationImpl_SetDeclaration