[PATCH 2/7] ddraw: Use wined3d_device_process_vertices for execute buffers.
Stefan Dösinger
stefandoesinger at gmx.at
Sun Oct 30 09:02:22 CDT 2016
Signed-off-by: Stefan Dösinger <stefandoesinger at gmx.at>
---
dlls/ddraw/ddraw_private.h | 2 +-
dlls/ddraw/executebuffer.c | 136 +++++++++++++--------------------------------
2 files changed, 41 insertions(+), 97 deletions(-)
diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h
index 5a25a93..9cf8d6c 100644
--- a/dlls/ddraw/ddraw_private.h
+++ b/dlls/ddraw/ddraw_private.h
@@ -527,7 +527,7 @@ struct d3d_execute_buffer
WORD *indices;
unsigned int index_size;
unsigned int vertex_size;
- struct wined3d_buffer *dst_vertex_buffer, *index_buffer;
+ struct wined3d_buffer *src_vertex_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 5c53f2b..1fc1f28 100644
--- a/dlls/ddraw/executebuffer.c
+++ b/dlls/ddraw/executebuffer.c
@@ -48,21 +48,6 @@ static void _dump_D3DEXECUTEBUFFERDESC(const D3DEXECUTEBUFFERDESC *lpDesc) {
TRACE("lpData : %p\n", lpDesc->lpData);
}
-static void transform_vertex(D3DTLVERTEX *dst, const D3DMATRIX *mat,
- const D3DVIEWPORT *vp, float x, float y, float z)
-{
- dst->u1.sx = (x * mat->_11) + (y * mat->_21) + (z * mat->_31) + mat->_41;
- dst->u2.sy = (x * mat->_12) + (y * mat->_22) + (z * mat->_32) + mat->_42;
- dst->u3.sz = (x * mat->_13) + (y * mat->_23) + (z * mat->_33) + mat->_43;
- dst->u4.rhw = (x * mat->_14) + (y * mat->_24) + (z * mat->_34) + mat->_44;
-
- dst->u4.rhw = 1.0f / dst->u4.rhw;
-
- dst->u1.sx = (dst->u1.sx * dst->u4.rhw + 1.0f) * vp->dwWidth * 0.5 + vp->dwX;
- dst->u2.sy = (-dst->u2.sy * dst->u4.rhw + 1.0f) * vp->dwHeight * 0.5 + vp->dwY;
- dst->u3.sz *= dst->u4.rhw;
-}
-
HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer,
struct d3d_device *device, struct d3d_viewport *viewport)
{
@@ -272,40 +257,14 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer,
break;
case D3DOP_PROCESSVERTICES:
- {
- /* TODO: Share code with d3d_vertex_buffer7_ProcessVertices()
- * and / or wined3d_device_process_vertices(). */
- D3DMATRIX view_mat, world_mat, proj_mat, mat;
-
TRACE("PROCESSVERTICES (%d)\n", count);
- /* Note that the projection set in wined3d has the legacy clip space
- * adjustment built in. */
- wined3d_device_get_transform(device->wined3d_device,
- D3DTRANSFORMSTATE_VIEW, (struct wined3d_matrix *)&view_mat);
- wined3d_device_get_transform(device->wined3d_device,
- D3DTRANSFORMSTATE_PROJECTION, (struct wined3d_matrix *)&proj_mat);
- wined3d_device_get_transform(device->wined3d_device,
- WINED3D_TS_WORLD_MATRIX(0), (struct wined3d_matrix *)&world_mat);
-
- if (TRACE_ON(ddraw))
- {
- TRACE(" Projection Matrix:\n");
- dump_D3DMATRIX(&proj_mat);
- TRACE(" View Matrix:\n");
- dump_D3DMATRIX(&view_mat);
- TRACE(" World Matrix:\n");
- dump_D3DMATRIX(&world_mat);
- }
-
- multiply_matrix(&mat, &view_mat, &world_mat);
- multiply_matrix(&mat, &proj_mat, &mat);
-
for (i = 0; i < count; ++i)
{
D3DPROCESSVERTICES *ci = (D3DPROCESSVERTICES *)instr;
DWORD op = ci->dwFlags & D3DPROCESSVERTICES_OPMASK;
- D3DTLVERTEX *src, *dst;
+ /* D3DVERTEX, D3DLVERTEX and D3DTLVERTEX all have a size of 32 bytes. */
+ const D3DVERTEX *src = (const D3DVERTEX *)((char *)buffer->desc.lpData + vs) + ci->wStart;
TRACE(" start %u, dest %u, count %u, flags %#x.\n",
ci->wStart, ci->wDest, ci->dwCount, ci->dwFlags);
@@ -318,65 +277,36 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer,
switch (op)
{
case D3DPROCESSVERTICES_TRANSFORMLIGHT:
- {
- const D3DVERTEX *src = (D3DVERTEX *)((char *)buffer->desc.lpData + vs) + ci->wStart;
- unsigned int vtx_idx;
- static unsigned int once;
-
- 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);
+ case D3DPROCESSVERTICES_TRANSFORM:
+ box.left = 0;
+ box.right = ci->dwCount * sizeof(*src);
+ hr = wined3d_resource_map(wined3d_buffer_get_resource(buffer->src_vertex_buffer), 0,
+ &map_desc, &box, WINED3D_MAP_DISCARD);
if (FAILED(hr))
return hr;
- dst = map_desc.data;
+ memcpy(map_desc.data, src, ci->dwCount * sizeof(*src));
+ wined3d_resource_unmap(wined3d_buffer_get_resource(buffer->dst_vertex_buffer), 0);
- for (vtx_idx = 0; vtx_idx < ci->dwCount; ++vtx_idx)
+ wined3d_device_set_stream_source(device->wined3d_device, 0,
+ buffer->src_vertex_buffer, 0, sizeof(*src));
+ if (op == D3DPROCESSVERTICES_TRANSFORMLIGHT)
{
- transform_vertex(&dst[vtx_idx], &mat, &viewport->viewports.vp1,
- src[vtx_idx].u1.x, src[vtx_idx].u2.y, src[vtx_idx].u3.z);
- /* No lighting yet */
- dst[vtx_idx].u5.color = 0xffffffff; /* Opaque white */
- dst[vtx_idx].u6.specular = 0xff000000; /* No specular and no fog factor */
- dst[vtx_idx].u7.tu = src[vtx_idx].u7.tu;
- dst[vtx_idx].u8.tv = src[vtx_idx].u8.tv;
+ wined3d_device_set_vertex_declaration(device->wined3d_device,
+ ddraw_find_decl(device->ddraw, D3DFVF_VERTEX));
+ wined3d_device_set_render_state(device->wined3d_device,
+ WINED3D_RS_LIGHTING, TRUE);
}
-
- wined3d_resource_unmap(wined3d_buffer_get_resource(buffer->dst_vertex_buffer), 0);
-
- break;
- }
-
- case D3DPROCESSVERTICES_TRANSFORM:
- {
- 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)
+ else
{
- transform_vertex(&dst[vtx_idx], &mat, &viewport->viewports.vp1,
- src[vtx_idx].u1.x, src[vtx_idx].u2.y, src[vtx_idx].u3.z);
- dst[vtx_idx].u5.color = src[vtx_idx].u4.color;
- dst[vtx_idx].u6.specular = src[vtx_idx].u5.specular;
- dst[vtx_idx].u7.tu = src[vtx_idx].u6.tu;
- dst[vtx_idx].u8.tv = src[vtx_idx].u7.tv;
+ wined3d_device_set_vertex_declaration(device->wined3d_device,
+ ddraw_find_decl(device->ddraw, D3DFVF_LVERTEX));
+ wined3d_device_set_render_state(device->wined3d_device,
+ WINED3D_RS_LIGHTING, FALSE);
}
- wined3d_resource_unmap(wined3d_buffer_get_resource(buffer->dst_vertex_buffer), 0);
-
+ wined3d_device_process_vertices(device->wined3d_device, 0, ci->wDest,
+ ci->dwCount, buffer->dst_vertex_buffer, NULL, 0, D3DFVF_TLVERTEX);
break;
- }
case D3DPROCESSVERTICES_COPY:
box.left = ci->wDest * sizeof(*src);
@@ -386,7 +316,6 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer,
if (FAILED(hr))
return hr;
- src = (D3DTLVERTEX *)((char *)buffer->desc.lpData + vs) + ci->wStart;
memcpy(map_desc.data, src, ci->dwCount * sizeof(*src));
wined3d_resource_unmap(wined3d_buffer_get_resource(buffer->dst_vertex_buffer), 0);
@@ -400,7 +329,6 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer,
instr += size;
}
break;
- }
case D3DOP_TEXTURELOAD: {
WARN("TEXTURELOAD-s (%d)\n", count);
@@ -538,7 +466,10 @@ static ULONG WINAPI d3d_execute_buffer_Release(IDirect3DExecuteBuffer *iface)
if (buffer->index_buffer)
wined3d_buffer_decref(buffer->index_buffer);
if (buffer->dst_vertex_buffer)
+ {
+ wined3d_buffer_decref(buffer->src_vertex_buffer);
wined3d_buffer_decref(buffer->dst_vertex_buffer);
+ }
HeapFree(GetProcessHeap(), 0, buffer);
}
@@ -636,16 +567,29 @@ static HRESULT WINAPI d3d_execute_buffer_SetExecuteData(IDirect3DExecuteBuffer *
{
HRESULT hr;
unsigned int new_size = max(data->dwVertexCount, buffer->vertex_size * 2);
- struct wined3d_buffer *dst_buffer;
+ struct wined3d_buffer *src_buffer, *dst_buffer;
+
+ hr = wined3d_buffer_create_vb(buffer->d3ddev->wined3d_device, new_size * sizeof(D3DVERTEX),
+ WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY, WINED3D_POOL_SYSTEM_MEM,
+ NULL, &ddraw_null_wined3d_parent_ops, &src_buffer);
+ if (FAILED(hr))
+ return hr;
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))
+ {
+ wined3d_buffer_decref(src_buffer);
return hr;
+ }
if (buffer->dst_vertex_buffer)
+ {
+ wined3d_buffer_decref(buffer->src_vertex_buffer);
wined3d_buffer_decref(buffer->dst_vertex_buffer);
+ }
+ buffer->src_vertex_buffer = src_buffer;
buffer->dst_vertex_buffer = dst_buffer;
buffer->vertex_size = new_size;
}
--
2.7.3
More information about the wine-patches
mailing list