From: Rico Schüller Date: Tue, 12 Apr 2011 19:25:06 +0000 (+0200) Subject: d3dx9: Parse effect pass and technique. X-Git-Tag: wine-1.3.18~64 X-Git-Url: http://git.etersoft.ru/projects/?a=commitdiff_plain;h=8ec21524ec0b2cb7f194838c37306bd0bce556c3;p=wine%2Feterwine.git d3dx9: Parse effect pass and technique. --- diff --git a/dlls/d3dx9_36/effect.c b/dlls/d3dx9_36/effect.c index ba02c56af2..66b5a40ec2 100644 --- a/dlls/d3dx9_36/effect.c +++ b/dlls/d3dx9_36/effect.c @@ -51,6 +51,29 @@ struct d3dx_parameter D3DXHANDLE *member_handles; }; +struct d3dx_pass +{ + struct ID3DXBaseEffectImpl *base; + + char *name; + UINT state_count; + UINT annotation_count; + + D3DXHANDLE *annotation_handles; +}; + +struct d3dx_technique +{ + struct ID3DXBaseEffectImpl *base; + + char *name; + UINT pass_count; + UINT annotation_count; + + D3DXHANDLE *annotation_handles; + D3DXHANDLE *pass_handles; +}; + struct ID3DXBaseEffectImpl { ID3DXBaseEffect ID3DXBaseEffect_iface; @@ -62,6 +85,7 @@ struct ID3DXBaseEffectImpl UINT technique_count; D3DXHANDLE *parameter_handles; + D3DXHANDLE *technique_handles; }; struct ID3DXEffectImpl @@ -107,11 +131,31 @@ static inline struct d3dx_parameter *get_parameter_struct(D3DXHANDLE handle) return (struct d3dx_parameter *) handle; } +static inline struct d3dx_pass *get_pass_struct(D3DXHANDLE handle) +{ + return (struct d3dx_pass *) handle; +} + +static inline struct d3dx_technique *get_technique_struct(D3DXHANDLE handle) +{ + return (struct d3dx_technique *) handle; +} + static inline D3DXHANDLE get_parameter_handle(struct d3dx_parameter *parameter) { return (D3DXHANDLE) parameter; } +static inline D3DXHANDLE get_technique_handle(struct d3dx_technique *technique) +{ + return (D3DXHANDLE) technique; +} + +static inline D3DXHANDLE get_pass_handle(struct d3dx_pass *pass) +{ + return (D3DXHANDLE) pass; +} + static void free_parameter(D3DXHANDLE handle, BOOL element, BOOL child) { unsigned int i; @@ -162,6 +206,65 @@ static void free_parameter(D3DXHANDLE handle, BOOL element, BOOL child) HeapFree(GetProcessHeap(), 0, param); } +static void free_pass(D3DXHANDLE handle) +{ + unsigned int i; + struct d3dx_pass *pass = get_pass_struct(handle); + + TRACE("Free pass %p\n", pass); + + if (!pass) + { + return; + } + + if (pass->annotation_handles) + { + for (i = 0; i < pass->annotation_count; ++i) + { + free_parameter(pass->annotation_handles[i], FALSE, FALSE); + } + HeapFree(GetProcessHeap(), 0, pass->annotation_handles); + } + + HeapFree(GetProcessHeap(), 0, pass->name); + HeapFree(GetProcessHeap(), 0, pass); +} + +static void free_technique(D3DXHANDLE handle) +{ + unsigned int i; + struct d3dx_technique *technique = get_technique_struct(handle); + + TRACE("Free technique %p\n", technique); + + if (!technique) + { + return; + } + + if (technique->annotation_handles) + { + for (i = 0; i < technique->annotation_count; ++i) + { + free_parameter(technique->annotation_handles[i], FALSE, FALSE); + } + HeapFree(GetProcessHeap(), 0, technique->annotation_handles); + } + + if (technique->pass_handles) + { + for (i = 0; i < technique->pass_count; ++i) + { + free_pass(technique->pass_handles[i]); + } + HeapFree(GetProcessHeap(), 0, technique->pass_handles); + } + + HeapFree(GetProcessHeap(), 0, technique->name); + HeapFree(GetProcessHeap(), 0, technique); +} + static void free_base_effect(struct ID3DXBaseEffectImpl *base) { unsigned int i; @@ -176,6 +279,15 @@ static void free_base_effect(struct ID3DXBaseEffectImpl *base) } HeapFree(GetProcessHeap(), 0, base->parameter_handles); } + + if (base->technique_handles) + { + for (i = 0; i < base->technique_count; ++i) + { + free_technique(base->technique_handles[i]); + } + HeapFree(GetProcessHeap(), 0, base->technique_handles); + } } static void free_effect(struct ID3DXEffectImpl *effect) @@ -2842,10 +2954,220 @@ err_out: return hr; } +static HRESULT d3dx9_parse_effect_pass(struct d3dx_pass *pass, const char *data, const char **ptr) +{ + DWORD offset; + HRESULT hr; + unsigned int i; + D3DXHANDLE *annotation_handles = NULL; + char *name = NULL; + + read_dword(ptr, &offset); + TRACE("Pass name offset: %#x\n", offset); + hr = d3dx9_parse_name(&name, data + offset); + if (hr != D3D_OK) + { + WARN("Failed to parse name\n"); + goto err_out; + } + + read_dword(ptr, &pass->annotation_count); + TRACE("Annotation count: %u\n", pass->annotation_count); + + read_dword(ptr, &pass->state_count); + TRACE("State count: %u\n", pass->state_count); + + if (pass->annotation_count) + { + annotation_handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*annotation_handles) * pass->annotation_count); + if (!annotation_handles) + { + ERR("Out of memory\n"); + hr = E_OUTOFMEMORY; + goto err_out; + } + + for (i = 0; i < pass->annotation_count; ++i) + { + struct d3dx_parameter *annotation; + + annotation = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*annotation)); + if (!annotation) + { + ERR("Out of memory\n"); + hr = E_OUTOFMEMORY; + goto err_out; + } + + annotation_handles[i] = get_parameter_handle(annotation); + annotation->base = pass->base; + + hr = d3dx9_parse_effect_annotation(annotation, data, ptr); + if (hr != D3D_OK) + { + WARN("Failed to parse annotations\n"); + goto err_out; + } + } + } + + if (pass->state_count) + { + for (i = 0; i < pass->state_count; ++i) + { + skip_dword_unknown(ptr, 4); + } + } + + pass->name = name; + pass->annotation_handles = annotation_handles; + + return D3D_OK; + +err_out: + + if (annotation_handles) + { + for (i = 0; i < pass->annotation_count; ++i) + { + free_parameter(annotation_handles[i], FALSE, FALSE); + } + HeapFree(GetProcessHeap(), 0, annotation_handles); + } + + HeapFree(GetProcessHeap(), 0, name); + + return hr; +} + +static HRESULT d3dx9_parse_effect_technique(struct d3dx_technique *technique, const char *data, const char **ptr) +{ + DWORD offset; + HRESULT hr; + unsigned int i; + D3DXHANDLE *annotation_handles = NULL; + D3DXHANDLE *pass_handles = NULL; + char *name = NULL; + + read_dword(ptr, &offset); + TRACE("Technique name offset: %#x\n", offset); + hr = d3dx9_parse_name(&name, data + offset); + if (hr != D3D_OK) + { + WARN("Failed to parse name\n"); + goto err_out; + } + + read_dword(ptr, &technique->annotation_count); + TRACE("Annotation count: %u\n", technique->annotation_count); + + read_dword(ptr, &technique->pass_count); + TRACE("Pass count: %u\n", technique->pass_count); + + if (technique->annotation_count) + { + annotation_handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*annotation_handles) * technique->annotation_count); + if (!annotation_handles) + { + ERR("Out of memory\n"); + hr = E_OUTOFMEMORY; + goto err_out; + } + + for (i = 0; i < technique->annotation_count; ++i) + { + struct d3dx_parameter *annotation; + + annotation = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*annotation)); + if (!annotation) + { + ERR("Out of memory\n"); + hr = E_OUTOFMEMORY; + goto err_out; + } + + annotation_handles[i] = get_parameter_handle(annotation); + annotation->base = technique->base; + + hr = d3dx9_parse_effect_annotation(annotation, data, ptr); + if (hr != D3D_OK) + { + WARN("Failed to parse annotations\n"); + goto err_out; + } + } + } + + if (technique->pass_count) + { + pass_handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pass_handles) * technique->pass_count); + if (!pass_handles) + { + ERR("Out of memory\n"); + hr = E_OUTOFMEMORY; + goto err_out; + } + + for (i = 0; i < technique->pass_count; ++i) + { + struct d3dx_pass *pass; + + pass = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pass)); + if (!pass) + { + ERR("Out of memory\n"); + hr = E_OUTOFMEMORY; + goto err_out; + } + + pass_handles[i] = get_pass_handle(pass); + pass->base = technique->base; + + hr = d3dx9_parse_effect_pass(pass, data, ptr); + if (hr != D3D_OK) + { + WARN("Failed to parse passes\n"); + goto err_out; + } + } + } + + technique->name = name; + technique->pass_handles = pass_handles; + technique->annotation_handles = annotation_handles; + + return D3D_OK; + +err_out: + + if (pass_handles) + { + for (i = 0; i < technique->pass_count; ++i) + { + free_pass(pass_handles[i]); + } + HeapFree(GetProcessHeap(), 0, pass_handles); + } + + if (annotation_handles) + { + for (i = 0; i < technique->annotation_count; ++i) + { + free_parameter(annotation_handles[i], FALSE, FALSE); + } + HeapFree(GetProcessHeap(), 0, annotation_handles); + } + + HeapFree(GetProcessHeap(), 0, name); + + return hr; +} + static HRESULT d3dx9_parse_effect(struct ID3DXBaseEffectImpl *base, const char *data, UINT data_size, DWORD start) { const char *ptr = data + start; D3DXHANDLE *parameter_handles = NULL; + D3DXHANDLE *technique_handles = NULL; HRESULT hr; unsigned int i; @@ -2891,14 +3213,56 @@ static HRESULT d3dx9_parse_effect(struct ID3DXBaseEffectImpl *base, const char * } } - /* todo: Parse techniques */ + if (base->technique_count) + { + technique_handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*technique_handles) * base->technique_count); + if (!technique_handles) + { + ERR("Out of memory\n"); + hr = E_OUTOFMEMORY; + goto err_out; + } + + for (i = 0; i < base->technique_count; ++i) + { + struct d3dx_technique *technique; + technique = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*technique)); + if (!technique) + { + ERR("Out of memory\n"); + hr = E_OUTOFMEMORY; + goto err_out; + } + + technique_handles[i] = get_technique_handle(technique); + technique->base = base; + + hr = d3dx9_parse_effect_technique(technique, data, &ptr); + if (hr != D3D_OK) + { + WARN("Failed to parse technique\n"); + goto err_out; + } + } + } + + base->technique_handles = technique_handles; base->parameter_handles = parameter_handles; return D3D_OK; err_out: + if (technique_handles) + { + for (i = 0; i < base->technique_count; ++i) + { + free_technique(technique_handles[i]); + } + HeapFree(GetProcessHeap(), 0, technique_handles); + } + if (parameter_handles) { for (i = 0; i < base->parameter_count; ++i)