From 6839d8cba3a8cb94297c6819a069d2014dca54b3 Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Tue, 26 Oct 2021 23:25:14 +0200 Subject: [PATCH] d3d10/effect: Implement default values handling. Signed-off-by: Nikolay Sivov Signed-off-by: Matteo Bruni Signed-off-by: Alexandre Julliard --- dlls/d3d10/effect.c | 76 +++++++++++++++++++++++++++++++++++++-- dlls/d3d10/tests/effect.c | 30 ++-------------- 2 files changed, 76 insertions(+), 30 deletions(-) diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c index e3ca46772dc..b4a2f448ad0 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c @@ -2076,6 +2076,65 @@ static HRESULT parse_fx10_technique(const char *data, size_t data_size, return S_OK; } +static void parse_fx10_set_default_numeric_value(const char **ptr, struct d3d10_effect_variable *v) +{ + float *dst = (float *)(v->buffer->u.buffer.local_buffer + v->buffer_offset), *src; + BOOL col_major = v->type->type_class == D3D10_SVC_MATRIX_COLUMNS; + unsigned int col_count = v->type->column_count, col; + unsigned int row_count = v->type->row_count, row; + + src = (float *)*ptr; + + if (col_major) + { + for (col = 0; col < col_count; ++col) + { + for (row = 0; row < row_count; ++row) + dst[row] = src[row * col_count + col]; + dst += 4; + } + } + else + { + for (row = 0; row < row_count; ++row) + { + memcpy(dst, src, col_count * sizeof(float)); + src += col_count; + dst += 4; + } + } + + *ptr += col_count * row_count * sizeof(float); +} + +static void parse_fx10_default_value(const char **ptr, struct d3d10_effect_variable *var) +{ + unsigned int element_count = max(var->type->element_count, 1), i, m; + struct d3d10_effect_variable *v; + + for (i = 0; i < element_count; ++i) + { + v = d3d10_array_get_element(var, i); + + switch (v->type->type_class) + { + case D3D10_SVC_STRUCT: + for (m = 0; m < v->type->member_count; ++m) + parse_fx10_default_value(ptr, &v->members[m]); + break; + case D3D10_SVC_SCALAR: + case D3D10_SVC_VECTOR: + case D3D10_SVC_MATRIX_COLUMNS: + case D3D10_SVC_MATRIX_ROWS: + parse_fx10_set_default_numeric_value(ptr, v); + break; + default: + FIXME("Unexpected initial value for type %#x.\n", v->type->basetype); + return; + } + } +} + static void d3d10_effect_variable_update_buffer_offsets(struct d3d10_effect_variable *v, unsigned int offset) { @@ -2093,8 +2152,8 @@ static void d3d10_effect_variable_update_buffer_offsets(struct d3d10_effect_vari static HRESULT parse_fx10_numeric_variable(const char *data, size_t data_size, const char **ptr, BOOL local, struct d3d10_effect_variable *v) { - DWORD offset, flags, default_value_offset; - uint32_t buffer_offset; + uint32_t offset, flags, default_value_offset, buffer_offset; + const char *data_ptr; HRESULT hr; if (FAILED(hr = parse_fx10_variable_head(data, data_size, ptr, v))) @@ -2114,6 +2173,7 @@ static HRESULT parse_fx10_numeric_variable(const char *data, size_t data_size, TRACE("Variable offset in buffer: %#x.\n", buffer_offset); read_dword(ptr, &default_value_offset); + TRACE("Variable default value offset: %#x.\n", default_value_offset); read_dword(ptr, &flags); TRACE("Variable flags: %#x.\n", flags); @@ -2127,7 +2187,17 @@ static HRESULT parse_fx10_numeric_variable(const char *data, size_t data_size, if (local) { if (default_value_offset) - FIXME("Set default variable value.\n"); + { + if (!require_space(default_value_offset, 1, v->type->size_packed, data_size)) + { + WARN("Invalid default value offset %#x, variable packed size %u.\n", default_value_offset, + v->type->size_packed); + return E_FAIL; + } + + data_ptr = data + default_value_offset; + parse_fx10_default_value(&data_ptr, v); + } read_dword(ptr, &v->annotations.count); TRACE("Variable has %u annotations.\n", v->annotations.count); diff --git a/dlls/d3d10/tests/effect.c b/dlls/d3d10/tests/effect.c index 4d853c64baa..ae4db49f283 100644 --- a/dlls/d3d10/tests/effect.c +++ b/dlls/d3d10/tests/effect.c @@ -7404,7 +7404,6 @@ static void test_effect_default_variable_value(void) vector = v->lpVtbl->AsVector(v); hr = vector->lpVtbl->GetFloatVector(vector, float_v); ok(hr == S_OK, "Unexpected hr %#x.\n", hr); -todo_wine ok(float_v[0] == 1.0f && float_v[1] == 2.0f && float_v[2] == 3.0f && float_v[3] == 4.0f, "Unexpected vector {%.8e,%.8e,%.8e,%.8e}\n", float_v[0], float_v[1], float_v[2], float_v[3]); @@ -7414,7 +7413,6 @@ todo_wine vector = v->lpVtbl->AsVector(v); hr = vector->lpVtbl->GetFloatVector(vector, float_v); ok(hr == S_OK, "Unexpected hr %#x.\n", hr); -todo_wine ok(float_v[0] == 1.0f && float_v[1] == 2.0f && float_v[2] == 5.0f && float_v[3] == 5.0f, "Unexpected vector {%.8e,%.8e,%.8e,%.8e}\n", float_v[0], float_v[1], float_v[2], float_v[3]); @@ -7424,7 +7422,6 @@ todo_wine vector = v->lpVtbl->AsVector(v); hr = vector->lpVtbl->GetFloatVector(vector, float_v); ok(hr == S_OK, "Unexpected hr %#x.\n", hr); -todo_wine ok(float_v[0] == 1.0f && float_v[1] == 5.0f && float_v[2] == 5.0f && float_v[3] == 5.0f, "Unexpected vector {%.8e,%.8e,%.8e,%.8e}\n", float_v[0], float_v[1], float_v[2], float_v[3]); @@ -7433,7 +7430,6 @@ todo_wine scalar = v->lpVtbl->AsScalar(v); hr = scalar->lpVtbl->GetInt(scalar, &int_s); ok(hr == S_OK, "Unexpected hr %#x.\n", hr); -todo_wine ok(int_s == 10, "Unexpected value %d.\n", int_s); memset(int_v, 0, sizeof(int_v)); @@ -7441,7 +7437,6 @@ todo_wine scalar = v->lpVtbl->AsScalar(v); hr = scalar->lpVtbl->GetIntArray(scalar, int_v, 0, 2); ok(hr == S_OK, "Unexpected hr %#x.\n", hr); -todo_wine ok(int_v[0] == 9 && int_v[1] == 12, "Unexpected vector {%d,%d}\n", int_v[0], int_v[1]); hr = v->lpVtbl->GetDesc(v, &var_desc); ok(hr == S_OK, "Unexpected hr %#x.\n", hr); @@ -7460,7 +7455,6 @@ todo_wine scalar = v->lpVtbl->AsScalar(v); hr = scalar->lpVtbl->GetFloat(scalar, &float_s); ok(hr == S_OK, "Unexpected hr %#x.\n", hr); -todo_wine ok(float_s == 0.2f, "Unexpected value %.8e.\n", float_s); /* Matrix */ @@ -7472,10 +7466,7 @@ todo_wine ok(hr == S_OK, "Unexpected hr %#x.\n", hr); set_test_matrix(&m_set, D3D10_SVT_INT, 2, 3, 1); -todo_wine -{ compare_matrix("m1", __LINE__, &m_set, &m_ret, 2, 3, FALSE); -} v = effect->lpVtbl->GetVariableByName(effect, "m2"); matrix = v->lpVtbl->AsMatrix(v); @@ -7485,10 +7476,8 @@ todo_wine ok(hr == S_OK, "Unexpected hr %#x.\n", hr); set_test_matrix(&m_set, D3D10_SVT_INT, 2, 3, 1); -todo_wine -{ compare_matrix("m2", __LINE__, &m_set, &m_ret, 2, 3, FALSE); -} + v = effect->lpVtbl->GetVariableByName(effect, "m3"); matrix = v->lpVtbl->AsMatrix(v); ok(matrix->lpVtbl->IsValid(matrix), "Expected valid matrix.\n"); @@ -7503,16 +7492,7 @@ todo_wine *(unsigned int *)&m_set.m[1][0] = 0; *(unsigned int *)&m_set.m[1][1] = 1; *(unsigned int *)&m_set.m[1][2] = 0; - -todo_wine - ok(m_ret.m[0][0] == m_set.m[0][0], "Unexpected value.\n"); - ok(m_ret.m[0][1] == m_set.m[0][1], "Unexpected value.\n"); -todo_wine - ok(m_ret.m[0][2] == m_set.m[0][2], "Unexpected value.\n"); - ok(m_ret.m[1][0] == m_set.m[1][0], "Unexpected value.\n"); -todo_wine - ok(m_ret.m[1][1] == m_set.m[1][1], "Unexpected value.\n"); - ok(m_ret.m[1][2] == m_set.m[1][2], "Unexpected value.\n"); + compare_matrix("m3", __LINE__, &m_set, &m_ret, 2, 3, FALSE); v = effect->lpVtbl->GetVariableByName(effect, "m4"); matrix = v->lpVtbl->AsMatrix(v); @@ -7522,10 +7502,8 @@ todo_wine ok(hr == S_OK, "Unexpected hr %#x.\n", hr); set_test_matrix(&m_set, D3D10_SVT_FLOAT, 2, 2, 1); -todo_wine -{ compare_matrix("m4", __LINE__, &m_set, &m_ret, 2, 2, FALSE); -} + /* Struct */ v = effect->lpVtbl->GetVariableByName(effect, "s1"); ok(v->lpVtbl->IsValid(v), "Expected valid variable.\n"); @@ -7535,7 +7513,6 @@ todo_wine scalar = m->lpVtbl->AsScalar(m); hr = scalar->lpVtbl->GetBool(scalar, &ret); ok(hr == S_OK, "Unexpected hr %#x.\n", hr); -todo_wine ok(ret == 1, "Unexpected value.\n"); m = v->lpVtbl->GetMemberByName(v, "f2"); @@ -7543,7 +7520,6 @@ todo_wine scalar = m->lpVtbl->AsScalar(m); hr = scalar->lpVtbl->GetFloat(scalar, &float_s); ok(hr == S_OK, "Unexpected hr %#x.\n", hr); -todo_wine ok(float_s == -0.2f, "Unexpected value %f.\n", float_s); m = v->lpVtbl->GetMemberByName(v, "b2");