[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