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
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;
......
......@@ -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,29 +6345,23 @@ 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;
}
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);
hr = d3dx_parse_effect_parameter(effect, &effect->params.parameters[i], data, &ptr, effect->objects);
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);
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);
}
if (effect->technique_count)
......@@ -6427,15 +6440,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)
{
......
......@@ -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;
......
......@@ -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 %lu.\n", size);
if (SUCCEEDED(hr))
{
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);
todo_wine
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. */
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 %#lx.\n", hr);
hr = D3DXFillTextureTX(texture, tx);
todo_wine
ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\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 %#lx.\n", hr);
hr = D3DXFillCubeTextureTX(cube_texture, tx);
todo_wine
ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\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 %#lx.\n", hr);
hr = D3DXFillVolumeTextureTX(volume_texture, tx);
todo_wine
ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\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 %#lx.\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)
......
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