From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d3dx9_36/d3dx9_private.h | 2 + dlls/d3dx9_36/effect.c | 82 +++++++++++++++++++---------------- dlls/d3dx9_36/shader.c | 18 ++++++++ dlls/d3dx9_36/tests/texture.c | 32 +++++++++----- 4 files changed, 86 insertions(+), 48 deletions(-)
diff --git a/dlls/d3dx9_36/d3dx9_private.h b/dlls/d3dx9_36/d3dx9_private.h index d22415b1f69..ce5abfcc735 100644 --- a/dlls/d3dx9_36/d3dx9_private.h +++ b/dlls/d3dx9_36/d3dx9_private.h @@ -396,6 +396,8 @@ struct d3dx_parameters_store unsigned int full_name_tmp_size; };
+HRESULT d3dx_init_parameters_store(struct d3dx_parameters_store *store, unsigned int count) DECLSPEC_HIDDEN; +void d3dx_parameters_store_cleanup(struct d3dx_parameters_store *store) DECLSPEC_HIDDEN; struct d3dx_parameter *get_parameter_by_name(struct d3dx_parameters_store *store, struct d3dx_parameter *parameter, const char *name) DECLSPEC_HIDDEN;
diff --git a/dlls/d3dx9_36/effect.c b/dlls/d3dx9_36/effect.c index c5e1f6ed348..d1946812cfb 100644 --- a/dlls/d3dx9_36/effect.c +++ b/dlls/d3dx9_36/effect.c @@ -745,6 +745,40 @@ static void free_parameter_block(struct d3dx_parameter_block *block) heap_free(block); }
+static int param_rb_compare(const void *key, const struct wine_rb_entry *entry) +{ + const char *name = key; + struct d3dx_parameter *param = WINE_RB_ENTRY_VALUE(entry, struct d3dx_parameter, rb_entry); + + return strcmp(name, param->full_name); +} + +HRESULT d3dx_init_parameters_store(struct d3dx_parameters_store *store, unsigned int count) +{ + store->count = count; + wine_rb_init(&store->tree, param_rb_compare); + + if (store->count && !(store->parameters = heap_alloc_zero(sizeof(*store->parameters) * store->count))) + return E_OUTOFMEMORY; + + return S_OK; +} + +void d3dx_parameters_store_cleanup(struct d3dx_parameters_store *store) +{ + unsigned int i; + + heap_free(store->full_name_tmp); + + if (store->parameters) + { + for (i = 0; i < store->count; ++i) + free_top_level_parameter(&store->parameters[i]); + heap_free(store->parameters); + store->parameters = NULL; + } +} + static void d3dx_effect_cleanup(struct d3dx_effect *effect) { struct d3dx_parameter_block *block, *cursor; @@ -760,14 +794,7 @@ static void d3dx_effect_cleanup(struct d3dx_effect *effect) free_parameter_block(block); }
- heap_free(effect->params.full_name_tmp); - - if (effect->params.parameters) - { - for (i = 0; i < effect->params.count; ++i) - free_top_level_parameter(&effect->params.parameters[i]); - heap_free(effect->params.parameters); - } + d3dx_parameters_store_cleanup(&effect->params);
if (effect->techniques) { @@ -5371,14 +5398,6 @@ static void param_set_magic_number(struct d3dx_parameter *param) memcpy(param->magic_string, parameter_magic_string, sizeof(parameter_magic_string)); }
-static int param_rb_compare(const void *key, const struct wine_rb_entry *entry) -{ - const char *name = key; - struct d3dx_parameter *param = WINE_RB_ENTRY_VALUE(entry, struct d3dx_parameter, rb_entry); - - return strcmp(name, param->full_name); -} - static void add_param_to_tree(struct d3dx_effect *effect, struct d3dx_parameter *param, struct d3dx_parameter *parent, char separator, unsigned int element) { @@ -6301,13 +6320,13 @@ static BOOL param_set_top_level_param(void *top_level_param, struct d3dx_paramet static HRESULT d3dx_parse_effect(struct d3dx_effect *effect, const char *data, UINT data_size, uint32_t start, const char **skip_constants, unsigned int skip_constants_count) { - unsigned int string_count, resource_count; + unsigned int string_count, resource_count, params_count; const char *ptr = data + start; unsigned int i; HRESULT hr;
- effect->params.count = read_u32(&ptr); - TRACE("Parameter count: %u.\n", effect->params.count); + params_count = read_u32(&ptr); + TRACE("Parameter count: %u.\n", params_count);
effect->technique_count = read_u32(&ptr); TRACE("Technique count: %u.\n", effect->technique_count); @@ -6326,17 +6345,14 @@ static HRESULT d3dx_parse_effect(struct d3dx_effect *effect, const char *data, U goto err_out; }
- wine_rb_init(&effect->params.tree, param_rb_compare); - if (effect->params.count) + if (FAILED(hr = d3dx_init_parameters_store(&effect->params, params_count))) { - effect->params.parameters = heap_alloc_zero(sizeof(*effect->params.parameters) * effect->params.count); - if (!effect->params.parameters) - { - ERR("Out of memory.\n"); - hr = E_OUTOFMEMORY; - goto err_out; - } + hr = E_OUTOFMEMORY; + goto err_out; + }
+ if (effect->params.count) + { for (i = 0; i < effect->params.count; ++i) { param_set_magic_number(&effect->params.parameters[i].param); @@ -6427,15 +6443,7 @@ err_out: effect->techniques = NULL; }
- if (effect->params.parameters) - { - for (i = 0; i < effect->params.count; ++i) - { - free_top_level_parameter(&effect->params.parameters[i]); - } - heap_free(effect->params.parameters); - effect->params.parameters = NULL; - } + d3dx_parameters_store_cleanup(&effect->params);
if (effect->objects) { diff --git a/dlls/d3dx9_36/shader.c b/dlls/d3dx9_36/shader.c index 3663eacf6da..a776a1d9a94 100644 --- a/dlls/d3dx9_36/shader.c +++ b/dlls/d3dx9_36/shader.c @@ -2361,6 +2361,9 @@ struct d3dx9_texture_shader LONG ref;
ID3DXBuffer *byte_code; + ULONG64 version_counter; + struct d3dx_parameters_store parameters; + struct d3dx_param_eval *eval; };
static inline struct d3dx9_texture_shader *impl_from_ID3DXTextureShader(ID3DXTextureShader *iface) @@ -2406,6 +2409,8 @@ static ULONG WINAPI d3dx9_texture_shader_Release(ID3DXTextureShader *iface) { if (texture_shader->byte_code) ID3DXBuffer_Release(texture_shader->byte_code); + d3dx_free_param_eval(texture_shader->eval); + d3dx_parameters_store_cleanup(&texture_shader->parameters); HeapFree(GetProcessHeap(), 0, texture_shader); }
@@ -2637,6 +2642,19 @@ HRESULT WINAPI D3DXCreateTextureShader(const DWORD *function, ID3DXTextureShader } memcpy(ID3DXBuffer_GetBufferPointer(object->byte_code), function, size);
+ if (FAILED(hr = d3dx_init_parameters_store(&object->parameters, 0))) + { + IUnknown_Release(&object->ID3DXTextureShader_iface); + return hr; + } + + if (FAILED(hr = d3dx_create_param_eval(&object->parameters, ID3DXBuffer_GetBufferPointer(object->byte_code), + size, D3DXPT_FLOAT, &object->eval, &object->version_counter, NULL, 0))) + { + IUnknown_Release(&object->ID3DXTextureShader_iface); + return hr; + } + *texture_shader = &object->ID3DXTextureShader_iface;
return D3D_OK; diff --git a/dlls/d3dx9_36/tests/texture.c b/dlls/d3dx9_36/tests/texture.c index e8a57fc609e..2fb05d57856 100644 --- a/dlls/d3dx9_36/tests/texture.c +++ b/dlls/d3dx9_36/tests/texture.c @@ -2471,21 +2471,20 @@ float4 main(float3 pos : POSITION, float3 size : PSIZE) : COLOR hr = tx->lpVtbl->GetConstantBuffer(tx, &buffer); todo_wine ok(SUCCEEDED(hr), "Failed to get texture shader constant buffer.\n"); - if (FAILED(hr)) - { - skip("Texture shaders not supported, skipping further tests.\n"); - IUnknown_Release(tx); - return; - }
- size = ID3DXBuffer_GetBufferSize(buffer); - ok(!size, "Unexpected buffer size %u.\n", size); + if (SUCCEEDED(hr)) + { + size = ID3DXBuffer_GetBufferSize(buffer); + ok(!size, "Unexpected buffer size %u.\n", size);
- ID3DXBuffer_Release(buffer); + ID3DXBuffer_Release(buffer); + }
hr = tx->lpVtbl->GetDesc(tx, &ctab_desc); + todo_wine ok(hr == S_OK, "Failed to get constant description, hr %#x.\n", hr); - ok(!ctab_desc.Constants, "Unexpected number of constants %u.\n", ctab_desc.Constants); + if (SUCCEEDED(hr)) + ok(!ctab_desc.Constants, "Unexpected number of constants %u.\n", ctab_desc.Constants);
/* Constant table access calls, without constant table. */ h = tx->lpVtbl->GetConstant(tx, NULL, 0); @@ -2528,6 +2527,7 @@ float4 main(float3 pos : POSITION, float3 size : PSIZE) : COLOR ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
hr = D3DXFillTextureTX(texture, tx); + todo_wine ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, D3DLOCK_READONLY); @@ -2541,6 +2541,7 @@ float4 main(float3 pos : POSITION, float3 size : PSIZE) : COLOR /* The third position coordinate is apparently undefined for 2D textures. */ unsigned int color = data[y * lr.Pitch / sizeof(*data) + x] & 0xffffff00;
+ todo_wine ok(compare_color(color, expected, 1), "Unexpected color %08x at (%u, %u).\n", color, x, y); } } @@ -2560,6 +2561,7 @@ float4 main(float3 pos : POSITION, float3 size : PSIZE) : COLOR ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
hr = D3DXFillCubeTextureTX(cube_texture, tx); + todo_wine ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
for (z = 0; z < 6; ++z) @@ -2599,6 +2601,7 @@ float4 main(float3 pos : POSITION, float3 size : PSIZE) : COLOR component = -component; expected |= max(component, 0) << i * 8; } + todo_wine ok(compare_color(color, expected, 1), "Unexpected color %08x at (%u, %u, %u).\n", color, x, y, z); } @@ -2619,6 +2622,7 @@ float4 main(float3 pos : POSITION, float3 size : PSIZE) : COLOR ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
hr = D3DXFillVolumeTextureTX(volume_texture, tx); + todo_wine ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
hr = IDirect3DVolumeTexture9_LockBox(volume_texture, 0, &lb, NULL, D3DLOCK_READONLY); @@ -2633,6 +2637,7 @@ float4 main(float3 pos : POSITION, float3 size : PSIZE) : COLOR unsigned int expected = 0xff000000 | ((x * 4 + 2) << 16) | ((y * 4 + 2) << 8) | (z * 4 + 2); unsigned int color = data[z * lb.SlicePitch / sizeof(*data) + y * lb.RowPitch / sizeof(*data) + x];
+ todo_wine ok(compare_color(color, expected, 1), "Unexpected color %08x at (%u, %u, %u).\n", color, x, y, z); } @@ -2646,8 +2651,12 @@ float4 main(float3 pos : POSITION, float3 size : PSIZE) : COLOR IUnknown_Release(tx);
/* With constant table */ + tx = NULL; hr = D3DXCreateTextureShader(shader_code2, &tx); + todo_wine ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr); + if (FAILED(hr)) + goto cleanup;
hr = tx->lpVtbl->GetConstantBuffer(tx, &buffer); todo_wine @@ -2768,7 +2777,8 @@ float4 main(float3 pos : POSITION, float3 size : PSIZE) : COLOR IDirect3DDevice9_Release(device); IDirect3D9_Release(d3d); DestroyWindow(wnd); - IUnknown_Release(tx); + if (tx) + IUnknown_Release(tx); }
START_TEST(texture)