Rico Schüller : d3dx9: Parse resources in the effect parser.
Alexandre Julliard
julliard at winehq.org
Tue Jun 14 11:57:49 CDT 2011
Module: wine
Branch: master
Commit: 86d381a56babf2ad5c4b9a18496bdf759a253138
URL: http://source.winehq.org/git/wine.git/?a=commit;h=86d381a56babf2ad5c4b9a18496bdf759a253138
Author: Rico Schüller <kgbricola at web.de>
Date: Tue Jun 14 11:20:43 2011 +0200
d3dx9: Parse resources in the effect parser.
---
dlls/d3dx9_36/effect.c | 169 ++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 158 insertions(+), 11 deletions(-)
diff --git a/dlls/d3dx9_36/effect.c b/dlls/d3dx9_36/effect.c
index ca88f76..271594c 100644
--- a/dlls/d3dx9_36/effect.c
+++ b/dlls/d3dx9_36/effect.c
@@ -85,6 +85,11 @@ enum SHADER_CONSTANT_TYPE
SCT_PSINT,
};
+enum STATE_TYPE
+{
+ ST_CONSTANT,
+};
+
struct d3dx_parameter
{
char *name;
@@ -108,7 +113,7 @@ struct d3dx_state
{
UINT operation;
UINT index;
-
+ enum STATE_TYPE type;
D3DXHANDLE parameter;
};
@@ -176,7 +181,7 @@ static struct d3dx_parameter *get_parameter_by_name(struct ID3DXBaseEffectImpl *
struct d3dx_parameter *parameter, LPCSTR name);
static struct d3dx_parameter *get_parameter_annotation_by_name(struct d3dx_parameter *parameter, LPCSTR name);
static HRESULT d3dx9_parse_state(struct d3dx_state *state, const char *data, const char **ptr, D3DXHANDLE *objects);
-static void free_parameter(D3DXHANDLE handle, BOOL element, BOOL child);
+static void free_parameter_state(D3DXHANDLE handle, BOOL element, BOOL child, enum STATE_TYPE st);
static const struct
{
@@ -552,7 +557,7 @@ static struct d3dx_parameter *is_valid_parameter(struct ID3DXBaseEffectImpl *bas
static void free_state(struct d3dx_state *state)
{
- free_parameter(state->parameter, FALSE, FALSE);
+ free_parameter_state(state->parameter, FALSE, FALSE, state->type);
}
static void free_sampler(struct d3dx_sampler *sampler)
@@ -568,10 +573,16 @@ static void free_sampler(struct d3dx_sampler *sampler)
static void free_parameter(D3DXHANDLE handle, BOOL element, BOOL child)
{
+ free_parameter_state(handle, element, child, ST_CONSTANT);
+}
+
+static void free_parameter_state(D3DXHANDLE handle, BOOL element, BOOL child, enum STATE_TYPE st)
+{
unsigned int i;
struct d3dx_parameter *param = get_parameter_struct(handle);
- TRACE("Free parameter %p, name %s, child %s\n", param, param->name, child ? "yes" : "no");
+ TRACE("Free parameter %p, name %s, type %s, child %s, state_type %x\n", param, param->name,
+ debug_d3dxparameter_type(param->type), child ? "yes" : "no", st);
if (!param)
{
@@ -617,7 +628,14 @@ static void free_parameter(D3DXHANDLE handle, BOOL element, BOOL child)
case D3DXPT_TEXTURECUBE:
case D3DXPT_PIXELSHADER:
case D3DXPT_VERTEXSHADER:
- if (*(IUnknown **)param->data) IUnknown_Release(*(IUnknown **)param->data);
+ if (st == ST_CONSTANT)
+ {
+ if (*(IUnknown **)param->data) IUnknown_Release(*(IUnknown **)param->data);
+ }
+ else
+ {
+ HeapFree(GetProcessHeap(), 0, *(LPSTR *)param->data);
+ }
if (!child) HeapFree(GetProcessHeap(), 0, param->data);
break;
@@ -626,7 +644,14 @@ static void free_parameter(D3DXHANDLE handle, BOOL element, BOOL child)
case D3DXPT_SAMPLER2D:
case D3DXPT_SAMPLER3D:
case D3DXPT_SAMPLERCUBE:
- free_sampler((struct d3dx_sampler *)param->data);
+ if (st == ST_CONSTANT)
+ {
+ free_sampler((struct d3dx_sampler *)param->data);
+ }
+ else
+ {
+ HeapFree(GetProcessHeap(), 0, *(LPSTR *)param->data);
+ }
/* samplers have always own data, so free that */
HeapFree(GetProcessHeap(), 0, param->data);
break;
@@ -640,6 +665,10 @@ static void free_parameter(D3DXHANDLE handle, BOOL element, BOOL child)
{
if (!child)
{
+ if (st != ST_CONSTANT)
+ {
+ HeapFree(GetProcessHeap(), 0, *(LPSTR *)param->data);
+ }
HeapFree(GetProcessHeap(), 0, param->data);
}
}
@@ -4263,6 +4292,8 @@ static HRESULT d3dx9_parse_state(struct d3dx_state *state, const char *data, con
return E_OUTOFMEMORY;
}
+ state->type = ST_CONSTANT;
+
read_dword(ptr, &state->operation);
TRACE("Operation: %#x (%s)\n", state->operation, state_table[state->operation].name);
@@ -4615,13 +4646,112 @@ err_out:
return hr;
}
+static HRESULT d3dx9_parse_resource(struct ID3DXBaseEffectImpl *base, const char *data, const char **ptr)
+{
+ DWORD technique_index;
+ DWORD index, state_index, usage;
+ struct d3dx_state *state;
+ struct d3dx_parameter *param;
+ HRESULT hr;
+
+ read_dword(ptr, &technique_index);
+ TRACE("techn: %u\n", technique_index);
+
+ read_dword(ptr, &index);
+ TRACE("index: %u\n", index);
+
+ skip_dword_unknown(ptr, 1);
+
+ read_dword(ptr, &state_index);
+ TRACE("state: %u\n", state_index);
+
+ read_dword(ptr, &usage);
+ TRACE("usage: %u\n", usage);
+
+ if (technique_index == 0xffffffff)
+ {
+ struct d3dx_parameter *parameter;
+ struct d3dx_sampler *sampler;
+
+ if (index >= base->parameter_count)
+ {
+ FIXME("Index out of bounds: index %u >= parameter_count %u\n", index, base->parameter_count);
+ return E_FAIL;
+ }
+
+ parameter = get_parameter_struct(base->parameter_handles[index]);
+ sampler = parameter->data;
+ if (state_index >= sampler->state_count)
+ {
+ FIXME("Index out of bounds: state_index %u >= state_count %u\n", state_index, sampler->state_count);
+ return E_FAIL;
+ }
+
+ state = &sampler->states[state_index];
+ }
+ else
+ {
+ struct d3dx_technique *technique;
+ struct d3dx_pass *pass;
+
+ if (technique_index >= base->technique_count)
+ {
+ FIXME("Index out of bounds: technique_index %u >= technique_count %u\n", technique_index, base->technique_count);
+ return E_FAIL;
+ }
+
+ technique = get_technique_struct(base->technique_handles[technique_index]);
+ if (index >= technique->pass_count)
+ {
+ FIXME("Index out of bounds: index %u >= pass_count %u\n", index, technique->pass_count);
+ return E_FAIL;
+ }
+
+ pass = get_pass_struct(technique->pass_handles[index]);
+ if (state_index >= pass->state_count)
+ {
+ FIXME("Index out of bounds: state_index %u >= state_count %u\n", state_index, pass->state_count);
+ return E_FAIL;
+ }
+
+ state = &pass->states[state_index];
+ }
+
+ param = get_parameter_struct(state->parameter);
+
+ switch (usage)
+ {
+ case 0:
+ TRACE("usage 0: type %s\n", debug_d3dxparameter_type(param->type));
+ switch (param->type)
+ {
+ case D3DXPT_VERTEXSHADER:
+ case D3DXPT_PIXELSHADER:
+ state->type = ST_CONSTANT;
+ hr = d3dx9_parse_data(param, ptr, base->effect->device);
+ break;
+
+ default:
+ FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
+ break;
+ }
+ break;
+
+ default:
+ FIXME("Unknown usage %x\n", usage);
+ break;
+ }
+
+ 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;
D3DXHANDLE *objects = NULL;
- UINT stringcount, objectcount;
+ UINT stringcount, objectcount, resourcecount;
HRESULT hr;
UINT i;
@@ -4710,10 +4840,15 @@ static HRESULT d3dx9_parse_effect(struct ID3DXBaseEffectImpl *base, const char *
}
}
+ /* needed for further parsing */
+ base->technique_handles = technique_handles;
+ base->parameter_handles = parameter_handles;
+
read_dword(&ptr, &stringcount);
TRACE("String count: %u\n", stringcount);
- skip_dword_unknown(&ptr, 1);
+ read_dword(&ptr, &resourcecount);
+ TRACE("Resource count: %u\n", resourcecount);
for (i = 0; i < stringcount; ++i)
{
@@ -4733,10 +4868,19 @@ static HRESULT d3dx9_parse_effect(struct ID3DXBaseEffectImpl *base, const char *
}
}
- HeapFree(GetProcessHeap(), 0, objects);
+ for (i = 0; i < resourcecount; ++i)
+ {
+ TRACE("parse resource %u\n", i);
- base->technique_handles = technique_handles;
- base->parameter_handles = parameter_handles;
+ hr = d3dx9_parse_resource(base, data, &ptr);
+ if (hr != D3D_OK)
+ {
+ WARN("Failed to parse data\n");
+ goto err_out;
+ }
+ }
+
+ HeapFree(GetProcessHeap(), 0, objects);
return D3D_OK;
@@ -4760,6 +4904,9 @@ err_out:
HeapFree(GetProcessHeap(), 0, parameter_handles);
}
+ base->technique_handles = NULL;
+ base->parameter_handles = NULL;
+
HeapFree(GetProcessHeap(), 0, objects);
return hr;
More information about the wine-cvs
mailing list