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
21 #include "ddraw_private.h"
23 /*****************************************************************************
25 * _dump_D3DEXECUTEBUFFERDESC
27 * Debug functions which write the executebuffer data to the console
29 *****************************************************************************/
31 static void _dump_executedata(const D3DEXECUTEDATA
*lpData
) {
32 TRACE("dwSize : %d\n", lpData
->dwSize
);
33 TRACE("Vertex Offset : %d Count : %d\n", lpData
->dwVertexOffset
, lpData
->dwVertexCount
);
34 TRACE("Instruction Offset : %d Length : %d\n", lpData
->dwInstructionOffset
, lpData
->dwInstructionLength
);
35 TRACE("HVertex Offset : %d\n", lpData
->dwHVertexOffset
);
38 static void _dump_D3DEXECUTEBUFFERDESC(const D3DEXECUTEBUFFERDESC
*lpDesc
) {
39 TRACE("dwSize : %d\n", lpDesc
->dwSize
);
40 TRACE("dwFlags : %x\n", lpDesc
->dwFlags
);
41 TRACE("dwCaps : %x\n", lpDesc
->dwCaps
);
42 TRACE("dwBufferSize : %d\n", lpDesc
->dwBufferSize
);
43 TRACE("lpData : %p\n", lpDesc
->lpData
);
46 HRESULT
d3d_execute_buffer_execute(struct d3d_execute_buffer
*buffer
,
47 struct d3d_device
*device
, struct d3d_viewport
*viewport
)
49 DWORD is
= buffer
->data
.dwInstructionOffset
;
50 char *instr
= (char *)buffer
->desc
.lpData
+ is
;
51 unsigned int i
, primitive_size
;
52 struct wined3d_map_desc map_desc
;
53 struct wined3d_box box
= {0};
56 if (viewport
->active_device
!= device
)
58 WARN("Viewport %p active device is %p.\n",
59 viewport
, viewport
->active_device
);
60 return DDERR_INVALIDPARAMS
;
63 /* Activate the viewport */
64 viewport_activate(viewport
, FALSE
);
66 TRACE("ExecuteData :\n");
68 _dump_executedata(&(buffer
->data
));
72 D3DINSTRUCTION
*current
= (D3DINSTRUCTION
*)instr
;
76 count
= current
->wCount
;
77 size
= current
->bSize
;
78 instr
+= sizeof(*current
);
81 switch (current
->bOpcode
)
85 const D3DPOINT
*p
= (D3DPOINT
*)instr
;
86 wined3d_device_set_primitive_type(device
->wined3d_device
, WINED3D_PT_POINTLIST
, 0);
87 wined3d_device_set_stream_source(device
->wined3d_device
, 0,
88 buffer
->dst_vertex_buffer
, 0, sizeof(D3DTLVERTEX
));
89 wined3d_device_set_vertex_declaration(device
->wined3d_device
,
90 ddraw_find_decl(device
->ddraw
, D3DFVF_TLVERTEX
));
92 for (i
= 0; i
< count
; ++i
)
93 wined3d_device_draw_primitive(device
->wined3d_device
, p
[i
].wFirst
, p
[i
].wCount
);
95 instr
+= sizeof(*p
) * count
;
101 wined3d_device_set_primitive_type(device
->wined3d_device
, WINED3D_PT_LINELIST
, 0);
106 unsigned int index_pos
= buffer
->index_pos
, index_count
;
107 TRACE("TRIANGLE (%d)\n", count
);
114 wined3d_device_set_primitive_type(device
->wined3d_device
, WINED3D_PT_TRIANGLELIST
, 0);
118 index_count
= count
* primitive_size
;
120 if (buffer
->index_size
< index_count
)
122 struct wined3d_buffer
*new_buffer
;
123 unsigned int new_size
= max(buffer
->index_size
* 2, index_count
);
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
;
137 else if (buffer
->index_size
- index_count
< index_pos
)
142 box
.left
= index_pos
* sizeof(*indices
);
143 box
.right
= (index_pos
+ index_count
) * sizeof(*indices
);
144 hr
= wined3d_resource_map(wined3d_buffer_get_resource(buffer
->index_buffer
), 0,
145 &map_desc
, &box
, index_pos
? WINED3D_MAP_NOOVERWRITE
: WINED3D_MAP_DISCARD
);
148 indices
= map_desc
.data
;
150 for (i
= 0; i
< count
; ++i
)
152 D3DTRIANGLE
*ci
= (D3DTRIANGLE
*)instr
;
153 TRACE(" v1: %d v2: %d v3: %d\n",ci
->u1
.v1
, ci
->u2
.v2
, ci
->u3
.v3
);
158 if (ci
->wFlags
& D3DTRIFLAG_EDGEENABLE1
)
159 TRACE("EDGEENABLE1 ");
160 if (ci
->wFlags
& D3DTRIFLAG_EDGEENABLE2
)
161 TRACE("EDGEENABLE2 ");
162 if (ci
->wFlags
& D3DTRIFLAG_EDGEENABLE1
)
163 TRACE("EDGEENABLE3 ");
165 if (ci
->wFlags
== D3DTRIFLAG_EVEN
)
167 if (ci
->wFlags
== D3DTRIFLAG_ODD
)
169 if (ci
->wFlags
== D3DTRIFLAG_START
)
171 if ((ci
->wFlags
> 0) && (ci
->wFlags
< 30))
172 TRACE("STARTFLAT(%u) ", ci
->wFlags
);
176 switch (primitive_size
)
179 indices
[(i
* primitive_size
) + 2] = ci
->u3
.v3
;
182 indices
[(i
* primitive_size
) + 1] = ci
->u2
.v2
;
183 indices
[(i
* primitive_size
) ] = ci
->u1
.v1
;
188 wined3d_resource_unmap(wined3d_buffer_get_resource(buffer
->index_buffer
), 0);
190 wined3d_device_set_stream_source(device
->wined3d_device
, 0,
191 buffer
->dst_vertex_buffer
, 0, sizeof(D3DTLVERTEX
));
192 wined3d_device_set_vertex_declaration(device
->wined3d_device
,
193 ddraw_find_decl(device
->ddraw
, D3DFVF_TLVERTEX
));
194 wined3d_device_set_index_buffer(device
->wined3d_device
, buffer
->index_buffer
, WINED3DFMT_R16_UINT
, 0);
195 wined3d_device_draw_indexed_primitive(device
->wined3d_device
, index_pos
, index_count
);
197 buffer
->index_pos
= index_pos
+ index_count
;
201 case D3DOP_MATRIXLOAD
:
202 WARN("MATRIXLOAD-s (%u)\n", count
);
203 instr
+= count
* size
;
206 case D3DOP_MATRIXMULTIPLY
:
207 TRACE("MATRIXMULTIPLY (%d)\n", count
);
208 for (i
= 0; i
< count
; ++i
)
210 D3DMATRIXMULTIPLY
*ci
= (D3DMATRIXMULTIPLY
*)instr
;
211 D3DMATRIX
*a
, *b
, *c
;
213 a
= ddraw_get_object(&device
->handle_table
, ci
->hDestMatrix
- 1, DDRAW_HANDLE_MATRIX
);
214 b
= ddraw_get_object(&device
->handle_table
, ci
->hSrcMatrix1
- 1, DDRAW_HANDLE_MATRIX
);
215 c
= ddraw_get_object(&device
->handle_table
, ci
->hSrcMatrix2
- 1, DDRAW_HANDLE_MATRIX
);
219 ERR("Invalid matrix handle (a %#x -> %p, b %#x -> %p, c %#x -> %p).\n",
220 ci
->hDestMatrix
, a
, ci
->hSrcMatrix1
, b
, ci
->hSrcMatrix2
, c
);
224 TRACE("dst %p, src1 %p, src2 %p.\n", a
, b
, c
);
225 multiply_matrix(a
, c
, b
);
232 case D3DOP_STATETRANSFORM
:
233 TRACE("STATETRANSFORM (%d)\n", count
);
234 for (i
= 0; i
< count
; ++i
)
236 D3DSTATE
*ci
= (D3DSTATE
*)instr
;
239 m
= ddraw_get_object(&device
->handle_table
, ci
->u2
.dwArg
[0] - 1, DDRAW_HANDLE_MATRIX
);
242 ERR("Invalid matrix handle %#x.\n", ci
->u2
.dwArg
[0]);
246 if (ci
->u1
.dtstTransformStateType
== D3DTRANSFORMSTATE_WORLD
)
247 device
->world
= ci
->u2
.dwArg
[0];
248 if (ci
->u1
.dtstTransformStateType
== D3DTRANSFORMSTATE_VIEW
)
249 device
->view
= ci
->u2
.dwArg
[0];
250 if (ci
->u1
.dtstTransformStateType
== D3DTRANSFORMSTATE_PROJECTION
)
251 device
->proj
= ci
->u2
.dwArg
[0];
252 IDirect3DDevice3_SetTransform(&device
->IDirect3DDevice3_iface
,
253 ci
->u1
.dtstTransformStateType
, m
);
260 case D3DOP_STATELIGHT
:
261 TRACE("STATELIGHT (%d)\n", count
);
262 for (i
= 0; i
< count
; ++i
)
264 D3DSTATE
*ci
= (D3DSTATE
*)instr
;
266 if (FAILED(IDirect3DDevice3_SetLightState(&device
->IDirect3DDevice3_iface
,
267 ci
->u1
.dlstLightStateType
, ci
->u2
.dwArg
[0])))
268 WARN("Failed to set light state.\n");
274 case D3DOP_STATERENDER
:
275 TRACE("STATERENDER (%d)\n", count
);
276 for (i
= 0; i
< count
; ++i
)
278 D3DSTATE
*ci
= (D3DSTATE
*)instr
;
280 if (FAILED(IDirect3DDevice3_SetRenderState(&device
->IDirect3DDevice3_iface
,
281 ci
->u1
.drstRenderStateType
, ci
->u2
.dwArg
[0])))
282 WARN("Failed to set render state.\n");
288 case D3DOP_PROCESSVERTICES
:
289 TRACE("PROCESSVERTICES (%d)\n", count
);
291 for (i
= 0; i
< count
; ++i
)
293 D3DPROCESSVERTICES
*ci
= (D3DPROCESSVERTICES
*)instr
;
294 DWORD op
= ci
->dwFlags
& D3DPROCESSVERTICES_OPMASK
;
296 TRACE(" start %u, dest %u, count %u, flags %#x.\n",
297 ci
->wStart
, ci
->wDest
, ci
->dwCount
, ci
->dwFlags
);
299 if (ci
->dwFlags
& D3DPROCESSVERTICES_UPDATEEXTENTS
)
300 FIXME("D3DPROCESSVERTICES_UPDATEEXTENTS not implemented.\n");
301 if (ci
->dwFlags
& D3DPROCESSVERTICES_NOCOLOR
)
302 FIXME("D3DPROCESSVERTICES_NOCOLOR not implemented.\n");
306 case D3DPROCESSVERTICES_TRANSFORMLIGHT
:
307 case D3DPROCESSVERTICES_TRANSFORM
:
308 wined3d_device_set_stream_source(device
->wined3d_device
, 0,
309 buffer
->src_vertex_buffer
, buffer
->src_vertex_pos
, sizeof(D3DVERTEX
));
310 if (op
== D3DPROCESSVERTICES_TRANSFORMLIGHT
)
312 wined3d_device_set_vertex_declaration(device
->wined3d_device
,
313 ddraw_find_decl(device
->ddraw
, D3DFVF_VERTEX
));
314 wined3d_device_set_render_state(device
->wined3d_device
,
315 WINED3D_RS_LIGHTING
, TRUE
);
319 wined3d_device_set_vertex_declaration(device
->wined3d_device
,
320 ddraw_find_decl(device
->ddraw
, D3DFVF_LVERTEX
));
321 wined3d_device_set_render_state(device
->wined3d_device
,
322 WINED3D_RS_LIGHTING
, FALSE
);
325 wined3d_device_process_vertices(device
->wined3d_device
, ci
->wStart
, ci
->wDest
,
326 ci
->dwCount
, buffer
->dst_vertex_buffer
, NULL
, 0, D3DFVF_TLVERTEX
);
329 case D3DPROCESSVERTICES_COPY
:
330 box
.left
= (buffer
->src_vertex_pos
+ ci
->wStart
) * sizeof(D3DTLVERTEX
);
331 box
.right
= box
.left
+ ci
->dwCount
* sizeof(D3DTLVERTEX
);
332 box
.top
= box
.front
= 0;
333 box
.bottom
= box
.back
= 1;
334 wined3d_device_copy_sub_resource_region(device
->wined3d_device
,
335 wined3d_buffer_get_resource(buffer
->dst_vertex_buffer
), 0,
336 ci
->wDest
* sizeof(D3DTLVERTEX
), 0, 0,
337 wined3d_buffer_get_resource(buffer
->src_vertex_buffer
), 0, &box
);
341 FIXME("Unhandled vertex processing op %#x.\n", op
);
349 case D3DOP_TEXTURELOAD
:
350 TRACE("TEXTURELOAD (%u)\n", count
);
352 for (i
= 0; i
< count
; ++i
)
354 D3DTEXTURELOAD
*ci
= (D3DTEXTURELOAD
*)instr
;
355 struct ddraw_surface
*dst
, *src
;
359 if (!(dst
= ddraw_get_object(&device
->handle_table
,
360 ci
->hDestTexture
- 1, DDRAW_HANDLE_SURFACE
)))
362 WARN("Invalid destination texture handle %#x.\n", ci
->hDestTexture
);
365 if (!(src
= ddraw_get_object(&device
->handle_table
,
366 ci
->hSrcTexture
- 1, DDRAW_HANDLE_SURFACE
)))
368 WARN("Invalid source texture handle %#x.\n", ci
->hSrcTexture
);
372 IDirect3DTexture2_Load(&dst
->IDirect3DTexture2_iface
, &src
->IDirect3DTexture2_iface
);
377 TRACE("EXIT (%u)\n", count
);
381 case D3DOP_BRANCHFORWARD
:
382 TRACE("BRANCHFORWARD (%d)\n", count
);
383 for (i
= 0; i
< count
; ++i
)
385 D3DBRANCH
*ci
= (D3DBRANCH
*)instr
;
387 if ((buffer
->data
.dsStatus
.dwStatus
& ci
->dwMask
) == ci
->dwValue
)
391 TRACE(" Branch to %d\n", ci
->dwOffset
);
393 instr
= (char*)current
+ ci
->dwOffset
;
402 TRACE(" Branch to %d\n", ci
->dwOffset
);
404 instr
= (char*)current
+ ci
->dwOffset
;
415 WARN("SPAN-s (%u)\n", count
);
416 instr
+= count
* size
;
419 case D3DOP_SETSTATUS
:
420 TRACE("SETSTATUS (%d)\n", count
);
421 for (i
= 0; i
< count
; ++i
)
423 buffer
->data
.dsStatus
= *(D3DSTATUS
*)instr
;
429 ERR("Unhandled OpCode %#x.\n",current
->bOpcode
);
430 instr
+= count
* size
;
439 static inline struct d3d_execute_buffer
*impl_from_IDirect3DExecuteBuffer(IDirect3DExecuteBuffer
*iface
)
441 return CONTAINING_RECORD(iface
, struct d3d_execute_buffer
, IDirect3DExecuteBuffer_iface
);
444 static HRESULT WINAPI
d3d_execute_buffer_QueryInterface(IDirect3DExecuteBuffer
*iface
, REFIID iid
, void **out
)
446 TRACE("iface %p, iid %s, out %p.\n", iface
, debugstr_guid(iid
), out
);
448 if (IsEqualGUID(&IID_IDirect3DExecuteBuffer
, iid
)
449 || IsEqualGUID(&IID_IUnknown
, iid
))
451 IDirect3DExecuteBuffer_AddRef(iface
);
456 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid
));
459 return E_NOINTERFACE
;
462 /*****************************************************************************
463 * IDirect3DExecuteBuffer::AddRef
465 * A normal AddRef method, nothing special
470 *****************************************************************************/
471 static ULONG WINAPI
d3d_execute_buffer_AddRef(IDirect3DExecuteBuffer
*iface
)
473 struct d3d_execute_buffer
*buffer
= impl_from_IDirect3DExecuteBuffer(iface
);
474 ULONG ref
= InterlockedIncrement(&buffer
->ref
);
476 TRACE("%p increasing refcount to %u.\n", buffer
, ref
);
481 /*****************************************************************************
482 * IDirect3DExecuteBuffer::Release
484 * A normal Release method, nothing special
489 *****************************************************************************/
490 static ULONG WINAPI
d3d_execute_buffer_Release(IDirect3DExecuteBuffer
*iface
)
492 struct d3d_execute_buffer
*buffer
= impl_from_IDirect3DExecuteBuffer(iface
);
493 ULONG ref
= InterlockedDecrement(&buffer
->ref
);
495 TRACE("%p decreasing refcount to %u.\n", buffer
, ref
);
499 if (buffer
->need_free
)
500 HeapFree(GetProcessHeap(), 0, buffer
->desc
.lpData
);
501 if (buffer
->index_buffer
)
502 wined3d_buffer_decref(buffer
->index_buffer
);
503 if (buffer
->dst_vertex_buffer
)
505 wined3d_buffer_decref(buffer
->src_vertex_buffer
);
506 wined3d_buffer_decref(buffer
->dst_vertex_buffer
);
508 HeapFree(GetProcessHeap(), 0, buffer
);
514 /*****************************************************************************
515 * IDirect3DExecuteBuffer::Initialize
517 * Initializes the Execute Buffer. This method exists for COM compliance
518 * Nothing to do here.
523 *****************************************************************************/
524 static HRESULT WINAPI
d3d_execute_buffer_Initialize(IDirect3DExecuteBuffer
*iface
,
525 IDirect3DDevice
*device
, D3DEXECUTEBUFFERDESC
*desc
)
527 TRACE("iface %p, device %p, desc %p.\n", iface
, device
, desc
);
532 /*****************************************************************************
533 * IDirect3DExecuteBuffer::Lock
535 * Locks the buffer, so the app can write into it.
538 * Desc: Pointer to return the buffer description. This Description contains
539 * a pointer to the buffer data.
542 * This implementation always returns D3D_OK
544 *****************************************************************************/
545 static HRESULT WINAPI
d3d_execute_buffer_Lock(IDirect3DExecuteBuffer
*iface
, D3DEXECUTEBUFFERDESC
*desc
)
547 struct d3d_execute_buffer
*buffer
= impl_from_IDirect3DExecuteBuffer(iface
);
550 TRACE("iface %p, desc %p.\n", iface
, desc
);
552 dwSize
= desc
->dwSize
;
553 memcpy(desc
, &buffer
->desc
, dwSize
);
557 TRACE(" Returning description :\n");
558 _dump_D3DEXECUTEBUFFERDESC(desc
);
563 /*****************************************************************************
564 * IDirect3DExecuteBuffer::Unlock
566 * Unlocks the buffer. We don't have anything to do here
569 * This implementation always returns D3D_OK
571 *****************************************************************************/
572 static HRESULT WINAPI
d3d_execute_buffer_Unlock(IDirect3DExecuteBuffer
*iface
)
574 TRACE("iface %p.\n", iface
);
579 /*****************************************************************************
580 * IDirect3DExecuteBuffer::SetExecuteData
582 * Sets the execute data. This data is used to describe the buffer's content
585 * Data: Pointer to a D3DEXECUTEDATA structure containing the data to
590 * DDERR_OUTOFMEMORY if the vertex buffer allocation failed
592 *****************************************************************************/
593 static HRESULT WINAPI
d3d_execute_buffer_SetExecuteData(IDirect3DExecuteBuffer
*iface
, D3DEXECUTEDATA
*data
)
595 struct d3d_execute_buffer
*buffer
= impl_from_IDirect3DExecuteBuffer(iface
);
596 struct wined3d_map_desc map_desc
;
597 struct wined3d_box box
= {0};
600 TRACE("iface %p, data %p.\n", iface
, data
);
602 /* Skip past previous vertex data. */
603 buffer
->src_vertex_pos
+= buffer
->data
.dwVertexCount
;
605 if (buffer
->vertex_size
< data
->dwVertexCount
)
607 unsigned int new_size
= max(data
->dwVertexCount
, buffer
->vertex_size
* 2);
608 struct wined3d_buffer
*src_buffer
, *dst_buffer
;
610 hr
= wined3d_buffer_create_vb(buffer
->d3ddev
->wined3d_device
, new_size
* sizeof(D3DVERTEX
),
611 WINED3DUSAGE_DYNAMIC
| WINED3DUSAGE_WRITEONLY
, WINED3D_POOL_SYSTEM_MEM
,
612 NULL
, &ddraw_null_wined3d_parent_ops
, &src_buffer
);
616 hr
= wined3d_buffer_create_vb(buffer
->d3ddev
->wined3d_device
, new_size
* sizeof(D3DTLVERTEX
),
617 WINED3DUSAGE_STATICDECL
, WINED3D_POOL_DEFAULT
,
618 NULL
, &ddraw_null_wined3d_parent_ops
, &dst_buffer
);
621 wined3d_buffer_decref(src_buffer
);
625 if (buffer
->dst_vertex_buffer
)
627 wined3d_buffer_decref(buffer
->src_vertex_buffer
);
628 wined3d_buffer_decref(buffer
->dst_vertex_buffer
);
630 buffer
->src_vertex_buffer
= src_buffer
;
631 buffer
->dst_vertex_buffer
= dst_buffer
;
632 buffer
->vertex_size
= new_size
;
633 buffer
->src_vertex_pos
= 0;
635 else if (buffer
->vertex_size
- data
->dwVertexCount
< buffer
->src_vertex_pos
)
637 buffer
->src_vertex_pos
= 0;
640 if (data
->dwVertexCount
)
642 box
.left
= buffer
->src_vertex_pos
* sizeof(D3DVERTEX
);
643 box
.right
= box
.left
+ data
->dwVertexCount
* sizeof(D3DVERTEX
);
644 hr
= wined3d_resource_map(wined3d_buffer_get_resource(buffer
->src_vertex_buffer
), 0,
645 &map_desc
, &box
, buffer
->src_vertex_pos
? WINED3D_MAP_NOOVERWRITE
: WINED3D_MAP_DISCARD
);
649 memcpy(map_desc
.data
, ((BYTE
*)buffer
->desc
.lpData
) + data
->dwVertexOffset
,
650 data
->dwVertexCount
* sizeof(D3DVERTEX
));
652 wined3d_resource_unmap(wined3d_buffer_get_resource(buffer
->src_vertex_buffer
), 0);
655 memcpy(&buffer
->data
, data
, data
->dwSize
);
658 _dump_executedata(data
);
663 /*****************************************************************************
664 * IDirect3DExecuteBuffer::GetExecuteData
666 * Returns the data in the execute buffer
669 * Data: Pointer to a D3DEXECUTEDATA structure used to return data
674 *****************************************************************************/
675 static HRESULT WINAPI
d3d_execute_buffer_GetExecuteData(IDirect3DExecuteBuffer
*iface
, D3DEXECUTEDATA
*data
)
677 struct d3d_execute_buffer
*buffer
= impl_from_IDirect3DExecuteBuffer(iface
);
680 TRACE("iface %p, data %p.\n", iface
, data
);
682 dwSize
= data
->dwSize
;
683 memcpy(data
, &buffer
->data
, dwSize
);
687 TRACE("Returning data :\n");
688 _dump_executedata(data
);
694 /*****************************************************************************
695 * IDirect3DExecuteBuffer::Validate
697 * DirectX 5 SDK: "The IDirect3DExecuteBuffer::Validate method is not
698 * currently implemented"
704 * DDERR_UNSUPPORTED, because it's not implemented in Windows.
706 *****************************************************************************/
707 static HRESULT WINAPI
d3d_execute_buffer_Validate(IDirect3DExecuteBuffer
*iface
,
708 DWORD
*offset
, LPD3DVALIDATECALLBACK callback
, void *context
, DWORD reserved
)
710 TRACE("iface %p, offset %p, callback %p, context %p, reserved %#x.\n",
711 iface
, offset
, callback
, context
, reserved
);
713 WARN("Not implemented.\n");
715 return DDERR_UNSUPPORTED
; /* Unchecked */
718 /*****************************************************************************
719 * IDirect3DExecuteBuffer::Optimize
721 * DirectX5 SDK: "The IDirect3DExecuteBuffer::Optimize method is not
722 * currently supported"
725 * Dummy: Seems to be an unused dummy ;)
728 * DDERR_UNSUPPORTED, because it's not implemented in Windows.
730 *****************************************************************************/
731 static HRESULT WINAPI
d3d_execute_buffer_Optimize(IDirect3DExecuteBuffer
*iface
, DWORD reserved
)
733 TRACE("iface %p, reserved %#x.\n", iface
, reserved
);
735 WARN("Not implemented.\n");
737 return DDERR_UNSUPPORTED
; /* Unchecked */
740 static const struct IDirect3DExecuteBufferVtbl d3d_execute_buffer_vtbl
=
742 d3d_execute_buffer_QueryInterface
,
743 d3d_execute_buffer_AddRef
,
744 d3d_execute_buffer_Release
,
745 d3d_execute_buffer_Initialize
,
746 d3d_execute_buffer_Lock
,
747 d3d_execute_buffer_Unlock
,
748 d3d_execute_buffer_SetExecuteData
,
749 d3d_execute_buffer_GetExecuteData
,
750 d3d_execute_buffer_Validate
,
751 d3d_execute_buffer_Optimize
,
754 HRESULT
d3d_execute_buffer_init(struct d3d_execute_buffer
*execute_buffer
,
755 struct d3d_device
*device
, D3DEXECUTEBUFFERDESC
*desc
)
757 execute_buffer
->IDirect3DExecuteBuffer_iface
.lpVtbl
= &d3d_execute_buffer_vtbl
;
758 execute_buffer
->ref
= 1;
759 execute_buffer
->d3ddev
= device
;
761 /* Initializes memory */
762 memcpy(&execute_buffer
->desc
, desc
, desc
->dwSize
);
764 /* No buffer given */
765 if (!(execute_buffer
->desc
.dwFlags
& D3DDEB_LPDATA
))
766 execute_buffer
->desc
.lpData
= NULL
;
768 /* No buffer size given */
769 if (!(execute_buffer
->desc
.dwFlags
& D3DDEB_BUFSIZE
))
770 execute_buffer
->desc
.dwBufferSize
= 0;
772 /* Create buffer if asked */
773 if (!execute_buffer
->desc
.lpData
&& execute_buffer
->desc
.dwBufferSize
)
775 execute_buffer
->need_free
= TRUE
;
776 execute_buffer
->desc
.lpData
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, execute_buffer
->desc
.dwBufferSize
);
777 if (!execute_buffer
->desc
.lpData
)
779 ERR("Failed to allocate execute buffer data.\n");
780 return DDERR_OUTOFMEMORY
;
784 execute_buffer
->desc
.dwFlags
|= D3DDEB_LPDATA
;
789 struct d3d_execute_buffer
*unsafe_impl_from_IDirect3DExecuteBuffer(IDirect3DExecuteBuffer
*iface
)
793 assert(iface
->lpVtbl
== &d3d_execute_buffer_vtbl
);
795 return impl_from_IDirect3DExecuteBuffer(iface
);