diff --git a/dlls/d3dx9_36/Makefile.in b/dlls/d3dx9_36/Makefile.in index 95e30457e1c..83f7d1c61b7 100644 --- a/dlls/d3dx9_36/Makefile.in +++ b/dlls/d3dx9_36/Makefile.in @@ -11,6 +11,7 @@ C_SRCS = \ line.c \ math.c \ mesh.c \ + preshader.c \ render.c \ shader.c \ skin.c \ diff --git a/dlls/d3dx9_36/d3dx9_private.h b/dlls/d3dx9_36/d3dx9_private.h index bc9581d9950..5ba93ac2bdf 100644 --- a/dlls/d3dx9_36/d3dx9_private.h +++ b/dlls/d3dx9_36/d3dx9_private.h @@ -108,4 +108,40 @@ const char *debug_d3dxparameter_registerset(D3DXREGISTER_SET r) DECLSPEC_HIDDEN; void set_number(void *outdata, D3DXPARAMETER_TYPE outtype, const void *indata, D3DXPARAMETER_TYPE intype) DECLSPEC_HIDDEN; +struct d3dx_param_eval; + +struct d3dx_parameter +{ + char *name; + char *semantic; + void *data; + D3DXPARAMETER_CLASS class; + D3DXPARAMETER_TYPE type; + UINT rows; + UINT columns; + UINT element_count; + UINT annotation_count; + UINT member_count; + DWORD flags; + UINT bytes; + DWORD object_id; + + D3DXHANDLE handle; + + struct d3dx_parameter *annotations; + struct d3dx_parameter *members; + + struct d3dx_parameter *referenced_param; + struct d3dx_param_eval *param_eval; +}; + +struct d3dx9_base_effect; + +struct d3dx_parameter *get_parameter_by_name(struct d3dx9_base_effect *base, + struct d3dx_parameter *parameter, const char *name) DECLSPEC_HIDDEN; + +HRESULT d3dx_create_param_eval(struct d3dx9_base_effect *base_effect, void *byte_code, + unsigned int byte_code_size, D3DXPARAMETER_TYPE type, struct d3dx_param_eval **peval) DECLSPEC_HIDDEN; +void d3dx_free_param_eval(struct d3dx_param_eval *peval) DECLSPEC_HIDDEN; + #endif /* __WINE_D3DX9_PRIVATE_H */ diff --git a/dlls/d3dx9_36/effect.c b/dlls/d3dx9_36/effect.c index a210bb3c910..76a012d3c2d 100644 --- a/dlls/d3dx9_36/effect.c +++ b/dlls/d3dx9_36/effect.c @@ -94,30 +94,6 @@ enum STATE_TYPE ST_ARRAY_SELECTOR, }; -struct d3dx_parameter -{ - char *name; - char *semantic; - void *data; - D3DXPARAMETER_CLASS class; - D3DXPARAMETER_TYPE type; - UINT rows; - UINT columns; - UINT element_count; - UINT annotation_count; - UINT member_count; - DWORD flags; - UINT bytes; - DWORD object_id; - - D3DXHANDLE handle; - - struct d3dx_parameter *annotations; - struct d3dx_parameter *members; - - struct d3dx_parameter *referenced_param; -}; - struct d3dx_object { UINT size; @@ -206,8 +182,6 @@ struct ID3DXEffectCompilerImpl struct d3dx9_base_effect base_effect; }; -static struct d3dx_parameter *get_parameter_by_name(struct d3dx9_base_effect *base, - struct d3dx_parameter *parameter, const char *name); static struct d3dx_parameter *get_annotation_by_name(UINT count, struct d3dx_parameter *parameters, const char *name); static HRESULT d3dx9_parse_state(struct d3dx9_base_effect *base, struct d3dx_state *state, @@ -535,6 +509,12 @@ static void free_parameter(struct d3dx_parameter *param, BOOL element, BOOL chil TRACE("Free parameter %p, name %s, type %s, child %s\n", param, param->name, debug_d3dxparameter_type(param->type), child ? "yes" : "no"); + if (param->param_eval) + { + d3dx_free_param_eval(param->param_eval); + param->param_eval = NULL; + } + if (param->annotations) { for (i = 0; i < param->annotation_count; ++i) @@ -886,7 +866,7 @@ static struct d3dx_parameter *get_annotation_by_name(UINT count, struct d3dx_par return NULL; } -static struct d3dx_parameter *get_parameter_by_name(struct d3dx9_base_effect *base, +struct d3dx_parameter *get_parameter_by_name(struct d3dx9_base_effect *base, struct d3dx_parameter *parameter, const char *name) { UINT i, count, length; @@ -5419,6 +5399,7 @@ static HRESULT d3dx9_parse_array_selector(struct d3dx9_base_effect *base, struct DWORD string_size; struct d3dx_object *object = &base->objects[param->object_id]; char *ptr = object->data; + HRESULT ret; TRACE("Parsing array entry selection state for parameter %p.\n", param); @@ -5435,9 +5416,32 @@ static HRESULT d3dx9_parse_array_selector(struct d3dx9_base_effect *base, struct } TRACE("Unknown DWORD: 0x%.8x.\n", *(DWORD *)(ptr + string_size)); - FIXME("Parse preshader.\n"); + if (string_size % sizeof(DWORD)) + FIXME("Unaligned string_size %u.\n", string_size); + d3dx_create_param_eval(base, (DWORD *)(ptr + string_size) + 1, object->size - (string_size + sizeof(DWORD)), + D3DXPT_INT, ¶m->param_eval); + ret = D3D_OK; + param = param->referenced_param; + if (param->type == D3DXPT_VERTEXSHADER || param->type == D3DXPT_PIXELSHADER) + { + unsigned int i; - return D3D_OK; + for (i = 0; i < param->element_count; i++) + { + if (param->members[i].type != param->type) + { + FIXME("Unexpected member parameter type %u, expected %u.\n", param->members[i].type, param->type); + return D3DXERR_INVALIDDATA; + } + if (!param->members[i].param_eval) + { + TRACE("Creating preshader for object %u.\n", param->members[i].object_id); + object = &base->objects[param->members[i].object_id]; + d3dx_create_param_eval(base, object->data, object->size, param->type, ¶m->members[i].param_eval); + } + } + } + return ret; } static HRESULT d3dx9_parse_resource(struct d3dx9_base_effect *base, const char *data, const char **ptr) @@ -5543,7 +5547,11 @@ static HRESULT d3dx9_parse_resource(struct d3dx9_base_effect *base, const char * return hr; if (object->data) - hr = d3dx9_create_object(base, object); + { + if (FAILED(hr = d3dx9_create_object(base, object))) + return hr; + d3dx_create_param_eval(base, object->data, object->size, param->type, ¶m->param_eval); + } break; case D3DXPT_BOOL: @@ -5551,7 +5559,9 @@ static HRESULT d3dx9_parse_resource(struct d3dx9_base_effect *base, const char * case D3DXPT_FLOAT: case D3DXPT_STRING: state->type = ST_FXLC; - hr = d3dx9_copy_data(&base->objects[param->object_id], ptr); + if (FAILED(hr = d3dx9_copy_data(&base->objects[param->object_id], ptr))) + return hr; + d3dx_create_param_eval(base, object->data, object->size, param->type, ¶m->param_eval); break; default: @@ -5569,7 +5579,17 @@ static HRESULT d3dx9_parse_resource(struct d3dx9_base_effect *base, const char * param->referenced_param = get_parameter_by_name(base, NULL, object->data); if (param->referenced_param) { - TRACE("Mapping to parameter %p.\n", param->referenced_param); + struct d3dx_parameter *refpar = param->referenced_param; + + TRACE("Mapping to parameter %p, having object id %u.\n", refpar, refpar->object_id); + if (refpar->type == D3DXPT_VERTEXSHADER || refpar->type == D3DXPT_PIXELSHADER) + { + struct d3dx_object *refobj = &base->objects[refpar->object_id]; + + if (!refpar->param_eval) + d3dx_create_param_eval(base, refobj->data, refobj->size, + refpar->type, &refpar->param_eval); + } } else { diff --git a/dlls/d3dx9_36/preshader.c b/dlls/d3dx9_36/preshader.c new file mode 100644 index 00000000000..d865fd0f1c6 --- /dev/null +++ b/dlls/d3dx9_36/preshader.c @@ -0,0 +1,41 @@ +/* + * Copyright 2016 Paul Gofman + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "wine/port.h" + +#include "d3dx9_private.h" + +#include + +WINE_DEFAULT_DEBUG_CHANNEL(d3dx); + +HRESULT d3dx_create_param_eval(struct d3dx9_base_effect *base_effect, void *byte_code, unsigned int byte_code_size, + D3DXPARAMETER_TYPE type, struct d3dx_param_eval **peval_out) +{ + FIXME("stub, base_effect %p, byte_code %p, byte_code_size %u, type %u, peval_out %p.\n", + base_effect, byte_code, byte_code_size, type, peval_out); + + *peval_out = NULL; + return E_NOTIMPL; +} + +void d3dx_free_param_eval(struct d3dx_param_eval *peval) +{ + FIXME("stub, peval %p.\n", peval); +}