VirtualBox

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

Last change on this file since 32891 was 25949, checked in by vboxsync, 15 years ago

crOpenGL: update to wine 1.1.36 and disable unnecessary fbo state poll

  • Property svn:eol-style set to native
File size: 10.3 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 * Copyright 2009 Henri Verbeet for CodeWeavers
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
25/*
26 * Sun LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
27 * other than GPL or LGPL is available it will apply instead, Sun elects to use only
28 * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
29 * a choice of LGPL license versions is made available with the language indicating
30 * that LGPLv2 or any later version may be used, or where a choice of which version
31 * of the LGPL is applied is otherwise unspecified.
32 */
33
34#include "config.h"
35#include "wined3d_private.h"
36
37WINE_DEFAULT_DEBUG_CHANNEL(d3d_decl);
38
39static void dump_wined3dvertexelement(const WINED3DVERTEXELEMENT *element) {
40 TRACE(" format: %s (%#x)\n", debug_d3dformat(element->format), element->format);
41 TRACE(" input_slot: %u\n", element->input_slot);
42 TRACE(" offset: %u\n", element->offset);
43 TRACE("output_slot: %u\n", element->output_slot);
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_idx: %u\n", element->usage_idx);
47}
48
49/* *******************************************
50 IWineD3DVertexDeclaration IUnknown parts follow
51 ******************************************* */
52static HRESULT WINAPI IWineD3DVertexDeclarationImpl_QueryInterface(IWineD3DVertexDeclaration *iface, REFIID riid, LPVOID *ppobj)
53{
54 IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
55 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj);
56 if (IsEqualGUID(riid, &IID_IUnknown)
57 || IsEqualGUID(riid, &IID_IWineD3DBase)
58 || IsEqualGUID(riid, &IID_IWineD3DVertexDeclaration)){
59 IUnknown_AddRef(iface);
60 *ppobj = This;
61 return S_OK;
62 }
63 *ppobj = NULL;
64 return E_NOINTERFACE;
65}
66
67static ULONG WINAPI IWineD3DVertexDeclarationImpl_AddRef(IWineD3DVertexDeclaration *iface) {
68 IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
69 TRACE("(%p) : AddRef increasing from %d\n", This, This->ref);
70 return InterlockedIncrement(&This->ref);
71}
72
73static ULONG WINAPI IWineD3DVertexDeclarationImpl_Release(IWineD3DVertexDeclaration *iface) {
74 IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
75 ULONG ref;
76 TRACE("(%p) : Releasing from %d\n", This, This->ref);
77 ref = InterlockedDecrement(&This->ref);
78 if (!ref)
79 {
80 HeapFree(GetProcessHeap(), 0, This->elements);
81 This->parent_ops->wined3d_object_destroyed(This->parent);
82 HeapFree(GetProcessHeap(), 0, This);
83 }
84 return ref;
85}
86
87/* *******************************************
88 IWineD3DVertexDeclaration parts follow
89 ******************************************* */
90
91static HRESULT WINAPI IWineD3DVertexDeclarationImpl_GetParent(IWineD3DVertexDeclaration *iface, IUnknown** parent){
92 IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
93
94 *parent= This->parent;
95 IUnknown_AddRef(*parent);
96 TRACE("(%p) : returning %p\n", This, *parent);
97 return WINED3D_OK;
98}
99
100static BOOL declaration_element_valid_ffp(const WINED3DVERTEXELEMENT *element)
101{
102 switch(element->usage)
103 {
104 case WINED3DDECLUSAGE_POSITION:
105 case WINED3DDECLUSAGE_POSITIONT:
106 switch(element->format)
107 {
108 case WINED3DFMT_R32G32_FLOAT:
109 case WINED3DFMT_R32G32B32_FLOAT:
110 case WINED3DFMT_R32G32B32A32_FLOAT:
111 case WINED3DFMT_R16G16_SINT:
112 case WINED3DFMT_R16G16B16A16_SINT:
113 case WINED3DFMT_R16G16_FLOAT:
114 case WINED3DFMT_R16G16B16A16_FLOAT:
115 return TRUE;
116 default:
117 return FALSE;
118 }
119
120 case WINED3DDECLUSAGE_BLENDWEIGHT:
121 switch(element->format)
122 {
123 case WINED3DFMT_R32_FLOAT:
124 case WINED3DFMT_R32G32_FLOAT:
125 case WINED3DFMT_R32G32B32_FLOAT:
126 case WINED3DFMT_R32G32B32A32_FLOAT:
127 case WINED3DFMT_B8G8R8A8_UNORM:
128 case WINED3DFMT_R8G8B8A8_UINT:
129 case WINED3DFMT_R16G16_SINT:
130 case WINED3DFMT_R16G16B16A16_SINT:
131 case WINED3DFMT_R16G16_FLOAT:
132 case WINED3DFMT_R16G16B16A16_FLOAT:
133 return TRUE;
134 default:
135 return FALSE;
136 }
137
138 case WINED3DDECLUSAGE_NORMAL:
139 switch(element->format)
140 {
141 case WINED3DFMT_R32G32B32_FLOAT:
142 case WINED3DFMT_R32G32B32A32_FLOAT:
143 case WINED3DFMT_R16G16B16A16_SINT:
144 case WINED3DFMT_R16G16B16A16_FLOAT:
145 return TRUE;
146 default:
147 return FALSE;
148 }
149
150 case WINED3DDECLUSAGE_TEXCOORD:
151 switch(element->format)
152 {
153 case WINED3DFMT_R32_FLOAT:
154 case WINED3DFMT_R32G32_FLOAT:
155 case WINED3DFMT_R32G32B32_FLOAT:
156 case WINED3DFMT_R32G32B32A32_FLOAT:
157 case WINED3DFMT_R16G16_SINT:
158 case WINED3DFMT_R16G16B16A16_SINT:
159 case WINED3DFMT_R16G16_FLOAT:
160 case WINED3DFMT_R16G16B16A16_FLOAT:
161 return TRUE;
162 default:
163 return FALSE;
164 }
165
166 case WINED3DDECLUSAGE_COLOR:
167 switch(element->format)
168 {
169 case WINED3DFMT_R32G32B32_FLOAT:
170 case WINED3DFMT_R32G32B32A32_FLOAT:
171 case WINED3DFMT_B8G8R8A8_UNORM:
172 case WINED3DFMT_R8G8B8A8_UINT:
173 case WINED3DFMT_R16G16B16A16_SINT:
174 case WINED3DFMT_R8G8B8A8_UNORM:
175 case WINED3DFMT_R16G16B16A16_SNORM:
176 case WINED3DFMT_R16G16B16A16_UNORM:
177 case WINED3DFMT_R16G16B16A16_FLOAT:
178 return TRUE;
179 default:
180 return FALSE;
181 }
182
183 default:
184 return FALSE;
185 }
186}
187
188static const IWineD3DVertexDeclarationVtbl IWineD3DVertexDeclaration_Vtbl =
189{
190 /* IUnknown */
191 IWineD3DVertexDeclarationImpl_QueryInterface,
192 IWineD3DVertexDeclarationImpl_AddRef,
193 IWineD3DVertexDeclarationImpl_Release,
194 /* IWineD3DVertexDeclaration */
195 IWineD3DVertexDeclarationImpl_GetParent,
196};
197
198HRESULT vertexdeclaration_init(IWineD3DVertexDeclarationImpl *declaration, IWineD3DDeviceImpl *device,
199 const WINED3DVERTEXELEMENT *elements, UINT element_count,
200 IUnknown *parent, const struct wined3d_parent_ops *parent_ops)
201{
202 const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
203 WORD preloaded = 0; /* MAX_STREAMS, 16 */
204 unsigned int i;
205
206 if (TRACE_ON(d3d_decl))
207 {
208 for (i = 0; i < element_count; ++i)
209 {
210 dump_wined3dvertexelement(elements + i);
211 }
212 }
213
214 declaration->lpVtbl = &IWineD3DVertexDeclaration_Vtbl;
215 declaration->ref = 1;
216 declaration->parent = parent;
217 declaration->parent_ops = parent_ops;
218 declaration->device = device;
219 declaration->elements = HeapAlloc(GetProcessHeap(), 0, sizeof(*declaration->elements) * element_count);
220 if (!declaration->elements)
221 {
222 ERR("Failed to allocate elements memory.\n");
223 return E_OUTOFMEMORY;
224 }
225 declaration->element_count = element_count;
226
227 /* Do some static analysis on the elements to make reading the
228 * declaration more comfortable for the drawing code. */
229 for (i = 0; i < element_count; ++i)
230 {
231 struct wined3d_vertex_declaration_element *e = &declaration->elements[i];
232
233 e->format_desc = getFormatDescEntry(elements[i].format, gl_info);
234 e->ffp_valid = declaration_element_valid_ffp(&elements[i]);
235 e->input_slot = elements[i].input_slot;
236 e->offset = elements[i].offset;
237 e->output_slot = elements[i].output_slot;
238 e->method = elements[i].method;
239 e->usage = elements[i].usage;
240 e->usage_idx = elements[i].usage_idx;
241
242 if (e->usage == WINED3DDECLUSAGE_POSITIONT) declaration->position_transformed = TRUE;
243
244 /* Find the streams used in the declaration. The vertex buffers have
245 * to be loaded when drawing, but filter tesselation pseudo streams. */
246 if (e->input_slot >= MAX_STREAMS) continue;
247
248 if (!e->format_desc->gl_vtx_format)
249 {
250 FIXME("The application tries to use an unsupported format (%s), returning E_FAIL.\n",
251 debug_d3dformat(elements[i].format));
252 HeapFree(GetProcessHeap(), 0, declaration->elements);
253 return E_FAIL;
254 }
255
256 if (e->offset & 0x3)
257 {
258 WARN("Declaration element %u is not 4 byte aligned(%u), returning E_FAIL.\n", i, e->offset);
259 HeapFree(GetProcessHeap(), 0, declaration->elements);
260 return E_FAIL;
261 }
262
263 if (!(preloaded & (1 << e->input_slot)))
264 {
265 declaration->streams[declaration->num_streams] = e->input_slot;
266 ++declaration->num_streams;
267 preloaded |= 1 << e->input_slot;
268 }
269
270 if (elements[i].format == WINED3DFMT_R16G16_FLOAT || elements[i].format == WINED3DFMT_R16G16B16A16_FLOAT)
271 {
272 if (!gl_info->supported[ARB_HALF_FLOAT_VERTEX]) declaration->half_float_conv_needed = TRUE;
273 }
274 }
275
276 return WINED3D_OK;
277}
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