VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/vertexdeclaration.c@ 16684

Last change on this file since 16684 was 16477, checked in by vboxsync, 16 years ago

LGPL disclaimer by filemuncher

  • Property svn:eol-style set to native
File size: 12.7 KB
Line 
1/*
2 * vertex declaration implementation
3 *
4 * Copyright 2002-2005 Raphael Junqueira
5 * Copyright 2004 Jason Edmeades
6 * Copyright 2004 Christian Costa
7 * Copyright 2005 Oliver Stieber
8 *
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.
13 *
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.
18 *
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
22 */
23
24/*
25 * Sun LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
26 * other than GPL or LGPL is available it will apply instead, Sun elects to use only
27 * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
28 * a choice of LGPL license versions is made available with the language indicating
29 * that LGPLv2 or any later version may be used, or where a choice of which version
30 * of the LGPL is applied is otherwise unspecified.
31 */
32
33#include "config.h"
34#include "wined3d_private.h"
35
36WINE_DEFAULT_DEBUG_CHANNEL(d3d_decl);
37
38#define GLINFO_LOCATION This->wineD3DDevice->adapter->gl_info
39
40static void dump_wined3dvertexelement(const WINED3DVERTEXELEMENT *element) {
41 TRACE(" Stream: %d\n", element->Stream);
42 TRACE(" Offset: %d\n", element->Offset);
43 TRACE(" Type: %s (%#x)\n", debug_d3ddecltype(element->Type), element->Type);
44 TRACE(" Method: %s (%#x)\n", debug_d3ddeclmethod(element->Method), element->Method);
45 TRACE(" Usage: %s (%#x)\n", debug_d3ddeclusage(element->Usage), element->Usage);
46 TRACE("Usage index: %d\n", element->UsageIndex);
47 TRACE(" Register: %d\n", element->Reg);
48}
49
50/* *******************************************
51 IWineD3DVertexDeclaration IUnknown parts follow
52 ******************************************* */
53static HRESULT WINAPI IWineD3DVertexDeclarationImpl_QueryInterface(IWineD3DVertexDeclaration *iface, REFIID riid, LPVOID *ppobj)
54{
55 IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
56 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj);
57 if (IsEqualGUID(riid, &IID_IUnknown)
58 || IsEqualGUID(riid, &IID_IWineD3DBase)
59 || IsEqualGUID(riid, &IID_IWineD3DVertexDeclaration)){
60 IUnknown_AddRef(iface);
61 *ppobj = This;
62 return S_OK;
63 }
64 *ppobj = NULL;
65 return E_NOINTERFACE;
66}
67
68static ULONG WINAPI IWineD3DVertexDeclarationImpl_AddRef(IWineD3DVertexDeclaration *iface) {
69 IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
70 TRACE("(%p) : AddRef increasing from %d\n", This, This->ref);
71 return InterlockedIncrement(&This->ref);
72}
73
74static ULONG WINAPI IWineD3DVertexDeclarationImpl_Release(IWineD3DVertexDeclaration *iface) {
75 IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
76 ULONG ref;
77 TRACE("(%p) : Releasing from %d\n", This, This->ref);
78 ref = InterlockedDecrement(&This->ref);
79 if (ref == 0) {
80 if(iface == This->wineD3DDevice->stateBlock->vertexDecl) {
81 /* See comment in PixelShader::Release */
82 IWineD3DDeviceImpl_MarkStateDirty(This->wineD3DDevice, STATE_VDECL);
83 }
84
85 HeapFree(GetProcessHeap(), 0, This->pDeclarationWine);
86 HeapFree(GetProcessHeap(), 0, This->ffp_valid);
87 HeapFree(GetProcessHeap(), 0, This);
88 }
89 return ref;
90}
91
92/* *******************************************
93 IWineD3DVertexDeclaration parts follow
94 ******************************************* */
95
96static HRESULT WINAPI IWineD3DVertexDeclarationImpl_GetParent(IWineD3DVertexDeclaration *iface, IUnknown** parent){
97 IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
98
99 *parent= This->parent;
100 IUnknown_AddRef(*parent);
101 TRACE("(%p) : returning %p\n", This, *parent);
102 return WINED3D_OK;
103}
104
105static HRESULT WINAPI IWineD3DVertexDeclarationImpl_GetDevice(IWineD3DVertexDeclaration *iface, IWineD3DDevice** ppDevice) {
106 IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
107 TRACE("(%p) : returning %p\n", This, This->wineD3DDevice);
108
109 *ppDevice = (IWineD3DDevice *) This->wineD3DDevice;
110 IWineD3DDevice_AddRef(*ppDevice);
111
112 return WINED3D_OK;
113}
114
115static HRESULT WINAPI IWineD3DVertexDeclarationImpl_GetDeclaration(IWineD3DVertexDeclaration *iface,
116 WINED3DVERTEXELEMENT *elements, UINT *element_count) {
117 IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
118 HRESULT hr = WINED3D_OK;
119
120 TRACE("(%p) : d3d version %d, elements %p, element_count %p\n",
121 This, ((IWineD3DImpl *)This->wineD3DDevice->wineD3D)->dxVersion, elements, element_count);
122
123 *element_count = This->declarationWNumElements;
124 if (elements) {
125 CopyMemory(elements, This->pDeclarationWine, This->declarationWNumElements * sizeof(WINED3DVERTEXELEMENT));
126 }
127
128 return hr;
129}
130
131static BOOL declaration_element_valid_ffp(const WINED3DVERTEXELEMENT *element)
132{
133 switch(element->Usage)
134 {
135 case WINED3DDECLUSAGE_POSITION:
136 case WINED3DDECLUSAGE_POSITIONT:
137 switch(element->Type)
138 {
139 case WINED3DDECLTYPE_FLOAT2:
140 case WINED3DDECLTYPE_FLOAT3:
141 case WINED3DDECLTYPE_FLOAT4:
142 case WINED3DDECLTYPE_SHORT2:
143 case WINED3DDECLTYPE_SHORT4:
144 case WINED3DDECLTYPE_FLOAT16_2:
145 case WINED3DDECLTYPE_FLOAT16_4:
146 return TRUE;
147 default:
148 return FALSE;
149 }
150
151 case WINED3DDECLUSAGE_BLENDWEIGHT:
152 switch(element->Type)
153 {
154 case WINED3DDECLTYPE_D3DCOLOR:
155 case WINED3DDECLTYPE_UBYTE4:
156 case WINED3DDECLTYPE_SHORT2:
157 case WINED3DDECLTYPE_SHORT4:
158 case WINED3DDECLTYPE_FLOAT16_2:
159 case WINED3DDECLTYPE_FLOAT16_4:
160 return TRUE;
161 default:
162 return FALSE;
163 }
164
165 case WINED3DDECLUSAGE_NORMAL:
166 switch(element->Type)
167 {
168 case WINED3DDECLTYPE_FLOAT3:
169 case WINED3DDECLTYPE_FLOAT4:
170 case WINED3DDECLTYPE_SHORT4:
171 case WINED3DDECLTYPE_FLOAT16_4:
172 return TRUE;
173 default:
174 return FALSE;
175 }
176
177 case WINED3DDECLUSAGE_TEXCOORD:
178 switch(element->Type)
179 {
180 case WINED3DDECLTYPE_FLOAT1:
181 case WINED3DDECLTYPE_FLOAT2:
182 case WINED3DDECLTYPE_FLOAT3:
183 case WINED3DDECLTYPE_FLOAT4:
184 case WINED3DDECLTYPE_SHORT2:
185 case WINED3DDECLTYPE_SHORT4:
186 case WINED3DDECLTYPE_FLOAT16_2:
187 case WINED3DDECLTYPE_FLOAT16_4:
188 return TRUE;
189 default:
190 return FALSE;
191 }
192
193 case WINED3DDECLUSAGE_COLOR:
194 switch(element->Type)
195 {
196 case WINED3DDECLTYPE_FLOAT3:
197 case WINED3DDECLTYPE_FLOAT4:
198 case WINED3DDECLTYPE_D3DCOLOR:
199 case WINED3DDECLTYPE_UBYTE4:
200 case WINED3DDECLTYPE_SHORT4:
201 case WINED3DDECLTYPE_UBYTE4N:
202 case WINED3DDECLTYPE_SHORT4N:
203 case WINED3DDECLTYPE_USHORT4N:
204 case WINED3DDECLTYPE_FLOAT16_4:
205 return TRUE;
206 default:
207 return FALSE;
208 }
209
210 default:
211 return FALSE;
212 }
213}
214
215static HRESULT WINAPI IWineD3DVertexDeclarationImpl_SetDeclaration(IWineD3DVertexDeclaration *iface,
216 const WINED3DVERTEXELEMENT *elements, UINT element_count) {
217 IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
218 HRESULT hr = WINED3D_OK;
219 int i, j;
220 char isPreLoaded[MAX_STREAMS];
221
222 TRACE("(%p) : d3d version %d\n", This, ((IWineD3DImpl *)This->wineD3DDevice->wineD3D)->dxVersion);
223 memset(isPreLoaded, 0, sizeof(isPreLoaded));
224
225 if (TRACE_ON(d3d_decl)) {
226 for (i = 0; i < element_count; ++i) {
227 dump_wined3dvertexelement(elements+i);
228 }
229 }
230
231 This->declarationWNumElements = element_count;
232 This->pDeclarationWine = HeapAlloc(GetProcessHeap(), 0, sizeof(WINED3DVERTEXELEMENT) * element_count);
233 This->ffp_valid = HeapAlloc(GetProcessHeap(), 0, sizeof(*This->ffp_valid) * element_count);
234 if (!This->pDeclarationWine || !This->ffp_valid) {
235 ERR("Memory allocation failed\n");
236 return WINED3DERR_OUTOFVIDEOMEMORY;
237 } else {
238 CopyMemory(This->pDeclarationWine, elements, sizeof(WINED3DVERTEXELEMENT) * element_count);
239 }
240
241 /* Do some static analysis on the elements to make reading the declaration more comfortable
242 * for the drawing code
243 */
244 This->num_streams = 0;
245 This->position_transformed = FALSE;
246 for (i = 0; i < element_count; ++i) {
247 This->ffp_valid[i] = declaration_element_valid_ffp(&This->pDeclarationWine[i]);
248
249 if(This->pDeclarationWine[i].Usage == WINED3DDECLUSAGE_POSITIONT) {
250 This->position_transformed = TRUE;
251 }
252
253 /* Find the Streams used in the declaration. The vertex buffers have to be loaded
254 * when drawing, but filter tesselation pseudo streams
255 */
256 if(This->pDeclarationWine[i].Stream >= MAX_STREAMS) continue;
257
258 if(This->pDeclarationWine[i].Type == WINED3DDECLTYPE_UNUSED) {
259 WARN("The application tries to use WINED3DDECLTYPE_UNUSED, returning E_FAIL\n");
260 /* The caller will release the vdecl, which will free This->pDeclarationWine */
261 return E_FAIL;
262 }
263
264 if(This->pDeclarationWine[i].Offset & 0x3) {
265 WARN("Declaration element %d is not 4 byte aligned(%d), returning E_FAIL\n", i, This->pDeclarationWine[i].Offset);
266 return E_FAIL;
267 }
268
269 if(!isPreLoaded[This->pDeclarationWine[i].Stream]) {
270 This->streams[This->num_streams] = This->pDeclarationWine[i].Stream;
271 This->num_streams++;
272 isPreLoaded[This->pDeclarationWine[i].Stream] = 1;
273 }
274
275 /* Create a sorted array containing the attribute declarations that are of type
276 * D3DCOLOR. D3DCOLOR requires swizzling of the r and b component, and if the
277 * declaration of one attribute changes the vertex shader needs recompilation.
278 * Having a sorted array of the attributes allows efficient comparison of the
279 * declaration against a shader
280 */
281 if(This->pDeclarationWine[i].Type == WINED3DDECLTYPE_D3DCOLOR) {
282 for(j = 0; j < This->num_swizzled_attribs; j++) {
283 if(This->swizzled_attribs[j].usage > This->pDeclarationWine[i].Usage ||
284 (This->swizzled_attribs[j].usage == This->pDeclarationWine[i].Usage &&
285 This->swizzled_attribs[j].idx > This->pDeclarationWine[i].UsageIndex)) {
286 memmove(&This->swizzled_attribs[j + 1], &This->swizzled_attribs[j],
287 sizeof(This->swizzled_attribs) - (sizeof(This->swizzled_attribs[0]) * (j + 1)));
288 break;
289 }
290 }
291
292 This->swizzled_attribs[j].usage = This->pDeclarationWine[i].Usage;
293 This->swizzled_attribs[j].idx = This->pDeclarationWine[i].UsageIndex;
294 This->num_swizzled_attribs++;
295 } else if(This->pDeclarationWine[i].Type == WINED3DDECLTYPE_FLOAT16_2 ||
296 This->pDeclarationWine[i].Type == WINED3DDECLTYPE_FLOAT16_4) {
297 if(!GL_SUPPORT(NV_HALF_FLOAT)) {
298 This->half_float_conv_needed = TRUE;
299 }
300 }
301 }
302
303 TRACE("Swizzled attributes found:\n");
304 for(i = 0; i < This->num_swizzled_attribs; i++) {
305 TRACE("%u: %s%d\n", i,
306 debug_d3ddeclusage(This->swizzled_attribs[i].usage), This->swizzled_attribs[i].idx);
307 }
308 TRACE("Returning\n");
309 return hr;
310}
311
312const IWineD3DVertexDeclarationVtbl IWineD3DVertexDeclaration_Vtbl =
313{
314 /* IUnknown */
315 IWineD3DVertexDeclarationImpl_QueryInterface,
316 IWineD3DVertexDeclarationImpl_AddRef,
317 IWineD3DVertexDeclarationImpl_Release,
318 /* IWineD3DVertexDeclaration */
319 IWineD3DVertexDeclarationImpl_GetParent,
320 IWineD3DVertexDeclarationImpl_GetDevice,
321 IWineD3DVertexDeclarationImpl_GetDeclaration,
322 IWineD3DVertexDeclarationImpl_SetDeclaration
323};
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette