From b7c9d14e8edfb42d4758a6892dcd42c4dcb1d3ef Mon Sep 17 00:00:00 2001 From: =?utf8?q?Stefan=20D=C3=B6singer?= Date: Sun, 30 Oct 2016 07:02:21 -0700 Subject: [PATCH] ddraw: Use d3d buffers for executebuffer data. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Stefan Dösinger Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- dlls/ddraw/ddraw_private.h | 5 +- dlls/ddraw/executebuffer.c | 128 +++++++++++++++++++++++++++++++++++---------- 2 files changed, 102 insertions(+), 31 deletions(-) diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h index 7c2f026107d..5a25a937199 100644 --- a/dlls/ddraw/ddraw_private.h +++ b/dlls/ddraw/ddraw_private.h @@ -525,8 +525,9 @@ struct d3d_execute_buffer /* This buffer will store the transformed vertices */ void *vertex_data; WORD *indices; - unsigned int nb_indices; - unsigned int nb_vertices; + unsigned int index_size; + unsigned int vertex_size; + struct wined3d_buffer *dst_vertex_buffer, *index_buffer; /* This flags is set to TRUE if we allocated ourselves the * data buffer diff --git a/dlls/ddraw/executebuffer.c b/dlls/ddraw/executebuffer.c index 3becf583935..5c53f2b9068 100644 --- a/dlls/ddraw/executebuffer.c +++ b/dlls/ddraw/executebuffer.c @@ -70,6 +70,9 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, DWORD is = buffer->data.dwInstructionOffset; char *instr = (char *)buffer->desc.lpData + is; unsigned int i; + struct wined3d_map_desc map_desc; + struct wined3d_box box = {0}; + HRESULT hr; if (viewport->active_device != device) { @@ -108,21 +111,42 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, case D3DOP_TRIANGLE: { - D3DTLVERTEX *tl_vx = buffer->vertex_data; - TRACE("TRIANGLE (%d)\n", count); + WORD *indices; + TRACE("TRIANGLE (%d)\n", count); - if (buffer->nb_indices < count * 3) + if (!count) + break; + + if (buffer->index_size < count * 3) { - buffer->nb_indices = count * 3; - HeapFree(GetProcessHeap(), 0, buffer->indices); - buffer->indices = HeapAlloc(GetProcessHeap(), 0, sizeof(*buffer->indices) * buffer->nb_indices); + struct wined3d_buffer *new_buffer; + unsigned int new_size = max(buffer->index_size * 2, count * 3); + + hr = wined3d_buffer_create_ib(device->wined3d_device, new_size * sizeof(*indices), + WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY, WINED3D_POOL_DEFAULT, + NULL, &ddraw_null_wined3d_parent_ops, &new_buffer); + if (FAILED(hr)) + return hr; + + buffer->index_size = new_size; + if (buffer->index_buffer) + wined3d_buffer_decref(buffer->index_buffer); + buffer->index_buffer = new_buffer; } + box.left = 0; + box.right = count * 3 * sizeof(*indices); + hr = wined3d_resource_map(wined3d_buffer_get_resource(buffer->index_buffer), 0, + &map_desc, &box, WINED3D_MAP_DISCARD); + if (FAILED(hr)) + return hr; + indices = map_desc.data; + for (i = 0; i < count; ++i) { D3DTRIANGLE *ci = (D3DTRIANGLE *)instr; - TRACE(" v1: %d v2: %d v3: %d\n",ci->u1.v1, ci->u2.v2, ci->u3.v3); - TRACE(" Flags : "); + TRACE(" v1: %d v2: %d v3: %d\n",ci->u1.v1, ci->u2.v2, ci->u3.v3); + TRACE(" Flags : "); if (TRACE_ON(ddraw)) { /* Wireframe */ @@ -143,14 +167,21 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, TRACE("STARTFLAT(%u) ", ci->wFlags); TRACE("\n"); } - buffer->indices[(i * 3) ] = ci->u1.v1; - buffer->indices[(i * 3) + 1] = ci->u2.v2; - buffer->indices[(i * 3) + 2] = ci->u3.v3; + indices[(i * 3) ] = ci->u1.v1; + indices[(i * 3) + 1] = ci->u2.v2; + indices[(i * 3) + 2] = ci->u3.v3; instr += size; } - IDirect3DDevice7_DrawIndexedPrimitive(&device->IDirect3DDevice7_iface, - D3DPT_TRIANGLELIST, D3DFVF_TLVERTEX, tl_vx, buffer->nb_vertices, - buffer->indices, count * 3, 0); + + wined3d_resource_unmap(wined3d_buffer_get_resource(buffer->index_buffer), 0); + + wined3d_device_set_stream_source(device->wined3d_device, 0, + buffer->dst_vertex_buffer, 0, sizeof(D3DTLVERTEX)); + wined3d_device_set_vertex_declaration(device->wined3d_device, + ddraw_find_decl(device->ddraw, D3DFVF_TLVERTEX)); + wined3d_device_set_index_buffer(device->wined3d_device, buffer->index_buffer, WINED3DFMT_R16_UINT, 0); + wined3d_device_set_primitive_type(device->wined3d_device, WINED3D_PT_TRIANGLELIST); + wined3d_device_draw_indexed_primitive(device->wined3d_device, 0, count * 3); } break; case D3DOP_MATRIXLOAD: @@ -273,8 +304,8 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, for (i = 0; i < count; ++i) { D3DPROCESSVERTICES *ci = (D3DPROCESSVERTICES *)instr; - D3DTLVERTEX *dst = (D3DTLVERTEX *)buffer->vertex_data + ci->wDest; DWORD op = ci->dwFlags & D3DPROCESSVERTICES_OPMASK; + D3DTLVERTEX *src, *dst; TRACE(" start %u, dest %u, count %u, flags %#x.\n", ci->wStart, ci->wDest, ci->dwCount, ci->dwFlags); @@ -295,6 +326,14 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, if (!once++) FIXME("Lighting not implemented.\n"); + box.left = ci->wDest * sizeof(*dst); + box.right = (ci->wDest + ci->dwCount) * sizeof(*dst); + hr = wined3d_resource_map(wined3d_buffer_get_resource(buffer->dst_vertex_buffer), 0, + &map_desc, &box, 0); + if (FAILED(hr)) + return hr; + dst = map_desc.data; + for (vtx_idx = 0; vtx_idx < ci->dwCount; ++vtx_idx) { transform_vertex(&dst[vtx_idx], &mat, &viewport->viewports.vp1, @@ -305,6 +344,9 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, dst[vtx_idx].u7.tu = src[vtx_idx].u7.tu; dst[vtx_idx].u8.tv = src[vtx_idx].u8.tv; } + + wined3d_resource_unmap(wined3d_buffer_get_resource(buffer->dst_vertex_buffer), 0); + break; } @@ -313,6 +355,14 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, const D3DLVERTEX *src = (D3DLVERTEX *)((char *)buffer->desc.lpData + vs) + ci->wStart; unsigned int vtx_idx; + box.left = ci->wDest * sizeof(*dst); + box.right = (ci->wDest + ci->dwCount) * sizeof(*dst); + hr = wined3d_resource_map(wined3d_buffer_get_resource(buffer->dst_vertex_buffer), 0, + &map_desc, &box, 0); + if (FAILED(hr)) + return hr; + dst = map_desc.data; + for (vtx_idx = 0; vtx_idx < ci->dwCount; ++vtx_idx) { transform_vertex(&dst[vtx_idx], &mat, &viewport->viewports.vp1, @@ -322,16 +372,25 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, dst[vtx_idx].u7.tu = src[vtx_idx].u6.tu; dst[vtx_idx].u8.tv = src[vtx_idx].u7.tv; } + + wined3d_resource_unmap(wined3d_buffer_get_resource(buffer->dst_vertex_buffer), 0); + break; } case D3DPROCESSVERTICES_COPY: - { - const D3DTLVERTEX *src = (D3DTLVERTEX *)((char *)buffer->desc.lpData + vs) + ci->wStart; + box.left = ci->wDest * sizeof(*src); + box.right = (ci->wDest + ci->dwCount) * sizeof(*src); + hr = wined3d_resource_map(wined3d_buffer_get_resource(buffer->dst_vertex_buffer), 0, + &map_desc, &box, 0); + if (FAILED(hr)) + return hr; + + src = (D3DTLVERTEX *)((char *)buffer->desc.lpData + vs) + ci->wStart; + memcpy(map_desc.data, src, ci->dwCount * sizeof(*src)); - memcpy(dst, src, ci->dwCount * sizeof(*dst)); + wined3d_resource_unmap(wined3d_buffer_get_resource(buffer->dst_vertex_buffer), 0); break; - } default: FIXME("Unhandled vertex processing op %#x.\n", op); @@ -476,8 +535,10 @@ static ULONG WINAPI d3d_execute_buffer_Release(IDirect3DExecuteBuffer *iface) { if (buffer->need_free) HeapFree(GetProcessHeap(), 0, buffer->desc.lpData); - HeapFree(GetProcessHeap(), 0, buffer->vertex_data); - HeapFree(GetProcessHeap(), 0, buffer->indices); + if (buffer->index_buffer) + wined3d_buffer_decref(buffer->index_buffer); + if (buffer->dst_vertex_buffer) + wined3d_buffer_decref(buffer->dst_vertex_buffer); HeapFree(GetProcessHeap(), 0, buffer); } @@ -566,19 +627,28 @@ static HRESULT WINAPI d3d_execute_buffer_Unlock(IDirect3DExecuteBuffer *iface) static HRESULT WINAPI d3d_execute_buffer_SetExecuteData(IDirect3DExecuteBuffer *iface, D3DEXECUTEDATA *data) { struct d3d_execute_buffer *buffer = impl_from_IDirect3DExecuteBuffer(iface); - DWORD nbvert; TRACE("iface %p, data %p.\n", iface, data); memcpy(&buffer->data, data, data->dwSize); - /* Get the number of vertices in the execute buffer */ - nbvert = buffer->data.dwVertexCount; - - /* Prepares the transformed vertex buffer */ - HeapFree(GetProcessHeap(), 0, buffer->vertex_data); - buffer->vertex_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nbvert * sizeof(D3DTLVERTEX)); - buffer->nb_vertices = nbvert; + if (buffer->vertex_size < data->dwVertexCount) + { + HRESULT hr; + unsigned int new_size = max(data->dwVertexCount, buffer->vertex_size * 2); + struct wined3d_buffer *dst_buffer; + + hr = wined3d_buffer_create_vb(buffer->d3ddev->wined3d_device, new_size * sizeof(D3DTLVERTEX), + WINED3DUSAGE_STATICDECL, WINED3D_POOL_DEFAULT, + NULL, &ddraw_null_wined3d_parent_ops, &dst_buffer); + if (FAILED(hr)) + return hr; + + if (buffer->dst_vertex_buffer) + wined3d_buffer_decref(buffer->dst_vertex_buffer); + buffer->dst_vertex_buffer = dst_buffer; + buffer->vertex_size = new_size; + } if (TRACE_ON(ddraw)) _dump_executedata(data); -- 2.11.4.GIT