1 /* Direct3D ExecuteBuffer
2 * Copyright (c) 1998-2004 Lionel ULMER
3 * Copyright (c) 2002-2004 Christian Costa
4 * Copyright (c) 2006 Stefan Dösinger
6 * This file contains the implementation of IDirect3DExecuteBuffer.
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include "ddraw_private.h"
25 /*****************************************************************************
27 * _dump_D3DEXECUTEBUFFERDESC
29 * Debug functions which write the executebuffer data to the console
31 *****************************************************************************/
33 static void _dump_executedata(const D3DEXECUTEDATA
*lpData
) {
34 TRACE("dwSize : %d\n", lpData
->dwSize
);
35 TRACE("Vertex Offset : %d Count : %d\n", lpData
->dwVertexOffset
, lpData
->dwVertexCount
);
36 TRACE("Instruction Offset : %d Length : %d\n", lpData
->dwInstructionOffset
, lpData
->dwInstructionLength
);
37 TRACE("HVertex Offset : %d\n", lpData
->dwHVertexOffset
);
40 static void _dump_D3DEXECUTEBUFFERDESC(const D3DEXECUTEBUFFERDESC
*lpDesc
) {
41 TRACE("dwSize : %d\n", lpDesc
->dwSize
);
42 TRACE("dwFlags : %x\n", lpDesc
->dwFlags
);
43 TRACE("dwCaps : %x\n", lpDesc
->dwCaps
);
44 TRACE("dwBufferSize : %d\n", lpDesc
->dwBufferSize
);
45 TRACE("lpData : %p\n", lpDesc
->lpData
);
48 static void transform_vertex(D3DTLVERTEX
*dst
, const D3DMATRIX
*mat
,
49 const D3DVIEWPORT
*vp
, float x
, float y
, float z
)
51 dst
->u1
.sx
= (x
* mat
->_11
) + (y
* mat
->_21
) + (z
* mat
->_31
) + mat
->_41
;
52 dst
->u2
.sy
= (x
* mat
->_12
) + (y
* mat
->_22
) + (z
* mat
->_32
) + mat
->_42
;
53 dst
->u3
.sz
= (x
* mat
->_13
) + (y
* mat
->_23
) + (z
* mat
->_33
) + mat
->_43
;
54 dst
->u4
.rhw
= (x
* mat
->_14
) + (y
* mat
->_24
) + (z
* mat
->_34
) + mat
->_44
;
56 dst
->u1
.sx
= dst
->u1
.sx
/ dst
->u4
.rhw
* vp
->dvScaleX
+ vp
->dwX
+ vp
->dwWidth
/ 2;
57 dst
->u2
.sy
= -dst
->u2
.sy
/ dst
->u4
.rhw
* vp
->dvScaleY
+ vp
->dwY
+ vp
->dwHeight
/ 2;
58 dst
->u3
.sz
/= dst
->u4
.rhw
;
59 dst
->u4
.rhw
= 1.0f
/ dst
->u4
.rhw
;
62 HRESULT
d3d_execute_buffer_execute(struct d3d_execute_buffer
*buffer
,
63 struct d3d_device
*device
, struct d3d_viewport
*viewport
)
65 DWORD vs
= buffer
->data
.dwVertexOffset
;
66 DWORD is
= buffer
->data
.dwInstructionOffset
;
67 char *instr
= (char *)buffer
->desc
.lpData
+ is
;
70 if (viewport
->active_device
!= device
)
72 WARN("Viewport %p active device is %p.\n",
73 viewport
, viewport
->active_device
);
74 return DDERR_INVALIDPARAMS
;
77 /* Activate the viewport */
78 viewport_activate(viewport
, FALSE
);
80 TRACE("ExecuteData :\n");
82 _dump_executedata(&(buffer
->data
));
86 D3DINSTRUCTION
*current
= (D3DINSTRUCTION
*)instr
;
90 count
= current
->wCount
;
91 size
= current
->bSize
;
92 instr
+= sizeof(D3DINSTRUCTION
);
94 switch (current
->bOpcode
) {
96 WARN("POINT-s (%d)\n", count
);
97 instr
+= count
* size
;
101 WARN("LINE-s (%d)\n", count
);
102 instr
+= count
* size
;
107 D3DTLVERTEX
*tl_vx
= buffer
->vertex_data
;
108 TRACE("TRIANGLE (%d)\n", count
);
110 if (buffer
->nb_indices
< count
* 3)
112 buffer
->nb_indices
= count
* 3;
113 HeapFree(GetProcessHeap(), 0, buffer
->indices
);
114 buffer
->indices
= HeapAlloc(GetProcessHeap(), 0, sizeof(*buffer
->indices
) * buffer
->nb_indices
);
117 for (i
= 0; i
< count
; ++i
)
119 D3DTRIANGLE
*ci
= (D3DTRIANGLE
*)instr
;
120 TRACE(" v1: %d v2: %d v3: %d\n",ci
->u1
.v1
, ci
->u2
.v2
, ci
->u3
.v3
);
125 if (ci
->wFlags
& D3DTRIFLAG_EDGEENABLE1
)
126 TRACE("EDGEENABLE1 ");
127 if (ci
->wFlags
& D3DTRIFLAG_EDGEENABLE2
)
128 TRACE("EDGEENABLE2 ");
129 if (ci
->wFlags
& D3DTRIFLAG_EDGEENABLE1
)
130 TRACE("EDGEENABLE3 ");
132 if (ci
->wFlags
== D3DTRIFLAG_EVEN
)
134 if (ci
->wFlags
== D3DTRIFLAG_ODD
)
136 if (ci
->wFlags
== D3DTRIFLAG_START
)
138 if ((ci
->wFlags
> 0) && (ci
->wFlags
< 30))
139 TRACE("STARTFLAT(%u) ", ci
->wFlags
);
142 buffer
->indices
[(i
* 3) ] = ci
->u1
.v1
;
143 buffer
->indices
[(i
* 3) + 1] = ci
->u2
.v2
;
144 buffer
->indices
[(i
* 3) + 2] = ci
->u3
.v3
;
147 IDirect3DDevice7_DrawIndexedPrimitive(&device
->IDirect3DDevice7_iface
,
148 D3DPT_TRIANGLELIST
, D3DFVF_TLVERTEX
, tl_vx
, buffer
->nb_vertices
,
149 buffer
->indices
, count
* 3, 0);
152 case D3DOP_MATRIXLOAD
:
153 WARN("MATRIXLOAD-s (%d)\n", count
);
154 instr
+= count
* size
;
157 case D3DOP_MATRIXMULTIPLY
:
158 TRACE("MATRIXMULTIPLY (%d)\n", count
);
159 for (i
= 0; i
< count
; ++i
)
161 D3DMATRIXMULTIPLY
*ci
= (D3DMATRIXMULTIPLY
*)instr
;
162 D3DMATRIX
*a
, *b
, *c
;
164 a
= ddraw_get_object(&device
->handle_table
, ci
->hDestMatrix
- 1, DDRAW_HANDLE_MATRIX
);
165 b
= ddraw_get_object(&device
->handle_table
, ci
->hSrcMatrix1
- 1, DDRAW_HANDLE_MATRIX
);
166 c
= ddraw_get_object(&device
->handle_table
, ci
->hSrcMatrix2
- 1, DDRAW_HANDLE_MATRIX
);
170 ERR("Invalid matrix handle (a %#x -> %p, b %#x -> %p, c %#x -> %p).\n",
171 ci
->hDestMatrix
, a
, ci
->hSrcMatrix1
, b
, ci
->hSrcMatrix2
, c
);
175 TRACE("dst %p, src1 %p, src2 %p.\n", a
, b
, c
);
176 multiply_matrix(a
, c
, b
);
183 case D3DOP_STATETRANSFORM
:
184 TRACE("STATETRANSFORM (%d)\n", count
);
185 for (i
= 0; i
< count
; ++i
)
187 D3DSTATE
*ci
= (D3DSTATE
*)instr
;
190 m
= ddraw_get_object(&device
->handle_table
, ci
->u2
.dwArg
[0] - 1, DDRAW_HANDLE_MATRIX
);
193 ERR("Invalid matrix handle %#x.\n", ci
->u2
.dwArg
[0]);
197 if (ci
->u1
.dtstTransformStateType
== D3DTRANSFORMSTATE_WORLD
)
198 device
->world
= ci
->u2
.dwArg
[0];
199 if (ci
->u1
.dtstTransformStateType
== D3DTRANSFORMSTATE_VIEW
)
200 device
->view
= ci
->u2
.dwArg
[0];
201 if (ci
->u1
.dtstTransformStateType
== D3DTRANSFORMSTATE_PROJECTION
)
202 device
->proj
= ci
->u2
.dwArg
[0];
203 IDirect3DDevice7_SetTransform(&device
->IDirect3DDevice7_iface
,
204 ci
->u1
.dtstTransformStateType
, m
);
211 case D3DOP_STATELIGHT
:
212 TRACE("STATELIGHT (%d)\n", count
);
213 for (i
= 0; i
< count
; ++i
)
215 D3DSTATE
*ci
= (D3DSTATE
*)instr
;
217 if (FAILED(IDirect3DDevice3_SetLightState(&device
->IDirect3DDevice3_iface
,
218 ci
->u1
.dlstLightStateType
, ci
->u2
.dwArg
[0])))
219 WARN("Failed to set light state.\n");
225 case D3DOP_STATERENDER
:
226 TRACE("STATERENDER (%d)\n", count
);
227 for (i
= 0; i
< count
; ++i
)
229 D3DSTATE
*ci
= (D3DSTATE
*)instr
;
231 if (FAILED(IDirect3DDevice3_SetRenderState(&device
->IDirect3DDevice3_iface
,
232 ci
->u1
.drstRenderStateType
, ci
->u2
.dwArg
[0])))
233 WARN("Failed to set render state.\n");
239 case D3DOP_PROCESSVERTICES
:
241 /* TODO: Share code with d3d_vertex_buffer7_ProcessVertices()
242 * and / or wined3d_device_process_vertices(). */
243 D3DMATRIX view_mat
, world_mat
, proj_mat
, mat
;
245 TRACE("PROCESSVERTICES (%d)\n", count
);
247 /* Get the transform and world matrix */
248 /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */
249 wined3d_device_get_transform(device
->wined3d_device
,
250 D3DTRANSFORMSTATE_VIEW
, (struct wined3d_matrix
*)&view_mat
);
251 wined3d_device_get_transform(device
->wined3d_device
,
252 D3DTRANSFORMSTATE_PROJECTION
, (struct wined3d_matrix
*)&proj_mat
);
253 wined3d_device_get_transform(device
->wined3d_device
,
254 WINED3D_TS_WORLD_MATRIX(0), (struct wined3d_matrix
*)&world_mat
);
258 TRACE(" Projection Matrix:\n");
259 dump_D3DMATRIX(&proj_mat
);
260 TRACE(" View Matrix:\n");
261 dump_D3DMATRIX(&view_mat
);
262 TRACE(" World Matrix:\n");
263 dump_D3DMATRIX(&world_mat
);
266 multiply_matrix(&mat
, &view_mat
, &world_mat
);
267 multiply_matrix(&mat
, &proj_mat
, &mat
);
269 for (i
= 0; i
< count
; ++i
)
271 D3DPROCESSVERTICES
*ci
= (D3DPROCESSVERTICES
*)instr
;
272 D3DTLVERTEX
*dst
= (D3DTLVERTEX
*)buffer
->vertex_data
+ ci
->wDest
;
273 DWORD op
= ci
->dwFlags
& D3DPROCESSVERTICES_OPMASK
;
275 TRACE(" start %u, dest %u, count %u, flags %#x.\n",
276 ci
->wStart
, ci
->wDest
, ci
->dwCount
, ci
->dwFlags
);
278 if (ci
->dwFlags
& D3DPROCESSVERTICES_UPDATEEXTENTS
)
279 FIXME("D3DPROCESSVERTICES_UPDATEEXTENTS not implemented.\n");
280 if (ci
->dwFlags
& D3DPROCESSVERTICES_NOCOLOR
)
281 FIXME("D3DPROCESSVERTICES_NOCOLOR not implemented.\n");
285 case D3DPROCESSVERTICES_TRANSFORMLIGHT
:
287 const D3DVERTEX
*src
= (D3DVERTEX
*)((char *)buffer
->desc
.lpData
+ vs
) + ci
->wStart
;
288 unsigned int vtx_idx
;
289 static unsigned int once
;
292 FIXME("Lighting not implemented.\n");
294 for (vtx_idx
= 0; vtx_idx
< ci
->dwCount
; ++vtx_idx
)
296 transform_vertex(&dst
[vtx_idx
], &mat
, &viewport
->viewports
.vp1
,
297 src
[vtx_idx
].u1
.x
, src
[vtx_idx
].u2
.y
, src
[vtx_idx
].u3
.z
);
298 /* No lighting yet */
299 dst
[vtx_idx
].u5
.color
= 0xffffffff; /* Opaque white */
300 dst
[vtx_idx
].u6
.specular
= 0xff000000; /* No specular and no fog factor */
301 dst
[vtx_idx
].u7
.tu
= src
[vtx_idx
].u7
.tu
;
302 dst
[vtx_idx
].u8
.tv
= src
[vtx_idx
].u8
.tv
;
307 case D3DPROCESSVERTICES_TRANSFORM
:
309 const D3DLVERTEX
*src
= (D3DLVERTEX
*)((char *)buffer
->desc
.lpData
+ vs
) + ci
->wStart
;
310 unsigned int vtx_idx
;
312 for (vtx_idx
= 0; vtx_idx
< ci
->dwCount
; ++vtx_idx
)
314 transform_vertex(&dst
[vtx_idx
], &mat
, &viewport
->viewports
.vp1
,
315 src
[vtx_idx
].u1
.x
, src
[vtx_idx
].u2
.y
, src
[vtx_idx
].u3
.z
);
316 dst
[vtx_idx
].u5
.color
= src
[vtx_idx
].u4
.color
;
317 dst
[vtx_idx
].u6
.specular
= src
[vtx_idx
].u5
.specular
;
318 dst
[vtx_idx
].u7
.tu
= src
[vtx_idx
].u6
.tu
;
319 dst
[vtx_idx
].u8
.tv
= src
[vtx_idx
].u7
.tv
;
324 case D3DPROCESSVERTICES_COPY
:
326 const D3DTLVERTEX
*src
= (D3DTLVERTEX
*)((char *)buffer
->desc
.lpData
+ vs
) + ci
->wStart
;
328 memcpy(dst
, src
, ci
->dwCount
* sizeof(*dst
));
333 FIXME("Unhandled vertex processing op %#x.\n", op
);
342 case D3DOP_TEXTURELOAD
: {
343 WARN("TEXTURELOAD-s (%d)\n", count
);
345 instr
+= count
* size
;
349 TRACE("EXIT (%d)\n", count
);
350 /* We did this instruction */
356 case D3DOP_BRANCHFORWARD
:
357 TRACE("BRANCHFORWARD (%d)\n", count
);
358 for (i
= 0; i
< count
; ++i
)
360 D3DBRANCH
*ci
= (D3DBRANCH
*)instr
;
362 if ((buffer
->data
.dsStatus
.dwStatus
& ci
->dwMask
) == ci
->dwValue
)
366 TRACE(" Branch to %d\n", ci
->dwOffset
);
368 instr
= (char*)current
+ ci
->dwOffset
;
374 TRACE(" Branch to %d\n", ci
->dwOffset
);
376 instr
= (char*)current
+ ci
->dwOffset
;
387 WARN("SPAN-s (%d)\n", count
);
389 instr
+= count
* size
;
392 case D3DOP_SETSTATUS
:
393 TRACE("SETSTATUS (%d)\n", count
);
394 for (i
= 0; i
< count
; ++i
)
396 buffer
->data
.dsStatus
= *(D3DSTATUS
*)instr
;
402 ERR("Unhandled OpCode %d !!!\n",current
->bOpcode
);
403 /* Try to save ... */
404 instr
+= count
* size
;
413 static inline struct d3d_execute_buffer
*impl_from_IDirect3DExecuteBuffer(IDirect3DExecuteBuffer
*iface
)
415 return CONTAINING_RECORD(iface
, struct d3d_execute_buffer
, IDirect3DExecuteBuffer_iface
);
418 static HRESULT WINAPI
d3d_execute_buffer_QueryInterface(IDirect3DExecuteBuffer
*iface
, REFIID iid
, void **out
)
420 TRACE("iface %p, iid %s, out %p.\n", iface
, debugstr_guid(iid
), out
);
422 if (IsEqualGUID(&IID_IDirect3DExecuteBuffer
, iid
)
423 || IsEqualGUID(&IID_IUnknown
, iid
))
425 IDirect3DExecuteBuffer_AddRef(iface
);
430 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid
));
433 return E_NOINTERFACE
;
436 /*****************************************************************************
437 * IDirect3DExecuteBuffer::AddRef
439 * A normal AddRef method, nothing special
444 *****************************************************************************/
445 static ULONG WINAPI
d3d_execute_buffer_AddRef(IDirect3DExecuteBuffer
*iface
)
447 struct d3d_execute_buffer
*buffer
= impl_from_IDirect3DExecuteBuffer(iface
);
448 ULONG ref
= InterlockedIncrement(&buffer
->ref
);
450 TRACE("%p increasing refcount to %u.\n", buffer
, ref
);
455 /*****************************************************************************
456 * IDirect3DExecuteBuffer::Release
458 * A normal Release method, nothing special
463 *****************************************************************************/
464 static ULONG WINAPI
d3d_execute_buffer_Release(IDirect3DExecuteBuffer
*iface
)
466 struct d3d_execute_buffer
*buffer
= impl_from_IDirect3DExecuteBuffer(iface
);
467 ULONG ref
= InterlockedDecrement(&buffer
->ref
);
469 TRACE("%p decreasing refcount to %u.\n", buffer
, ref
);
473 if (buffer
->need_free
)
474 HeapFree(GetProcessHeap(), 0, buffer
->desc
.lpData
);
475 HeapFree(GetProcessHeap(), 0, buffer
->vertex_data
);
476 HeapFree(GetProcessHeap(), 0, buffer
->indices
);
477 HeapFree(GetProcessHeap(), 0, buffer
);
483 /*****************************************************************************
484 * IDirect3DExecuteBuffer::Initialize
486 * Initializes the Execute Buffer. This method exists for COM compliance
487 * Nothing to do here.
492 *****************************************************************************/
493 static HRESULT WINAPI
d3d_execute_buffer_Initialize(IDirect3DExecuteBuffer
*iface
,
494 IDirect3DDevice
*device
, D3DEXECUTEBUFFERDESC
*desc
)
496 TRACE("iface %p, device %p, desc %p.\n", iface
, device
, desc
);
501 /*****************************************************************************
502 * IDirect3DExecuteBuffer::Lock
504 * Locks the buffer, so the app can write into it.
507 * Desc: Pointer to return the buffer description. This Description contains
508 * a pointer to the buffer data.
511 * This implementation always returns D3D_OK
513 *****************************************************************************/
514 static HRESULT WINAPI
d3d_execute_buffer_Lock(IDirect3DExecuteBuffer
*iface
, D3DEXECUTEBUFFERDESC
*desc
)
516 struct d3d_execute_buffer
*buffer
= impl_from_IDirect3DExecuteBuffer(iface
);
519 TRACE("iface %p, desc %p.\n", iface
, desc
);
521 dwSize
= desc
->dwSize
;
522 memcpy(desc
, &buffer
->desc
, dwSize
);
526 TRACE(" Returning description :\n");
527 _dump_D3DEXECUTEBUFFERDESC(desc
);
532 /*****************************************************************************
533 * IDirect3DExecuteBuffer::Unlock
535 * Unlocks the buffer. We don't have anything to do here
538 * This implementation always returns D3D_OK
540 *****************************************************************************/
541 static HRESULT WINAPI
d3d_execute_buffer_Unlock(IDirect3DExecuteBuffer
*iface
)
543 TRACE("iface %p.\n", iface
);
548 /*****************************************************************************
549 * IDirect3DExecuteBuffer::SetExecuteData
551 * Sets the execute data. This data is used to describe the buffer's content
554 * Data: Pointer to a D3DEXECUTEDATA structure containing the data to
559 * DDERR_OUTOFMEMORY if the vertex buffer allocation failed
561 *****************************************************************************/
562 static HRESULT WINAPI
d3d_execute_buffer_SetExecuteData(IDirect3DExecuteBuffer
*iface
, D3DEXECUTEDATA
*data
)
564 struct d3d_execute_buffer
*buffer
= impl_from_IDirect3DExecuteBuffer(iface
);
567 TRACE("iface %p, data %p.\n", iface
, data
);
569 memcpy(&buffer
->data
, data
, data
->dwSize
);
571 /* Get the number of vertices in the execute buffer */
572 nbvert
= buffer
->data
.dwVertexCount
;
574 /* Prepares the transformed vertex buffer */
575 HeapFree(GetProcessHeap(), 0, buffer
->vertex_data
);
576 buffer
->vertex_data
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, nbvert
* sizeof(D3DTLVERTEX
));
577 buffer
->nb_vertices
= nbvert
;
580 _dump_executedata(data
);
585 /*****************************************************************************
586 * IDirect3DExecuteBuffer::GetExecuteData
588 * Returns the data in the execute buffer
591 * Data: Pointer to a D3DEXECUTEDATA structure used to return data
596 *****************************************************************************/
597 static HRESULT WINAPI
d3d_execute_buffer_GetExecuteData(IDirect3DExecuteBuffer
*iface
, D3DEXECUTEDATA
*data
)
599 struct d3d_execute_buffer
*buffer
= impl_from_IDirect3DExecuteBuffer(iface
);
602 TRACE("iface %p, data %p.\n", iface
, data
);
604 dwSize
= data
->dwSize
;
605 memcpy(data
, &buffer
->data
, dwSize
);
609 TRACE("Returning data :\n");
610 _dump_executedata(data
);
616 /*****************************************************************************
617 * IDirect3DExecuteBuffer::Validate
619 * DirectX 5 SDK: "The IDirect3DExecuteBuffer::Validate method is not
620 * currently implemented"
626 * DDERR_UNSUPPORTED, because it's not implemented in Windows.
628 *****************************************************************************/
629 static HRESULT WINAPI
d3d_execute_buffer_Validate(IDirect3DExecuteBuffer
*iface
,
630 DWORD
*offset
, LPD3DVALIDATECALLBACK callback
, void *context
, DWORD reserved
)
632 TRACE("iface %p, offset %p, callback %p, context %p, reserved %#x.\n",
633 iface
, offset
, callback
, context
, reserved
);
635 WARN("Not implemented.\n");
637 return DDERR_UNSUPPORTED
; /* Unchecked */
640 /*****************************************************************************
641 * IDirect3DExecuteBuffer::Optimize
643 * DirectX5 SDK: "The IDirect3DExecuteBuffer::Optimize method is not
644 * currently supported"
647 * Dummy: Seems to be an unused dummy ;)
650 * DDERR_UNSUPPORTED, because it's not implemented in Windows.
652 *****************************************************************************/
653 static HRESULT WINAPI
d3d_execute_buffer_Optimize(IDirect3DExecuteBuffer
*iface
, DWORD reserved
)
655 TRACE("iface %p, reserved %#x.\n", iface
, reserved
);
657 WARN("Not implemented.\n");
659 return DDERR_UNSUPPORTED
; /* Unchecked */
662 static const struct IDirect3DExecuteBufferVtbl d3d_execute_buffer_vtbl
=
664 d3d_execute_buffer_QueryInterface
,
665 d3d_execute_buffer_AddRef
,
666 d3d_execute_buffer_Release
,
667 d3d_execute_buffer_Initialize
,
668 d3d_execute_buffer_Lock
,
669 d3d_execute_buffer_Unlock
,
670 d3d_execute_buffer_SetExecuteData
,
671 d3d_execute_buffer_GetExecuteData
,
672 d3d_execute_buffer_Validate
,
673 d3d_execute_buffer_Optimize
,
676 HRESULT
d3d_execute_buffer_init(struct d3d_execute_buffer
*execute_buffer
,
677 struct d3d_device
*device
, D3DEXECUTEBUFFERDESC
*desc
)
679 execute_buffer
->IDirect3DExecuteBuffer_iface
.lpVtbl
= &d3d_execute_buffer_vtbl
;
680 execute_buffer
->ref
= 1;
681 execute_buffer
->d3ddev
= device
;
683 /* Initializes memory */
684 memcpy(&execute_buffer
->desc
, desc
, desc
->dwSize
);
686 /* No buffer given */
687 if (!(execute_buffer
->desc
.dwFlags
& D3DDEB_LPDATA
))
688 execute_buffer
->desc
.lpData
= NULL
;
690 /* No buffer size given */
691 if (!(execute_buffer
->desc
.dwFlags
& D3DDEB_BUFSIZE
))
692 execute_buffer
->desc
.dwBufferSize
= 0;
694 /* Create buffer if asked */
695 if (!execute_buffer
->desc
.lpData
&& execute_buffer
->desc
.dwBufferSize
)
697 execute_buffer
->need_free
= TRUE
;
698 execute_buffer
->desc
.lpData
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, execute_buffer
->desc
.dwBufferSize
);
699 if (!execute_buffer
->desc
.lpData
)
701 ERR("Failed to allocate execute buffer data.\n");
702 return DDERR_OUTOFMEMORY
;
706 execute_buffer
->desc
.dwFlags
|= D3DDEB_LPDATA
;
711 struct d3d_execute_buffer
*unsafe_impl_from_IDirect3DExecuteBuffer(IDirect3DExecuteBuffer
*iface
)
715 assert(iface
->lpVtbl
== &d3d_execute_buffer_vtbl
);
717 return impl_from_IDirect3DExecuteBuffer(iface
);