1 /* Direct3D ExecuteBuffer
2 * Copyright (c) 1998 Lionel ULMER
4 * This file contains the implementation of Direct3DExecuteBuffer.
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #define NONAMELESSUNION
27 #define NONAMELESSSTRUCT
35 #include "wine/debug.h"
37 #include "d3d_private.h"
38 #include "mesa_private.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(ddraw
);
41 WINE_DECLARE_DEBUG_CHANNEL(ddraw_geom
);
43 static void _dump_d3dstatus(LPD3DSTATUS lpStatus
) {
47 static void _dump_executedata(LPD3DEXECUTEDATA lpData
) {
48 DPRINTF("dwSize : %ld\n", lpData
->dwSize
);
49 DPRINTF("Vertex Offset : %ld Count : %ld\n", lpData
->dwVertexOffset
, lpData
->dwVertexCount
);
50 DPRINTF("Instruction Offset : %ld Length : %ld\n", lpData
->dwInstructionOffset
, lpData
->dwInstructionLength
);
51 DPRINTF("HVertex Offset : %ld\n", lpData
->dwHVertexOffset
);
52 _dump_d3dstatus(&(lpData
->dsStatus
));
55 static void _dump_D3DEXECUTEBUFFERDESC(LPD3DEXECUTEBUFFERDESC lpDesc
) {
59 static void execute(IDirect3DExecuteBufferImpl
*This
,
60 IDirect3DDeviceImpl
*lpDevice
,
61 IDirect3DViewportImpl
*lpViewport
)
63 /* DWORD bs = This->desc.dwBufferSize; */
64 DWORD vs
= This
->data
.dwVertexOffset
;
65 /* DWORD vc = This->data.dwVertexCount; */
66 DWORD is
= This
->data
.dwInstructionOffset
;
67 /* DWORD il = This->data.dwInstructionLength; */
69 char *instr
= (char *)This
->desc
.lpData
+ is
;
71 /* Should check if the viewport was added or not to the device */
73 /* Activate the viewport */
74 lpViewport
->active_device
= lpDevice
;
75 lpViewport
->activate(lpViewport
);
77 TRACE("ExecuteData : \n");
79 _dump_executedata(&(This
->data
));
82 LPD3DINSTRUCTION current
= (LPD3DINSTRUCTION
) instr
;
86 count
= current
->wCount
;
87 size
= current
->bSize
;
88 instr
+= sizeof(D3DINSTRUCTION
);
90 switch (current
->bOpcode
) {
92 WARN("POINT-s (%d)\n", count
);
93 instr
+= count
* size
;
97 WARN("LINE-s (%d)\n", count
);
98 instr
+= count
* size
;
101 case D3DOP_TRIANGLE
: {
103 D3DTLVERTEX
*tl_vx
= (D3DTLVERTEX
*) This
->vertex_data
;
104 TRACE("TRIANGLE (%d)\n", count
);
106 if (count
*3>This
->nb_indices
) {
107 This
->nb_indices
= count
* 3;
109 HeapFree(GetProcessHeap(),0,This
->indices
);
110 This
->indices
= HeapAlloc(GetProcessHeap(),0,sizeof(WORD
)*This
->nb_indices
);
113 for (i
= 0; i
< count
; i
++) {
114 LPD3DTRIANGLE ci
= (LPD3DTRIANGLE
) instr
;
115 TRACE_(ddraw_geom
)(" v1: %d v2: %d v3: %d\n",ci
->u1
.v1
, ci
->u2
.v2
, ci
->u3
.v3
);
116 TRACE_(ddraw_geom
)(" Flags : ");
117 if (TRACE_ON(ddraw
)) {
119 if (ci
->wFlags
& D3DTRIFLAG_EDGEENABLE1
)
120 TRACE_(ddraw_geom
)("EDGEENABLE1 ");
121 if (ci
->wFlags
& D3DTRIFLAG_EDGEENABLE2
)
122 TRACE_(ddraw_geom
)("EDGEENABLE2 ");
123 if (ci
->wFlags
& D3DTRIFLAG_EDGEENABLE1
)
124 TRACE_(ddraw_geom
)("EDGEENABLE3 ");
126 if (ci
->wFlags
== D3DTRIFLAG_EVEN
)
127 TRACE_(ddraw_geom
)("EVEN ");
128 if (ci
->wFlags
== D3DTRIFLAG_ODD
)
129 TRACE_(ddraw_geom
)("ODD ");
130 if (ci
->wFlags
== D3DTRIFLAG_START
)
131 TRACE_(ddraw_geom
)("START ");
132 if ((ci
->wFlags
> 0) && (ci
->wFlags
< 30))
133 TRACE_(ddraw_geom
)("STARTFLAT(%d) ", ci
->wFlags
);
134 TRACE_(ddraw_geom
)("\n");
136 This
->indices
[(i
* 3) ] = ci
->u1
.v1
;
137 This
->indices
[(i
* 3) + 1] = ci
->u2
.v2
;
138 This
->indices
[(i
* 3) + 2] = ci
->u3
.v3
;
141 IDirect3DDevice7_DrawIndexedPrimitive(ICOM_INTERFACE(lpDevice
,IDirect3DDevice7
),
142 D3DPT_TRIANGLELIST
,D3DFVF_TLVERTEX
,tl_vx
,0,This
->indices
,count
*3,0);
145 case D3DOP_MATRIXLOAD
:
146 WARN("MATRIXLOAD-s (%d)\n", count
);
147 instr
+= count
* size
;
150 case D3DOP_MATRIXMULTIPLY
: {
152 TRACE("MATRIXMULTIPLY (%d)\n", count
);
154 for (i
= 0; i
< count
; i
++) {
155 LPD3DMATRIXMULTIPLY ci
= (LPD3DMATRIXMULTIPLY
) instr
;
156 LPD3DMATRIX a
= (LPD3DMATRIX
) ci
->hDestMatrix
;
157 LPD3DMATRIX b
= (LPD3DMATRIX
) ci
->hSrcMatrix1
;
158 LPD3DMATRIX c
= (LPD3DMATRIX
) ci
->hSrcMatrix2
;
160 TRACE(" Dest : %08lx Src1 : %08lx Src2 : %08lx\n",
161 ci
->hDestMatrix
, ci
->hSrcMatrix1
, ci
->hSrcMatrix2
);
163 multiply_matrix(a
,c
,b
);
169 case D3DOP_STATETRANSFORM
: {
171 TRACE("STATETRANSFORM (%d)\n", count
);
173 for (i
= 0; i
< count
; i
++) {
174 LPD3DSTATE ci
= (LPD3DSTATE
) instr
;
176 IDirect3DDevice7_SetTransform(ICOM_INTERFACE(lpDevice
, IDirect3DDevice7
),
177 ci
->u1
.drstRenderStateType
, (LPD3DMATRIX
)ci
->u2
.dwArg
[0]);
183 case D3DOP_STATELIGHT
: {
185 TRACE("STATELIGHT (%d)\n", count
);
187 for (i
= 0; i
< count
; i
++) {
188 LPD3DSTATE ci
= (LPD3DSTATE
) instr
;
190 TRACE("(%08x,%08lx)\n",ci
->u1
.dlstLightStateType
, ci
->u2
.dwArg
[0]);
192 if (!ci
->u1
.dlstLightStateType
&& (ci
->u1
.dlstLightStateType
> D3DLIGHTSTATE_COLORVERTEX
))
193 ERR("Unexpected Light State Type\n");
194 else if (ci
->u1
.dlstLightStateType
== D3DLIGHTSTATE_MATERIAL
/* 1 */) {
195 IDirect3DMaterialImpl
*mat
= (IDirect3DMaterialImpl
*) ci
->u2
.dwArg
[0];
200 FIXME(" D3DLIGHTSTATE_MATERIAL called with NULL material !!!\n");
203 else if (ci
->u1
.dlstLightStateType
== D3DLIGHTSTATE_COLORMODEL
/* 3 */) {
204 switch (ci
->u2
.dwArg
[0]) {
206 ERR("DDCOLOR_MONO should not happen!\n");
209 /* We are already in this mode */
212 ERR("Unknown color model!\n");
215 D3DRENDERSTATETYPE rs
= 0;
216 switch (ci
->u1
.dlstLightStateType
) {
218 case D3DLIGHTSTATE_AMBIENT
: /* 2 */
219 rs
= D3DRENDERSTATE_AMBIENT
;
221 case D3DLIGHTSTATE_FOGMODE
: /* 4 */
222 rs
= D3DRENDERSTATE_FOGVERTEXMODE
;
224 case D3DLIGHTSTATE_FOGSTART
: /* 5 */
225 rs
= D3DRENDERSTATE_FOGSTART
;
227 case D3DLIGHTSTATE_FOGEND
: /* 6 */
228 rs
= D3DRENDERSTATE_FOGEND
;
230 case D3DLIGHTSTATE_FOGDENSITY
: /* 7 */
231 rs
= D3DRENDERSTATE_FOGDENSITY
;
233 case D3DLIGHTSTATE_COLORVERTEX
: /* 8 */
234 rs
= D3DRENDERSTATE_COLORVERTEX
;
240 IDirect3DDevice7_SetRenderState(ICOM_INTERFACE(lpDevice
, IDirect3DDevice7
),
248 case D3DOP_STATERENDER
: {
250 TRACE("STATERENDER (%d)\n", count
);
252 for (i
= 0; i
< count
; i
++) {
253 LPD3DSTATE ci
= (LPD3DSTATE
) instr
;
255 IDirect3DDevice7_SetRenderState(ICOM_INTERFACE(lpDevice
, IDirect3DDevice7
),
256 ci
->u1
.drstRenderStateType
, ci
->u2
.dwArg
[0]);
262 case D3DOP_PROCESSVERTICES
: {
264 TRACE("PROCESSVERTICES (%d)\n", count
);
266 for (i
= 0; i
< count
; i
++) {
267 LPD3DPROCESSVERTICES ci
= (LPD3DPROCESSVERTICES
) instr
;
269 TRACE(" Start : %d Dest : %d Count : %ld\n",
270 ci
->wStart
, ci
->wDest
, ci
->dwCount
);
272 if (TRACE_ON(ddraw
)) {
273 if (ci
->dwFlags
& D3DPROCESSVERTICES_COPY
)
275 if (ci
->dwFlags
& D3DPROCESSVERTICES_NOCOLOR
)
277 if (ci
->dwFlags
== D3DPROCESSVERTICES_OPMASK
)
279 if (ci
->dwFlags
& D3DPROCESSVERTICES_TRANSFORM
)
281 if (ci
->dwFlags
== D3DPROCESSVERTICES_TRANSFORMLIGHT
)
282 TRACE("TRANSFORMLIGHT ");
283 if (ci
->dwFlags
& D3DPROCESSVERTICES_UPDATEEXTENTS
)
284 TRACE("UPDATEEXTENTS ");
288 /* This is where doing Direct3D on top on OpenGL is quite difficult.
289 This method transforms a set of vertices using the CURRENT state
290 (lighting, projection, ...) but does not rasterize them.
291 They will only be put on screen later (with the POINT / LINE and
292 TRIANGLE op-codes). The problem is that you can have a triangle
293 with each point having been transformed using another state...
295 In this implementation, I will emulate only ONE thing : each
296 vertex can have its own "WORLD" transformation (this is used in the
297 TWIST.EXE demo of the 5.2 SDK). I suppose that all vertices of the
298 execute buffer use the same state.
300 If I find applications that change other states, I will try to do a
301 more 'fine-tuned' state emulation (but I may become quite tricky if
302 it changes a light position in the middle of a triangle).
304 In this case, a 'direct' approach (i.e. without using OpenGL, but
305 writing our own 3D rasterizer) would be easier. */
307 /* The current method (with the hypothesis that only the WORLD matrix
308 will change between two points) is like this :
309 - I transform 'manually' all the vertices with the current WORLD
310 matrix and store them in the vertex buffer
311 - during the rasterization phase, the WORLD matrix will be set to
312 the Identity matrix */
314 /* Enough for the moment */
315 if (ci
->dwFlags
== D3DPROCESSVERTICES_TRANSFORMLIGHT
) {
317 D3DVERTEX
*src
= ((LPD3DVERTEX
) ((char *)This
->desc
.lpData
+ vs
)) + ci
->wStart
;
318 D3DTLVERTEX
*dst
= ((LPD3DTLVERTEX
) (This
->vertex_data
)) + ci
->wDest
;
319 D3DMATRIX
*mat2
= lpDevice
->world_mat
;
322 D3DVIEWPORT
* Viewport
= &lpViewport
->viewports
.vp1
;
324 if (TRACE_ON(ddraw
)) {
325 TRACE(" Projection Matrix : (%p)\n", lpDevice
->proj_mat
);
326 dump_D3DMATRIX(lpDevice
->proj_mat
);
327 TRACE(" View Matrix : (%p)\n", lpDevice
->view_mat
);
328 dump_D3DMATRIX(lpDevice
->view_mat
);
329 TRACE(" World Matrix : (%p)\n", &mat
);
330 dump_D3DMATRIX(&mat
);
333 multiply_matrix(&mat
,lpDevice
->view_mat
,lpDevice
->world_mat
);
334 multiply_matrix(&mat
,lpDevice
->proj_mat
,&mat
);
336 for (nb
= 0; nb
< ci
->dwCount
; nb
++) {
337 /* Normals transformation */
338 nx
= (src
->u4
.nx
* mat2
->_11
) + (src
->u5
.ny
* mat2
->_21
) + (src
->u6
.nz
* mat2
->_31
);
339 ny
= (src
->u4
.nx
* mat2
->_12
) + (src
->u5
.ny
* mat2
->_22
) + (src
->u6
.nz
* mat2
->_32
);
340 nz
= (src
->u4
.nx
* mat2
->_13
) + (src
->u5
.ny
* mat2
->_23
) + (src
->u6
.nz
* mat2
->_33
);
342 /* No lighting yet */
343 dst
->u5
.color
= 0xFFFFFFFF; /* Opaque white */
344 dst
->u6
.specular
= 0xFF000000; /* No specular and no fog factor */
346 dst
->u7
.tu
= src
->u7
.tu
;
347 dst
->u8
.tv
= src
->u8
.tv
;
349 /* Now, the matrix multiplication */
350 dst
->u1
.sx
= (src
->u1
.x
* mat
._11
) + (src
->u2
.y
* mat
._21
) + (src
->u3
.z
* mat
._31
) + (1.0 * mat
._41
);
351 dst
->u2
.sy
= (src
->u1
.x
* mat
._12
) + (src
->u2
.y
* mat
._22
) + (src
->u3
.z
* mat
._32
) + (1.0 * mat
._42
);
352 dst
->u3
.sz
= (src
->u1
.x
* mat
._13
) + (src
->u2
.y
* mat
._23
) + (src
->u3
.z
* mat
._33
) + (1.0 * mat
._43
);
353 dst
->u4
.rhw
= (src
->u1
.x
* mat
._14
) + (src
->u2
.y
* mat
._24
) + (src
->u3
.z
* mat
._34
) + (1.0 * mat
._44
);
355 dst
->u1
.sx
= dst
->u1
.sx
/ dst
->u4
.rhw
* Viewport
->dwWidth
/ 2
356 + Viewport
->dwX
+ Viewport
->dwWidth
/ 2;
357 dst
->u2
.sy
= dst
->u2
.sy
/ dst
->u4
.rhw
* Viewport
->dwHeight
/ 2
358 + Viewport
->dwY
+ Viewport
->dwHeight
/ 2;
359 dst
->u3
.sz
/= dst
->u4
.rhw
;
360 dst
->u4
.rhw
= 1 / dst
->u4
.rhw
;
366 } else if (ci
->dwFlags
== D3DPROCESSVERTICES_TRANSFORM
) {
368 D3DLVERTEX
*src
= ((LPD3DLVERTEX
) ((char *)This
->desc
.lpData
+ vs
)) + ci
->wStart
;
369 D3DTLVERTEX
*dst
= ((LPD3DTLVERTEX
) (This
->vertex_data
)) + ci
->wDest
;
371 D3DVIEWPORT
* Viewport
= &lpViewport
->viewports
.vp1
;
373 if (TRACE_ON(ddraw
)) {
374 TRACE(" Projection Matrix : (%p)\n", lpDevice
->proj_mat
);
375 dump_D3DMATRIX(lpDevice
->proj_mat
);
376 TRACE(" View Matrix : (%p)\n", lpDevice
->view_mat
);
377 dump_D3DMATRIX(lpDevice
->view_mat
);
378 TRACE(" World Matrix : (%p)\n", &mat
);
379 dump_D3DMATRIX(&mat
);
382 multiply_matrix(&mat
,lpDevice
->view_mat
,lpDevice
->world_mat
);
383 multiply_matrix(&mat
,lpDevice
->proj_mat
,&mat
);
385 for (nb
= 0; nb
< ci
->dwCount
; nb
++) {
386 dst
->u5
.color
= src
->u4
.color
;
387 dst
->u6
.specular
= src
->u5
.specular
;
388 dst
->u7
.tu
= src
->u6
.tu
;
389 dst
->u8
.tv
= src
->u7
.tv
;
391 /* Now, the matrix multiplication */
392 dst
->u1
.sx
= (src
->u1
.x
* mat
._11
) + (src
->u2
.y
* mat
._21
) + (src
->u3
.z
* mat
._31
) + (1.0 * mat
._41
);
393 dst
->u2
.sy
= (src
->u1
.x
* mat
._12
) + (src
->u2
.y
* mat
._22
) + (src
->u3
.z
* mat
._32
) + (1.0 * mat
._42
);
394 dst
->u3
.sz
= (src
->u1
.x
* mat
._13
) + (src
->u2
.y
* mat
._23
) + (src
->u3
.z
* mat
._33
) + (1.0 * mat
._43
);
395 dst
->u4
.rhw
= (src
->u1
.x
* mat
._14
) + (src
->u2
.y
* mat
._24
) + (src
->u3
.z
* mat
._34
) + (1.0 * mat
._44
);
397 dst
->u1
.sx
/= dst
->u4
.rhw
* Viewport
->dvScaleX
* Viewport
->dwWidth
/ 2 + Viewport
->dwX
;
398 dst
->u2
.sy
/= dst
->u4
.rhw
* Viewport
->dvScaleY
* Viewport
->dwHeight
/ 2 + Viewport
->dwY
;
399 dst
->u3
.sz
/= dst
->u4
.rhw
;
400 dst
->u4
.rhw
= 1 / dst
->u4
.rhw
;
405 } else if (ci
->dwFlags
== D3DPROCESSVERTICES_COPY
) {
406 D3DTLVERTEX
*src
= ((LPD3DTLVERTEX
) ((char *)This
->desc
.lpData
+ vs
)) + ci
->wStart
;
407 D3DTLVERTEX
*dst
= ((LPD3DTLVERTEX
) (This
->vertex_data
)) + ci
->wDest
;
409 memcpy(dst
, src
, ci
->dwCount
* sizeof(D3DTLVERTEX
));
411 ERR("Unhandled vertex processing !\n");
418 case D3DOP_TEXTURELOAD
: {
419 WARN("TEXTURELOAD-s (%d)\n", count
);
421 instr
+= count
* size
;
425 TRACE("EXIT (%d)\n", count
);
426 /* We did this instruction */
432 case D3DOP_BRANCHFORWARD
: {
434 TRACE("BRANCHFORWARD (%d)\n", count
);
436 for (i
= 0; i
< count
; i
++) {
437 LPD3DBRANCH ci
= (LPD3DBRANCH
) instr
;
439 if ((This
->data
.dsStatus
.dwStatus
& ci
->dwMask
) == ci
->dwValue
) {
441 TRACE(" Branch to %ld\n", ci
->dwOffset
);
442 instr
= (char*)current
+ ci
->dwOffset
;
447 TRACE(" Branch to %ld\n", ci
->dwOffset
);
448 instr
= (char*)current
+ ci
->dwOffset
;
458 WARN("SPAN-s (%d)\n", count
);
460 instr
+= count
* size
;
463 case D3DOP_SETSTATUS
: {
465 TRACE("SETSTATUS (%d)\n", count
);
467 for (i
= 0; i
< count
; i
++) {
468 LPD3DSTATUS ci
= (LPD3DSTATUS
) instr
;
470 This
->data
.dsStatus
= *ci
;
477 ERR("Unhandled OpCode %d !!!\n",current
->bOpcode
);
478 /* Try to save ... */
479 instr
+= count
* size
;
489 Main_IDirect3DExecuteBufferImpl_1_QueryInterface(LPDIRECT3DEXECUTEBUFFER iface
,
493 ICOM_THIS_FROM(IDirect3DExecuteBufferImpl
, IDirect3DExecuteBuffer
, iface
);
494 TRACE("(%p/%p)->(%s,%p)\n", This
, iface
, debugstr_guid(riid
), obp
);
498 if ( IsEqualGUID( &IID_IUnknown
, riid
) ) {
499 IDirect3DExecuteBuffer_AddRef(ICOM_INTERFACE(This
, IDirect3DExecuteBuffer
));
501 TRACE(" Creating IUnknown interface at %p.\n", *obp
);
504 if ( IsEqualGUID( &IID_IDirect3DMaterial
, riid
) ) {
505 IDirect3DExecuteBuffer_AddRef(ICOM_INTERFACE(This
, IDirect3DExecuteBuffer
));
506 *obp
= ICOM_INTERFACE(This
, IDirect3DExecuteBuffer
);
507 TRACE(" Creating IDirect3DExecuteBuffer interface %p\n", *obp
);
510 FIXME("(%p): interface for IID %s NOT found!\n", This
, debugstr_guid(riid
));
511 return OLE_E_ENUM_NOMORE
;
515 Main_IDirect3DExecuteBufferImpl_1_AddRef(LPDIRECT3DEXECUTEBUFFER iface
)
517 ICOM_THIS_FROM(IDirect3DExecuteBufferImpl
, IDirect3DExecuteBuffer
, iface
);
518 FIXME("(%p/%p)->()incrementing from %lu.\n", This
, iface
, This
->ref
);
519 return ++(This
->ref
);
523 Main_IDirect3DExecuteBufferImpl_1_Release(LPDIRECT3DEXECUTEBUFFER iface
)
525 ICOM_THIS_FROM(IDirect3DExecuteBufferImpl
, IDirect3DExecuteBuffer
, iface
);
526 TRACE("(%p/%p)->()decrementing from %lu.\n", This
, iface
, This
->ref
);
527 if (!--(This
->ref
)) {
528 if ((This
->desc
.lpData
!= NULL
) && This
->need_free
)
529 HeapFree(GetProcessHeap(),0,This
->desc
.lpData
);
530 if (This
->vertex_data
!= NULL
)
531 HeapFree(GetProcessHeap(),0,This
->vertex_data
);
532 if (This
->indices
!= NULL
)
533 HeapFree(GetProcessHeap(),0,This
->indices
);
534 HeapFree(GetProcessHeap(),0,This
);
542 Main_IDirect3DExecuteBufferImpl_1_Initialize(LPDIRECT3DEXECUTEBUFFER iface
,
543 LPDIRECT3DDEVICE lpDirect3DDevice
,
544 LPD3DEXECUTEBUFFERDESC lpDesc
)
546 ICOM_THIS_FROM(IDirect3DExecuteBufferImpl
, IDirect3DExecuteBuffer
, iface
);
547 TRACE("(%p/%p)->(%p,%p) no-op....\n", This
, iface
, lpDirect3DDevice
, lpDesc
);
552 Main_IDirect3DExecuteBufferImpl_1_Lock(LPDIRECT3DEXECUTEBUFFER iface
,
553 LPD3DEXECUTEBUFFERDESC lpDesc
)
555 ICOM_THIS_FROM(IDirect3DExecuteBufferImpl
, IDirect3DExecuteBuffer
, iface
);
557 TRACE("(%p/%p)->(%p)\n", This
, iface
, lpDesc
);
559 dwSize
= lpDesc
->dwSize
;
560 memset(lpDesc
, 0, dwSize
);
561 memcpy(lpDesc
, &This
->desc
, dwSize
);
563 if (TRACE_ON(ddraw
)) {
564 TRACE(" Returning description : \n");
565 _dump_D3DEXECUTEBUFFERDESC(lpDesc
);
571 Main_IDirect3DExecuteBufferImpl_1_Unlock(LPDIRECT3DEXECUTEBUFFER iface
)
573 ICOM_THIS_FROM(IDirect3DExecuteBufferImpl
, IDirect3DExecuteBuffer
, iface
);
574 TRACE("(%p/%p)->() no-op...\n", This
, iface
);
579 Main_IDirect3DExecuteBufferImpl_1_SetExecuteData(LPDIRECT3DEXECUTEBUFFER iface
,
580 LPD3DEXECUTEDATA lpData
)
582 ICOM_THIS_FROM(IDirect3DExecuteBufferImpl
, IDirect3DExecuteBuffer
, iface
);
584 TRACE("(%p/%p)->(%p)\n", This
, iface
, lpData
);
586 memcpy(&This
->data
, lpData
, lpData
->dwSize
);
588 /* Get the number of vertices in the execute buffer */
589 nbvert
= This
->data
.dwVertexCount
;
591 /* Prepares the transformed vertex buffer */
592 if (This
->vertex_data
!= NULL
)
593 HeapFree(GetProcessHeap(), 0, This
->vertex_data
);
594 This
->vertex_data
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, nbvert
* sizeof(D3DTLVERTEX
));
596 if (TRACE_ON(ddraw
)) {
597 _dump_executedata(lpData
);
604 Main_IDirect3DExecuteBufferImpl_1_GetExecuteData(LPDIRECT3DEXECUTEBUFFER iface
,
605 LPD3DEXECUTEDATA lpData
)
607 ICOM_THIS_FROM(IDirect3DExecuteBufferImpl
, IDirect3DExecuteBuffer
, iface
);
609 TRACE("(%p/%p)->(%p): stub!\n", This
, iface
, lpData
);
611 dwSize
= lpData
->dwSize
;
612 memset(lpData
, 0, dwSize
);
613 memcpy(lpData
, &This
->data
, dwSize
);
615 if (TRACE_ON(ddraw
)) {
616 TRACE("Returning data : \n");
617 _dump_executedata(lpData
);
624 Main_IDirect3DExecuteBufferImpl_1_Validate(LPDIRECT3DEXECUTEBUFFER iface
,
626 LPD3DVALIDATECALLBACK lpFunc
,
630 ICOM_THIS_FROM(IDirect3DExecuteBufferImpl
, IDirect3DExecuteBuffer
, iface
);
631 FIXME("(%p/%p)->(%p,%p,%p,%08lx): stub!\n", This
, iface
, lpdwOffset
, lpFunc
, lpUserArg
, dwReserved
);
636 Main_IDirect3DExecuteBufferImpl_1_Optimize(LPDIRECT3DEXECUTEBUFFER iface
,
639 ICOM_THIS_FROM(IDirect3DExecuteBufferImpl
, IDirect3DExecuteBuffer
, iface
);
640 TRACE("(%p/%p)->(%08lx) no-op...\n", This
, iface
, dwDummy
);
644 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
645 # define XCAST(fun) (typeof(VTABLE_IDirect3DExecuteBuffer.fun))
647 # define XCAST(fun) (void*)
650 ICOM_VTABLE(IDirect3DExecuteBuffer
) VTABLE_IDirect3DExecuteBuffer
=
652 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
653 XCAST(QueryInterface
) Main_IDirect3DExecuteBufferImpl_1_QueryInterface
,
654 XCAST(AddRef
) Main_IDirect3DExecuteBufferImpl_1_AddRef
,
655 XCAST(Release
) Main_IDirect3DExecuteBufferImpl_1_Release
,
656 XCAST(Initialize
) Main_IDirect3DExecuteBufferImpl_1_Initialize
,
657 XCAST(Lock
) Main_IDirect3DExecuteBufferImpl_1_Lock
,
658 XCAST(Unlock
) Main_IDirect3DExecuteBufferImpl_1_Unlock
,
659 XCAST(SetExecuteData
) Main_IDirect3DExecuteBufferImpl_1_SetExecuteData
,
660 XCAST(GetExecuteData
) Main_IDirect3DExecuteBufferImpl_1_GetExecuteData
,
661 XCAST(Validate
) Main_IDirect3DExecuteBufferImpl_1_Validate
,
662 XCAST(Optimize
) Main_IDirect3DExecuteBufferImpl_1_Optimize
,
665 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
670 HRESULT
d3dexecutebuffer_create(IDirect3DExecuteBufferImpl
**obj
, IDirectDrawImpl
*d3d
, IDirect3DDeviceImpl
*d3ddev
, LPD3DEXECUTEBUFFERDESC lpDesc
)
672 IDirect3DExecuteBufferImpl
* object
;
674 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirect3DExecuteBufferImpl
));
676 ICOM_INIT_INTERFACE(object
, IDirect3DExecuteBuffer
, VTABLE_IDirect3DExecuteBuffer
);
680 object
->d3ddev
= d3ddev
;
682 /* Initializes memory */
683 memcpy(&object
->desc
, lpDesc
, lpDesc
->dwSize
);
685 /* No buffer given */
686 if ((object
->desc
.dwFlags
& D3DDEB_LPDATA
) == 0)
687 object
->desc
.lpData
= NULL
;
689 /* No buffer size given */
690 if ((lpDesc
->dwFlags
& D3DDEB_BUFSIZE
) == 0)
691 object
->desc
.dwBufferSize
= 0;
693 /* Create buffer if asked */
694 if ((object
->desc
.lpData
== NULL
) && (object
->desc
.dwBufferSize
> 0)) {
695 object
->need_free
= TRUE
;
696 object
->desc
.lpData
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,object
->desc
.dwBufferSize
);
698 object
->need_free
= FALSE
;
701 /* No vertices for the moment */
702 object
->vertex_data
= NULL
;
704 object
->desc
.dwFlags
|= D3DDEB_LPDATA
;
706 object
->execute
= execute
;
708 object
->indices
= NULL
;
709 object
->nb_indices
= 0;
713 TRACE(" creating implementation at %p.\n", *obj
);