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 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "wine/port.h"
24 #include "ddraw_private.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(ddraw
);
28 /*****************************************************************************
30 * _dump_D3DEXECUTEBUFFERDESC
32 * Debug functions which write the executebuffer data to the console
34 *****************************************************************************/
36 static void _dump_executedata(const D3DEXECUTEDATA
*lpData
) {
37 TRACE("dwSize : %d\n", lpData
->dwSize
);
38 TRACE("Vertex Offset : %d Count : %d\n", lpData
->dwVertexOffset
, lpData
->dwVertexCount
);
39 TRACE("Instruction Offset : %d Length : %d\n", lpData
->dwInstructionOffset
, lpData
->dwInstructionLength
);
40 TRACE("HVertex Offset : %d\n", lpData
->dwHVertexOffset
);
43 static void _dump_D3DEXECUTEBUFFERDESC(const D3DEXECUTEBUFFERDESC
*lpDesc
) {
44 TRACE("dwSize : %d\n", lpDesc
->dwSize
);
45 TRACE("dwFlags : %x\n", lpDesc
->dwFlags
);
46 TRACE("dwCaps : %x\n", lpDesc
->dwCaps
);
47 TRACE("dwBufferSize : %d\n", lpDesc
->dwBufferSize
);
48 TRACE("lpData : %p\n", lpDesc
->lpData
);
51 HRESULT
d3d_execute_buffer_execute(struct d3d_execute_buffer
*buffer
,
52 struct d3d_device
*device
, struct d3d_viewport
*viewport
)
54 DWORD is
= buffer
->data
.dwInstructionOffset
;
55 char *instr
= (char *)buffer
->desc
.lpData
+ is
;
57 struct wined3d_map_desc map_desc
;
58 struct wined3d_box box
= {0};
61 if (viewport
->active_device
!= device
)
63 WARN("Viewport %p active device is %p.\n",
64 viewport
, viewport
->active_device
);
65 return DDERR_INVALIDPARAMS
;
68 /* Activate the viewport */
69 viewport_activate(viewport
, FALSE
);
71 TRACE("ExecuteData :\n");
73 _dump_executedata(&(buffer
->data
));
77 D3DINSTRUCTION
*current
= (D3DINSTRUCTION
*)instr
;
81 count
= current
->wCount
;
82 size
= current
->bSize
;
83 instr
+= sizeof(D3DINSTRUCTION
);
85 switch (current
->bOpcode
) {
87 WARN("POINT-s (%d)\n", count
);
88 instr
+= count
* size
;
92 WARN("LINE-s (%d)\n", count
);
93 instr
+= count
* size
;
99 TRACE("TRIANGLE (%d)\n", count
);
104 if (buffer
->index_size
< count
* 3)
106 struct wined3d_buffer
*new_buffer
;
107 unsigned int new_size
= max(buffer
->index_size
* 2, count
* 3);
109 hr
= wined3d_buffer_create_ib(device
->wined3d_device
, new_size
* sizeof(*indices
),
110 WINED3DUSAGE_DYNAMIC
| WINED3DUSAGE_WRITEONLY
, WINED3D_POOL_DEFAULT
,
111 NULL
, &ddraw_null_wined3d_parent_ops
, &new_buffer
);
115 buffer
->index_size
= new_size
;
116 if (buffer
->index_buffer
)
117 wined3d_buffer_decref(buffer
->index_buffer
);
118 buffer
->index_buffer
= new_buffer
;
122 box
.right
= count
* 3 * sizeof(*indices
);
123 hr
= wined3d_resource_map(wined3d_buffer_get_resource(buffer
->index_buffer
), 0,
124 &map_desc
, &box
, WINED3D_MAP_DISCARD
);
127 indices
= map_desc
.data
;
129 for (i
= 0; i
< count
; ++i
)
131 D3DTRIANGLE
*ci
= (D3DTRIANGLE
*)instr
;
132 TRACE(" v1: %d v2: %d v3: %d\n",ci
->u1
.v1
, ci
->u2
.v2
, ci
->u3
.v3
);
137 if (ci
->wFlags
& D3DTRIFLAG_EDGEENABLE1
)
138 TRACE("EDGEENABLE1 ");
139 if (ci
->wFlags
& D3DTRIFLAG_EDGEENABLE2
)
140 TRACE("EDGEENABLE2 ");
141 if (ci
->wFlags
& D3DTRIFLAG_EDGEENABLE1
)
142 TRACE("EDGEENABLE3 ");
144 if (ci
->wFlags
== D3DTRIFLAG_EVEN
)
146 if (ci
->wFlags
== D3DTRIFLAG_ODD
)
148 if (ci
->wFlags
== D3DTRIFLAG_START
)
150 if ((ci
->wFlags
> 0) && (ci
->wFlags
< 30))
151 TRACE("STARTFLAT(%u) ", ci
->wFlags
);
154 indices
[(i
* 3) ] = ci
->u1
.v1
;
155 indices
[(i
* 3) + 1] = ci
->u2
.v2
;
156 indices
[(i
* 3) + 2] = ci
->u3
.v3
;
160 wined3d_resource_unmap(wined3d_buffer_get_resource(buffer
->index_buffer
), 0);
162 wined3d_device_set_stream_source(device
->wined3d_device
, 0,
163 buffer
->dst_vertex_buffer
, 0, sizeof(D3DTLVERTEX
));
164 wined3d_device_set_vertex_declaration(device
->wined3d_device
,
165 ddraw_find_decl(device
->ddraw
, D3DFVF_TLVERTEX
));
166 wined3d_device_set_index_buffer(device
->wined3d_device
, buffer
->index_buffer
, WINED3DFMT_R16_UINT
, 0);
167 wined3d_device_set_primitive_type(device
->wined3d_device
, WINED3D_PT_TRIANGLELIST
);
168 wined3d_device_draw_indexed_primitive(device
->wined3d_device
, 0, count
* 3);
171 case D3DOP_MATRIXLOAD
:
172 WARN("MATRIXLOAD-s (%d)\n", count
);
173 instr
+= count
* size
;
176 case D3DOP_MATRIXMULTIPLY
:
177 TRACE("MATRIXMULTIPLY (%d)\n", count
);
178 for (i
= 0; i
< count
; ++i
)
180 D3DMATRIXMULTIPLY
*ci
= (D3DMATRIXMULTIPLY
*)instr
;
181 D3DMATRIX
*a
, *b
, *c
;
183 a
= ddraw_get_object(&device
->handle_table
, ci
->hDestMatrix
- 1, DDRAW_HANDLE_MATRIX
);
184 b
= ddraw_get_object(&device
->handle_table
, ci
->hSrcMatrix1
- 1, DDRAW_HANDLE_MATRIX
);
185 c
= ddraw_get_object(&device
->handle_table
, ci
->hSrcMatrix2
- 1, DDRAW_HANDLE_MATRIX
);
189 ERR("Invalid matrix handle (a %#x -> %p, b %#x -> %p, c %#x -> %p).\n",
190 ci
->hDestMatrix
, a
, ci
->hSrcMatrix1
, b
, ci
->hSrcMatrix2
, c
);
194 TRACE("dst %p, src1 %p, src2 %p.\n", a
, b
, c
);
195 multiply_matrix(a
, c
, b
);
202 case D3DOP_STATETRANSFORM
:
203 TRACE("STATETRANSFORM (%d)\n", count
);
204 for (i
= 0; i
< count
; ++i
)
206 D3DSTATE
*ci
= (D3DSTATE
*)instr
;
209 m
= ddraw_get_object(&device
->handle_table
, ci
->u2
.dwArg
[0] - 1, DDRAW_HANDLE_MATRIX
);
212 ERR("Invalid matrix handle %#x.\n", ci
->u2
.dwArg
[0]);
216 if (ci
->u1
.dtstTransformStateType
== D3DTRANSFORMSTATE_WORLD
)
217 device
->world
= ci
->u2
.dwArg
[0];
218 if (ci
->u1
.dtstTransformStateType
== D3DTRANSFORMSTATE_VIEW
)
219 device
->view
= ci
->u2
.dwArg
[0];
220 if (ci
->u1
.dtstTransformStateType
== D3DTRANSFORMSTATE_PROJECTION
)
221 device
->proj
= ci
->u2
.dwArg
[0];
222 IDirect3DDevice3_SetTransform(&device
->IDirect3DDevice3_iface
,
223 ci
->u1
.dtstTransformStateType
, m
);
230 case D3DOP_STATELIGHT
:
231 TRACE("STATELIGHT (%d)\n", count
);
232 for (i
= 0; i
< count
; ++i
)
234 D3DSTATE
*ci
= (D3DSTATE
*)instr
;
236 if (FAILED(IDirect3DDevice3_SetLightState(&device
->IDirect3DDevice3_iface
,
237 ci
->u1
.dlstLightStateType
, ci
->u2
.dwArg
[0])))
238 WARN("Failed to set light state.\n");
244 case D3DOP_STATERENDER
:
245 TRACE("STATERENDER (%d)\n", count
);
246 for (i
= 0; i
< count
; ++i
)
248 D3DSTATE
*ci
= (D3DSTATE
*)instr
;
250 if (FAILED(IDirect3DDevice3_SetRenderState(&device
->IDirect3DDevice3_iface
,
251 ci
->u1
.drstRenderStateType
, ci
->u2
.dwArg
[0])))
252 WARN("Failed to set render state.\n");
258 case D3DOP_PROCESSVERTICES
:
259 TRACE("PROCESSVERTICES (%d)\n", count
);
261 for (i
= 0; i
< count
; ++i
)
263 D3DPROCESSVERTICES
*ci
= (D3DPROCESSVERTICES
*)instr
;
264 DWORD op
= ci
->dwFlags
& D3DPROCESSVERTICES_OPMASK
;
266 TRACE(" start %u, dest %u, count %u, flags %#x.\n",
267 ci
->wStart
, ci
->wDest
, ci
->dwCount
, ci
->dwFlags
);
269 if (ci
->dwFlags
& D3DPROCESSVERTICES_UPDATEEXTENTS
)
270 FIXME("D3DPROCESSVERTICES_UPDATEEXTENTS not implemented.\n");
271 if (ci
->dwFlags
& D3DPROCESSVERTICES_NOCOLOR
)
272 FIXME("D3DPROCESSVERTICES_NOCOLOR not implemented.\n");
276 case D3DPROCESSVERTICES_TRANSFORMLIGHT
:
277 case D3DPROCESSVERTICES_TRANSFORM
:
278 wined3d_device_set_stream_source(device
->wined3d_device
, 0,
279 buffer
->src_vertex_buffer
, 0, sizeof(D3DVERTEX
));
280 if (op
== D3DPROCESSVERTICES_TRANSFORMLIGHT
)
282 wined3d_device_set_vertex_declaration(device
->wined3d_device
,
283 ddraw_find_decl(device
->ddraw
, D3DFVF_VERTEX
));
284 wined3d_device_set_render_state(device
->wined3d_device
,
285 WINED3D_RS_LIGHTING
, TRUE
);
289 wined3d_device_set_vertex_declaration(device
->wined3d_device
,
290 ddraw_find_decl(device
->ddraw
, D3DFVF_LVERTEX
));
291 wined3d_device_set_render_state(device
->wined3d_device
,
292 WINED3D_RS_LIGHTING
, FALSE
);
295 wined3d_device_process_vertices(device
->wined3d_device
, ci
->wStart
, ci
->wDest
,
296 ci
->dwCount
, buffer
->dst_vertex_buffer
, NULL
, 0, D3DFVF_TLVERTEX
);
299 case D3DPROCESSVERTICES_COPY
:
300 box
.left
= ci
->wStart
* sizeof(D3DTLVERTEX
);
301 box
.right
= (ci
->wStart
+ ci
->dwCount
) * sizeof(D3DTLVERTEX
);
302 box
.top
= box
.front
= 0;
303 box
.bottom
= box
.back
= 1;
304 wined3d_device_copy_sub_resource_region(device
->wined3d_device
,
305 wined3d_buffer_get_resource(buffer
->dst_vertex_buffer
), 0,
306 ci
->wDest
* sizeof(D3DTLVERTEX
), 0, 0,
307 wined3d_buffer_get_resource(buffer
->src_vertex_buffer
), 0, &box
);
311 FIXME("Unhandled vertex processing op %#x.\n", op
);
319 case D3DOP_TEXTURELOAD
: {
320 WARN("TEXTURELOAD-s (%d)\n", count
);
322 instr
+= count
* size
;
326 TRACE("EXIT (%d)\n", count
);
327 /* We did this instruction */
333 case D3DOP_BRANCHFORWARD
:
334 TRACE("BRANCHFORWARD (%d)\n", count
);
335 for (i
= 0; i
< count
; ++i
)
337 D3DBRANCH
*ci
= (D3DBRANCH
*)instr
;
339 if ((buffer
->data
.dsStatus
.dwStatus
& ci
->dwMask
) == ci
->dwValue
)
343 TRACE(" Branch to %d\n", ci
->dwOffset
);
345 instr
= (char*)current
+ ci
->dwOffset
;
351 TRACE(" Branch to %d\n", ci
->dwOffset
);
353 instr
= (char*)current
+ ci
->dwOffset
;
364 WARN("SPAN-s (%d)\n", count
);
366 instr
+= count
* size
;
369 case D3DOP_SETSTATUS
:
370 TRACE("SETSTATUS (%d)\n", count
);
371 for (i
= 0; i
< count
; ++i
)
373 buffer
->data
.dsStatus
= *(D3DSTATUS
*)instr
;
379 ERR("Unhandled OpCode %d !!!\n",current
->bOpcode
);
380 /* Try to save ... */
381 instr
+= count
* size
;
390 static inline struct d3d_execute_buffer
*impl_from_IDirect3DExecuteBuffer(IDirect3DExecuteBuffer
*iface
)
392 return CONTAINING_RECORD(iface
, struct d3d_execute_buffer
, IDirect3DExecuteBuffer_iface
);
395 static HRESULT WINAPI
d3d_execute_buffer_QueryInterface(IDirect3DExecuteBuffer
*iface
, REFIID iid
, void **out
)
397 TRACE("iface %p, iid %s, out %p.\n", iface
, debugstr_guid(iid
), out
);
399 if (IsEqualGUID(&IID_IDirect3DExecuteBuffer
, iid
)
400 || IsEqualGUID(&IID_IUnknown
, iid
))
402 IDirect3DExecuteBuffer_AddRef(iface
);
407 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid
));
410 return E_NOINTERFACE
;
413 /*****************************************************************************
414 * IDirect3DExecuteBuffer::AddRef
416 * A normal AddRef method, nothing special
421 *****************************************************************************/
422 static ULONG WINAPI
d3d_execute_buffer_AddRef(IDirect3DExecuteBuffer
*iface
)
424 struct d3d_execute_buffer
*buffer
= impl_from_IDirect3DExecuteBuffer(iface
);
425 ULONG ref
= InterlockedIncrement(&buffer
->ref
);
427 TRACE("%p increasing refcount to %u.\n", buffer
, ref
);
432 /*****************************************************************************
433 * IDirect3DExecuteBuffer::Release
435 * A normal Release method, nothing special
440 *****************************************************************************/
441 static ULONG WINAPI
d3d_execute_buffer_Release(IDirect3DExecuteBuffer
*iface
)
443 struct d3d_execute_buffer
*buffer
= impl_from_IDirect3DExecuteBuffer(iface
);
444 ULONG ref
= InterlockedDecrement(&buffer
->ref
);
446 TRACE("%p decreasing refcount to %u.\n", buffer
, ref
);
450 if (buffer
->need_free
)
451 HeapFree(GetProcessHeap(), 0, buffer
->desc
.lpData
);
452 if (buffer
->index_buffer
)
453 wined3d_buffer_decref(buffer
->index_buffer
);
454 if (buffer
->dst_vertex_buffer
)
456 wined3d_buffer_decref(buffer
->src_vertex_buffer
);
457 wined3d_buffer_decref(buffer
->dst_vertex_buffer
);
459 HeapFree(GetProcessHeap(), 0, buffer
);
465 /*****************************************************************************
466 * IDirect3DExecuteBuffer::Initialize
468 * Initializes the Execute Buffer. This method exists for COM compliance
469 * Nothing to do here.
474 *****************************************************************************/
475 static HRESULT WINAPI
d3d_execute_buffer_Initialize(IDirect3DExecuteBuffer
*iface
,
476 IDirect3DDevice
*device
, D3DEXECUTEBUFFERDESC
*desc
)
478 TRACE("iface %p, device %p, desc %p.\n", iface
, device
, desc
);
483 /*****************************************************************************
484 * IDirect3DExecuteBuffer::Lock
486 * Locks the buffer, so the app can write into it.
489 * Desc: Pointer to return the buffer description. This Description contains
490 * a pointer to the buffer data.
493 * This implementation always returns D3D_OK
495 *****************************************************************************/
496 static HRESULT WINAPI
d3d_execute_buffer_Lock(IDirect3DExecuteBuffer
*iface
, D3DEXECUTEBUFFERDESC
*desc
)
498 struct d3d_execute_buffer
*buffer
= impl_from_IDirect3DExecuteBuffer(iface
);
501 TRACE("iface %p, desc %p.\n", iface
, desc
);
503 dwSize
= desc
->dwSize
;
504 memcpy(desc
, &buffer
->desc
, dwSize
);
508 TRACE(" Returning description :\n");
509 _dump_D3DEXECUTEBUFFERDESC(desc
);
514 /*****************************************************************************
515 * IDirect3DExecuteBuffer::Unlock
517 * Unlocks the buffer. We don't have anything to do here
520 * This implementation always returns D3D_OK
522 *****************************************************************************/
523 static HRESULT WINAPI
d3d_execute_buffer_Unlock(IDirect3DExecuteBuffer
*iface
)
525 TRACE("iface %p.\n", iface
);
530 /*****************************************************************************
531 * IDirect3DExecuteBuffer::SetExecuteData
533 * Sets the execute data. This data is used to describe the buffer's content
536 * Data: Pointer to a D3DEXECUTEDATA structure containing the data to
541 * DDERR_OUTOFMEMORY if the vertex buffer allocation failed
543 *****************************************************************************/
544 static HRESULT WINAPI
d3d_execute_buffer_SetExecuteData(IDirect3DExecuteBuffer
*iface
, D3DEXECUTEDATA
*data
)
546 struct d3d_execute_buffer
*buffer
= impl_from_IDirect3DExecuteBuffer(iface
);
547 struct wined3d_map_desc map_desc
;
548 struct wined3d_box box
= {0};
551 TRACE("iface %p, data %p.\n", iface
, data
);
553 if (buffer
->vertex_size
< data
->dwVertexCount
)
555 unsigned int new_size
= max(data
->dwVertexCount
, buffer
->vertex_size
* 2);
556 struct wined3d_buffer
*src_buffer
, *dst_buffer
;
558 hr
= wined3d_buffer_create_vb(buffer
->d3ddev
->wined3d_device
, new_size
* sizeof(D3DVERTEX
),
559 WINED3DUSAGE_DYNAMIC
| WINED3DUSAGE_WRITEONLY
, WINED3D_POOL_SYSTEM_MEM
,
560 NULL
, &ddraw_null_wined3d_parent_ops
, &src_buffer
);
564 hr
= wined3d_buffer_create_vb(buffer
->d3ddev
->wined3d_device
, new_size
* sizeof(D3DTLVERTEX
),
565 WINED3DUSAGE_STATICDECL
, WINED3D_POOL_DEFAULT
,
566 NULL
, &ddraw_null_wined3d_parent_ops
, &dst_buffer
);
569 wined3d_buffer_decref(src_buffer
);
573 if (buffer
->dst_vertex_buffer
)
575 wined3d_buffer_decref(buffer
->src_vertex_buffer
);
576 wined3d_buffer_decref(buffer
->dst_vertex_buffer
);
578 buffer
->src_vertex_buffer
= src_buffer
;
579 buffer
->dst_vertex_buffer
= dst_buffer
;
580 buffer
->vertex_size
= new_size
;
583 if (data
->dwVertexCount
)
586 box
.right
= data
->dwVertexCount
* sizeof(D3DVERTEX
);
587 hr
= wined3d_resource_map(wined3d_buffer_get_resource(buffer
->src_vertex_buffer
), 0,
588 &map_desc
, &box
, WINED3D_MAP_DISCARD
);
592 memcpy(map_desc
.data
, ((BYTE
*)buffer
->desc
.lpData
) + data
->dwVertexOffset
, box
.right
);
594 wined3d_resource_unmap(wined3d_buffer_get_resource(buffer
->src_vertex_buffer
), 0);
597 memcpy(&buffer
->data
, data
, data
->dwSize
);
600 _dump_executedata(data
);
605 /*****************************************************************************
606 * IDirect3DExecuteBuffer::GetExecuteData
608 * Returns the data in the execute buffer
611 * Data: Pointer to a D3DEXECUTEDATA structure used to return data
616 *****************************************************************************/
617 static HRESULT WINAPI
d3d_execute_buffer_GetExecuteData(IDirect3DExecuteBuffer
*iface
, D3DEXECUTEDATA
*data
)
619 struct d3d_execute_buffer
*buffer
= impl_from_IDirect3DExecuteBuffer(iface
);
622 TRACE("iface %p, data %p.\n", iface
, data
);
624 dwSize
= data
->dwSize
;
625 memcpy(data
, &buffer
->data
, dwSize
);
629 TRACE("Returning data :\n");
630 _dump_executedata(data
);
636 /*****************************************************************************
637 * IDirect3DExecuteBuffer::Validate
639 * DirectX 5 SDK: "The IDirect3DExecuteBuffer::Validate method is not
640 * currently implemented"
646 * DDERR_UNSUPPORTED, because it's not implemented in Windows.
648 *****************************************************************************/
649 static HRESULT WINAPI
d3d_execute_buffer_Validate(IDirect3DExecuteBuffer
*iface
,
650 DWORD
*offset
, LPD3DVALIDATECALLBACK callback
, void *context
, DWORD reserved
)
652 TRACE("iface %p, offset %p, callback %p, context %p, reserved %#x.\n",
653 iface
, offset
, callback
, context
, reserved
);
655 WARN("Not implemented.\n");
657 return DDERR_UNSUPPORTED
; /* Unchecked */
660 /*****************************************************************************
661 * IDirect3DExecuteBuffer::Optimize
663 * DirectX5 SDK: "The IDirect3DExecuteBuffer::Optimize method is not
664 * currently supported"
667 * Dummy: Seems to be an unused dummy ;)
670 * DDERR_UNSUPPORTED, because it's not implemented in Windows.
672 *****************************************************************************/
673 static HRESULT WINAPI
d3d_execute_buffer_Optimize(IDirect3DExecuteBuffer
*iface
, DWORD reserved
)
675 TRACE("iface %p, reserved %#x.\n", iface
, reserved
);
677 WARN("Not implemented.\n");
679 return DDERR_UNSUPPORTED
; /* Unchecked */
682 static const struct IDirect3DExecuteBufferVtbl d3d_execute_buffer_vtbl
=
684 d3d_execute_buffer_QueryInterface
,
685 d3d_execute_buffer_AddRef
,
686 d3d_execute_buffer_Release
,
687 d3d_execute_buffer_Initialize
,
688 d3d_execute_buffer_Lock
,
689 d3d_execute_buffer_Unlock
,
690 d3d_execute_buffer_SetExecuteData
,
691 d3d_execute_buffer_GetExecuteData
,
692 d3d_execute_buffer_Validate
,
693 d3d_execute_buffer_Optimize
,
696 HRESULT
d3d_execute_buffer_init(struct d3d_execute_buffer
*execute_buffer
,
697 struct d3d_device
*device
, D3DEXECUTEBUFFERDESC
*desc
)
699 execute_buffer
->IDirect3DExecuteBuffer_iface
.lpVtbl
= &d3d_execute_buffer_vtbl
;
700 execute_buffer
->ref
= 1;
701 execute_buffer
->d3ddev
= device
;
703 /* Initializes memory */
704 memcpy(&execute_buffer
->desc
, desc
, desc
->dwSize
);
706 /* No buffer given */
707 if (!(execute_buffer
->desc
.dwFlags
& D3DDEB_LPDATA
))
708 execute_buffer
->desc
.lpData
= NULL
;
710 /* No buffer size given */
711 if (!(execute_buffer
->desc
.dwFlags
& D3DDEB_BUFSIZE
))
712 execute_buffer
->desc
.dwBufferSize
= 0;
714 /* Create buffer if asked */
715 if (!execute_buffer
->desc
.lpData
&& execute_buffer
->desc
.dwBufferSize
)
717 execute_buffer
->need_free
= TRUE
;
718 execute_buffer
->desc
.lpData
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, execute_buffer
->desc
.dwBufferSize
);
719 if (!execute_buffer
->desc
.lpData
)
721 ERR("Failed to allocate execute buffer data.\n");
722 return DDERR_OUTOFMEMORY
;
726 execute_buffer
->desc
.dwFlags
|= D3DDEB_LPDATA
;
731 struct d3d_execute_buffer
*unsafe_impl_from_IDirect3DExecuteBuffer(IDirect3DExecuteBuffer
*iface
)
735 assert(iface
->lpVtbl
== &d3d_execute_buffer_vtbl
);
737 return impl_from_IDirect3DExecuteBuffer(iface
);