=?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