=?UTF-8?Q?Stefan=20D=C3=B6singer=20?=: ddraw: Implement DrawPrimitiveStrided with regular draws.
Alexandre Julliard
julliard at winehq.org
Fri Jan 25 13:31:48 CST 2013
Module: wine
Branch: master
Commit: 7e62acc62e3d5f0e6fd199caab34b26f35b2326d
URL: http://source.winehq.org/git/wine.git/?a=commit;h=7e62acc62e3d5f0e6fd199caab34b26f35b2326d
Author: Stefan Dösinger <stefan at codeweavers.com>
Date: Thu Jan 24 00:39:10 2013 +0100
ddraw: Implement DrawPrimitiveStrided with regular draws.
---
dlls/ddraw/device.c | 142 ++++++++++++++++++++++++++++++---------------------
1 files changed, 83 insertions(+), 59 deletions(-)
diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c
index 76bdcff..faf7146 100644
--- a/dlls/ddraw/device.c
+++ b/dlls/ddraw/device.c
@@ -3806,82 +3806,106 @@ static HRESULT WINAPI d3d_device2_GetClipStatus(IDirect3DDevice2 *iface, D3DCLIP
* (For details, see IWineD3DDevice::DrawPrimitiveStrided)
*
*****************************************************************************/
-static HRESULT d3d_device7_DrawPrimitiveStrided(IDirect3DDevice7 *iface, D3DPRIMITIVETYPE PrimitiveType,
- DWORD VertexType, D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData, DWORD VertexCount, DWORD Flags)
+static void pack_strided_data(BYTE *dst, DWORD count, const D3DDRAWPRIMITIVESTRIDEDDATA *src, DWORD fvf)
{
- struct d3d_device *device = impl_from_IDirect3DDevice7(iface);
- struct wined3d_strided_data wined3d_strided;
- DWORD i;
- HRESULT hr;
+ DWORD i, tex, offset;
- TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, flags %#x.\n",
- iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
-
- memset(&wined3d_strided, 0, sizeof(wined3d_strided));
- /* Get the strided data right. the wined3d structure is a bit bigger
- * Watch out: The contents of the strided data are determined by the fvf,
- * not by the members set in D3DDrawPrimStrideData. So it's valid
- * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
- * not set in the fvf.
- */
- if(VertexType & D3DFVF_POSITION_MASK)
+ for (i = 0; i < count; i++)
{
- wined3d_strided.position.format = WINED3DFMT_R32G32B32_FLOAT;
- wined3d_strided.position.data = D3DDrawPrimStrideData->position.lpvData;
- wined3d_strided.position.stride = D3DDrawPrimStrideData->position.dwStride;
- if (VertexType & D3DFVF_XYZRHW)
+ /* The contents of the strided data are determined by the fvf,
+ * not by the members set in src. So it's valid
+ * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
+ * not set in the fvf. */
+ if (fvf & D3DFVF_POSITION_MASK)
{
- wined3d_strided.position.format = WINED3DFMT_R32G32B32A32_FLOAT;
- wined3d_strided.position_transformed = TRUE;
+ offset = i * src->position.dwStride;
+ if (fvf & D3DFVF_XYZRHW)
+ {
+ memcpy(dst, ((BYTE *)src->position.lpvData) + offset, 4 * sizeof(float));
+ dst += 4 * sizeof(float);
+ }
+ else
+ {
+ memcpy(dst, ((BYTE *)src->position.lpvData) + offset, 3 * sizeof(float));
+ dst += 3 * sizeof(float);
+ }
}
- else
+
+ if (fvf & D3DFVF_NORMAL)
{
- wined3d_strided.position_transformed = FALSE;
+ offset = i * src->normal.dwStride;
+ memcpy(dst, ((BYTE *)src->normal.lpvData) + offset, 3 * sizeof(float));
+ dst += 3 * sizeof(float);
}
- }
- if (VertexType & D3DFVF_NORMAL)
- {
- wined3d_strided.normal.format = WINED3DFMT_R32G32B32_FLOAT;
- wined3d_strided.normal.data = D3DDrawPrimStrideData->normal.lpvData;
- wined3d_strided.normal.stride = D3DDrawPrimStrideData->normal.dwStride;
- }
-
- if (VertexType & D3DFVF_DIFFUSE)
- {
- wined3d_strided.diffuse.format = WINED3DFMT_B8G8R8A8_UNORM;
- wined3d_strided.diffuse.data = D3DDrawPrimStrideData->diffuse.lpvData;
- wined3d_strided.diffuse.stride = D3DDrawPrimStrideData->diffuse.dwStride;
- }
+ if (fvf & D3DFVF_DIFFUSE)
+ {
+ offset = i * src->diffuse.dwStride;
+ memcpy(dst, ((BYTE *)src->diffuse.lpvData) + offset, sizeof(DWORD));
+ dst += sizeof(DWORD);
+ }
- if (VertexType & D3DFVF_SPECULAR)
- {
- wined3d_strided.specular.format = WINED3DFMT_B8G8R8A8_UNORM;
- wined3d_strided.specular.data = D3DDrawPrimStrideData->specular.lpvData;
- wined3d_strided.specular.stride = D3DDrawPrimStrideData->specular.dwStride;
- }
+ if (fvf & D3DFVF_SPECULAR)
+ {
+ offset = i * src->specular.dwStride;
+ memcpy(dst, ((BYTE *)src->specular.lpvData) + offset, sizeof(DWORD));
+ dst += sizeof(DWORD);
+ }
- for (i = 0; i < GET_TEXCOUNT_FROM_FVF(VertexType); ++i)
- {
- switch (GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i))
+ for (tex = 0; tex < GET_TEXCOUNT_FROM_FVF(fvf); ++tex)
{
- case 1: wined3d_strided.tex_coords[i].format = WINED3DFMT_R32_FLOAT; break;
- case 2: wined3d_strided.tex_coords[i].format = WINED3DFMT_R32G32_FLOAT; break;
- case 3: wined3d_strided.tex_coords[i].format = WINED3DFMT_R32G32B32_FLOAT; break;
- case 4: wined3d_strided.tex_coords[i].format = WINED3DFMT_R32G32B32A32_FLOAT; break;
- default: ERR("Unexpected texture coordinate size %d\n",
- GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i));
+ DWORD attrib_count = GET_TEXCOORD_SIZE_FROM_FVF(fvf, tex);
+ offset = i * src->textureCoords[tex].dwStride;
+ memcpy(dst, ((BYTE *)src->textureCoords[tex].lpvData) + offset, attrib_count * sizeof(float));
+ dst += attrib_count * sizeof(float);
}
- wined3d_strided.tex_coords[i].data = D3DDrawPrimStrideData->textureCoords[i].lpvData;
- wined3d_strided.tex_coords[i].stride = D3DDrawPrimStrideData->textureCoords[i].dwStride;
}
+}
+
+static HRESULT d3d_device7_DrawPrimitiveStrided(IDirect3DDevice7 *iface, D3DPRIMITIVETYPE PrimitiveType,
+ DWORD VertexType, D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData, DWORD VertexCount, DWORD Flags)
+{
+ struct d3d_device *device = impl_from_IDirect3DDevice7(iface);
+ HRESULT hr;
+ UINT dst_stride = get_flexible_vertex_size(VertexType);
+ UINT dst_size = dst_stride * VertexCount;
+ UINT vb_pos, align;
+ BYTE *dst_data;
+
+ TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, flags %#x.\n",
+ iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
- /* WineD3D doesn't need the FVF here */
wined3d_mutex_lock();
+ hr = d3d_device_prepare_vertex_buffer(device, dst_size);
+ if (FAILED(hr))
+ goto done;
+
+ vb_pos = device->vertex_buffer_pos;
+ align = vb_pos % dst_stride;
+ if (align) align = dst_stride - align;
+ if (vb_pos + dst_size + align > device->vertex_buffer_size)
+ vb_pos = 0;
+ else
+ vb_pos += align;
+
+ hr = wined3d_buffer_map(device->vertex_buffer, vb_pos, dst_size, &dst_data,
+ vb_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD);
+ if (FAILED(hr))
+ goto done;
+ pack_strided_data(dst_data, VertexCount, D3DDrawPrimStrideData, VertexType);
+ wined3d_buffer_unmap(device->vertex_buffer);
+ device->vertex_buffer_pos = vb_pos + dst_size;
+
+ hr = wined3d_device_set_stream_source(device->wined3d_device, 0, device->vertex_buffer, 0, dst_stride);
+ if (FAILED(hr))
+ goto done;
+ wined3d_device_set_vertex_declaration(device->wined3d_device, ddraw_find_decl(device->ddraw, VertexType));
+
wined3d_device_set_primitive_type(device->wined3d_device, PrimitiveType);
- hr = wined3d_device_draw_primitive_strided(device->wined3d_device, VertexCount, &wined3d_strided);
- wined3d_mutex_unlock();
+ hr = wined3d_device_draw_primitive(device->wined3d_device, vb_pos / dst_stride, VertexCount);
+done:
+ wined3d_mutex_unlock();
return hr;
}
More information about the wine-cvs
mailing list