[PATCH 3/6] wined3d: Cleanup vertex declaration initialization.

Henri Verbeet hverbeet at codeweavers.com
Sun Sep 20 13:09:24 CDT 2009


---
 dlls/wined3d/device.c            |   63 ++++++++++++-------------
 dlls/wined3d/vertexdeclaration.c |   96 +++++++++++++++++++-------------------
 dlls/wined3d/wined3d_private.h   |    6 +--
 3 files changed, 80 insertions(+), 85 deletions(-)

diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 368bcd2..91c12fb 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -1572,41 +1572,36 @@ static HRESULT  WINAPI  IWineD3DDeviceImpl_GetSwapChain(IWineD3DDevice *iface, U
     }
 }
 
-/*****
- * Vertex Declaration
- *****/
-static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexDeclaration(IWineD3DDevice* iface, IWineD3DVertexDeclaration** ppVertexDeclaration,
-        IUnknown *parent, const WINED3DVERTEXELEMENT *elements, UINT element_count) {
-    IWineD3DDeviceImpl            *This   = (IWineD3DDeviceImpl *)iface;
+static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexDeclaration(IWineD3DDevice *iface,
+        IWineD3DVertexDeclaration **declaration, IUnknown *parent,
+        const WINED3DVERTEXELEMENT *elements, UINT element_count)
+{
+    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     IWineD3DVertexDeclarationImpl *object = NULL;
-    HRESULT hr = WINED3D_OK;
+    HRESULT hr;
 
-    TRACE("(%p) : directXVersion %u, elements %p, element_count %d, ppDecl=%p\n",
-            This, ((IWineD3DImpl *)This->wineD3D)->dxVersion, elements, element_count, ppVertexDeclaration);
+    TRACE("iface %p, declaration %p, parent %p, elements %p, element_count %u.\n",
+            iface, declaration, parent, elements, element_count);
 
     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
     if(!object)
     {
-        ERR("Out of memory\n");
-        *ppVertexDeclaration = NULL;
-        return WINED3DERR_OUTOFVIDEOMEMORY;
+        ERR("Failed to allocate vertex declaration memory.\n");
+        return E_OUTOFMEMORY;
     }
 
-    object->lpVtbl = &IWineD3DVertexDeclaration_Vtbl;
-    object->wineD3DDevice = This;
-    object->parent = parent;
-    object->ref = 1;
-
-    *ppVertexDeclaration = (IWineD3DVertexDeclaration *)object;
-
-    hr = vertexdeclaration_init(object, elements, element_count);
-
-    if(FAILED(hr)) {
-        IWineD3DVertexDeclaration_Release((IWineD3DVertexDeclaration *)object);
-        *ppVertexDeclaration = NULL;
+    hr = vertexdeclaration_init(object, This, elements, element_count, parent);
+    if (FAILED(hr))
+    {
+        WARN("Failed to initialize vertex declaration, hr %#x.\n", hr);
+        HeapFree(GetProcessHeap(), 0, object);
+        return hr;
     }
 
-    return hr;
+    TRACE("Created verrtex declaration %p.\n", object);
+    *declaration = (IWineD3DVertexDeclaration *)object;
+
+    return WINED3D_OK;
 }
 
 static unsigned int ConvertFvfToDeclaration(IWineD3DDeviceImpl *This, /* For the GL info, which has the type table */
@@ -1746,20 +1741,22 @@ static unsigned int ConvertFvfToDeclaration(IWineD3DDeviceImpl *This, /* For the
     return size;
 }
 
-static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexDeclarationFromFVF(IWineD3DDevice* iface, IWineD3DVertexDeclaration** ppVertexDeclaration, IUnknown *Parent, DWORD Fvf) {
-    WINED3DVERTEXELEMENT* elements = NULL;
+static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexDeclarationFromFVF(IWineD3DDevice *iface,
+        IWineD3DVertexDeclaration **declaration, IUnknown *parent, DWORD fvf)
+{
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
+    WINED3DVERTEXELEMENT *elements;
     unsigned int size;
     DWORD hr;
 
-    size = ConvertFvfToDeclaration(This, Fvf, &elements);
-    if (size == ~0U) return WINED3DERR_OUTOFVIDEOMEMORY;
+    TRACE("iface %p, declaration %p, parent %p, fvf %#x.\n", iface, declaration, parent, fvf);
 
-    hr = IWineD3DDevice_CreateVertexDeclaration(iface, ppVertexDeclaration, Parent, elements, size);
-    HeapFree(GetProcessHeap(), 0, elements);
-    if (hr != S_OK) return hr;
+    size = ConvertFvfToDeclaration(This, fvf, &elements);
+    if (size == ~0U) return E_OUTOFMEMORY;
 
-    return WINED3D_OK;
+    hr = IWineD3DDevice_CreateVertexDeclaration(iface, declaration, parent, elements, size);
+    HeapFree(GetProcessHeap(), 0, elements);
+    return hr;
 }
 
 static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexShader(IWineD3DDevice *iface,
diff --git a/dlls/wined3d/vertexdeclaration.c b/dlls/wined3d/vertexdeclaration.c
index 2c2b763..e19aba5 100644
--- a/dlls/wined3d/vertexdeclaration.c
+++ b/dlls/wined3d/vertexdeclaration.c
@@ -190,39 +190,51 @@ static BOOL declaration_element_valid_ffp(const WINED3DVERTEXELEMENT *element)
     }
 }
 
-HRESULT vertexdeclaration_init(IWineD3DVertexDeclarationImpl *This,
-        const WINED3DVERTEXELEMENT *elements, UINT element_count)
+static const IWineD3DVertexDeclarationVtbl IWineD3DVertexDeclaration_Vtbl =
 {
-    HRESULT hr = WINED3D_OK;
-    unsigned int i;
-    char isPreLoaded[MAX_STREAMS];
+    /* IUnknown */
+    IWineD3DVertexDeclarationImpl_QueryInterface,
+    IWineD3DVertexDeclarationImpl_AddRef,
+    IWineD3DVertexDeclarationImpl_Release,
+    /* IWineD3DVertexDeclaration */
+    IWineD3DVertexDeclarationImpl_GetParent,
+    IWineD3DVertexDeclarationImpl_GetDevice,
+};
 
-    TRACE("(%p) : d3d version %d\n", This, ((IWineD3DImpl *)This->wineD3DDevice->wineD3D)->dxVersion);
-    memset(isPreLoaded, 0, sizeof(isPreLoaded));
+HRESULT vertexdeclaration_init(IWineD3DVertexDeclarationImpl *declaration, IWineD3DDeviceImpl *device,
+        const WINED3DVERTEXELEMENT *elements, UINT element_count, IUnknown *parent)
+{
+    const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+    WORD preloaded = 0; /* MAX_STREAMS, 16 */
+    unsigned int i;
 
-    if (TRACE_ON(d3d_decl)) {
-        for (i = 0; i < element_count; ++i) {
-            dump_wined3dvertexelement(elements+i);
+    if (TRACE_ON(d3d_decl))
+    {
+        for (i = 0; i < element_count; ++i)
+        {
+            dump_wined3dvertexelement(elements + i);
         }
     }
 
-    This->element_count = element_count;
-    This->elements = HeapAlloc(GetProcessHeap(), 0, sizeof(*This->elements) * element_count);
-    if (!This->elements)
+    declaration->lpVtbl = &IWineD3DVertexDeclaration_Vtbl;
+    declaration->ref = 1;
+    declaration->parent = parent;
+    declaration->wineD3DDevice = device;
+    declaration->elements = HeapAlloc(GetProcessHeap(), 0, sizeof(*declaration->elements) * element_count);
+    if (!declaration->elements)
     {
-        ERR("Memory allocation failed\n");
-        return WINED3DERR_OUTOFVIDEOMEMORY;
+        ERR("Failed to allocate elements memory.\n");
+        return E_OUTOFMEMORY;
     }
+    declaration->element_count = element_count;
 
-    /* Do some static analysis on the elements to make reading the declaration more comfortable
-     * for the drawing code
-     */
-    This->num_streams = 0;
-    This->position_transformed = FALSE;
-    for (i = 0; i < element_count; ++i) {
-        struct wined3d_vertex_declaration_element *e = &This->elements[i];
+    /* Do some static analysis on the elements to make reading the
+     * declaration more comfortable for the drawing code. */
+    for (i = 0; i < element_count; ++i)
+    {
+        struct wined3d_vertex_declaration_element *e = &declaration->elements[i];
 
-        e->format_desc = getFormatDescEntry(elements[i].format, &This->wineD3DDevice->adapter->gl_info);
+        e->format_desc = getFormatDescEntry(elements[i].format, gl_info);
         e->ffp_valid = declaration_element_valid_ffp(&elements[i]);
         e->input_slot = elements[i].input_slot;
         e->offset = elements[i].offset;
@@ -231,51 +243,39 @@ HRESULT vertexdeclaration_init(IWineD3DVertexDeclarationImpl *This,
         e->usage = elements[i].usage;
         e->usage_idx = elements[i].usage_idx;
 
-        if (e->usage == WINED3DDECLUSAGE_POSITIONT) This->position_transformed = TRUE;
+        if (e->usage == WINED3DDECLUSAGE_POSITIONT) declaration->position_transformed = TRUE;
 
-        /* Find the Streams used in the declaration. The vertex buffers have to be loaded
-         * when drawing, but filter tesselation pseudo streams
-         */
+        /* Find the streams used in the declaration. The vertex buffers have
+         * to be loaded when drawing, but filter tesselation pseudo streams. */
         if (e->input_slot >= MAX_STREAMS) continue;
 
         if (!e->format_desc->gl_vtx_format)
         {
-            FIXME("The application tries to use an unsupported format (%s), returning E_FAIL\n",
+            FIXME("The application tries to use an unsupported format (%s), returning E_FAIL.\n",
                     debug_d3dformat(elements[i].format));
-            /* The caller will release the vdecl, which will free This->elements */
+            HeapFree(GetProcessHeap(), 0, declaration->elements);
             return E_FAIL;
         }
 
         if (e->offset & 0x3)
         {
-            WARN("Declaration element %u is not 4 byte aligned(%u), returning E_FAIL\n", i, e->offset);
+            WARN("Declaration element %u is not 4 byte aligned(%u), returning E_FAIL.\n", i, e->offset);
+            HeapFree(GetProcessHeap(), 0, declaration->elements);
             return E_FAIL;
         }
 
-        if (!isPreLoaded[e->input_slot])
+        if (!(preloaded & (1 << e->input_slot)))
         {
-            This->streams[This->num_streams] = e->input_slot;
-            This->num_streams++;
-            isPreLoaded[e->input_slot] = 1;
+            declaration->streams[declaration->num_streams] = e->input_slot;
+            ++declaration->num_streams;
+            preloaded |= 1 << e->input_slot;
         }
 
         if (elements[i].format == WINED3DFMT_R16G16_FLOAT || elements[i].format == WINED3DFMT_R16G16B16A16_FLOAT)
         {
-            if (!GL_SUPPORT(ARB_HALF_FLOAT_VERTEX)) This->half_float_conv_needed = TRUE;
+            if (!gl_info->supported[ARB_HALF_FLOAT_VERTEX]) declaration->half_float_conv_needed = TRUE;
         }
     }
 
-    TRACE("Returning\n");
-    return hr;
+    return WINED3D_OK;
 }
-
-const IWineD3DVertexDeclarationVtbl IWineD3DVertexDeclaration_Vtbl =
-{
-    /* IUnknown */
-    IWineD3DVertexDeclarationImpl_QueryInterface,
-    IWineD3DVertexDeclarationImpl_AddRef,
-    IWineD3DVertexDeclarationImpl_Release,
-    /* IWineD3DVertexDeclaration */
-    IWineD3DVertexDeclarationImpl_GetParent,
-    IWineD3DVertexDeclarationImpl_GetDevice,
-};
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 0f0ad4a..f06ab72 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2198,10 +2198,8 @@ typedef struct IWineD3DVertexDeclarationImpl {
     BOOL                    half_float_conv_needed;
 } IWineD3DVertexDeclarationImpl;
 
-extern const IWineD3DVertexDeclarationVtbl IWineD3DVertexDeclaration_Vtbl DECLSPEC_HIDDEN;
-
-HRESULT vertexdeclaration_init(IWineD3DVertexDeclarationImpl *This,
-        const WINED3DVERTEXELEMENT *elements, UINT element_count) DECLSPEC_HIDDEN;
+HRESULT vertexdeclaration_init(IWineD3DVertexDeclarationImpl *This, IWineD3DDeviceImpl *device,
+        const WINED3DVERTEXELEMENT *elements, UINT element_count, IUnknown *parent) DECLSPEC_HIDDEN;
 
 /*****************************************************************************
  * IWineD3DStateBlock implementation structure
-- 
1.6.0.6




More information about the wine-patches mailing list