VirtualBox

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

最後變更 在這個檔案從23571是 23571,由 vboxsync 提交於 15 年 前

crOpenGL: update to wine 1.1.30

  • 屬性 svn:eol-style 設為 native
檔案大小: 11.0 KB
 
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
39#define GLINFO_LOCATION This->wineD3DDevice->adapter->gl_info
40
41static void dump_wined3dvertexelement(const WINED3DVERTEXELEMENT *element) {
42 TRACE(" format: %s (%#x)\n", debug_d3dformat(element->format), element->format);
43 TRACE(" input_slot: %u\n", element->input_slot);
44 TRACE(" offset: %u\n", element->offset);
45 TRACE("output_slot: %u\n", element->output_slot);
46 TRACE(" method: %s (%#x)\n", debug_d3ddeclmethod(element->method), element->method);
47 TRACE(" usage: %s (%#x)\n", debug_d3ddeclusage(element->usage), element->usage);
48 TRACE(" usage_idx: %u\n", element->usage_idx);
49}
50
51/* *******************************************
52 IWineD3DVertexDeclaration IUnknown parts follow
53 ******************************************* */
54static HRESULT WINAPI IWineD3DVertexDeclarationImpl_QueryInterface(IWineD3DVertexDeclaration *iface, REFIID riid, LPVOID *ppobj)
55{
56 IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
57 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj);
58 if (IsEqualGUID(riid, &IID_IUnknown)
59 || IsEqualGUID(riid, &IID_IWineD3DBase)
60 || IsEqualGUID(riid, &IID_IWineD3DVertexDeclaration)){
61 IUnknown_AddRef(iface);
62 *ppobj = This;
63 return S_OK;
64 }
65 *ppobj = NULL;
66 return E_NOINTERFACE;
67}
68
69static ULONG WINAPI IWineD3DVertexDeclarationImpl_AddRef(IWineD3DVertexDeclaration *iface) {
70 IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
71 TRACE("(%p) : AddRef increasing from %d\n", This, This->ref);
72 return InterlockedIncrement(&This->ref);
73}
74
75static ULONG WINAPI IWineD3DVertexDeclarationImpl_Release(IWineD3DVertexDeclaration *iface) {
76 IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
77 ULONG ref;
78 TRACE("(%p) : Releasing from %d\n", This, This->ref);
79 ref = InterlockedDecrement(&This->ref);
80 if (ref == 0) {
81 if(iface == This->wineD3DDevice->stateBlock->vertexDecl) {
82 /* See comment in PixelShader::Release */
83 IWineD3DDeviceImpl_MarkStateDirty(This->wineD3DDevice, STATE_VDECL);
84 }
85
86 HeapFree(GetProcessHeap(), 0, This->elements);
87 This->parent_ops->wined3d_object_destroyed(This->parent);
88 HeapFree(GetProcessHeap(), 0, This);
89 }
90 return ref;
91}
92
93/* *******************************************
94 IWineD3DVertexDeclaration parts follow
95 ******************************************* */
96
97static HRESULT WINAPI IWineD3DVertexDeclarationImpl_GetParent(IWineD3DVertexDeclaration *iface, IUnknown** parent){
98 IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
99
100 *parent= This->parent;
101 IUnknown_AddRef(*parent);
102 TRACE("(%p) : returning %p\n", This, *parent);
103 return WINED3D_OK;
104}
105
106static HRESULT WINAPI IWineD3DVertexDeclarationImpl_GetDevice(IWineD3DVertexDeclaration *iface, IWineD3DDevice** ppDevice) {
107 IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
108 TRACE("(%p) : returning %p\n", This, This->wineD3DDevice);
109
110 *ppDevice = (IWineD3DDevice *) This->wineD3DDevice;
111 IWineD3DDevice_AddRef(*ppDevice);
112
113 return WINED3D_OK;
114}
115
116static BOOL declaration_element_valid_ffp(const WINED3DVERTEXELEMENT *element)
117{
118 switch(element->usage)
119 {
120 case WINED3DDECLUSAGE_POSITION:
121 case WINED3DDECLUSAGE_POSITIONT:
122 switch(element->format)
123 {
124 case WINED3DFMT_R32G32_FLOAT:
125 case WINED3DFMT_R32G32B32_FLOAT:
126 case WINED3DFMT_R32G32B32A32_FLOAT:
127 case WINED3DFMT_R16G16_SINT:
128 case WINED3DFMT_R16G16B16A16_SINT:
129 case WINED3DFMT_R16G16_FLOAT:
130 case WINED3DFMT_R16G16B16A16_FLOAT:
131 return TRUE;
132 default:
133 return FALSE;
134 }
135
136 case WINED3DDECLUSAGE_BLENDWEIGHT:
137 switch(element->format)
138 {
139 case WINED3DFMT_R32_FLOAT:
140 case WINED3DFMT_R32G32_FLOAT:
141 case WINED3DFMT_R32G32B32_FLOAT:
142 case WINED3DFMT_R32G32B32A32_FLOAT:
143 case WINED3DFMT_B8G8R8A8_UNORM:
144 case WINED3DFMT_R8G8B8A8_UINT:
145 case WINED3DFMT_R16G16_SINT:
146 case WINED3DFMT_R16G16B16A16_SINT:
147 case WINED3DFMT_R16G16_FLOAT:
148 case WINED3DFMT_R16G16B16A16_FLOAT:
149 return TRUE;
150 default:
151 return FALSE;
152 }
153
154 case WINED3DDECLUSAGE_NORMAL:
155 switch(element->format)
156 {
157 case WINED3DFMT_R32G32B32_FLOAT:
158 case WINED3DFMT_R32G32B32A32_FLOAT:
159 case WINED3DFMT_R16G16B16A16_SINT:
160 case WINED3DFMT_R16G16B16A16_FLOAT:
161 return TRUE;
162 default:
163 return FALSE;
164 }
165
166 case WINED3DDECLUSAGE_TEXCOORD:
167 switch(element->format)
168 {
169 case WINED3DFMT_R32_FLOAT:
170 case WINED3DFMT_R32G32_FLOAT:
171 case WINED3DFMT_R32G32B32_FLOAT:
172 case WINED3DFMT_R32G32B32A32_FLOAT:
173 case WINED3DFMT_R16G16_SINT:
174 case WINED3DFMT_R16G16B16A16_SINT:
175 case WINED3DFMT_R16G16_FLOAT:
176 case WINED3DFMT_R16G16B16A16_FLOAT:
177 return TRUE;
178 default:
179 return FALSE;
180 }
181
182 case WINED3DDECLUSAGE_COLOR:
183 switch(element->format)
184 {
185 case WINED3DFMT_R32G32B32_FLOAT:
186 case WINED3DFMT_R32G32B32A32_FLOAT:
187 case WINED3DFMT_B8G8R8A8_UNORM:
188 case WINED3DFMT_R8G8B8A8_UINT:
189 case WINED3DFMT_R16G16B16A16_SINT:
190 case WINED3DFMT_R8G8B8A8_UNORM:
191 case WINED3DFMT_R16G16B16A16_SNORM:
192 case WINED3DFMT_R16G16B16A16_UNORM:
193 case WINED3DFMT_R16G16B16A16_FLOAT:
194 return TRUE;
195 default:
196 return FALSE;
197 }
198
199 default:
200 return FALSE;
201 }
202}
203
204static const IWineD3DVertexDeclarationVtbl IWineD3DVertexDeclaration_Vtbl =
205{
206 /* IUnknown */
207 IWineD3DVertexDeclarationImpl_QueryInterface,
208 IWineD3DVertexDeclarationImpl_AddRef,
209 IWineD3DVertexDeclarationImpl_Release,
210 /* IWineD3DVertexDeclaration */
211 IWineD3DVertexDeclarationImpl_GetParent,
212 IWineD3DVertexDeclarationImpl_GetDevice,
213};
214
215HRESULT vertexdeclaration_init(IWineD3DVertexDeclarationImpl *declaration, IWineD3DDeviceImpl *device,
216 const WINED3DVERTEXELEMENT *elements, UINT element_count,
217 IUnknown *parent, const struct wined3d_parent_ops *parent_ops)
218{
219 const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
220 WORD preloaded = 0; /* MAX_STREAMS, 16 */
221 unsigned int i;
222
223 if (TRACE_ON(d3d_decl))
224 {
225 for (i = 0; i < element_count; ++i)
226 {
227 dump_wined3dvertexelement(elements + i);
228 }
229 }
230
231 declaration->lpVtbl = &IWineD3DVertexDeclaration_Vtbl;
232 declaration->ref = 1;
233 declaration->parent = parent;
234 declaration->parent_ops = parent_ops;
235 declaration->wineD3DDevice = device;
236 declaration->elements = HeapAlloc(GetProcessHeap(), 0, sizeof(*declaration->elements) * element_count);
237 if (!declaration->elements)
238 {
239 ERR("Failed to allocate elements memory.\n");
240 return E_OUTOFMEMORY;
241 }
242 declaration->element_count = element_count;
243
244 /* Do some static analysis on the elements to make reading the
245 * declaration more comfortable for the drawing code. */
246 for (i = 0; i < element_count; ++i)
247 {
248 struct wined3d_vertex_declaration_element *e = &declaration->elements[i];
249
250 e->format_desc = getFormatDescEntry(elements[i].format, gl_info);
251 e->ffp_valid = declaration_element_valid_ffp(&elements[i]);
252 e->input_slot = elements[i].input_slot;
253 e->offset = elements[i].offset;
254 e->output_slot = elements[i].output_slot;
255 e->method = elements[i].method;
256 e->usage = elements[i].usage;
257 e->usage_idx = elements[i].usage_idx;
258
259 if (e->usage == WINED3DDECLUSAGE_POSITIONT) declaration->position_transformed = TRUE;
260
261 /* Find the streams used in the declaration. The vertex buffers have
262 * to be loaded when drawing, but filter tesselation pseudo streams. */
263 if (e->input_slot >= MAX_STREAMS) continue;
264
265 if (!e->format_desc->gl_vtx_format)
266 {
267 FIXME("The application tries to use an unsupported format (%s), returning E_FAIL.\n",
268 debug_d3dformat(elements[i].format));
269 HeapFree(GetProcessHeap(), 0, declaration->elements);
270 return E_FAIL;
271 }
272
273 if (e->offset & 0x3)
274 {
275 WARN("Declaration element %u is not 4 byte aligned(%u), returning E_FAIL.\n", i, e->offset);
276 HeapFree(GetProcessHeap(), 0, declaration->elements);
277 return E_FAIL;
278 }
279
280 if (!(preloaded & (1 << e->input_slot)))
281 {
282 declaration->streams[declaration->num_streams] = e->input_slot;
283 ++declaration->num_streams;
284 preloaded |= 1 << e->input_slot;
285 }
286
287 if (elements[i].format == WINED3DFMT_R16G16_FLOAT || elements[i].format == WINED3DFMT_R16G16B16A16_FLOAT)
288 {
289 if (!gl_info->supported[ARB_HALF_FLOAT_VERTEX]) declaration->half_float_conv_needed = TRUE;
290 }
291 }
292
293 return WINED3D_OK;
294}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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