From: Steve Schnepp steve.schnepp@pwkf.org
The D3DPT_POINTLIST are used to write blips on the minimap. *Each* point has its own DrawPrimitive(), which is very costly!
---
The implementation itself needs to be refactored with helper functions. Will amend the commit later, but i pushed early for feedback --- dlls/ddraw/ddraw_private.h | 1 + dlls/ddraw/device.c | 52 +++++++++++++++++++++++++------------- 2 files changed, 35 insertions(+), 18 deletions(-)
diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h index 2a322117202..020f1be1173 100644 --- a/dlls/ddraw/ddraw_private.h +++ b/dlls/ddraw/ddraw_private.h @@ -318,6 +318,7 @@ void *ddraw_free_handle(struct ddraw_handle_table *t, DWORD handle, enum ddraw_h void *ddraw_get_object(struct ddraw_handle_table *t, DWORD handle, enum ddraw_handle_type type) DECLSPEC_HIDDEN;
struct d3d_device_buffer { + D3DPRIMITIVETYPE primitive_type; DWORD fvf; UINT stride; DWORD buffer_indice_count; diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c index cc19e992dda..5dfa8e2a890 100644 --- a/dlls/ddraw/device.c +++ b/dlls/ddraw/device.c @@ -7016,9 +7016,7 @@ HRESULT d3d_device_create(struct ddraw *ddraw, const GUID *guid, struct ddraw_su * * For now, it only supports : * d3d_device.version == 7 - * primitive_type == D3DPT_TRIANGLEFAN * flags == 0 - * vertex_count >= 3 * * Note : it does transform D3DPT_TRIANGLEFAN into D3DPT_TRIANGLELIST. */ @@ -7027,16 +7025,11 @@ static HRESULT ddraw_buffer_add_d7(IDirect3DDevice7 *iface, D3DPRIMITIVETYPE pri int buffer_indice_count_initial = device->ddraw_device_buffer.buffer_vertex_count;
if (!TRACE_ON(ddraw_buffer)) return WINED3DERR_NOTAVAILABLE; - if (primitive_type != D3DPT_TRIANGLEFAN) return WINED3DERR_NOTAVAILABLE; if (flags) return WINED3DERR_NOTAVAILABLE;
- if (vertex_count < 3) { - WARN("vertex_count %lu lower than 3. not buffering", vertex_count); - return WINED3DERR_NOTAVAILABLE; - } - if (! device->ddraw_device_buffer.buffer_vertex_count) { /* New buffer, setting everything up */ + device->ddraw_device_buffer.primitive_type = primitive_type; device->ddraw_device_buffer.fvf = fvf; device->ddraw_device_buffer.stride = stride;
@@ -7056,24 +7049,41 @@ static HRESULT ddraw_buffer_add_d7(IDirect3DDevice7 *iface, D3DPRIMITIVETYPE pri /* 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 if (primitive_type != device->ddraw_device_buffer.primitive_type) { + TRACE_(ddraw_perf)("Buffering failed due to mismatched primitive_type %d != buffer.primitive_type %d \n", primitive_type, device->ddraw_device_buffer.primitive_type); + 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); - - TRACE_(ddraw_perf)("vertex count %lu stride %d buffer_vertex_count %lu buffer_indice_count %lu\n", vertex_count, stride, + TRACE_(ddraw_perf)("vertex count %lu stride %d buffer_vertex_count %05lu buffer_indice_count %05lu\n", vertex_count, stride, device->ddraw_device_buffer.buffer_vertex_count, device->ddraw_device_buffer.buffer_indice_count);
/* Create the index */ + if (primitive_type == D3DPT_TRIANGLEFAN) goto fan; + if (primitive_type == D3DPT_POINTLIST) goto points; + + FIXME("primitive_type %#x not supported\n", primitive_type); + goto done; + +points: + for (int idx = 0; idx < vertex_count; idx ++) { + device->ddraw_device_buffer.buffer_indices[device->ddraw_device_buffer.buffer_indice_count++] = device->ddraw_device_buffer.buffer_vertex_count++; + } + + goto done; + +fan: + if (vertex_count < 3) { + WARN("vertex_count %lu lower than 3. not buffering", vertex_count); + return WINED3DERR_NOTAVAILABLE; + }
/* The first triangle is the same, therefore the indices are simply copied over */ device->ddraw_device_buffer.buffer_indices[device->ddraw_device_buffer.buffer_indice_count++] = device->ddraw_device_buffer.buffer_vertex_count++; device->ddraw_device_buffer.buffer_indices[device->ddraw_device_buffer.buffer_indice_count++] = device->ddraw_device_buffer.buffer_vertex_count++; device->ddraw_device_buffer.buffer_indices[device->ddraw_device_buffer.buffer_indice_count++] = device->ddraw_device_buffer.buffer_vertex_count++;
- TRACE_(ddraw_perf)("vertex count %lu stride %d buffer_vertex_count %lu buffer_indice_count %lu\n", vertex_count, stride, - device->ddraw_device_buffer.buffer_vertex_count, device->ddraw_device_buffer.buffer_indice_count); - /* 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 = 3; idx < vertex_count; idx ++) { @@ -7083,11 +7093,12 @@ static HRESULT ddraw_buffer_add_d7(IDirect3DDevice7 *iface, D3DPRIMITIVETYPE pri device->ddraw_device_buffer.buffer_indices[device->ddraw_device_buffer.buffer_indice_count++] = buffer_indice_count_initial; device->ddraw_device_buffer.buffer_vertex_count++;
- TRACE_(ddraw_perf)("idx %d vertex count %lu stride %d buffer_vertex_count %lu buffer_indice_count %lu\n", idx, vertex_count, stride, - device->ddraw_device_buffer.buffer_vertex_count, device->ddraw_device_buffer.buffer_indice_count); + TRACE_(ddraw_perf)("vertex count %lu stride %d buffer_vertex_count %05lu buffer_indice_count %05lu idx %d\n", vertex_count, stride, + device->ddraw_device_buffer.buffer_vertex_count, device->ddraw_device_buffer.buffer_indice_count, idx); }
- TRACE_(ddraw_perf)("buffer_vertex_count %lu buffer_indice_count %lu max %d\n", +done: + TRACE_(ddraw_perf)("buffer_vertex_count %05lu buffer_indice_count %05lu max %d\n", device->ddraw_device_buffer.buffer_vertex_count, device->ddraw_device_buffer.buffer_indice_count, D3DMAXNUMVERTICES);
/* Buffered ! */ @@ -7102,7 +7113,7 @@ static HRESULT ddraw_buffer_add_d7(IDirect3DDevice7 *iface, D3DPRIMITIVETYPE pri 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); + TRACE_(ddraw_perf)("primitive_type %#x buffer_vertex_count %05lu buffer_indice_count %05lu\n", device->ddraw_device_buffer.primitive_type, device->ddraw_device_buffer.buffer_vertex_count, device->ddraw_device_buffer.buffer_indice_count);
/* Calling wined3d directly */ wined3d_mutex_lock(); @@ -7114,7 +7125,13 @@ static HRESULT ddraw_buffer_flush_d7_internal(struct d3d_device *device) {
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); + + if (device->ddraw_device_buffer.primitive_type == D3DPT_POINTLIST) { + wined3d_device_context_set_primitive_type(device->immediate_context, wined3d_primitive_type_from_ddraw(D3DPT_POINTLIST), 0); + } + wined3d_device_apply_stateblock(device->wined3d_device, device->state); d3d_device_sync_surfaces(device);
@@ -7123,7 +7140,6 @@ static HRESULT ddraw_buffer_flush_d7_internal(struct d3d_device *device) { 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 */