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 WINE_DEFAULT_DEBUG_CHANNEL(ddraw
);
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 : %lu\n", lpData
->dwSize
);
35 TRACE("Vertex Offset : %lu Count : %lu\n", lpData
->dwVertexOffset
, lpData
->dwVertexCount
);
36 TRACE("Instruction Offset : %lu Length : %lu\n", lpData
->dwInstructionOffset
, lpData
->dwInstructionLength
);
37 TRACE("HVertex Offset : %lu\n", lpData
->dwHVertexOffset
);
40 static void _dump_D3DEXECUTEBUFFERDESC(const D3DEXECUTEBUFFERDESC
*lpDesc
) {
41 TRACE("dwSize : %lu\n", lpDesc
->dwSize
);
42 TRACE("dwFlags : %#lx\n", lpDesc
->dwFlags
);
43 TRACE("dwCaps : %#lx\n", lpDesc
->dwCaps
);
44 TRACE("dwBufferSize : %lu\n", lpDesc
->dwBufferSize
);
45 TRACE("lpData : %p\n", lpDesc
->lpData
);
48 HRESULT
d3d_execute_buffer_execute(struct d3d_execute_buffer
*buffer
, struct d3d_device
*device
)
50 DWORD is
= buffer
->data
.dwInstructionOffset
;
51 char *instr
= (char *)buffer
->desc
.lpData
+ is
;
52 unsigned int i
, primitive_size
;
53 struct wined3d_map_desc map_desc
;
54 struct wined3d_box box
= {0};
57 TRACE("ExecuteData :\n");
59 _dump_executedata(&(buffer
->data
));
63 D3DINSTRUCTION
*current
= (D3DINSTRUCTION
*)instr
;
67 count
= current
->wCount
;
68 size
= current
->bSize
;
69 instr
+= sizeof(*current
);
72 switch (current
->bOpcode
)
76 const D3DPOINT
*p
= (D3DPOINT
*)instr
;
77 wined3d_device_context_set_primitive_type(device
->immediate_context
, WINED3D_PT_POINTLIST
, 0);
78 wined3d_stateblock_set_stream_source(device
->state
, 0,
79 buffer
->dst_vertex_buffer
, 0, sizeof(D3DTLVERTEX
));
80 wined3d_stateblock_set_vertex_declaration(device
->state
,
81 ddraw_find_decl(device
->ddraw
, D3DFVF_TLVERTEX
));
83 wined3d_device_apply_stateblock(device
->wined3d_device
, device
->state
);
84 d3d_device_sync_surfaces(device
);
85 for (i
= 0; i
< count
; ++i
)
86 wined3d_device_context_draw(device
->immediate_context
, p
[i
].wFirst
, p
[i
].wCount
, 0, 0);
88 instr
+= sizeof(*p
) * count
;
94 wined3d_device_context_set_primitive_type(device
->immediate_context
, WINED3D_PT_LINELIST
, 0);
99 unsigned int index_pos
= buffer
->index_pos
, index_count
;
100 TRACE("TRIANGLE (%d)\n", count
);
107 wined3d_device_context_set_primitive_type(device
->immediate_context
, WINED3D_PT_TRIANGLELIST
, 0);
111 index_count
= count
* primitive_size
;
112 if (buffer
->index_size
< index_count
)
114 unsigned int new_size
= max(buffer
->index_size
* 2, index_count
);
115 struct wined3d_buffer
*new_buffer
;
116 struct wined3d_buffer_desc desc
;
118 desc
.byte_width
= new_size
* sizeof(*indices
);
119 desc
.usage
= WINED3DUSAGE_DYNAMIC
| WINED3DUSAGE_STATICDECL
;
120 desc
.bind_flags
= WINED3D_BIND_INDEX_BUFFER
;
121 desc
.access
= WINED3D_RESOURCE_ACCESS_GPU
| WINED3D_RESOURCE_ACCESS_MAP_W
;
123 desc
.structure_byte_stride
= 0;
125 if (FAILED(hr
= wined3d_buffer_create(device
->wined3d_device
, &desc
,
126 NULL
, NULL
, &ddraw_null_wined3d_parent_ops
, &new_buffer
)))
129 buffer
->index_size
= new_size
;
130 if (buffer
->index_buffer
)
131 wined3d_buffer_decref(buffer
->index_buffer
);
132 buffer
->index_buffer
= new_buffer
;
135 else if (buffer
->index_size
- index_count
< index_pos
)
140 box
.left
= index_pos
* sizeof(*indices
);
141 box
.right
= (index_pos
+ index_count
) * sizeof(*indices
);
142 if (FAILED(hr
= wined3d_resource_map(wined3d_buffer_get_resource(buffer
->index_buffer
), 0, &map_desc
,
143 &box
, WINED3D_MAP_WRITE
| (index_pos
? WINED3D_MAP_NOOVERWRITE
: WINED3D_MAP_DISCARD
))))
145 indices
= map_desc
.data
;
147 for (i
= 0; i
< count
; ++i
)
149 D3DTRIANGLE
*ci
= (D3DTRIANGLE
*)instr
;
150 TRACE(" v1: %d v2: %d v3: %d\n",ci
->v1
, ci
->v2
, ci
->v3
);
155 if (ci
->wFlags
& D3DTRIFLAG_EDGEENABLE1
)
156 TRACE("EDGEENABLE1 ");
157 if (ci
->wFlags
& D3DTRIFLAG_EDGEENABLE2
)
158 TRACE("EDGEENABLE2 ");
159 if (ci
->wFlags
& D3DTRIFLAG_EDGEENABLE1
)
160 TRACE("EDGEENABLE3 ");
162 if (ci
->wFlags
== D3DTRIFLAG_EVEN
)
164 if (ci
->wFlags
== D3DTRIFLAG_ODD
)
166 if (ci
->wFlags
== D3DTRIFLAG_START
)
168 if ((ci
->wFlags
> 0) && (ci
->wFlags
< 30))
169 TRACE("STARTFLAT(%u) ", ci
->wFlags
);
173 switch (primitive_size
)
176 indices
[(i
* primitive_size
) + 2] = ci
->v3
;
179 indices
[(i
* primitive_size
) + 1] = ci
->v2
;
180 indices
[(i
* primitive_size
) ] = ci
->v1
;
185 wined3d_resource_unmap(wined3d_buffer_get_resource(buffer
->index_buffer
), 0);
187 wined3d_stateblock_set_stream_source(device
->state
, 0,
188 buffer
->dst_vertex_buffer
, 0, sizeof(D3DTLVERTEX
));
189 wined3d_stateblock_set_vertex_declaration(device
->state
,
190 ddraw_find_decl(device
->ddraw
, D3DFVF_TLVERTEX
));
191 wined3d_stateblock_set_index_buffer(device
->state
, buffer
->index_buffer
, WINED3DFMT_R16_UINT
);
192 wined3d_device_apply_stateblock(device
->wined3d_device
, device
->state
);
193 d3d_device_sync_surfaces(device
);
194 wined3d_device_context_draw_indexed(device
->immediate_context
, 0, index_pos
, index_count
, 0, 0);
196 buffer
->index_pos
= index_pos
+ index_count
;
200 case D3DOP_MATRIXLOAD
:
201 WARN("MATRIXLOAD-s (%u)\n", count
);
202 instr
+= count
* size
;
205 case D3DOP_MATRIXMULTIPLY
:
206 TRACE("MATRIXMULTIPLY (%d)\n", count
);
207 for (i
= 0; i
< count
; ++i
)
209 D3DMATRIXMULTIPLY
*ci
= (D3DMATRIXMULTIPLY
*)instr
;
210 struct wined3d_matrix
*a
, *b
, *c
;
212 a
= ddraw_get_object(NULL
, ci
->hDestMatrix
- 1, DDRAW_HANDLE_MATRIX
);
213 b
= ddraw_get_object(NULL
, ci
->hSrcMatrix1
- 1, DDRAW_HANDLE_MATRIX
);
214 c
= ddraw_get_object(NULL
, ci
->hSrcMatrix2
- 1, DDRAW_HANDLE_MATRIX
);
218 ERR("Invalid matrix handle (a %#lx -> %p, b %#lx -> %p, c %#lx -> %p).\n",
219 ci
->hDestMatrix
, a
, ci
->hSrcMatrix1
, b
, ci
->hSrcMatrix2
, c
);
223 TRACE("dst %p, src1 %p, src2 %p.\n", a
, b
, c
);
224 multiply_matrix(a
, c
, b
);
231 case D3DOP_STATETRANSFORM
:
232 TRACE("STATETRANSFORM (%d)\n", count
);
233 for (i
= 0; i
< count
; ++i
)
235 D3DSTATE
*ci
= (D3DSTATE
*)instr
;
238 m
= ddraw_get_object(NULL
, ci
->dwArg
[0] - 1, DDRAW_HANDLE_MATRIX
);
241 ERR("Invalid matrix handle %#lx.\n", ci
->dwArg
[0]);
245 if (ci
->dtstTransformStateType
== D3DTRANSFORMSTATE_WORLD
)
246 device
->world
= ci
->dwArg
[0];
247 if (ci
->dtstTransformStateType
== D3DTRANSFORMSTATE_VIEW
)
248 device
->view
= ci
->dwArg
[0];
249 if (ci
->dtstTransformStateType
== D3DTRANSFORMSTATE_PROJECTION
)
250 device
->proj
= ci
->dwArg
[0];
251 IDirect3DDevice3_SetTransform(&device
->IDirect3DDevice3_iface
,
252 ci
->dtstTransformStateType
, m
);
259 case D3DOP_STATELIGHT
:
260 TRACE("STATELIGHT (%d)\n", count
);
261 for (i
= 0; i
< count
; ++i
)
263 D3DSTATE
*ci
= (D3DSTATE
*)instr
;
265 if (FAILED(IDirect3DDevice3_SetLightState(&device
->IDirect3DDevice3_iface
,
266 ci
->dlstLightStateType
, ci
->dwArg
[0])))
267 WARN("Failed to set light state.\n");
273 case D3DOP_STATERENDER
:
274 TRACE("STATERENDER (%d)\n", count
);
275 for (i
= 0; i
< count
; ++i
)
277 D3DSTATE
*ci
= (D3DSTATE
*)instr
;
279 if (FAILED(IDirect3DDevice3_SetRenderState(&device
->IDirect3DDevice3_iface
,
280 ci
->drstRenderStateType
, ci
->dwArg
[0])))
281 WARN("Failed to set render state.\n");
287 case D3DOP_PROCESSVERTICES
:
288 TRACE("PROCESSVERTICES (%d)\n", count
);
290 for (i
= 0; i
< count
; ++i
)
292 D3DPROCESSVERTICES
*ci
= (D3DPROCESSVERTICES
*)instr
;
293 DWORD op
= ci
->dwFlags
& D3DPROCESSVERTICES_OPMASK
;
295 TRACE(" start %u, dest %u, count %lu, flags %#lx.\n",
296 ci
->wStart
, ci
->wDest
, ci
->dwCount
, ci
->dwFlags
);
298 if (ci
->dwFlags
& D3DPROCESSVERTICES_UPDATEEXTENTS
)
299 FIXME("D3DPROCESSVERTICES_UPDATEEXTENTS not implemented.\n");
300 if (ci
->dwFlags
& D3DPROCESSVERTICES_NOCOLOR
)
301 FIXME("D3DPROCESSVERTICES_NOCOLOR not implemented.\n");
305 case D3DPROCESSVERTICES_TRANSFORMLIGHT
:
306 case D3DPROCESSVERTICES_TRANSFORM
:
307 wined3d_stateblock_set_stream_source(device
->state
, 0,
308 buffer
->src_vertex_buffer
, buffer
->src_vertex_pos
* sizeof(D3DVERTEX
), sizeof(D3DVERTEX
));
309 wined3d_stateblock_set_render_state(device
->state
, WINED3D_RS_LIGHTING
,
310 op
== D3DPROCESSVERTICES_TRANSFORMLIGHT
&& !!device
->material
);
311 wined3d_stateblock_set_vertex_declaration(device
->state
,
312 ddraw_find_decl(device
->ddraw
, op
== D3DPROCESSVERTICES_TRANSFORMLIGHT
313 ? D3DFVF_VERTEX
: D3DFVF_LVERTEX
));
314 wined3d_device_apply_stateblock(device
->wined3d_device
, device
->state
);
315 d3d_device_sync_surfaces(device
);
316 wined3d_device_process_vertices(device
->wined3d_device
, ci
->wStart
, ci
->wDest
,
317 ci
->dwCount
, buffer
->dst_vertex_buffer
, NULL
, 0, D3DFVF_TLVERTEX
);
320 case D3DPROCESSVERTICES_COPY
:
321 box
.left
= (buffer
->src_vertex_pos
+ ci
->wStart
) * sizeof(D3DTLVERTEX
);
322 box
.right
= box
.left
+ ci
->dwCount
* sizeof(D3DTLVERTEX
);
323 box
.top
= box
.front
= 0;
324 box
.bottom
= box
.back
= 1;
325 wined3d_device_context_copy_sub_resource_region(device
->immediate_context
,
326 wined3d_buffer_get_resource(buffer
->dst_vertex_buffer
), 0,
327 ci
->wDest
* sizeof(D3DTLVERTEX
), 0, 0,
328 wined3d_buffer_get_resource(buffer
->src_vertex_buffer
), 0, &box
, 0);
332 FIXME("Unhandled vertex processing op %#lx.\n", op
);
340 case D3DOP_TEXTURELOAD
:
341 TRACE("TEXTURELOAD (%u)\n", count
);
343 for (i
= 0; i
< count
; ++i
)
345 D3DTEXTURELOAD
*ci
= (D3DTEXTURELOAD
*)instr
;
346 struct ddraw_surface
*dst
, *src
;
350 if (!(dst
= ddraw_get_object(NULL
, ci
->hDestTexture
- 1, DDRAW_HANDLE_SURFACE
)))
352 WARN("Invalid destination texture handle %#lx.\n", ci
->hDestTexture
);
355 if (!(src
= ddraw_get_object(NULL
, ci
->hSrcTexture
- 1, DDRAW_HANDLE_SURFACE
)))
357 WARN("Invalid source texture handle %#lx.\n", ci
->hSrcTexture
);
361 IDirect3DTexture2_Load(&dst
->IDirect3DTexture2_iface
, &src
->IDirect3DTexture2_iface
);
366 TRACE("EXIT (%u)\n", count
);
370 case D3DOP_BRANCHFORWARD
:
371 TRACE("BRANCHFORWARD (%d)\n", count
);
372 for (i
= 0; i
< count
; ++i
)
374 D3DBRANCH
*ci
= (D3DBRANCH
*)instr
;
376 if ((buffer
->data
.dsStatus
.dwStatus
& ci
->dwMask
) == ci
->dwValue
)
380 TRACE(" Branch to %ld\n", ci
->dwOffset
);
382 instr
= (char*)current
+ ci
->dwOffset
;
391 TRACE(" Branch to %ld\n", ci
->dwOffset
);
393 instr
= (char*)current
+ ci
->dwOffset
;
404 WARN("SPAN-s (%u)\n", count
);
405 instr
+= count
* size
;
408 case D3DOP_SETSTATUS
:
409 TRACE("SETSTATUS (%d)\n", count
);
410 for (i
= 0; i
< count
; ++i
)
412 buffer
->data
.dsStatus
= *(D3DSTATUS
*)instr
;
418 ERR("Unhandled OpCode %#x.\n",current
->bOpcode
);
419 instr
+= count
* size
;
428 static inline struct d3d_execute_buffer
*impl_from_IDirect3DExecuteBuffer(IDirect3DExecuteBuffer
*iface
)
430 return CONTAINING_RECORD(iface
, struct d3d_execute_buffer
, IDirect3DExecuteBuffer_iface
);
433 static HRESULT WINAPI
d3d_execute_buffer_QueryInterface(IDirect3DExecuteBuffer
*iface
, REFIID iid
, void **out
)
435 TRACE("iface %p, iid %s, out %p.\n", iface
, debugstr_guid(iid
), out
);
437 if (IsEqualGUID(&IID_IDirect3DExecuteBuffer
, iid
)
438 || IsEqualGUID(&IID_IUnknown
, iid
))
440 IDirect3DExecuteBuffer_AddRef(iface
);
445 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid
));
448 return E_NOINTERFACE
;
451 /*****************************************************************************
452 * IDirect3DExecuteBuffer::AddRef
454 * A normal AddRef method, nothing special
459 *****************************************************************************/
460 static ULONG WINAPI
d3d_execute_buffer_AddRef(IDirect3DExecuteBuffer
*iface
)
462 struct d3d_execute_buffer
*buffer
= impl_from_IDirect3DExecuteBuffer(iface
);
463 ULONG ref
= InterlockedIncrement(&buffer
->ref
);
465 TRACE("%p increasing refcount to %lu.\n", buffer
, ref
);
470 /*****************************************************************************
471 * IDirect3DExecuteBuffer::Release
473 * A normal Release method, nothing special
478 *****************************************************************************/
479 static ULONG WINAPI
d3d_execute_buffer_Release(IDirect3DExecuteBuffer
*iface
)
481 struct d3d_execute_buffer
*buffer
= impl_from_IDirect3DExecuteBuffer(iface
);
482 ULONG ref
= InterlockedDecrement(&buffer
->ref
);
484 TRACE("%p decreasing refcount to %lu.\n", buffer
, ref
);
488 if (buffer
->need_free
)
489 free(buffer
->desc
.lpData
);
490 if (buffer
->index_buffer
)
491 wined3d_buffer_decref(buffer
->index_buffer
);
492 if (buffer
->dst_vertex_buffer
)
494 wined3d_buffer_decref(buffer
->src_vertex_buffer
);
495 wined3d_buffer_decref(buffer
->dst_vertex_buffer
);
503 /*****************************************************************************
504 * IDirect3DExecuteBuffer::Initialize
506 * Initializes the Execute Buffer. This method exists for COM compliance
507 * Nothing to do here.
512 *****************************************************************************/
513 static HRESULT WINAPI
d3d_execute_buffer_Initialize(IDirect3DExecuteBuffer
*iface
,
514 IDirect3DDevice
*device
, D3DEXECUTEBUFFERDESC
*desc
)
516 TRACE("iface %p, device %p, desc %p.\n", iface
, device
, desc
);
521 /*****************************************************************************
522 * IDirect3DExecuteBuffer::Lock
524 * Locks the buffer, so the app can write into it.
527 * Desc: Pointer to return the buffer description. This Description contains
528 * a pointer to the buffer data.
531 * This implementation always returns D3D_OK
533 *****************************************************************************/
534 static HRESULT WINAPI
d3d_execute_buffer_Lock(IDirect3DExecuteBuffer
*iface
, D3DEXECUTEBUFFERDESC
*desc
)
536 struct d3d_execute_buffer
*buffer
= impl_from_IDirect3DExecuteBuffer(iface
);
539 TRACE("iface %p, desc %p.\n", iface
, desc
);
541 dwSize
= desc
->dwSize
;
542 memcpy(desc
, &buffer
->desc
, dwSize
);
546 TRACE(" Returning description :\n");
547 _dump_D3DEXECUTEBUFFERDESC(desc
);
552 /*****************************************************************************
553 * IDirect3DExecuteBuffer::Unlock
555 * Unlocks the buffer. We don't have anything to do here
558 * This implementation always returns D3D_OK
560 *****************************************************************************/
561 static HRESULT WINAPI
d3d_execute_buffer_Unlock(IDirect3DExecuteBuffer
*iface
)
563 TRACE("iface %p.\n", iface
);
568 /*****************************************************************************
569 * IDirect3DExecuteBuffer::SetExecuteData
571 * Sets the execute data. This data is used to describe the buffer's content
574 * Data: Pointer to a D3DEXECUTEDATA structure containing the data to
579 * DDERR_OUTOFMEMORY if the vertex buffer allocation failed
581 *****************************************************************************/
582 static HRESULT WINAPI
d3d_execute_buffer_SetExecuteData(IDirect3DExecuteBuffer
*iface
, D3DEXECUTEDATA
*data
)
584 struct d3d_execute_buffer
*buffer
= impl_from_IDirect3DExecuteBuffer(iface
);
585 struct wined3d_map_desc map_desc
;
586 struct wined3d_box box
= {0};
588 DWORD buf_size
= buffer
->desc
.dwBufferSize
, copy_size
;
590 TRACE("iface %p, data %p.\n", iface
, data
);
592 if (data
->dwSize
!= sizeof(*data
))
594 WARN("data->dwSize is %lu, returning DDERR_INVALIDPARAMS.\n", data
->dwSize
);
595 return DDERR_INVALIDPARAMS
;
598 /* Skip past previous vertex data. */
599 buffer
->src_vertex_pos
+= buffer
->data
.dwVertexCount
;
601 if (buffer
->vertex_size
< data
->dwVertexCount
)
603 unsigned int new_size
= max(data
->dwVertexCount
, buffer
->vertex_size
* 2);
604 struct wined3d_buffer
*src_buffer
, *dst_buffer
;
605 struct wined3d_buffer_desc desc
;
607 desc
.byte_width
= new_size
* sizeof(D3DVERTEX
);
609 desc
.bind_flags
= WINED3D_BIND_VERTEX_BUFFER
;
610 desc
.access
= WINED3D_RESOURCE_ACCESS_CPU
| WINED3D_RESOURCE_ACCESS_MAP_R
| WINED3D_RESOURCE_ACCESS_MAP_W
;
612 desc
.structure_byte_stride
= 0;
614 if (FAILED(hr
= wined3d_buffer_create(buffer
->d3ddev
->wined3d_device
, &desc
,
615 NULL
, NULL
, &ddraw_null_wined3d_parent_ops
, &src_buffer
)))
618 desc
.byte_width
= new_size
* sizeof(D3DTLVERTEX
);
619 desc
.usage
= WINED3DUSAGE_STATICDECL
;
620 desc
.access
= WINED3D_RESOURCE_ACCESS_GPU
| WINED3D_RESOURCE_ACCESS_MAP_W
;
622 if (FAILED(hr
= wined3d_buffer_create(buffer
->d3ddev
->wined3d_device
, &desc
,
623 NULL
, NULL
, &ddraw_null_wined3d_parent_ops
, &dst_buffer
)))
625 wined3d_buffer_decref(src_buffer
);
629 if (buffer
->dst_vertex_buffer
)
631 wined3d_buffer_decref(buffer
->src_vertex_buffer
);
632 wined3d_buffer_decref(buffer
->dst_vertex_buffer
);
634 buffer
->src_vertex_buffer
= src_buffer
;
635 buffer
->dst_vertex_buffer
= dst_buffer
;
636 buffer
->vertex_size
= new_size
;
637 buffer
->src_vertex_pos
= 0;
639 else if (buffer
->vertex_size
- data
->dwVertexCount
< buffer
->src_vertex_pos
)
641 buffer
->src_vertex_pos
= 0;
644 if (data
->dwVertexCount
&& (!buf_size
|| data
->dwVertexOffset
< buf_size
))
646 box
.left
= buffer
->src_vertex_pos
* sizeof(D3DVERTEX
);
647 box
.right
= box
.left
+ data
->dwVertexCount
* sizeof(D3DVERTEX
);
648 if (FAILED(hr
= wined3d_resource_map(wined3d_buffer_get_resource(buffer
->src_vertex_buffer
),
649 0, &map_desc
, &box
, WINED3D_MAP_WRITE
)))
652 copy_size
= data
->dwVertexCount
* sizeof(D3DVERTEX
);
654 copy_size
= min(copy_size
, buf_size
- data
->dwVertexOffset
);
656 memcpy(map_desc
.data
, ((BYTE
*)buffer
->desc
.lpData
) + data
->dwVertexOffset
, copy_size
);
658 wined3d_resource_unmap(wined3d_buffer_get_resource(buffer
->src_vertex_buffer
), 0);
661 memcpy(&buffer
->data
, data
, data
->dwSize
);
664 _dump_executedata(data
);
669 /*****************************************************************************
670 * IDirect3DExecuteBuffer::GetExecuteData
672 * Returns the data in the execute buffer
675 * Data: Pointer to a D3DEXECUTEDATA structure used to return data
680 *****************************************************************************/
681 static HRESULT WINAPI
d3d_execute_buffer_GetExecuteData(IDirect3DExecuteBuffer
*iface
, D3DEXECUTEDATA
*data
)
683 struct d3d_execute_buffer
*buffer
= impl_from_IDirect3DExecuteBuffer(iface
);
685 TRACE("iface %p, data %p.\n", iface
, data
);
687 /* Tests show that dwSize is ignored. */
688 memcpy(data
, &buffer
->data
, sizeof(*data
));
692 TRACE("Returning data :\n");
693 _dump_executedata(data
);
699 /*****************************************************************************
700 * IDirect3DExecuteBuffer::Validate
702 * DirectX 5 SDK: "The IDirect3DExecuteBuffer::Validate method is not
703 * currently implemented"
709 * DDERR_UNSUPPORTED, because it's not implemented in Windows.
711 *****************************************************************************/
712 static HRESULT WINAPI
d3d_execute_buffer_Validate(IDirect3DExecuteBuffer
*iface
,
713 DWORD
*offset
, LPD3DVALIDATECALLBACK callback
, void *context
, DWORD reserved
)
715 TRACE("iface %p, offset %p, callback %p, context %p, reserved %#lx.\n",
716 iface
, offset
, callback
, context
, reserved
);
718 WARN("Not implemented.\n");
720 return DDERR_UNSUPPORTED
; /* Unchecked */
723 /*****************************************************************************
724 * IDirect3DExecuteBuffer::Optimize
726 * DirectX5 SDK: "The IDirect3DExecuteBuffer::Optimize method is not
727 * currently supported"
730 * Dummy: Seems to be an unused dummy ;)
733 * DDERR_UNSUPPORTED, because it's not implemented in Windows.
735 *****************************************************************************/
736 static HRESULT WINAPI
d3d_execute_buffer_Optimize(IDirect3DExecuteBuffer
*iface
, DWORD reserved
)
738 TRACE("iface %p, reserved %#lx.\n", iface
, reserved
);
740 WARN("Not implemented.\n");
742 return DDERR_UNSUPPORTED
; /* Unchecked */
745 static const struct IDirect3DExecuteBufferVtbl d3d_execute_buffer_vtbl
=
747 d3d_execute_buffer_QueryInterface
,
748 d3d_execute_buffer_AddRef
,
749 d3d_execute_buffer_Release
,
750 d3d_execute_buffer_Initialize
,
751 d3d_execute_buffer_Lock
,
752 d3d_execute_buffer_Unlock
,
753 d3d_execute_buffer_SetExecuteData
,
754 d3d_execute_buffer_GetExecuteData
,
755 d3d_execute_buffer_Validate
,
756 d3d_execute_buffer_Optimize
,
759 HRESULT
d3d_execute_buffer_init(struct d3d_execute_buffer
*execute_buffer
,
760 struct d3d_device
*device
, D3DEXECUTEBUFFERDESC
*desc
)
762 execute_buffer
->IDirect3DExecuteBuffer_iface
.lpVtbl
= &d3d_execute_buffer_vtbl
;
763 execute_buffer
->ref
= 1;
764 execute_buffer
->d3ddev
= device
;
766 /* Initializes memory */
767 memcpy(&execute_buffer
->desc
, desc
, desc
->dwSize
);
769 /* No buffer given */
770 if (!(execute_buffer
->desc
.dwFlags
& D3DDEB_LPDATA
))
771 execute_buffer
->desc
.lpData
= NULL
;
773 /* No buffer size given */
774 if (!(execute_buffer
->desc
.dwFlags
& D3DDEB_BUFSIZE
))
775 execute_buffer
->desc
.dwBufferSize
= 0;
777 /* Create buffer if asked */
778 if (!execute_buffer
->desc
.lpData
&& execute_buffer
->desc
.dwBufferSize
)
780 execute_buffer
->need_free
= TRUE
;
781 if (!(execute_buffer
->desc
.lpData
= calloc(1, execute_buffer
->desc
.dwBufferSize
)))
783 ERR("Failed to allocate execute buffer data.\n");
784 return DDERR_OUTOFMEMORY
;
788 execute_buffer
->desc
.dwFlags
|= D3DDEB_LPDATA
;
793 struct d3d_execute_buffer
*unsafe_impl_from_IDirect3DExecuteBuffer(IDirect3DExecuteBuffer
*iface
)
797 assert(iface
->lpVtbl
== &d3d_execute_buffer_vtbl
);
799 return impl_from_IDirect3DExecuteBuffer(iface
);