2 * vertex declaration implementation
4 * Copyright 2002-2005 Raphael Junqueira
5 * Copyright 2004 Jason Edmeades
6 * Copyright 2004 Christian Costa
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include "wined3d_private.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(d3d_decl);
29 * DirectX9 SDK download
30 * http://msdn.microsoft.com/library/default.asp?url=/downloads/list/directx.asp
33 * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndrive/html/directx07162002.asp
35 * Using Vertex Shaders
36 * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndrive/html/directx02192001.asp
39 * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/whatsnew.asp
42 * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/Shaders/VertexShader2_0/VertexShader2_0.asp
43 * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/Shaders/VertexShader2_0/Instructions/Instructions.asp
44 * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/programmingguide/GettingStarted/VertexDeclaration/VertexDeclaration.asp
45 * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/Shaders/VertexShader3_0/VertexShader3_0.asp
48 * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/programmingguide/advancedtopics/VertexPipe/matrixstack/matrixstack.asp
51 * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/programmingguide/GettingStarted/VertexFormats/vformats.asp
53 * NVIDIA: DX8 Vertex Shader to NV Vertex Program
54 * http://developer.nvidia.com/view.asp?IO=vstovp
56 * NVIDIA: Memory Management with VAR
57 * http://developer.nvidia.com/view.asp?IO=var_memory_management
60 /** Vertex Shader Declaration 8 data types tokens */
61 #define MAX_VSHADER_DECL_TYPES 8
63 static CONST char* VertexDecl8_DataTypes[] = {
75 static CONST char* VertexDecl8_Registers[] = {
77 "D3DVSDE_BLENDWEIGHT",
78 "D3DVSDE_BLENDINDICES",
96 typedef enum _D3DVSD_TOKENTYPE {
98 D3DVSD_TOKEN_STREAM = 1,
99 D3DVSD_TOKEN_STREAMDATA = 2,
100 D3DVSD_TOKEN_TESSELLATOR = 3,
101 D3DVSD_TOKEN_CONSTMEM = 4,
102 D3DVSD_TOKEN_EXT = 5,
104 D3DVSD_TOKEN_END = 7,
105 D3DVSD_FORCE_DWORD = 0x7FFFFFFF
108 typedef enum _D3DVSDE_REGISTER {
109 D3DVSDE_POSITION = 0,
110 D3DVSDE_BLENDWEIGHT = 1,
111 D3DVSDE_BLENDINDICES = 2,
115 D3DVSDE_SPECULAR = 6,
116 D3DVSDE_TEXCOORD0 = 7,
117 D3DVSDE_TEXCOORD1 = 8,
118 D3DVSDE_TEXCOORD2 = 9,
119 D3DVSDE_TEXCOORD3 = 10,
120 D3DVSDE_TEXCOORD4 = 11,
121 D3DVSDE_TEXCOORD5 = 12,
122 D3DVSDE_TEXCOORD6 = 13,
123 D3DVSDE_TEXCOORD7 = 14,
124 D3DVSDE_POSITION2 = 15,
128 typedef enum _D3DVSDT_TYPE {
129 D3DVSDT_FLOAT1 = 0x00,
130 D3DVSDT_FLOAT2 = 0x01,
131 D3DVSDT_FLOAT3 = 0x02,
132 D3DVSDT_FLOAT4 = 0x03,
133 D3DVSDT_D3DCOLOR = 0x04,
134 D3DVSDT_UBYTE4 = 0x05,
135 D3DVSDT_SHORT2 = 0x06,
136 D3DVSDT_SHORT4 = 0x07
140 #define D3DVSD_CONSTADDRESSSHIFT 0
141 #define D3DVSD_EXTINFOSHIFT 0
142 #define D3DVSD_STREAMNUMBERSHIFT 0
143 #define D3DVSD_VERTEXREGSHIFT 0
144 #define D3DVSD_CONSTRSSHIFT 16
145 #define D3DVSD_DATATYPESHIFT 16
146 #define D3DVSD_SKIPCOUNTSHIFT 16
147 #define D3DVSD_VERTEXREGINSHIFT 20
148 #define D3DVSD_EXTCOUNTSHIFT 24
149 #define D3DVSD_CONSTCOUNTSHIFT 25
150 #define D3DVSD_DATALOADTYPESHIFT 28
151 #define D3DVSD_STREAMTESSSHIFT 28
152 #define D3DVSD_TOKENTYPESHIFT 29
154 #define D3DVSD_CONSTADDRESSMASK (0x7F << D3DVSD_CONSTADDRESSSHIFT)
155 #define D3DVSD_EXTINFOMASK (0xFFFFFF << D3DVSD_EXTINFOSHIFT)
156 #define D3DVSD_STREAMNUMBERMASK (0xF << D3DVSD_STREAMNUMBERSHIFT)
157 #define D3DVSD_VERTEXREGMASK (0x1F << D3DVSD_VERTEXREGSHIFT)
158 #define D3DVSD_CONSTRSMASK (0x1FFF << D3DVSD_CONSTRSSHIFT)
159 #define D3DVSD_DATATYPEMASK (0xF << D3DVSD_DATATYPESHIFT)
160 #define D3DVSD_SKIPCOUNTMASK (0xF << D3DVSD_SKIPCOUNTSHIFT)
161 #define D3DVSD_EXTCOUNTMASK (0x1F << D3DVSD_EXTCOUNTSHIFT)
162 #define D3DVSD_VERTEXREGINMASK (0xF << D3DVSD_VERTEXREGINSHIFT)
163 #define D3DVSD_CONSTCOUNTMASK (0xF << D3DVSD_CONSTCOUNTSHIFT)
164 #define D3DVSD_DATALOADTYPEMASK (0x1 << D3DVSD_DATALOADTYPESHIFT)
165 #define D3DVSD_STREAMTESSMASK (0x1 << D3DVSD_STREAMTESSSHIFT)
166 #define D3DVSD_TOKENTYPEMASK (0x7 << D3DVSD_TOKENTYPESHIFT)
168 #define D3DVSD_END() 0xFFFFFFFF
169 #define D3DVSD_NOP() 0x00000000
171 DWORD IWineD3DVertexDeclarationImpl_ParseToken8(const DWORD* pToken) {
172 const DWORD token = *pToken;
175 switch ((token & D3DVSD_TOKENTYPEMASK) >> D3DVSD_TOKENTYPESHIFT) { /* maybe a macro to inverse ... */
176 case D3DVSD_TOKEN_NOP:
177 TRACE(" 0x%08lx NOP()\n", token);
179 case D3DVSD_TOKEN_STREAM:
180 if (token & D3DVSD_STREAMTESSMASK) {
181 TRACE(" 0x%08lx STREAM_TESS()\n", token);
183 TRACE(" 0x%08lx STREAM(%lu)\n", token, ((token & D3DVSD_STREAMNUMBERMASK) >> D3DVSD_STREAMNUMBERSHIFT));
186 case D3DVSD_TOKEN_STREAMDATA:
187 if (token & 0x10000000) {
188 TRACE(" 0x%08lx SKIP(%lu)\n", token, ((token & D3DVSD_SKIPCOUNTMASK) >> D3DVSD_SKIPCOUNTSHIFT));
190 DWORD type = ((token & D3DVSD_DATATYPEMASK) >> D3DVSD_DATATYPESHIFT);
191 DWORD reg = ((token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT);
192 TRACE(" 0x%08lx REG(%s, %s)\n", token, VertexDecl8_Registers[reg], VertexDecl8_DataTypes[type]);
195 case D3DVSD_TOKEN_TESSELLATOR:
196 if (token & 0x10000000) {
197 DWORD type = ((token & D3DVSD_DATATYPEMASK) >> D3DVSD_DATATYPESHIFT);
198 DWORD reg = ((token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT);
199 TRACE(" 0x%08lx TESSUV(%s) as %s\n", token, VertexDecl8_Registers[reg], VertexDecl8_DataTypes[type]);
201 DWORD type = ((token & D3DVSD_DATATYPEMASK) >> D3DVSD_DATATYPESHIFT);
202 DWORD regout = ((token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT);
203 DWORD regin = ((token & D3DVSD_VERTEXREGINMASK) >> D3DVSD_VERTEXREGINSHIFT);
204 TRACE(" 0x%08lx TESSNORMAL(%s, %s) as %s\n", token, VertexDecl8_Registers[regin], VertexDecl8_Registers[regout], VertexDecl8_DataTypes[type]);
207 case D3DVSD_TOKEN_CONSTMEM:
210 DWORD count = ((token & D3DVSD_CONSTCOUNTMASK) >> D3DVSD_CONSTCOUNTSHIFT);
211 DWORD constaddress = ((token & D3DVSD_CONSTADDRESSMASK) >> D3DVSD_CONSTADDRESSSHIFT);
212 TRACE(" 0x%08lx CONST(%lu, %lu)\n", token, constaddress, count);
214 for (i = 0; i < count; ++i) {
216 TRACE(" c[%lu] = (0x%08lx, 0x%08lx, 0x%08lx, 0x%08lx)\n",
223 TRACE(" c[%lu] = (%8f, %8f, %8f, %8f)\n",
225 *(const float*) pToken,
226 *(const float*) (pToken + 1),
227 *(const float*) (pToken + 2),
228 *(const float*) (pToken + 3));
232 tokenlen = (4 * count) + 1;
235 case D3DVSD_TOKEN_EXT:
237 DWORD count = ((token & D3DVSD_CONSTCOUNTMASK) >> D3DVSD_CONSTCOUNTSHIFT);
238 DWORD extinfo = ((token & D3DVSD_EXTINFOMASK) >> D3DVSD_EXTINFOSHIFT);
239 TRACE(" 0x%08lx EXT(%lu, %lu)\n", token, count, extinfo);
240 /* todo ... print extension */
241 tokenlen = count + 1;
244 case D3DVSD_TOKEN_END:
245 TRACE(" 0x%08lx END()\n", token);
248 TRACE(" 0x%08lx UNKNOWN\n", token);
254 DWORD IWineD3DVertexDeclarationImpl_ParseToken9(const D3DVERTEXELEMENT9* pToken);
256 HRESULT IWineD3DVertexDeclarationImpl_ParseDeclaration8(IWineD3DDeviceImpl* This, const DWORD* pDecl, IWineD3DVertexDeclarationImpl* object) {
257 const DWORD* pToken = pDecl;
259 BOOL invalid_fvf = FALSE;
260 DWORD tex = D3DFVF_TEX0;
267 D3DVERTEXELEMENT9 convTo9[128];
269 TRACE("(%p) : pDecl(%p)\n", This, pDecl);
271 while (D3DVSD_END() != *pToken) {
273 tokenlen = IWineD3DVertexDeclarationImpl_ParseToken8(pToken);
274 tokentype = ((token & D3DVSD_TOKENTYPEMASK) >> D3DVSD_TOKENTYPESHIFT);
276 /** FVF generation block */
277 if (D3DVSD_TOKEN_STREAM == tokentype && 0 == (D3DVSD_STREAMTESSMASK & token)) {
279 * how really works streams,
280 * in DolphinVS dx8 dsk sample they seems to decal reg numbers !!!
282 DWORD oldStream = stream;
283 stream = ((token & D3DVSD_STREAMNUMBERMASK) >> D3DVSD_STREAMNUMBERSHIFT);
285 /* copy fvf if valid */
286 if (FALSE == invalid_fvf) {
287 fvf |= tex << D3DFVF_TEXCOUNT_SHIFT;
289 object->fvf[oldStream] = fvf;
290 object->allFVF |= fvf;
292 object->fvf[oldStream] = 0;
296 /* reset valid/invalid fvf */
300 } else if (D3DVSD_TOKEN_STREAMDATA == tokentype && 0 == (0x10000000 & tokentype)) {
301 DWORD type = ((token & D3DVSD_DATATYPEMASK) >> D3DVSD_DATATYPESHIFT);
302 DWORD reg = ((token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT);
304 convTo9[nTokens].Stream = stream;
305 convTo9[nTokens].Method = D3DDECLMETHOD_DEFAULT;
306 convTo9[nTokens].UsageIndex = 0;
307 convTo9[nTokens].Type = D3DDECLTYPE_UNUSED;
310 case D3DVSDE_POSITION:
311 convTo9[nTokens].Usage = D3DDECLUSAGE_POSITION;
312 convTo9[nTokens].Type = type;
314 case D3DVSDT_FLOAT3: fvf |= D3DFVF_XYZ; break;
315 case D3DVSDT_FLOAT4: fvf |= D3DFVF_XYZRHW; break;
317 /** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */
319 if (type >= MAX_VSHADER_DECL_TYPES) {
320 TRACE("Mismatched use in VertexShader declaration of D3DVSDE_POSITION register: unsupported and unrecognized type %08lx\n", type);
322 TRACE("Mismatched use in VertexShader declaration of D3DVSDE_POSITION register: unsupported type %s\n", VertexDecl8_DataTypes[type]);
327 case D3DVSDE_BLENDWEIGHT:
328 convTo9[nTokens].Usage = D3DDECLUSAGE_BLENDWEIGHT;
329 convTo9[nTokens].Type = type;
331 case D3DVSDT_FLOAT1: fvf |= D3DFVF_XYZB1; break;
332 case D3DVSDT_FLOAT2: fvf |= D3DFVF_XYZB2; break;
333 case D3DVSDT_FLOAT3: fvf |= D3DFVF_XYZB3; break;
334 case D3DVSDT_FLOAT4: fvf |= D3DFVF_XYZB4; break;
336 /** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */
338 TRACE("Mismatched use in VertexShader declaration of D3DVSDE_BLENDWEIGHT register: unsupported type %s\n", VertexDecl8_DataTypes[type]);
342 case D3DVSDE_BLENDINDICES: /* seem to be B5 as said in MSDN Dx9SDK ?? */
343 convTo9[nTokens].Usage = D3DDECLUSAGE_BLENDINDICES;
344 convTo9[nTokens].Type = type;
346 case D3DVSDT_UBYTE4: fvf |= D3DFVF_LASTBETA_UBYTE4; break;
348 /** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */
350 TRACE("Mismatched use in VertexShader declaration of D3DVSDE_BLENDINDINCES register: unsupported type %s\n", VertexDecl8_DataTypes[type]);
354 case D3DVSDE_NORMAL: /* TODO: only FLOAT3 supported ... another choice possible ? */
355 convTo9[nTokens].Usage = D3DDECLUSAGE_NORMAL;
356 convTo9[nTokens].Type = type;
358 case D3DVSDT_FLOAT3: fvf |= D3DFVF_NORMAL; break;
360 /** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */
362 TRACE("Mismatched use in VertexShader declaration of D3DVSDE_NORMAL register: unsupported type %s\n", VertexDecl8_DataTypes[type]);
366 case D3DVSDE_PSIZE: /* TODO: only FLOAT1 supported ... another choice possible ? */
367 convTo9[nTokens].Usage = D3DDECLUSAGE_PSIZE;
368 convTo9[nTokens].Type = type;
370 case D3DVSDT_FLOAT1: fvf |= D3DFVF_PSIZE; break;
372 /** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */
374 TRACE("Mismatched use in VertexShader declaration of D3DVSDE_PSIZE register: unsupported type %s\n", VertexDecl8_DataTypes[type]);
378 case D3DVSDE_DIFFUSE: /* TODO: only D3DCOLOR supported */
379 convTo9[nTokens].Usage = D3DDECLUSAGE_COLOR;
380 convTo9[nTokens].UsageIndex = 0;
381 convTo9[nTokens].Type = type;
383 case D3DVSDT_D3DCOLOR: fvf |= D3DFVF_DIFFUSE; break;
385 /** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */
387 TRACE("Mismatched use in VertexShader declaration of D3DVSDE_DIFFUSE register: unsupported type %s\n", VertexDecl8_DataTypes[type]);
391 case D3DVSDE_SPECULAR: /* TODO: only D3DCOLOR supported */
392 convTo9[nTokens].Usage = D3DDECLUSAGE_COLOR;
393 convTo9[nTokens].UsageIndex = 1;
394 convTo9[nTokens].Type = type;
396 case D3DVSDT_D3DCOLOR: fvf |= D3DFVF_SPECULAR; break;
398 /** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */
400 TRACE("Mismatched use in VertexShader declaration of D3DVSDE_SPECULAR register: unsupported type %s\n", VertexDecl8_DataTypes[type]);
404 case D3DVSDE_TEXCOORD0:
405 case D3DVSDE_TEXCOORD1:
406 case D3DVSDE_TEXCOORD2:
407 case D3DVSDE_TEXCOORD3:
408 case D3DVSDE_TEXCOORD4:
409 case D3DVSDE_TEXCOORD5:
410 case D3DVSDE_TEXCOORD6:
411 case D3DVSDE_TEXCOORD7:
412 /* Fixme? - assume all tex coords in same stream */
414 int texNo = 1 + (reg - D3DVSDE_TEXCOORD0);
415 convTo9[nTokens].Usage = D3DDECLUSAGE_TEXCOORD;
416 convTo9[nTokens].UsageIndex = texNo;
417 convTo9[nTokens].Type = type;
418 tex = max(tex, texNo);
420 case D3DVSDT_FLOAT1: fvf |= D3DFVF_TEXCOORDSIZE1(texNo); break;
421 case D3DVSDT_FLOAT2: fvf |= D3DFVF_TEXCOORDSIZE2(texNo); break;
422 case D3DVSDT_FLOAT3: fvf |= D3DFVF_TEXCOORDSIZE3(texNo); break;
423 case D3DVSDT_FLOAT4: fvf |= D3DFVF_TEXCOORDSIZE4(texNo); break;
425 /** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */
427 TRACE("Mismatched use in VertexShader declaration of D3DVSDE_TEXCOORD? register: unsupported type %s\n", VertexDecl8_DataTypes[type]);
432 case D3DVSDE_POSITION2: /* maybe D3DFVF_XYZRHW instead D3DFVF_XYZ (of D3DVDE_POSITION) ... to see */
433 case D3DVSDE_NORMAL2: /* FIXME i don't know what to do here ;( */
434 FIXME("[%lu] registers in VertexShader declaration not supported yet (token:0x%08lx)\n", reg, token);
437 TRACE("VertexShader declaration define %lx as current FVF\n", fvf);
443 /* here D3DVSD_END() */
444 len += IWineD3DVertexDeclarationImpl_ParseToken8(pToken);
446 convTo9[nTokens].Stream = 0xFF;
447 convTo9[nTokens].Type = D3DDECLTYPE_UNUSED;
449 /* copy fvf if valid */
450 if (FALSE == invalid_fvf) {
451 fvf |= tex << D3DFVF_TEXCOUNT_SHIFT;
452 object->fvf[stream] = fvf;
453 object->allFVF |= fvf;
455 object->fvf[stream] = 0;
457 TRACE("Completed, allFVF = %lx\n", object->allFVF);
460 object->declaration8Length = len * sizeof(DWORD);
461 /* copy the declaration */
462 object->pDeclaration8 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->declaration8Length);
463 memcpy(object->pDeclaration8, pDecl, object->declaration8Length);
465 /* compute convTo9 size */
466 object->declaration9NumElements = nTokens;
467 /* copy the convTo9 declaration */
468 object->pDeclaration9 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nTokens * sizeof(D3DVERTEXELEMENT9));
469 memcpy(object->pDeclaration9, convTo9, nTokens * sizeof(D3DVERTEXELEMENT9));
472 D3DVERTEXELEMENT9* pIt = object->pDeclaration9;
473 TRACE("dumping of D3D9 Convertion:\n");
474 while (0xFF != pIt->Stream) {
475 IWineD3DVertexDeclarationImpl_ParseToken9(pIt);
478 IWineD3DVertexDeclarationImpl_ParseToken9(pIt);
485 static CONST char* VertexDecl9_DeclUsages[] = {
486 "D3DDECLUSAGE_POSITION",
487 "D3DDECLUSAGE_BLENDWEIGHT",
488 "D3DDECLUSAGE_BLENDINDICES",
489 "D3DDECLUSAGE_NORMAL",
490 "D3DDECLUSAGE_PSIZE",
491 "D3DDECLUSAGE_TEXCOORD",
492 "D3DDECLUSAGE_TANGENT",
493 "D3DDECLUSAGE_BINORMAL",
494 "D3DDECLUSAGE_TESSFACTOR",
495 "D3DDECLUSAGE_POSITIONT",
496 "D3DDECLUSAGE_COLOR",
498 "D3DDECLUSAGE_DEPTH",
499 "D3DDECLUSAGE_SAMPLE",
503 static CONST char* VertexDecl9_DeclMethods[] = {
504 "D3DDECLMETHOD_DEFAULT",
505 "D3DDECLMETHOD_PARTIALU",
506 "D3DDECLMETHOD_PARTIALV",
507 "D3DDECLMETHOD_CROSSUV",
509 "D3DDECLMETHOD_LOOKUP",
510 "D3DDECLMETHOD_LOOKUPPRESAMPLED",
514 static CONST char* VertexDecl9_DeclTypes[] = {
515 "D3DDECLTYPE_FLOAT1",
516 "D3DDECLTYPE_FLOAT2",
517 "D3DDECLTYPE_FLOAT3",
518 "D3DDECLTYPE_FLOAT4",
519 "D3DDECLTYPE_D3DCOLOR",
520 "D3DDECLTYPE_UBYTE4",
521 "D3DDECLTYPE_SHORT2",
522 "D3DDECLTYPE_SHORT4",
524 "D3DDECLTYPE_UBYTE4N",
525 "D3DDECLTYPE_SHORT2N",
526 "D3DDECLTYPE_SHORT4N",
527 "D3DDECLTYPE_USHORT2N",
528 "D3DDECLTYPE_USHORT4N",
531 "D3DDECLTYPE_FLOAT16_2",
532 "D3DDECLTYPE_FLOAT16_4",
533 "D3DDECLTYPE_UNUSED",
537 DWORD IWineD3DVertexDeclarationImpl_ParseToken9(const D3DVERTEXELEMENT9* pToken) {
540 if (0xFF != pToken->Stream) {
541 TRACE(" D3DDECL(%u, %u, %s, %s, %s, %u)\n",
544 VertexDecl9_DeclTypes[pToken->Type],
545 VertexDecl9_DeclMethods[pToken->Method],
546 VertexDecl9_DeclUsages[pToken->Usage],
550 TRACE(" D3DDECL_END()\n" );
555 HRESULT IWineD3DVertexDeclarationImpl_ParseDeclaration9(IWineD3DDeviceImpl* This, const D3DVERTEXELEMENT9* pDecl, IWineD3DVertexDeclarationImpl* object) {
556 const D3DVERTEXELEMENT9* pToken = pDecl;
558 BOOL invalid_fvf = FALSE;
559 DWORD tex = D3DFVF_TEX0;
563 TRACE("(%p) : pDecl(%p)\n", This, pDecl);
565 while (0xFF != pToken->Stream) {
566 DWORD type = pToken->Type;
567 DWORD oldStream = stream;
568 stream = pToken->Stream;
570 IWineD3DVertexDeclarationImpl_ParseToken9(pToken);
572 if (D3DDECLMETHOD_DEFAULT != pToken->Method) {
574 "%s register: Unsupported Method of %s (only D3DDECLMETHOD_DEFAULT for now) for VertexDeclaration (type %s)\n",
575 VertexDecl9_DeclUsages[pToken->Usage],
576 VertexDecl9_DeclMethods[pToken->Method],
577 VertexDecl9_DeclTypes[pToken->Type]
581 if (oldStream != stream) {
583 if (FALSE == invalid_fvf) {
584 fvf |= tex << D3DFVF_TEXCOUNT_SHIFT;
586 object->fvf[oldStream] = fvf;
587 object->allFVF |= fvf;
589 object->fvf[oldStream] = 0;
593 /* reset valid/invalid fvf */
598 switch (pToken->Usage) {
599 case D3DDECLUSAGE_POSITION:
600 if (0 < pToken->UsageIndex) {
602 TRACE("Mismatched UsageIndex (%u) in VertexDeclaration for D3DDECLUSAGE_POSITION register: unsupported type %s\n",
603 pToken->UsageIndex, VertexDecl9_DeclTypes[type]);
607 case D3DDECLTYPE_FLOAT3: fvf |= D3DFVF_XYZ; break;
608 case D3DDECLTYPE_FLOAT4: fvf |= D3DFVF_XYZRHW; break;
610 /** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */
612 TRACE("Mismatched use in VertexDeclaration of D3DDECLUSAGE_POSITION register: unsupported type %s\n", VertexDecl9_DeclTypes[type]);
616 case D3DDECLUSAGE_BLENDWEIGHT:
618 case D3DDECLTYPE_FLOAT1: fvf |= D3DFVF_XYZB1; break;
619 case D3DDECLTYPE_FLOAT2: fvf |= D3DFVF_XYZB2; break;
620 case D3DDECLTYPE_FLOAT3: fvf |= D3DFVF_XYZB3; break;
621 case D3DDECLTYPE_FLOAT4: fvf |= D3DFVF_XYZB4; break;
623 /** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */
625 TRACE("Mismatched use in VertexDeclaration of D3DDECLUSAGE_BLENDWEIGHT register: unsupported type %s\n", VertexDecl9_DeclTypes[type]);
629 case D3DDECLUSAGE_BLENDINDICES:
631 case D3DDECLTYPE_UBYTE4: fvf |= D3DFVF_LASTBETA_UBYTE4; break;
633 /** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */
635 TRACE("Mismatched use in VertexDeclaration of D3DDECLUSAGE_BLENDINDINCES register: unsupported type %s\n", VertexDecl9_DeclTypes[type]);
639 case D3DDECLUSAGE_NORMAL:
640 if (0 < pToken->UsageIndex) {
642 TRACE("Mismatched UsageIndex (%u) in VertexDeclaration for D3DDECLUSAGE_NORMAL register: unsupported type %s\n",
643 pToken->UsageIndex, VertexDecl9_DeclTypes[type]);
647 case D3DDECLTYPE_FLOAT3: fvf |= D3DFVF_NORMAL; break;
649 /** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */
651 TRACE("Mismatched use in VertexDeclaration of D3DDECLUSAGE_NORMAL register: unsupported type %s\n", VertexDecl9_DeclTypes[type]);
655 case D3DDECLUSAGE_PSIZE:
657 case D3DDECLTYPE_FLOAT1: fvf |= D3DFVF_PSIZE; break;
659 /** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */
661 TRACE("Mismatched use in VertexDeclaration of D3DDECLUSAGE_PSIZE register: unsupported type %s\n", VertexDecl9_DeclTypes[type]);
665 case D3DDECLUSAGE_TEXCOORD:
667 DWORD texNo = pToken->UsageIndex;
668 tex = max(tex, texNo);
670 case D3DDECLTYPE_FLOAT1: fvf |= D3DFVF_TEXCOORDSIZE1(texNo); break;
671 case D3DDECLTYPE_FLOAT2: fvf |= D3DFVF_TEXCOORDSIZE2(texNo); break;
672 case D3DDECLTYPE_FLOAT3: fvf |= D3DFVF_TEXCOORDSIZE3(texNo); break;
673 case D3DDECLTYPE_FLOAT4: fvf |= D3DFVF_TEXCOORDSIZE4(texNo); break;
675 /** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */
677 TRACE("Mismatched use in VertexDeclaration of D3DDECLUSAGE_TEXCOORD[%lu] register: unsupported type %s\n", texNo, VertexDecl9_DeclTypes[type]);
682 case D3DDECLUSAGE_COLOR:
684 DWORD colorNo = pToken->UsageIndex;
686 case D3DDECLTYPE_D3DCOLOR:
687 switch (pToken->UsageIndex) {
688 case 0: fvf |= D3DFVF_DIFFUSE; break;
689 case 1: fvf |= D3DFVF_SPECULAR; break;
691 /** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */
693 TRACE("Mismatched use in VertexDeclaration of D3DDECLUSAGE_COLOR[%lu] unsupported COLOR register\n", colorNo);
697 /** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */
699 TRACE("Mismatched use in VertexDeclaration of D3DDECLUSAGE_COLOR[%lu] register: unsupported type %s\n", colorNo, VertexDecl9_DeclTypes[type]);
704 case D3DDECLUSAGE_TANGENT:
705 case D3DDECLUSAGE_BINORMAL:
706 case D3DDECLUSAGE_TESSFACTOR:
707 case D3DDECLUSAGE_POSITIONT:
708 case D3DDECLUSAGE_FOG:
709 case D3DDECLUSAGE_DEPTH:
710 case D3DDECLUSAGE_SAMPLE:
711 FIXME("%s Usage not supported yet by VertexDeclaration (type is %s)\n", VertexDecl9_DeclUsages[pToken->Usage], VertexDecl9_DeclTypes[type]);
718 ++len; /* D3DDECL_END() */
720 /* copy fvf if valid */
721 if (FALSE == invalid_fvf) {
722 fvf |= tex << D3DFVF_TEXCOUNT_SHIFT;
723 object->fvf[stream] = fvf;
724 object->allFVF |= fvf;
726 object->fvf[stream] = 0;
730 TRACE("Completed, allFVF = %lx\n", object->allFVF);
733 object->declaration9NumElements = len;
734 /* copy the declaration */
735 object->pDeclaration9 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(D3DVERTEXELEMENT9));
736 memcpy(object->pDeclaration9, pDecl, len * sizeof(D3DVERTEXELEMENT9));
739 TRACE("Returns allFVF = %lx\n", object->allFVF);
744 /* *******************************************
745 IWineD3DVertexDeclaration IUnknown parts follow
746 ******************************************* */
747 HRESULT WINAPI IWineD3DVertexDeclarationImpl_QueryInterface(IWineD3DVertexDeclaration *iface, REFIID riid, LPVOID *ppobj)
749 IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
750 WARN("(%p)->(%s,%p) should not be called\n",This,debugstr_guid(riid),ppobj);
751 return E_NOINTERFACE;
754 ULONG WINAPI IWineD3DVertexDeclarationImpl_AddRef(IWineD3DVertexDeclaration *iface) {
755 IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
756 TRACE("(%p) : AddRef increasing from %ld\n", This, This->ref);
757 return InterlockedIncrement(&This->ref);
760 ULONG WINAPI IWineD3DVertexDeclarationImpl_Release(IWineD3DVertexDeclaration *iface) {
761 IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
763 TRACE("(%p) : Releasing from %ld\n", This, This->ref);
764 ref = InterlockedDecrement(&This->ref);
766 HeapFree(GetProcessHeap(), 0, This->pDeclaration8);
767 HeapFree(GetProcessHeap(), 0, This->pDeclaration9);
768 HeapFree(GetProcessHeap(), 0, This);
773 /* *******************************************
774 IWineD3DVertexDeclaration parts follow
775 ******************************************* */
777 HRESULT WINAPI IWineD3DVertexDeclarationImpl_GetDevice(IWineD3DVertexDeclaration *iface, IWineD3DDevice** ppDevice) {
778 IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
779 TRACE("(%p) : returning %p\n", This, This->wineD3DDevice);
781 *ppDevice = (IWineD3DDevice *) This->wineD3DDevice;
782 IWineD3DDevice_AddRef(*ppDevice);
787 static HRESULT WINAPI IWineD3DVertexDeclarationImpl_GetDeclaration8(IWineD3DVertexDeclaration* iface, DWORD* pData, DWORD* pSizeOfData) {
788 IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
790 *pSizeOfData = This->declaration8Length;
793 if (*pSizeOfData < This->declaration8Length) {
794 *pSizeOfData = This->declaration8Length;
795 return D3DERR_MOREDATA;
797 TRACE("(%p) : GetVertexDeclaration8 copying to %p\n", This, pData);
798 memcpy(pData, This->pDeclaration8, This->declaration8Length);
802 HRESULT WINAPI IWineD3DVertexDeclarationImpl_GetDeclaration9(IWineD3DVertexDeclaration* iface, D3DVERTEXELEMENT9* pData, DWORD* pNumElements) {
803 IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
805 *pNumElements = This->declaration9NumElements;
808 if (*pNumElements < This->declaration9NumElements) {
809 *pNumElements = This->declaration9NumElements;
810 return D3DERR_MOREDATA;
812 TRACE("(%p) : GetVertexDeclaration9 copying to %p\n", This, pData);
813 memcpy(pData, This->pDeclaration9, This->declaration9NumElements);
817 HRESULT WINAPI IWineD3DVertexDeclarationImpl_GetDeclaration(IWineD3DVertexDeclaration* iface, UINT iDeclVersion, VOID* pData, DWORD* pSize) {
818 if (8 == iDeclVersion) {
819 return IWineD3DVertexDeclarationImpl_GetDeclaration8(iface, (DWORD*) pData, pSize);
821 return IWineD3DVertexDeclarationImpl_GetDeclaration9(iface, (D3DVERTEXELEMENT9*) pData, pSize);
824 IWineD3DVertexDeclarationVtbl IWineD3DVertexDeclaration_Vtbl =
826 IWineD3DVertexDeclarationImpl_QueryInterface,
827 IWineD3DVertexDeclarationImpl_AddRef,
828 IWineD3DVertexDeclarationImpl_Release,
829 IWineD3DVertexDeclarationImpl_GetDevice,
830 IWineD3DVertexDeclarationImpl_GetDeclaration,