Commit bd2a787d authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

d3dx9: Create parameter evaluator for texture shaders.

parent a0ed7434
...@@ -396,6 +396,8 @@ struct d3dx_parameters_store ...@@ -396,6 +396,8 @@ struct d3dx_parameters_store
unsigned int full_name_tmp_size; 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 *get_parameter_by_name(struct d3dx_parameters_store *store,
struct d3dx_parameter *parameter, const char *name) DECLSPEC_HIDDEN; struct d3dx_parameter *parameter, const char *name) DECLSPEC_HIDDEN;
......
...@@ -745,6 +745,40 @@ static void free_parameter_block(struct d3dx_parameter_block *block) ...@@ -745,6 +745,40 @@ static void free_parameter_block(struct d3dx_parameter_block *block)
heap_free(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) static void d3dx_effect_cleanup(struct d3dx_effect *effect)
{ {
struct d3dx_parameter_block *block, *cursor; struct d3dx_parameter_block *block, *cursor;
...@@ -760,14 +794,7 @@ static void d3dx_effect_cleanup(struct d3dx_effect *effect) ...@@ -760,14 +794,7 @@ static void d3dx_effect_cleanup(struct d3dx_effect *effect)
free_parameter_block(block); free_parameter_block(block);
} }
heap_free(effect->params.full_name_tmp); d3dx_parameters_store_cleanup(&effect->params);
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);
}
if (effect->techniques) if (effect->techniques)
{ {
...@@ -5371,14 +5398,6 @@ static void param_set_magic_number(struct d3dx_parameter *param) ...@@ -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)); 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, static void add_param_to_tree(struct d3dx_effect *effect, struct d3dx_parameter *param,
struct d3dx_parameter *parent, char separator, unsigned int element) 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 ...@@ -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, 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) 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; const char *ptr = data + start;
unsigned int i; unsigned int i;
HRESULT hr; HRESULT hr;
effect->params.count = read_u32(&ptr); params_count = read_u32(&ptr);
TRACE("Parameter count: %u.\n", effect->params.count); TRACE("Parameter count: %u.\n", params_count);
effect->technique_count = read_u32(&ptr); effect->technique_count = read_u32(&ptr);
TRACE("Technique count: %u.\n", effect->technique_count); TRACE("Technique count: %u.\n", effect->technique_count);
...@@ -6326,29 +6345,23 @@ static HRESULT d3dx_parse_effect(struct d3dx_effect *effect, const char *data, U ...@@ -6326,29 +6345,23 @@ static HRESULT d3dx_parse_effect(struct d3dx_effect *effect, const char *data, U
goto err_out; goto err_out;
} }
wine_rb_init(&effect->params.tree, param_rb_compare); if (FAILED(hr = d3dx_init_parameters_store(&effect->params, params_count)))
if (effect->params.count)
{ {
effect->params.parameters = heap_alloc_zero(sizeof(*effect->params.parameters) * effect->params.count); hr = E_OUTOFMEMORY;
if (!effect->params.parameters) goto err_out;
{ }
ERR("Out of memory.\n");
hr = E_OUTOFMEMORY;
goto err_out;
}
for (i = 0; i < effect->params.count; ++i) for (i = 0; i < effect->params.count; ++i)
{
param_set_magic_number(&effect->params.parameters[i].param);
hr = d3dx_parse_effect_parameter(effect, &effect->params.parameters[i], data, &ptr, effect->objects);
if (hr != D3D_OK)
{ {
param_set_magic_number(&effect->params.parameters[i].param); WARN("Failed to parse parameter %u.\n", i);
hr = d3dx_parse_effect_parameter(effect, &effect->params.parameters[i], data, &ptr, effect->objects); goto err_out;
if (hr != D3D_OK)
{
WARN("Failed to parse parameter %u.\n", i);
goto err_out;
}
walk_parameter_tree(&effect->params.parameters[i].param, param_set_top_level_param, &effect->params.parameters[i]);
add_param_to_tree(effect, &effect->params.parameters[i].param, NULL, 0, 0);
} }
walk_parameter_tree(&effect->params.parameters[i].param, param_set_top_level_param, &effect->params.parameters[i]);
add_param_to_tree(effect, &effect->params.parameters[i].param, NULL, 0, 0);
} }
if (effect->technique_count) if (effect->technique_count)
...@@ -6427,15 +6440,7 @@ err_out: ...@@ -6427,15 +6440,7 @@ err_out:
effect->techniques = NULL; effect->techniques = NULL;
} }
if (effect->params.parameters) d3dx_parameters_store_cleanup(&effect->params);
{
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;
}
if (effect->objects) if (effect->objects)
{ {
......
...@@ -2361,6 +2361,9 @@ struct d3dx9_texture_shader ...@@ -2361,6 +2361,9 @@ struct d3dx9_texture_shader
LONG ref; LONG ref;
ID3DXBuffer *byte_code; 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) static inline struct d3dx9_texture_shader *impl_from_ID3DXTextureShader(ID3DXTextureShader *iface)
...@@ -2406,6 +2409,8 @@ static ULONG WINAPI d3dx9_texture_shader_Release(ID3DXTextureShader *iface) ...@@ -2406,6 +2409,8 @@ static ULONG WINAPI d3dx9_texture_shader_Release(ID3DXTextureShader *iface)
{ {
if (texture_shader->byte_code) if (texture_shader->byte_code)
ID3DXBuffer_Release(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); HeapFree(GetProcessHeap(), 0, texture_shader);
} }
...@@ -2637,6 +2642,19 @@ HRESULT WINAPI D3DXCreateTextureShader(const DWORD *function, ID3DXTextureShader ...@@ -2637,6 +2642,19 @@ HRESULT WINAPI D3DXCreateTextureShader(const DWORD *function, ID3DXTextureShader
} }
memcpy(ID3DXBuffer_GetBufferPointer(object->byte_code), function, size); 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; *texture_shader = &object->ID3DXTextureShader_iface;
return D3D_OK; return D3D_OK;
......
...@@ -2471,21 +2471,20 @@ float4 main(float3 pos : POSITION, float3 size : PSIZE) : COLOR ...@@ -2471,21 +2471,20 @@ float4 main(float3 pos : POSITION, float3 size : PSIZE) : COLOR
hr = tx->lpVtbl->GetConstantBuffer(tx, &buffer); hr = tx->lpVtbl->GetConstantBuffer(tx, &buffer);
todo_wine todo_wine
ok(SUCCEEDED(hr), "Failed to get texture shader constant buffer.\n"); 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); if (SUCCEEDED(hr))
ok(!size, "Unexpected buffer size %lu.\n", size); {
size = ID3DXBuffer_GetBufferSize(buffer);
ok(!size, "Unexpected buffer size %lu.\n", size);
ID3DXBuffer_Release(buffer); ID3DXBuffer_Release(buffer);
}
hr = tx->lpVtbl->GetDesc(tx, &ctab_desc); hr = tx->lpVtbl->GetDesc(tx, &ctab_desc);
todo_wine
ok(hr == S_OK, "Failed to get constant description, hr %#lx.\n", hr); ok(hr == S_OK, "Failed to get constant description, hr %#lx.\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. */ /* Constant table access calls, without constant table. */
h = tx->lpVtbl->GetConstant(tx, NULL, 0); h = tx->lpVtbl->GetConstant(tx, NULL, 0);
...@@ -2528,6 +2527,7 @@ float4 main(float3 pos : POSITION, float3 size : PSIZE) : COLOR ...@@ -2528,6 +2527,7 @@ float4 main(float3 pos : POSITION, float3 size : PSIZE) : COLOR
ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr); ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
hr = D3DXFillTextureTX(texture, tx); hr = D3DXFillTextureTX(texture, tx);
todo_wine
ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr); ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, D3DLOCK_READONLY); hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, D3DLOCK_READONLY);
...@@ -2541,6 +2541,7 @@ float4 main(float3 pos : POSITION, float3 size : PSIZE) : COLOR ...@@ -2541,6 +2541,7 @@ float4 main(float3 pos : POSITION, float3 size : PSIZE) : COLOR
/* The third position coordinate is apparently undefined for 2D textures. */ /* The third position coordinate is apparently undefined for 2D textures. */
unsigned int color = data[y * lr.Pitch / sizeof(*data) + x] & 0xffffff00; 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); 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 ...@@ -2560,6 +2561,7 @@ float4 main(float3 pos : POSITION, float3 size : PSIZE) : COLOR
ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr); ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
hr = D3DXFillCubeTextureTX(cube_texture, tx); hr = D3DXFillCubeTextureTX(cube_texture, tx);
todo_wine
ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr); ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
for (z = 0; z < 6; ++z) for (z = 0; z < 6; ++z)
...@@ -2599,6 +2601,7 @@ float4 main(float3 pos : POSITION, float3 size : PSIZE) : COLOR ...@@ -2599,6 +2601,7 @@ float4 main(float3 pos : POSITION, float3 size : PSIZE) : COLOR
component = -component; component = -component;
expected |= max(component, 0) << i * 8; expected |= max(component, 0) << i * 8;
} }
todo_wine
ok(compare_color(color, expected, 1), "Unexpected color %08x at (%u, %u, %u).\n", ok(compare_color(color, expected, 1), "Unexpected color %08x at (%u, %u, %u).\n",
color, x, y, z); color, x, y, z);
} }
...@@ -2619,6 +2622,7 @@ float4 main(float3 pos : POSITION, float3 size : PSIZE) : COLOR ...@@ -2619,6 +2622,7 @@ float4 main(float3 pos : POSITION, float3 size : PSIZE) : COLOR
ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr); ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
hr = D3DXFillVolumeTextureTX(volume_texture, tx); hr = D3DXFillVolumeTextureTX(volume_texture, tx);
todo_wine
ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr); ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
hr = IDirect3DVolumeTexture9_LockBox(volume_texture, 0, &lb, NULL, D3DLOCK_READONLY); hr = IDirect3DVolumeTexture9_LockBox(volume_texture, 0, &lb, NULL, D3DLOCK_READONLY);
...@@ -2633,6 +2637,7 @@ float4 main(float3 pos : POSITION, float3 size : PSIZE) : COLOR ...@@ -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 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]; 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", ok(compare_color(color, expected, 1), "Unexpected color %08x at (%u, %u, %u).\n",
color, x, y, z); color, x, y, z);
} }
...@@ -2646,8 +2651,12 @@ float4 main(float3 pos : POSITION, float3 size : PSIZE) : COLOR ...@@ -2646,8 +2651,12 @@ float4 main(float3 pos : POSITION, float3 size : PSIZE) : COLOR
IUnknown_Release(tx); IUnknown_Release(tx);
/* With constant table */ /* With constant table */
tx = NULL;
hr = D3DXCreateTextureShader(shader_code2, &tx); hr = D3DXCreateTextureShader(shader_code2, &tx);
todo_wine
ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr); ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
if (FAILED(hr))
goto cleanup;
hr = tx->lpVtbl->GetConstantBuffer(tx, &buffer); hr = tx->lpVtbl->GetConstantBuffer(tx, &buffer);
todo_wine todo_wine
...@@ -2768,7 +2777,8 @@ float4 main(float3 pos : POSITION, float3 size : PSIZE) : COLOR ...@@ -2768,7 +2777,8 @@ float4 main(float3 pos : POSITION, float3 size : PSIZE) : COLOR
IDirect3DDevice9_Release(device); IDirect3DDevice9_Release(device);
IDirect3D9_Release(d3d); IDirect3D9_Release(d3d);
DestroyWindow(wnd); DestroyWindow(wnd);
IUnknown_Release(tx); if (tx)
IUnknown_Release(tx);
} }
START_TEST(texture) START_TEST(texture)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment