From: Steve Schnepp steve.schnepp@pwkf.org
--- dlls/ddraw/ddraw_private.h | 10 ++-- dlls/ddraw/device.c | 97 +++++++++++++++++++++++++++----------- 2 files changed, 76 insertions(+), 31 deletions(-)
diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h index 8455b157522..2a322117202 100644 --- a/dlls/ddraw/ddraw_private.h +++ b/dlls/ddraw/ddraw_private.h @@ -317,14 +317,16 @@ DWORD ddraw_allocate_handle(struct ddraw_handle_table *t, void *object, enum ddr void *ddraw_free_handle(struct ddraw_handle_table *t, DWORD handle, enum ddraw_handle_type type) DECLSPEC_HIDDEN; void *ddraw_get_object(struct ddraw_handle_table *t, DWORD handle, enum ddraw_handle_type type) DECLSPEC_HIDDEN;
-#define D3D_BUFFER_SIZE (2 * 1024 * 1024) /* 2 MiB buffer */ - struct d3d_device_buffer { DWORD fvf; + UINT stride; DWORD buffer_indice_count; DWORD buffer_vertex_count; - WORD buffer_indices[D3DMAXNUMVERTICES]; - char buffer_vertices[D3D_BUFFER_SIZE]; + WORD *buffer_indices; + char *buffer_vertices; + + unsigned int idx_buffer_pos; + unsigned int vertex_buffer_pos; };
struct d3d_device diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c index ed1873d1594..cc19e992dda 100644 --- a/dlls/ddraw/device.c +++ b/dlls/ddraw/device.c @@ -3468,8 +3468,23 @@ static HRESULT d3d_device7_DrawPrimitive(IDirect3DDevice7 *iface, return D3D_OK; }
+ FIXME("iface %p, primitive_type %#x, fvf %#lx, vertices %p, vertex_count %lu, flags %#lx.\n", + iface, primitive_type, fvf, vertices, vertex_count, flags); + FIXME("cannot buffer, flushing first\n"); + // Cannot buffer, need to flush the rest, then process this one - ddraw_buffer_flush_d7(iface); + hr = ddraw_buffer_flush_d7(iface); + + hr = ddraw_buffer_add_d7(iface, primitive_type, fvf, vertices, vertex_count, flags, stride); + if (hr == D3D_OK) { + /* Buffered successfuly -> returning immediatly :-) */ + return D3D_OK; + } + + FIXME("REALLY cannot buffer skip\n"); + + // let's skip ;) + return hr;
wined3d_mutex_lock();
@@ -7020,17 +7035,28 @@ static HRESULT ddraw_buffer_add_d7(IDirect3DDevice7 *iface, D3DPRIMITIVETYPE pri return WINED3DERR_NOTAVAILABLE; }
- if (device->ddraw_device_buffer.buffer_vertex_count) { - if (fvf != device->ddraw_device_buffer.fvf) { - /* Not the same fvf as the buffered one. Cannot buffer more of those */ - TRACE_(ddraw_perf)("Buffering failed due to mismatched fvf %ld != buffer.fvf %ld \n", fvf, device->ddraw_device_buffer.fvf); - return WINED3DERR_NOTAVAILABLE; - } - } else { - /* New buffer, setting fvf */ + if (! device->ddraw_device_buffer.buffer_vertex_count) { + /* New buffer, setting everything up */ device->ddraw_device_buffer.fvf = fvf; - } + device->ddraw_device_buffer.stride = stride; + + /* We map & unmap directly. + * That way, we only reserve the space and other calls will have a new one. + * It should not happen, but let's be safe. + * + * We will fill it with following calls */ + wined3d_streaming_buffer_map(device->wined3d_device, &device->vertex_buffer, D3DMAXNUMVERTICES, stride, + &device->ddraw_device_buffer.vertex_buffer_pos, (void**) &device->ddraw_device_buffer.buffer_vertices); + wined3d_streaming_buffer_unmap(&device->vertex_buffer);
+ wined3d_streaming_buffer_map(device->wined3d_device, &device->index_buffer, D3DMAXNUMVERTICES, sizeof(*device->ddraw_device_buffer.buffer_indices), + &device->ddraw_device_buffer.idx_buffer_pos, (void**) &device->ddraw_device_buffer.buffer_indices); + wined3d_streaming_buffer_unmap(&device->index_buffer); + } else if (fvf != device->ddraw_device_buffer.fvf) { + /* Not the same fvf as the buffered one. Cannot buffer more of those */ + TRACE_(ddraw_perf)("Buffering failed due to mismatched fvf %ld != buffer.fvf %ld \n", fvf, device->ddraw_device_buffer.fvf); + return WINED3DERR_NOTAVAILABLE; + }
/* append all the vertices to the buffer */ memcpy(device->ddraw_device_buffer.buffer_vertices + device->ddraw_device_buffer.buffer_vertex_count * stride, vertices, vertex_count * stride); @@ -7050,7 +7076,7 @@ static HRESULT ddraw_buffer_add_d7(IDirect3DDevice7 *iface, D3DPRIMITIVETYPE pri
/* Next triangles are recreated with : 2 next vertices then the 1rst one. * So, it will *increase* the number of total vertices from 4 to 6, 5 to 9, 6 to 12, ... */ - for (int idx = 2; idx < vertex_count-1; idx ++) { + for (int idx = 3; idx < vertex_count; idx ++) { /* Copy the 2 last ones */ device->ddraw_device_buffer.buffer_indices[device->ddraw_device_buffer.buffer_indice_count++] = device->ddraw_device_buffer.buffer_vertex_count - 1; device->ddraw_device_buffer.buffer_indices[device->ddraw_device_buffer.buffer_indice_count++] = device->ddraw_device_buffer.buffer_vertex_count; @@ -7061,6 +7087,9 @@ static HRESULT ddraw_buffer_add_d7(IDirect3DDevice7 *iface, D3DPRIMITIVETYPE pri device->ddraw_device_buffer.buffer_vertex_count, device->ddraw_device_buffer.buffer_indice_count); }
+ TRACE_(ddraw_perf)("buffer_vertex_count %lu buffer_indice_count %lu max %d\n", + device->ddraw_device_buffer.buffer_vertex_count, device->ddraw_device_buffer.buffer_indice_count, D3DMAXNUMVERTICES); + /* Buffered ! */ return D3D_OK; } @@ -7070,31 +7099,45 @@ static HRESULT ddraw_buffer_add_d7(IDirect3DDevice7 *iface, D3DPRIMITIVETYPE pri * It will delegate to a single call to DrawPrimitive with the correct parameters, * and a (hopefully) huge list of triangles vertices. */
-static HRESULT ddraw_buffer_flush_d7(IDirect3DDevice7 *iface) { - struct d3d_device *device = impl_from_IDirect3DDevice7(iface); +static HRESULT ddraw_buffer_flush_d7_internal(struct d3d_device *device) { + HRESULT hr;
TRACE_(ddraw_perf)("buffer_vertex_count %lu buffer_indice_count %lu\n", device->ddraw_device_buffer.buffer_vertex_count, device->ddraw_device_buffer.buffer_indice_count);
- /* Nothing to do if it is empty */ - if (! device->ddraw_device_buffer.buffer_vertex_count) return D3D_OK; + /* Calling wined3d directly */ + wined3d_mutex_lock();
- /* Delegate the call */ - { - HRESULT ret; - const DWORD from_flush_flags = 0xF0F0F0F0; // Using a specific flag to recognise & avoid recursion loops + hr = wined3d_stateblock_set_stream_source(device->state, 0, device->vertex_buffer.buffer, 0, device->ddraw_device_buffer.stride);
- ret = d3d_device7_DrawIndexedPrimitive(iface, D3DPT_TRIANGLELIST, device->ddraw_device_buffer.fvf, - device->ddraw_device_buffer.buffer_vertices, device->ddraw_device_buffer.buffer_vertex_count, - device->ddraw_device_buffer.buffer_indices, device->ddraw_device_buffer.buffer_indice_count, - from_flush_flags); + if (FAILED(hr)) + goto done;
- if (ret != D3D_OK) FIXME("error in call delegation %ld", ret); - } + wined3d_stateblock_set_index_buffer(device->state, device->index_buffer.buffer, WINED3DFMT_R16_UINT); + wined3d_stateblock_set_vertex_declaration(device->state, ddraw_find_decl(device->ddraw, device->ddraw_device_buffer.fvf)); + wined3d_device_context_set_primitive_type(device->immediate_context, wined3d_primitive_type_from_ddraw(D3DPT_TRIANGLELIST), 0); + wined3d_device_apply_stateblock(device->wined3d_device, device->state); + d3d_device_sync_surfaces(device); + + wined3d_device_context_draw_indexed(device->immediate_context, + device->ddraw_device_buffer.vertex_buffer_pos / device->ddraw_device_buffer.stride, + device->ddraw_device_buffer.idx_buffer_pos / sizeof(*device->ddraw_device_buffer.buffer_indices), + device->ddraw_device_buffer.buffer_indice_count, 0, 0);
+ +done: + wined3d_mutex_unlock(); /* Reset the buffer */ device->ddraw_device_buffer.buffer_vertex_count = 0; device->ddraw_device_buffer.buffer_indice_count = 0;
- /* The error isn't really useful as it is too late, so always returning */ - return D3D_OK; + return hr; +} + +static HRESULT ddraw_buffer_flush_d7(IDirect3DDevice7 *iface) { + struct d3d_device *device = impl_from_IDirect3DDevice7(iface); + + /* Nothing to do if it is empty */ + if (! device->ddraw_device_buffer.buffer_vertex_count) return D3D_OK; + + return ddraw_buffer_flush_d7_internal(device); }