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 static void transform_vertex(D3DTLVERTEX
*dst
, const D3DMATRIX
*mat
,
52 const D3DVIEWPORT
*vp
, float x
, float y
, float z
)
54 dst
->u1
.sx
= (x
* mat
->_11
) + (y
* mat
->_21
) + (z
* mat
->_31
) + mat
->_41
;
55 dst
->u2
.sy
= (x
* mat
->_12
) + (y
* mat
->_22
) + (z
* mat
->_32
) + mat
->_42
;
56 dst
->u3
.sz
= (x
* mat
->_13
) + (y
* mat
->_23
) + (z
* mat
->_33
) + mat
->_43
;
57 dst
->u4
.rhw
= (x
* mat
->_14
) + (y
* mat
->_24
) + (z
* mat
->_34
) + mat
->_44
;
59 dst
->u4
.rhw
= 1.0f
/ dst
->u4
.rhw
;
61 dst
->u1
.sx
= (dst
->u1
.sx
* dst
->u4
.rhw
+ 1.0f
) * vp
->dwWidth
* 0.5 + vp
->dwX
;
62 dst
->u2
.sy
= (-dst
->u2
.sy
* dst
->u4
.rhw
+ 1.0f
) * vp
->dwHeight
* 0.5 + vp
->dwY
;
63 dst
->u3
.sz
*= dst
->u4
.rhw
;
66 HRESULT
d3d_execute_buffer_execute(struct d3d_execute_buffer
*buffer
,
67 struct d3d_device
*device
, struct d3d_viewport
*viewport
)
69 DWORD vs
= buffer
->data
.dwVertexOffset
;
70 DWORD is
= buffer
->data
.dwInstructionOffset
;
71 char *instr
= (char *)buffer
->desc
.lpData
+ is
;
73 struct wined3d_map_desc map_desc
;
74 struct wined3d_box box
= {0};
77 if (viewport
->active_device
!= device
)
79 WARN("Viewport %p active device is %p.\n",
80 viewport
, viewport
->active_device
);
81 return DDERR_INVALIDPARAMS
;
84 /* Activate the viewport */
85 viewport_activate(viewport
, FALSE
);
87 TRACE("ExecuteData :\n");
89 _dump_executedata(&(buffer
->data
));
93 D3DINSTRUCTION
*current
= (D3DINSTRUCTION
*)instr
;
97 count
= current
->wCount
;
98 size
= current
->bSize
;
99 instr
+= sizeof(D3DINSTRUCTION
);
101 switch (current
->bOpcode
) {
103 WARN("POINT-s (%d)\n", count
);
104 instr
+= count
* size
;
108 WARN("LINE-s (%d)\n", count
);
109 instr
+= count
* size
;
115 TRACE("TRIANGLE (%d)\n", count
);
120 if (buffer
->index_size
< count
* 3)
122 struct wined3d_buffer
*new_buffer
;
123 unsigned int new_size
= max(buffer
->index_size
* 2, count
* 3);
125 hr
= wined3d_buffer_create_ib(device
->wined3d_device
, new_size
* sizeof(*indices
),
126 WINED3DUSAGE_DYNAMIC
| WINED3DUSAGE_WRITEONLY
, WINED3D_POOL_DEFAULT
,
127 NULL
, &ddraw_null_wined3d_parent_ops
, &new_buffer
);
131 buffer
->index_size
= new_size
;
132 if (buffer
->index_buffer
)
133 wined3d_buffer_decref(buffer
->index_buffer
);
134 buffer
->index_buffer
= new_buffer
;
138 box
.right
= count
* 3 * sizeof(*indices
);
139 hr
= wined3d_resource_map(wined3d_buffer_get_resource(buffer
->index_buffer
), 0,
140 &map_desc
, &box
, WINED3D_MAP_DISCARD
);
143 indices
= map_desc
.data
;
145 for (i
= 0; i
< count
; ++i
)
147 D3DTRIANGLE
*ci
= (D3DTRIANGLE
*)instr
;
148 TRACE(" v1: %d v2: %d v3: %d\n",ci
->u1
.v1
, ci
->u2
.v2
, ci
->u3
.v3
);
153 if (ci
->wFlags
& D3DTRIFLAG_EDGEENABLE1
)
154 TRACE("EDGEENABLE1 ");
155 if (ci
->wFlags
& D3DTRIFLAG_EDGEENABLE2
)
156 TRACE("EDGEENABLE2 ");
157 if (ci
->wFlags
& D3DTRIFLAG_EDGEENABLE1
)
158 TRACE("EDGEENABLE3 ");
160 if (ci
->wFlags
== D3DTRIFLAG_EVEN
)
162 if (ci
->wFlags
== D3DTRIFLAG_ODD
)
164 if (ci
->wFlags
== D3DTRIFLAG_START
)
166 if ((ci
->wFlags
> 0) && (ci
->wFlags
< 30))
167 TRACE("STARTFLAT(%u) ", ci
->wFlags
);
170 indices
[(i
* 3) ] = ci
->u1
.v1
;
171 indices
[(i
* 3) + 1] = ci
->u2
.v2
;
172 indices
[(i
* 3) + 2] = ci
->u3
.v3
;
176 wined3d_resource_unmap(wined3d_buffer_get_resource(buffer
->index_buffer
), 0);
178 wined3d_device_set_stream_source(device
->wined3d_device
, 0,
179 buffer
->dst_vertex_buffer
, 0, sizeof(D3DTLVERTEX
));
180 wined3d_device_set_vertex_declaration(device
->wined3d_device
,
181 ddraw_find_decl(device
->ddraw
, D3DFVF_TLVERTEX
));
182 wined3d_device_set_index_buffer(device
->wined3d_device
, buffer
->index_buffer
, WINED3DFMT_R16_UINT
, 0);
183 wined3d_device_set_primitive_type(device
->wined3d_device
, WINED3D_PT_TRIANGLELIST
);
184 wined3d_device_draw_indexed_primitive(device
->wined3d_device
, 0, count
* 3);
187 case D3DOP_MATRIXLOAD
:
188 WARN("MATRIXLOAD-s (%d)\n", count
);
189 instr
+= count
* size
;
192 case D3DOP_MATRIXMULTIPLY
:
193 TRACE("MATRIXMULTIPLY (%d)\n", count
);
194 for (i
= 0; i
< count
; ++i
)
196 D3DMATRIXMULTIPLY
*ci
= (D3DMATRIXMULTIPLY
*)instr
;
197 D3DMATRIX
*a
, *b
, *c
;
199 a
= ddraw_get_object(&device
->handle_table
, ci
->hDestMatrix
- 1, DDRAW_HANDLE_MATRIX
);
200 b
= ddraw_get_object(&device
->handle_table
, ci
->hSrcMatrix1
- 1, DDRAW_HANDLE_MATRIX
);
201 c
= ddraw_get_object(&device
->handle_table
, ci
->hSrcMatrix2
- 1, DDRAW_HANDLE_MATRIX
);
205 ERR("Invalid matrix handle (a %#x -> %p, b %#x -> %p, c %#x -> %p).\n",
206 ci
->hDestMatrix
, a
, ci
->hSrcMatrix1
, b
, ci
->hSrcMatrix2
, c
);
210 TRACE("dst %p, src1 %p, src2 %p.\n", a
, b
, c
);
211 multiply_matrix(a
, c
, b
);
218 case D3DOP_STATETRANSFORM
:
219 TRACE("STATETRANSFORM (%d)\n", count
);
220 for (i
= 0; i
< count
; ++i
)
222 D3DSTATE
*ci
= (D3DSTATE
*)instr
;
225 m
= ddraw_get_object(&device
->handle_table
, ci
->u2
.dwArg
[0] - 1, DDRAW_HANDLE_MATRIX
);
228 ERR("Invalid matrix handle %#x.\n", ci
->u2
.dwArg
[0]);
232 if (ci
->u1
.dtstTransformStateType
== D3DTRANSFORMSTATE_WORLD
)
233 device
->world
= ci
->u2
.dwArg
[0];
234 if (ci
->u1
.dtstTransformStateType
== D3DTRANSFORMSTATE_VIEW
)
235 device
->view
= ci
->u2
.dwArg
[0];
236 if (ci
->u1
.dtstTransformStateType
== D3DTRANSFORMSTATE_PROJECTION
)
237 device
->proj
= ci
->u2
.dwArg
[0];
238 IDirect3DDevice3_SetTransform(&device
->IDirect3DDevice3_iface
,
239 ci
->u1
.dtstTransformStateType
, m
);
246 case D3DOP_STATELIGHT
:
247 TRACE("STATELIGHT (%d)\n", count
);
248 for (i
= 0; i
< count
; ++i
)
250 D3DSTATE
*ci
= (D3DSTATE
*)instr
;
252 if (FAILED(IDirect3DDevice3_SetLightState(&device
->IDirect3DDevice3_iface
,
253 ci
->u1
.dlstLightStateType
, ci
->u2
.dwArg
[0])))
254 WARN("Failed to set light state.\n");
260 case D3DOP_STATERENDER
:
261 TRACE("STATERENDER (%d)\n", count
);
262 for (i
= 0; i
< count
; ++i
)
264 D3DSTATE
*ci
= (D3DSTATE
*)instr
;
266 if (FAILED(IDirect3DDevice3_SetRenderState(&device
->IDirect3DDevice3_iface
,
267 ci
->u1
.drstRenderStateType
, ci
->u2
.dwArg
[0])))
268 WARN("Failed to set render state.\n");
274 case D3DOP_PROCESSVERTICES
:
276 /* TODO: Share code with d3d_vertex_buffer7_ProcessVertices()
277 * and / or wined3d_device_process_vertices(). */
278 D3DMATRIX view_mat
, world_mat
, proj_mat
, mat
;
280 TRACE("PROCESSVERTICES (%d)\n", count
);
282 /* Note that the projection set in wined3d has the legacy clip space
283 * adjustment built in. */
284 wined3d_device_get_transform(device
->wined3d_device
,
285 D3DTRANSFORMSTATE_VIEW
, (struct wined3d_matrix
*)&view_mat
);
286 wined3d_device_get_transform(device
->wined3d_device
,
287 D3DTRANSFORMSTATE_PROJECTION
, (struct wined3d_matrix
*)&proj_mat
);
288 wined3d_device_get_transform(device
->wined3d_device
,
289 WINED3D_TS_WORLD_MATRIX(0), (struct wined3d_matrix
*)&world_mat
);
293 TRACE(" Projection Matrix:\n");
294 dump_D3DMATRIX(&proj_mat
);
295 TRACE(" View Matrix:\n");
296 dump_D3DMATRIX(&view_mat
);
297 TRACE(" World Matrix:\n");
298 dump_D3DMATRIX(&world_mat
);
301 multiply_matrix(&mat
, &view_mat
, &world_mat
);
302 multiply_matrix(&mat
, &proj_mat
, &mat
);
304 for (i
= 0; i
< count
; ++i
)
306 D3DPROCESSVERTICES
*ci
= (D3DPROCESSVERTICES
*)instr
;
307 DWORD op
= ci
->dwFlags
& D3DPROCESSVERTICES_OPMASK
;
308 D3DTLVERTEX
*src
, *dst
;
310 TRACE(" start %u, dest %u, count %u, flags %#x.\n",
311 ci
->wStart
, ci
->wDest
, ci
->dwCount
, ci
->dwFlags
);
313 if (ci
->dwFlags
& D3DPROCESSVERTICES_UPDATEEXTENTS
)
314 FIXME("D3DPROCESSVERTICES_UPDATEEXTENTS not implemented.\n");
315 if (ci
->dwFlags
& D3DPROCESSVERTICES_NOCOLOR
)
316 FIXME("D3DPROCESSVERTICES_NOCOLOR not implemented.\n");
320 case D3DPROCESSVERTICES_TRANSFORMLIGHT
:
322 const D3DVERTEX
*src
= (D3DVERTEX
*)((char *)buffer
->desc
.lpData
+ vs
) + ci
->wStart
;
323 unsigned int vtx_idx
;
324 static unsigned int once
;
327 FIXME("Lighting not implemented.\n");
329 box
.left
= ci
->wDest
* sizeof(*dst
);
330 box
.right
= (ci
->wDest
+ ci
->dwCount
) * sizeof(*dst
);
331 hr
= wined3d_resource_map(wined3d_buffer_get_resource(buffer
->dst_vertex_buffer
), 0,
337 for (vtx_idx
= 0; vtx_idx
< ci
->dwCount
; ++vtx_idx
)
339 transform_vertex(&dst
[vtx_idx
], &mat
, &viewport
->viewports
.vp1
,
340 src
[vtx_idx
].u1
.x
, src
[vtx_idx
].u2
.y
, src
[vtx_idx
].u3
.z
);
341 /* No lighting yet */
342 dst
[vtx_idx
].u5
.color
= 0xffffffff; /* Opaque white */
343 dst
[vtx_idx
].u6
.specular
= 0xff000000; /* No specular and no fog factor */
344 dst
[vtx_idx
].u7
.tu
= src
[vtx_idx
].u7
.tu
;
345 dst
[vtx_idx
].u8
.tv
= src
[vtx_idx
].u8
.tv
;
348 wined3d_resource_unmap(wined3d_buffer_get_resource(buffer
->dst_vertex_buffer
), 0);
353 case D3DPROCESSVERTICES_TRANSFORM
:
355 const D3DLVERTEX
*src
= (D3DLVERTEX
*)((char *)buffer
->desc
.lpData
+ vs
) + ci
->wStart
;
356 unsigned int vtx_idx
;
358 box
.left
= ci
->wDest
* sizeof(*dst
);
359 box
.right
= (ci
->wDest
+ ci
->dwCount
) * sizeof(*dst
);
360 hr
= wined3d_resource_map(wined3d_buffer_get_resource(buffer
->dst_vertex_buffer
), 0,
366 for (vtx_idx
= 0; vtx_idx
< ci
->dwCount
; ++vtx_idx
)
368 transform_vertex(&dst
[vtx_idx
], &mat
, &viewport
->viewports
.vp1
,
369 src
[vtx_idx
].u1
.x
, src
[vtx_idx
].u2
.y
, src
[vtx_idx
].u3
.z
);
370 dst
[vtx_idx
].u5
.color
= src
[vtx_idx
].u4
.color
;
371 dst
[vtx_idx
].u6
.specular
= src
[vtx_idx
].u5
.specular
;
372 dst
[vtx_idx
].u7
.tu
= src
[vtx_idx
].u6
.tu
;
373 dst
[vtx_idx
].u8
.tv
= src
[vtx_idx
].u7
.tv
;
376 wined3d_resource_unmap(wined3d_buffer_get_resource(buffer
->dst_vertex_buffer
), 0);
381 case D3DPROCESSVERTICES_COPY
:
382 box
.left
= ci
->wDest
* sizeof(*src
);
383 box
.right
= (ci
->wDest
+ ci
->dwCount
) * sizeof(*src
);
384 hr
= wined3d_resource_map(wined3d_buffer_get_resource(buffer
->dst_vertex_buffer
), 0,
389 src
= (D3DTLVERTEX
*)((char *)buffer
->desc
.lpData
+ vs
) + ci
->wStart
;
390 memcpy(map_desc
.data
, src
, ci
->dwCount
* sizeof(*src
));
392 wined3d_resource_unmap(wined3d_buffer_get_resource(buffer
->dst_vertex_buffer
), 0);
396 FIXME("Unhandled vertex processing op %#x.\n", op
);
405 case D3DOP_TEXTURELOAD
: {
406 WARN("TEXTURELOAD-s (%d)\n", count
);
408 instr
+= count
* size
;
412 TRACE("EXIT (%d)\n", count
);
413 /* We did this instruction */
419 case D3DOP_BRANCHFORWARD
:
420 TRACE("BRANCHFORWARD (%d)\n", count
);
421 for (i
= 0; i
< count
; ++i
)
423 D3DBRANCH
*ci
= (D3DBRANCH
*)instr
;
425 if ((buffer
->data
.dsStatus
.dwStatus
& ci
->dwMask
) == ci
->dwValue
)
429 TRACE(" Branch to %d\n", ci
->dwOffset
);
431 instr
= (char*)current
+ ci
->dwOffset
;
437 TRACE(" Branch to %d\n", ci
->dwOffset
);
439 instr
= (char*)current
+ ci
->dwOffset
;
450 WARN("SPAN-s (%d)\n", count
);
452 instr
+= count
* size
;
455 case D3DOP_SETSTATUS
:
456 TRACE("SETSTATUS (%d)\n", count
);
457 for (i
= 0; i
< count
; ++i
)
459 buffer
->data
.dsStatus
= *(D3DSTATUS
*)instr
;
465 ERR("Unhandled OpCode %d !!!\n",current
->bOpcode
);
466 /* Try to save ... */
467 instr
+= count
* size
;
476 static inline struct d3d_execute_buffer
*impl_from_IDirect3DExecuteBuffer(IDirect3DExecuteBuffer
*iface
)
478 return CONTAINING_RECORD(iface
, struct d3d_execute_buffer
, IDirect3DExecuteBuffer_iface
);
481 static HRESULT WINAPI
d3d_execute_buffer_QueryInterface(IDirect3DExecuteBuffer
*iface
, REFIID iid
, void **out
)
483 TRACE("iface %p, iid %s, out %p.\n", iface
, debugstr_guid(iid
), out
);
485 if (IsEqualGUID(&IID_IDirect3DExecuteBuffer
, iid
)
486 || IsEqualGUID(&IID_IUnknown
, iid
))
488 IDirect3DExecuteBuffer_AddRef(iface
);
493 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid
));
496 return E_NOINTERFACE
;
499 /*****************************************************************************
500 * IDirect3DExecuteBuffer::AddRef
502 * A normal AddRef method, nothing special
507 *****************************************************************************/
508 static ULONG WINAPI
d3d_execute_buffer_AddRef(IDirect3DExecuteBuffer
*iface
)
510 struct d3d_execute_buffer
*buffer
= impl_from_IDirect3DExecuteBuffer(iface
);
511 ULONG ref
= InterlockedIncrement(&buffer
->ref
);
513 TRACE("%p increasing refcount to %u.\n", buffer
, ref
);
518 /*****************************************************************************
519 * IDirect3DExecuteBuffer::Release
521 * A normal Release method, nothing special
526 *****************************************************************************/
527 static ULONG WINAPI
d3d_execute_buffer_Release(IDirect3DExecuteBuffer
*iface
)
529 struct d3d_execute_buffer
*buffer
= impl_from_IDirect3DExecuteBuffer(iface
);
530 ULONG ref
= InterlockedDecrement(&buffer
->ref
);
532 TRACE("%p decreasing refcount to %u.\n", buffer
, ref
);
536 if (buffer
->need_free
)
537 HeapFree(GetProcessHeap(), 0, buffer
->desc
.lpData
);
538 if (buffer
->index_buffer
)
539 wined3d_buffer_decref(buffer
->index_buffer
);
540 if (buffer
->dst_vertex_buffer
)
541 wined3d_buffer_decref(buffer
->dst_vertex_buffer
);
542 HeapFree(GetProcessHeap(), 0, buffer
);
548 /*****************************************************************************
549 * IDirect3DExecuteBuffer::Initialize
551 * Initializes the Execute Buffer. This method exists for COM compliance
552 * Nothing to do here.
557 *****************************************************************************/
558 static HRESULT WINAPI
d3d_execute_buffer_Initialize(IDirect3DExecuteBuffer
*iface
,
559 IDirect3DDevice
*device
, D3DEXECUTEBUFFERDESC
*desc
)
561 TRACE("iface %p, device %p, desc %p.\n", iface
, device
, desc
);
566 /*****************************************************************************
567 * IDirect3DExecuteBuffer::Lock
569 * Locks the buffer, so the app can write into it.
572 * Desc: Pointer to return the buffer description. This Description contains
573 * a pointer to the buffer data.
576 * This implementation always returns D3D_OK
578 *****************************************************************************/
579 static HRESULT WINAPI
d3d_execute_buffer_Lock(IDirect3DExecuteBuffer
*iface
, D3DEXECUTEBUFFERDESC
*desc
)
581 struct d3d_execute_buffer
*buffer
= impl_from_IDirect3DExecuteBuffer(iface
);
584 TRACE("iface %p, desc %p.\n", iface
, desc
);
586 dwSize
= desc
->dwSize
;
587 memcpy(desc
, &buffer
->desc
, dwSize
);
591 TRACE(" Returning description :\n");
592 _dump_D3DEXECUTEBUFFERDESC(desc
);
597 /*****************************************************************************
598 * IDirect3DExecuteBuffer::Unlock
600 * Unlocks the buffer. We don't have anything to do here
603 * This implementation always returns D3D_OK
605 *****************************************************************************/
606 static HRESULT WINAPI
d3d_execute_buffer_Unlock(IDirect3DExecuteBuffer
*iface
)
608 TRACE("iface %p.\n", iface
);
613 /*****************************************************************************
614 * IDirect3DExecuteBuffer::SetExecuteData
616 * Sets the execute data. This data is used to describe the buffer's content
619 * Data: Pointer to a D3DEXECUTEDATA structure containing the data to
624 * DDERR_OUTOFMEMORY if the vertex buffer allocation failed
626 *****************************************************************************/
627 static HRESULT WINAPI
d3d_execute_buffer_SetExecuteData(IDirect3DExecuteBuffer
*iface
, D3DEXECUTEDATA
*data
)
629 struct d3d_execute_buffer
*buffer
= impl_from_IDirect3DExecuteBuffer(iface
);
631 TRACE("iface %p, data %p.\n", iface
, data
);
633 memcpy(&buffer
->data
, data
, data
->dwSize
);
635 if (buffer
->vertex_size
< data
->dwVertexCount
)
638 unsigned int new_size
= max(data
->dwVertexCount
, buffer
->vertex_size
* 2);
639 struct wined3d_buffer
*dst_buffer
;
641 hr
= wined3d_buffer_create_vb(buffer
->d3ddev
->wined3d_device
, new_size
* sizeof(D3DTLVERTEX
),
642 WINED3DUSAGE_STATICDECL
, WINED3D_POOL_DEFAULT
,
643 NULL
, &ddraw_null_wined3d_parent_ops
, &dst_buffer
);
647 if (buffer
->dst_vertex_buffer
)
648 wined3d_buffer_decref(buffer
->dst_vertex_buffer
);
649 buffer
->dst_vertex_buffer
= dst_buffer
;
650 buffer
->vertex_size
= new_size
;
654 _dump_executedata(data
);
659 /*****************************************************************************
660 * IDirect3DExecuteBuffer::GetExecuteData
662 * Returns the data in the execute buffer
665 * Data: Pointer to a D3DEXECUTEDATA structure used to return data
670 *****************************************************************************/
671 static HRESULT WINAPI
d3d_execute_buffer_GetExecuteData(IDirect3DExecuteBuffer
*iface
, D3DEXECUTEDATA
*data
)
673 struct d3d_execute_buffer
*buffer
= impl_from_IDirect3DExecuteBuffer(iface
);
676 TRACE("iface %p, data %p.\n", iface
, data
);
678 dwSize
= data
->dwSize
;
679 memcpy(data
, &buffer
->data
, dwSize
);
683 TRACE("Returning data :\n");
684 _dump_executedata(data
);
690 /*****************************************************************************
691 * IDirect3DExecuteBuffer::Validate
693 * DirectX 5 SDK: "The IDirect3DExecuteBuffer::Validate method is not
694 * currently implemented"
700 * DDERR_UNSUPPORTED, because it's not implemented in Windows.
702 *****************************************************************************/
703 static HRESULT WINAPI
d3d_execute_buffer_Validate(IDirect3DExecuteBuffer
*iface
,
704 DWORD
*offset
, LPD3DVALIDATECALLBACK callback
, void *context
, DWORD reserved
)
706 TRACE("iface %p, offset %p, callback %p, context %p, reserved %#x.\n",
707 iface
, offset
, callback
, context
, reserved
);
709 WARN("Not implemented.\n");
711 return DDERR_UNSUPPORTED
; /* Unchecked */
714 /*****************************************************************************
715 * IDirect3DExecuteBuffer::Optimize
717 * DirectX5 SDK: "The IDirect3DExecuteBuffer::Optimize method is not
718 * currently supported"
721 * Dummy: Seems to be an unused dummy ;)
724 * DDERR_UNSUPPORTED, because it's not implemented in Windows.
726 *****************************************************************************/
727 static HRESULT WINAPI
d3d_execute_buffer_Optimize(IDirect3DExecuteBuffer
*iface
, DWORD reserved
)
729 TRACE("iface %p, reserved %#x.\n", iface
, reserved
);
731 WARN("Not implemented.\n");
733 return DDERR_UNSUPPORTED
; /* Unchecked */
736 static const struct IDirect3DExecuteBufferVtbl d3d_execute_buffer_vtbl
=
738 d3d_execute_buffer_QueryInterface
,
739 d3d_execute_buffer_AddRef
,
740 d3d_execute_buffer_Release
,
741 d3d_execute_buffer_Initialize
,
742 d3d_execute_buffer_Lock
,
743 d3d_execute_buffer_Unlock
,
744 d3d_execute_buffer_SetExecuteData
,
745 d3d_execute_buffer_GetExecuteData
,
746 d3d_execute_buffer_Validate
,
747 d3d_execute_buffer_Optimize
,
750 HRESULT
d3d_execute_buffer_init(struct d3d_execute_buffer
*execute_buffer
,
751 struct d3d_device
*device
, D3DEXECUTEBUFFERDESC
*desc
)
753 execute_buffer
->IDirect3DExecuteBuffer_iface
.lpVtbl
= &d3d_execute_buffer_vtbl
;
754 execute_buffer
->ref
= 1;
755 execute_buffer
->d3ddev
= device
;
757 /* Initializes memory */
758 memcpy(&execute_buffer
->desc
, desc
, desc
->dwSize
);
760 /* No buffer given */
761 if (!(execute_buffer
->desc
.dwFlags
& D3DDEB_LPDATA
))
762 execute_buffer
->desc
.lpData
= NULL
;
764 /* No buffer size given */
765 if (!(execute_buffer
->desc
.dwFlags
& D3DDEB_BUFSIZE
))
766 execute_buffer
->desc
.dwBufferSize
= 0;
768 /* Create buffer if asked */
769 if (!execute_buffer
->desc
.lpData
&& execute_buffer
->desc
.dwBufferSize
)
771 execute_buffer
->need_free
= TRUE
;
772 execute_buffer
->desc
.lpData
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, execute_buffer
->desc
.dwBufferSize
);
773 if (!execute_buffer
->desc
.lpData
)
775 ERR("Failed to allocate execute buffer data.\n");
776 return DDERR_OUTOFMEMORY
;
780 execute_buffer
->desc
.dwFlags
|= D3DDEB_LPDATA
;
785 struct d3d_execute_buffer
*unsafe_impl_from_IDirect3DExecuteBuffer(IDirect3DExecuteBuffer
*iface
)
789 assert(iface
->lpVtbl
== &d3d_execute_buffer_vtbl
);
791 return impl_from_IDirect3DExecuteBuffer(iface
);