[PATCH 1/5] d3dx9_36: Implement D3DXHANDLE more robustly

Travis Athougies iammisc at gmail.com
Tue Jul 5 16:45:00 CDT 2011


Fixes bug 26583.

Allows deadspace 2 to run without native dlls.

---
 dlls/d3dx9_36/shader.c |   79 +++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 69 insertions(+), 10 deletions(-)

diff --git a/dlls/d3dx9_36/shader.c b/dlls/d3dx9_36/shader.c
index bddef33..e3068c9 100644
--- a/dlls/d3dx9_36/shader.c
+++ b/dlls/d3dx9_36/shader.c
@@ -612,9 +612,17 @@ HRESULT WINAPI D3DXPreprocessShaderFromResourceW(HMODULE module,
 
 typedef struct ctab_constant {
     D3DXCONSTANT_DESC desc;
+    WORD handle;
+
+    DWORD member_count;
     struct ctab_constant *members;
 } ctab_constant;
 
+typedef struct ctab_handle {
+    char *full_name;
+    D3DXCONSTANT_DESC desc;
+} ctab_handle;
+
 static const struct ID3DXConstantTableVtbl ID3DXConstantTable_Vtbl;
 
 typedef struct ID3DXConstantTableImpl {
@@ -624,6 +632,9 @@ typedef struct ID3DXConstantTableImpl {
     DWORD size;
     D3DXCONSTANTTABLE_DESC desc;
     ctab_constant *constants;
+
+    WORD handle_count;
+    ctab_handle *handles;
 } ID3DXConstantTableImpl;
 
 static inline ID3DXConstantTableImpl *impl_from_ID3DXConstantTable(ID3DXConstantTable *iface)
@@ -666,6 +677,17 @@ static ULONG WINAPI ID3DXConstantTableImpl_AddRef(ID3DXConstantTable* iface)
     return InterlockedIncrement(&This->ref);
 }
 
+static void release_constants(ctab_constant *constants, UINT count)
+{
+    UINT i;
+
+    for (i = 0; i < count; i++)
+        if (constants[i].member_count > 0)
+            release_constants(constants[i].members, constants[i].member_count);
+
+    HeapFree(GetProcessHeap(), 0, constants);
+}
+
 static ULONG WINAPI ID3DXConstantTableImpl_Release(ID3DXConstantTable* iface)
 {
     ID3DXConstantTableImpl *This = impl_from_ID3DXConstantTable(iface);
@@ -675,6 +697,15 @@ static ULONG WINAPI ID3DXConstantTableImpl_Release(ID3DXConstantTable* iface)
 
     if (!ref)
     {
+        UINT i;
+        for (i = 0; i < This->handle_count; i++)
+        {
+            free(This->handles[i].full_name);
+            free((CHAR *)This->handles[i].desc.Name);
+        }
+
+        release_constants(This->constants, This->desc.Constants);
+
         HeapFree(GetProcessHeap(), 0, This->constants);
         HeapFree(GetProcessHeap(), 0, This->ctab);
         HeapFree(GetProcessHeap(), 0, This);
@@ -703,6 +734,28 @@ static DWORD WINAPI ID3DXConstantTableImpl_GetBufferSize(ID3DXConstantTable* ifa
 }
 
 /*** ID3DXConstantTable methods ***/
+static WORD new_handle_with_desc_and_name(ID3DXConstantTableImpl* This, D3DXCONSTANT_DESC* desc, LPCSTR name, LPCSTR full_name)
+{
+    ++This->handle_count;
+    if (This->handles)
+        This->handles = HeapReAlloc(GetProcessHeap(), 0, This->handles, sizeof(ctab_handle) * This->handle_count);
+    else
+        This->handles = HeapAlloc(GetProcessHeap(), 0, sizeof(ctab_handle) * This->handle_count);
+
+    This->handles[This->handle_count - 1].desc = *desc;
+    This->handles[This->handle_count - 1].desc.Name = strdup(name);
+    This->handles[This->handle_count - 1].full_name = strdup(full_name);
+
+    return This->handle_count;
+}
+
+static WORD new_handle(ID3DXConstantTableImpl* This, ctab_constant* constant)
+{
+    WORD handle = new_handle_with_desc_and_name(This, &constant->desc, constant->desc.Name, constant->desc.Name);
+    constant->handle = handle;
+    return handle;
+}
+
 static HRESULT WINAPI ID3DXConstantTableImpl_GetDesc(ID3DXConstantTable* iface, D3DXCONSTANTTABLE_DESC *desc)
 {
     ID3DXConstantTableImpl *This = impl_from_ID3DXConstantTable(iface);
@@ -721,7 +774,7 @@ static HRESULT WINAPI ID3DXConstantTableImpl_GetConstantDesc(ID3DXConstantTable*
                                                              D3DXCONSTANT_DESC *desc, UINT *count)
 {
     ID3DXConstantTableImpl *This = impl_from_ID3DXConstantTable(iface);
-    ctab_constant *constant_info;
+    D3DXCONSTANT_DESC *constant_info;
 
     TRACE("(%p)->(%p, %p, %p)\n", This, constant, desc, count);
 
@@ -730,18 +783,18 @@ static HRESULT WINAPI ID3DXConstantTableImpl_GetConstantDesc(ID3DXConstantTable*
 
     /* Applications can pass the name of the constant in place of the handle */
     if (!((UINT_PTR)constant >> 16))
-        constant_info = &This->constants[(UINT_PTR)constant - 1];
+        constant_info = &This->handles[(UINT_PTR)constant - 1].desc;
     else
     {
         D3DXHANDLE c = ID3DXConstantTable_GetConstantByName(iface, NULL, constant);
         if (!c)
             return D3DERR_INVALIDCALL;
 
-        constant_info = &This->constants[(UINT_PTR)c - 1];
+        constant_info = &This->handles[(UINT_PTR)c - 1].desc;
     }
 
     if (desc)
-        *desc = constant_info->desc;
+        *desc = *constant_info;
     if (count)
         *count = 1;
 
@@ -782,7 +835,10 @@ static D3DXHANDLE WINAPI ID3DXConstantTableImpl_GetConstant(ID3DXConstantTable*
     if (index >= This->desc.Constants)
         return NULL;
 
-    return (D3DXHANDLE)(DWORD_PTR)(index + 1);
+    if (!This->constants[index].handle)
+        return (D3DXHANDLE)(DWORD_PTR)new_handle(This, &This->constants[index]);
+    else
+        return (D3DXHANDLE)(DWORD_PTR)This->constants[index].handle;
 }
 
 static D3DXHANDLE WINAPI ID3DXConstantTableImpl_GetConstantByName(ID3DXConstantTable* iface, D3DXHANDLE constant, LPCSTR name)
@@ -801,9 +857,13 @@ static D3DXHANDLE WINAPI ID3DXConstantTableImpl_GetConstantByName(ID3DXConstantT
         return NULL;
     }
 
+    for (i = 0; i < This->handle_count; i++)
+        if (!strcmp(This->handles[i].full_name, name))
+            return (D3DXHANDLE)(DWORD_PTR)(i + 1);
+
     for (i = 0; i < This->desc.Constants; i++)
         if (!strcmp(This->constants[i].desc.Name, name))
-            return (D3DXHANDLE)(DWORD_PTR)(i + 1);
+            return (D3DXHANDLE)(DWORD_PTR)new_handle(This, &This->constants[i]);
 
     return NULL;
 }
@@ -1219,6 +1279,8 @@ HRESULT WINAPI D3DXGetShaderConstantTableEx(CONST DWORD* byte_code,
          hr = E_OUTOFMEMORY;
          goto error;
     }
+    object->handles = NULL;
+    object->handle_count = 0;
 
     constant_info = (LPD3DXSHADER_CONSTANTINFO)(object->ctab + ctab_header->ConstantInfo);
     for (i = 0; i < ctab_header->Constants; i++)
@@ -1257,10 +1319,7 @@ HRESULT WINAPI D3DXGetShaderConstantTableEx(CONST DWORD* byte_code,
     return D3D_OK;
 
 error:
-
-    HeapFree(GetProcessHeap(), 0, object->constants);
-    HeapFree(GetProcessHeap(), 0, object->ctab);
-    HeapFree(GetProcessHeap(), 0, object);
+    ID3DXConstantTableImpl_Release((ID3DXConstantTable *)object);
 
     return hr;
 }
-- 
1.6.4.4




More information about the wine-patches mailing list