Implement SetMatrix/SetMatrixArray and SetMatrixTranspose/SetMatrixTransposeArray methods for the matrix effect variable interface.
Signed-off-by: Connor McAdams conmanx360@gmail.com --- dlls/d3d10/d3d10_private.h | 5 ++ dlls/d3d10/effect.c | 107 ++++++++++++++++++++++++++++++++++--- 2 files changed, 104 insertions(+), 8 deletions(-)
diff --git a/dlls/d3d10/d3d10_private.h b/dlls/d3d10/d3d10_private.h index 5c6c7a2d72..2be381f608 100644 --- a/dlls/d3d10/d3d10_private.h +++ b/dlls/d3d10/d3d10_private.h @@ -61,6 +61,11 @@ enum d3d10_effect_object_operation D3D10_EOO_ANONYMOUS_SHADER = 7, };
+struct d3d10_effect_matrix +{ + float m[4][4]; +}; + struct d3d10_effect_object { struct d3d10_effect_pass *pass; diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c index 93be257b81..1bc7968499 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c @@ -4967,8 +4967,87 @@ static const struct ID3D10EffectVectorVariableVtbl d3d10_effect_vector_variable_ d3d10_effect_vector_variable_GetFloatVectorArray, };
+static void write_matrix_to_buffer(struct d3d10_effect_variable *variable, float *buf, + struct d3d10_effect_matrix *matrix, BOOL transpose) +{ + unsigned int row, col; + + if (variable->type->type_class == D3D10_SVC_MATRIX_COLUMNS) + { + for (col = 0; col < variable->type->column_count; col++) + { + for (row = 0; row < variable->type->row_count; row++) + { + if (transpose) + buf[(col * 4) + row] = matrix->m[col][row]; + else + buf[(col * 4) + row] = matrix->m[row][col]; + } + } + } + else + { + for (col = 0; col < variable->type->column_count; col++) + { + for (row = 0; row < variable->type->row_count; row++) + { + if (transpose) + buf[(row * 4) + col] = matrix->m[col][row]; + else + buf[(row * 4) + col] = matrix->m[row][col]; + } + } + } +} + +static void write_matrix_variable_to_buffer(struct d3d10_effect_variable *variable, void *data, BOOL transpose) +{ + char *buf = variable->buffer->u.buffer.local_buffer + variable->buffer_offset; + + write_matrix_to_buffer(variable, (float *)buf, data, transpose); + + variable->buffer->u.buffer.changed = 1; +} + +static void write_matrix_variable_array_to_buffer(struct d3d10_effect_variable *variable, void *data, UINT offset, + UINT count, BOOL transpose) +{ + char *buf = variable->buffer->u.buffer.local_buffer + variable->buffer_offset; + struct d3d10_effect_matrix *input_data = data; + unsigned int i; + + if (!variable->type->element_count) + { + write_matrix_variable_to_buffer(variable, data, transpose); + return; + } + + if (offset >= variable->type->element_count) + return; + + if (count > variable->type->element_count - offset) + count = variable->type->element_count - offset; + + if (offset) + buf += variable->type->stride * offset; + + for (i = 0; i < count; i++) + { + write_matrix_to_buffer(variable, (float *)buf, &input_data[i], transpose); + + buf += variable->type->stride; + } + + variable->buffer->u.buffer.changed = 1; +} + /* ID3D10EffectVariable methods */
+static inline struct d3d10_effect_variable *impl_from_ID3D10EffectMatrixVariable(ID3D10EffectMatrixVariable *iface) +{ + return CONTAINING_RECORD(iface, struct d3d10_effect_variable, ID3D10EffectVariable_iface); +} + static BOOL STDMETHODCALLTYPE d3d10_effect_matrix_variable_IsValid(ID3D10EffectMatrixVariable *iface) { TRACE("iface %p\n", iface); @@ -5125,9 +5204,12 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_matrix_variable_GetRawValue(ID3D10 static HRESULT STDMETHODCALLTYPE d3d10_effect_matrix_variable_SetMatrix(ID3D10EffectMatrixVariable *iface, float *data) { - FIXME("iface %p, data %p stub!\n", iface, data); + struct d3d10_effect_variable *effect_var = impl_from_ID3D10EffectMatrixVariable(iface);
- return E_NOTIMPL; + TRACE("iface %p, data %p.\n", iface, data); + write_matrix_variable_to_buffer(effect_var, data, FALSE); + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d3d10_effect_matrix_variable_GetMatrix(ID3D10EffectMatrixVariable *iface, @@ -5141,9 +5223,12 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_matrix_variable_GetMatrix(ID3D10Ef static HRESULT STDMETHODCALLTYPE d3d10_effect_matrix_variable_SetMatrixArray(ID3D10EffectMatrixVariable *iface, float *data, UINT offset, UINT count) { - FIXME("iface %p, data %p, offset %u, count %u stub!\n", iface, data, offset, count); + struct d3d10_effect_variable *effect_var = impl_from_ID3D10EffectMatrixVariable(iface);
- return E_NOTIMPL; + TRACE("iface %p, data %p, offset %u, count %u.\n", iface, data, offset, count); + write_matrix_variable_array_to_buffer(effect_var, data, offset, count, FALSE); + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d3d10_effect_matrix_variable_GetMatrixArray(ID3D10EffectMatrixVariable *iface, @@ -5157,9 +5242,12 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_matrix_variable_GetMatrixArray(ID3 static HRESULT STDMETHODCALLTYPE d3d10_effect_matrix_variable_SetMatrixTranspose(ID3D10EffectMatrixVariable *iface, float *data) { - FIXME("iface %p, data %p stub!\n", iface, data); + struct d3d10_effect_variable *effect_var = impl_from_ID3D10EffectMatrixVariable(iface);
- return E_NOTIMPL; + TRACE("iface %p, data %p.\n", iface, data); + write_matrix_variable_to_buffer(effect_var, data, TRUE); + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d3d10_effect_matrix_variable_GetMatrixTranspose(ID3D10EffectMatrixVariable *iface, @@ -5173,9 +5261,12 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_matrix_variable_GetMatrixTranspose static HRESULT STDMETHODCALLTYPE d3d10_effect_matrix_variable_SetMatrixTransposeArray(ID3D10EffectMatrixVariable *iface, float *data, UINT offset, UINT count) { - FIXME("iface %p, data %p, offset %u, count %u stub!\n", iface, data, offset, count); + struct d3d10_effect_variable *effect_var = impl_from_ID3D10EffectMatrixVariable(iface);
- return E_NOTIMPL; + TRACE("iface %p, data %p, offset %u, count %u.\n", iface, data, offset, count); + write_matrix_variable_array_to_buffer(effect_var, data, offset, count, TRUE); + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d3d10_effect_matrix_variable_GetMatrixTransposeArray(ID3D10EffectMatrixVariable *iface,
Implement GetMatrix/GetMatrixArray and GetMatrixTranspose/GetMatrixTransposeArray methods for the matrix effect variable interface.
Signed-off-by: Connor McAdams conmanx360@gmail.com --- dlls/d3d10/effect.c | 92 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 84 insertions(+), 8 deletions(-)
diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c index 1bc7968499..44f3bfa0ae 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c @@ -5041,6 +5041,70 @@ static void write_matrix_variable_array_to_buffer(struct d3d10_effect_variable * variable->buffer->u.buffer.changed = 1; }
+static void read_matrix_from_buffer(struct d3d10_effect_variable *variable, float *buf, + struct d3d10_effect_matrix *matrix, BOOL transpose) +{ + unsigned int row, col; + + if (variable->type->type_class == D3D10_SVC_MATRIX_COLUMNS) + { + for (col = 0; col < variable->type->column_count; col++) + { + for (row = 0; row < variable->type->row_count; row++) + { + if (transpose) + matrix->m[col][row] = buf[(col * 4) + row]; + else + matrix->m[row][col] = buf[(col * 4) + row]; + } + } + } + else + { + for (col = 0; col < variable->type->column_count; col++) + { + for (row = 0; row < variable->type->row_count; row++) + { + if (transpose) + matrix->m[col][row] = buf[(row * 4) + col]; + else + matrix->m[row][col] = buf[(row * 4) + col]; + } + } + } +} + +static void read_matrix_variable_from_buffer(struct d3d10_effect_variable *variable, void *data, BOOL transpose) +{ + char *buf = variable->buffer->u.buffer.local_buffer + variable->buffer_offset; + + read_matrix_from_buffer(variable, (float *)buf, data, transpose); +} + +static void read_matrix_variable_array_from_buffer(struct d3d10_effect_variable *variable, void *data, UINT offset, + UINT count, BOOL transpose) +{ + char *buf = variable->buffer->u.buffer.local_buffer + variable->buffer_offset; + struct d3d10_effect_matrix *input_data = data; + unsigned int i; + + if (offset >= variable->type->element_count) + return; + + if (count > variable->type->element_count - offset) + count = variable->type->element_count - offset; + + if (offset) + buf += variable->type->stride * offset; + + for (i = 0; i < count; i++) + { + read_matrix_from_buffer(variable, (float *)buf, &input_data[i], transpose); + + buf += variable->type->stride; + } +} + /* ID3D10EffectVariable methods */
static inline struct d3d10_effect_variable *impl_from_ID3D10EffectMatrixVariable(ID3D10EffectMatrixVariable *iface) @@ -5215,9 +5279,12 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_matrix_variable_SetMatrix(ID3D10Ef static HRESULT STDMETHODCALLTYPE d3d10_effect_matrix_variable_GetMatrix(ID3D10EffectMatrixVariable *iface, float *data) { - FIXME("iface %p, data %p stub!\n", iface, data); + struct d3d10_effect_variable *effect_var = impl_from_ID3D10EffectMatrixVariable(iface);
- return E_NOTIMPL; + TRACE("iface %p, data %p.\n", iface, data); + read_matrix_variable_from_buffer(effect_var, data, FALSE); + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d3d10_effect_matrix_variable_SetMatrixArray(ID3D10EffectMatrixVariable *iface, @@ -5234,9 +5301,12 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_matrix_variable_SetMatrixArray(ID3 static HRESULT STDMETHODCALLTYPE d3d10_effect_matrix_variable_GetMatrixArray(ID3D10EffectMatrixVariable *iface, float *data, UINT offset, UINT count) { - FIXME("iface %p, data %p, offset %u, count %u stub!\n", iface, data, offset, count); + struct d3d10_effect_variable *effect_var = impl_from_ID3D10EffectMatrixVariable(iface);
- return E_NOTIMPL; + TRACE("iface %p, data %p, offset %u, count %u.\n", iface, data, offset, count); + read_matrix_variable_array_from_buffer(effect_var, data, offset, count, FALSE); + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d3d10_effect_matrix_variable_SetMatrixTranspose(ID3D10EffectMatrixVariable *iface, @@ -5253,9 +5323,12 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_matrix_variable_SetMatrixTranspose static HRESULT STDMETHODCALLTYPE d3d10_effect_matrix_variable_GetMatrixTranspose(ID3D10EffectMatrixVariable *iface, float *data) { - FIXME("iface %p, data %p stub!\n", iface, data); + struct d3d10_effect_variable *effect_var = impl_from_ID3D10EffectMatrixVariable(iface);
- return E_NOTIMPL; + TRACE("iface %p, data %p.\n", iface, data); + read_matrix_variable_from_buffer(effect_var, data, TRUE); + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d3d10_effect_matrix_variable_SetMatrixTransposeArray(ID3D10EffectMatrixVariable *iface, @@ -5272,9 +5345,12 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_matrix_variable_SetMatrixTranspose static HRESULT STDMETHODCALLTYPE d3d10_effect_matrix_variable_GetMatrixTransposeArray(ID3D10EffectMatrixVariable *iface, float *data, UINT offset, UINT count) { - FIXME("iface %p, data %p, offset %u, count %u stub!\n", iface, data, offset, count); + struct d3d10_effect_variable *effect_var = impl_from_ID3D10EffectMatrixVariable(iface);
- return E_NOTIMPL; + TRACE("iface %p, data %p, offset %u, count %u.\n", iface, data, offset, count); + read_matrix_variable_array_from_buffer(effect_var, data, offset, count, TRUE); + + return S_OK; }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=65273
Your paranoid android.
=== debian10 (build log) ===
../../../wine/dlls/d3d10/effect.c:4776:36: error: ‘union <anonymous>’ has no member named ‘buffer’ ../../../wine/dlls/d3d10/effect.c:4780:24: error: ‘union <anonymous>’ has no member named ‘buffer’ ../../../wine/dlls/d3d10/effect.c:4786:36: error: ‘union <anonymous>’ has no member named ‘buffer’ ../../../wine/dlls/d3d10/effect.c:4812:24: error: ‘union <anonymous>’ has no member named ‘buffer’ ../../../wine/dlls/d3d10/effect.c:4850:36: error: ‘union <anonymous>’ has no member named ‘buffer’ ../../../wine/dlls/d3d10/effect.c:4858:36: error: ‘union <anonymous>’ has no member named ‘buffer’ Task: The win32 build failed
=== debian10 (build log) ===
../../../wine/dlls/d3d10/effect.c:4776:36: error: ‘union <anonymous>’ has no member named ‘buffer’ ../../../wine/dlls/d3d10/effect.c:4780:24: error: ‘union <anonymous>’ has no member named ‘buffer’ ../../../wine/dlls/d3d10/effect.c:4786:36: error: ‘union <anonymous>’ has no member named ‘buffer’ ../../../wine/dlls/d3d10/effect.c:4812:24: error: ‘union <anonymous>’ has no member named ‘buffer’ ../../../wine/dlls/d3d10/effect.c:4850:36: error: ‘union <anonymous>’ has no member named ‘buffer’ ../../../wine/dlls/d3d10/effect.c:4858:36: error: ‘union <anonymous>’ has no member named ‘buffer’ Task: The wow64 build failed
Add tests for the ID3D10EffectMatrixVariable get/set.
Signed-off-by: Connor McAdams conmanx360@gmail.com --- dlls/d3d10/tests/effect.c | 207 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 207 insertions(+)
diff --git a/dlls/d3d10/tests/effect.c b/dlls/d3d10/tests/effect.c index 24c20a51a5..339689557b 100644 --- a/dlls/d3d10/tests/effect.c +++ b/dlls/d3d10/tests/effect.c @@ -4626,6 +4626,212 @@ static void test_effect_vector_variable(void) ok(!refcount, "Device has %u references left.\n", refcount); }
+/* + * test_effect_matrix_variable + */ +#if 0 +cbuffer cb +{ + float4x4 m_f0; + float4x4 m_f_a[2]; + + row_major int2x3 m_i0; + + bool3x2 m_b0; + bool3x2 m_b_a[2]; +}; +#endif + +static DWORD fx_test_matrix_variable[] = +{ + 0x43425844, 0xc95a5c42, 0xa138d3cb, 0x8a4ef493, + 0x3515b7ee, 0x00000001, 0x000001e2, 0x00000001, + 0x00000024, 0x30315846, 0x000001b6, 0xfeff1001, + 0x00000001, 0x00000005, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x000000c6, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x66006263, + 0x74616f6c, 0x00347834, 0x00000007, 0x00000001, + 0x00000000, 0x00000040, 0x00000040, 0x00000040, + 0x0000640b, 0x30665f6d, 0x00000700, 0x00000100, + 0x00000200, 0x00008000, 0x00004000, 0x00008000, + 0x00640b00, 0x665f6d00, 0x6900615f, 0x7832746e, + 0x00530033, 0x00010000, 0x00000000, 0x001c0000, + 0x00200000, 0x00180000, 0x1a130000, 0x5f6d0000, + 0x62003069, 0x336c6f6f, 0x7b003278, 0x01000000, + 0x00000000, 0x1c000000, 0x20000000, 0x18000000, + 0x23000000, 0x6d000053, 0x0030625f, 0x0000007b, + 0x00000001, 0x00000002, 0x0000003c, 0x00000020, + 0x00000030, 0x00005323, 0x5f625f6d, 0x00040061, + 0x01400000, 0x00000000, 0x00050000, 0xffff0000, + 0x0000ffff, 0x002c0000, 0x00100000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x004d0000, 0x00310000, 0x00000000, 0x00400000, + 0x00000000, 0x00000000, 0x00000000, 0x00760000, + 0x005a0000, 0x00000000, 0x00c00000, 0x00000000, + 0x00000000, 0x00000000, 0x009f0000, 0x00830000, + 0x00000000, 0x00e00000, 0x00000000, 0x00000000, + 0x00000000, 0x00c00000, 0x00a40000, 0x00000000, + 0x01000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, +}; + +static void test_effect_matrix_variable(void) +{ + ID3D10Device *device; + ID3D10Effect *effect; + ID3D10EffectVariable *var; + ID3D10EffectType *type; + ID3D10EffectMatrixVariable *m_f0, *m_f_a, *m_i0, *m_b0, *m_b_a; + float m_f0_ret[16], m_f_a_ret[32], m_f0_set[16], m_f_a_set[32]; + int m_i0_ret[16], m_i0_set[16]; + BOOL m_b0_ret[16], m_b_a_ret[32], m_b0_set[16], m_b_a_set[32]; + D3D10_EFFECT_TYPE_DESC type_desc; + ULONG refcount; + HRESULT hr; + unsigned int i; + float tmp; + + if (!(device = create_device())) + { + skip("Failed to create device, skipping tests.\n"); + return; + } + + hr = create_effect(fx_test_matrix_variable, 0, device, NULL, &effect); + ok(SUCCEEDED(hr), "D3D10CreateEffectFromMemory failed (%x)\n", hr); + + /* Matrix effect variables only have one set of methods for + * getting/setting, as opposed to the scalar and vector methods which have + * different methods for int, bool, and float. The input and output always + * expects a 4x4 matrix, regardless of the size of matrix within the + * shader. The input is also a float pointer, so we'll have to typecast + * int and bool types to floats for setting, and the reverse for reading + * back. */ + + /* Vector floating point variable. */ + var = effect->lpVtbl->GetVariableByName(effect, "m_f0"); + type = var->lpVtbl->GetType(var); + hr = type->lpVtbl->GetDesc(type, &type_desc); + ok(SUCCEEDED(hr), "GetDesc failed (%x)\n", hr); + ok(type_desc.Type == D3D10_SVT_FLOAT, "Type is %x, expected %x\n", type_desc.Type, D3D10_SVT_FLOAT); + m_f0 = var->lpVtbl->AsMatrix(var); + + m_f0_set[0] = 1.0f; m_f0_set[1] = 2.0f; m_f0_set[2] = 3.0f; m_f0_set[3] = 4.0f; + m_f0_set[4] = 5.0f; m_f0_set[5] = 6.0f; m_f0_set[6] = 7.0f; m_f0_set[7] = 8.0f; + m_f0_set[8] = 9.0f; m_f0_set[9] = 10.0f; m_f0_set[10] = 11.0f; m_f0_set[11] = 12.0f; + m_f0_set[12] = 13.0f; m_f0_set[13] = 14.0f; m_f0_set[14] = 15.0f; m_f0_set[15] = 16.0f; + + m_f0->lpVtbl->SetMatrix(m_f0, m_f0_set); + m_f0->lpVtbl->GetMatrix(m_f0, m_f0_ret); + for (i = 0; i < 16; i++) + ok(m_f0_ret[i] == m_f0_set[i], "m_f0_ret[%d] is %f, expected %f.\n", i, m_f0_ret[i], m_f0_set[i]); + + /* Matrix floating point array variable. */ + var = effect->lpVtbl->GetVariableByName(effect, "m_f_a"); + type = var->lpVtbl->GetType(var); + hr = type->lpVtbl->GetDesc(type, &type_desc); + ok(SUCCEEDED(hr), "GetDesc failed (%x)\n", hr); + ok(type_desc.Type == D3D10_SVT_FLOAT, "Type is %x, expected %x\n", type_desc.Type, D3D10_SVT_FLOAT); + m_f_a = var->lpVtbl->AsMatrix(var); + + for (i = 0, tmp = 1.0f; i < 32; i++, tmp += 1.0f) + m_f_a_set[i] = tmp; + + m_f_a->lpVtbl->SetMatrixArray(m_f_a, m_f_a_set, 0, 2); + m_f_a->lpVtbl->GetMatrixArray(m_f_a, m_f_a_ret, 0, 2); + for (i = 0; i < 32; i++) + ok(m_f_a_ret[i] == m_f_a_set[i], "m_f_a_ret[%d] is %f, expected %f.\n", i, m_f_a_ret[i], m_f_a_set[i]); + + /* Matrix int variable. */ + var = effect->lpVtbl->GetVariableByName(effect, "m_i0"); + type = var->lpVtbl->GetType(var); + hr = type->lpVtbl->GetDesc(type, &type_desc); + ok(SUCCEEDED(hr), "GetDesc failed (%x)\n", hr); + ok(type_desc.Type == D3D10_SVT_INT, "Type is %x, expected %x\n", type_desc.Type, D3D10_SVT_INT); + m_i0 = var->lpVtbl->AsMatrix(var); + + m_i0_set[0] = 1; m_i0_set[1] = 2; m_i0_set[2] = 3; m_i0_set[3] = 0; + m_i0_set[4] = 4; m_i0_set[5] = 5; m_i0_set[6] = 6; m_i0_set[7] = 0; + m_i0_set[8] = 0; m_i0_set[9] = 0; m_i0_set[10] = 0; m_i0_set[11] = 0; + m_i0_set[12] = 0; m_i0_set[13] = 0; m_i0_set[14] = 0; m_i0_set[15] = 0; + + memset(m_i0_ret, 0, sizeof(m_i0_ret)); + m_i0->lpVtbl->SetMatrix(m_i0, (float *)m_i0_set); + m_i0->lpVtbl->GetMatrix(m_i0, (float *)m_i0_ret); + for (i = 0; i < 16; i++) + ok(m_i0_ret[i] == m_i0_set[i], "m_i0_ret[%d] is %d, expected %d.\n", i, m_i0_ret[i], m_i0_set[i]); + + /* Test that transpose is working properly. */ + memset(m_i0_ret, 0, sizeof(m_i0_ret)); + m_i0->lpVtbl->SetMatrixTranspose(m_i0, (float *)m_i0_set); + m_i0->lpVtbl->GetMatrix(m_i0, (float *)m_i0_ret); + m_i0_set[0] = 1; m_i0_set[1] = 4; m_i0_set[2] = 0; m_i0_set[3] = 0; + m_i0_set[4] = 2; m_i0_set[5] = 5; m_i0_set[6] = 0; m_i0_set[7] = 0; + m_i0_set[8] = 0; m_i0_set[9] = 0; m_i0_set[10] = 0; m_i0_set[11] = 0; + m_i0_set[12] = 0; m_i0_set[13] = 0; m_i0_set[14] = 0; m_i0_set[15] = 0; + for (i = 0; i < 16; i++) + ok(m_i0_ret[i] == m_i0_set[i], "m_i0_ret[%d] is %d, expected %d. Transpose failure.\n", i, m_i0_ret[i], m_i0_set[i]); + + /* Matrix bool variable. */ + var = effect->lpVtbl->GetVariableByName(effect, "m_b0"); + type = var->lpVtbl->GetType(var); + hr = type->lpVtbl->GetDesc(type, &type_desc); + ok(SUCCEEDED(hr), "GetDesc failed (%x)\n", hr); + ok(type_desc.Type == D3D10_SVT_BOOL, "Type is %x, expected %x\n", type_desc.Type, D3D10_SVT_BOOL); + m_b0 = var->lpVtbl->AsMatrix(var); + + m_b0_set[0] = TRUE; m_b0_set[1] = TRUE; m_b0_set[2] = FALSE; m_b0_set[3] = FALSE; + m_b0_set[4] = TRUE; m_b0_set[5] = FALSE; m_b0_set[6] = FALSE; m_b0_set[7] = FALSE; + m_b0_set[8] = FALSE; m_b0_set[9] = TRUE; m_b0_set[10] = FALSE; m_b0_set[11] = FALSE; + m_b0_set[12] = FALSE; m_b0_set[13] = FALSE; m_b0_set[14] = FALSE; m_b0_set[15] = FALSE; + + memset(m_b0_ret, 0, sizeof(m_b0_ret)); + m_b0->lpVtbl->SetMatrix(m_b0, (float *)m_b0_set); + m_b0->lpVtbl->GetMatrix(m_b0, (float *)m_b0_ret); + for (i = 0; i < 16; i++) + ok(m_b0_ret[i] == m_b0_set[i], "m_b0_ret[%d] is %d, expected %d.\n", i, m_b0_ret[i], m_b0_set[i]); + + /* Matrix bool array variable. */ + var = effect->lpVtbl->GetVariableByName(effect, "m_b_a"); + type = var->lpVtbl->GetType(var); + hr = type->lpVtbl->GetDesc(type, &type_desc); + ok(SUCCEEDED(hr), "GetDesc failed (%x)\n", hr); + ok(type_desc.Type == D3D10_SVT_BOOL, "Type is %x, expected %x\n", type_desc.Type, D3D10_SVT_BOOL); + m_b_a = var->lpVtbl->AsMatrix(var); + + /* First 3x2 matrix. */ + m_b_a_set[0] = TRUE; m_b_a_set[1] = TRUE; m_b_a_set[2] = FALSE; m_b_a_set[3] = FALSE; + m_b_a_set[4] = TRUE; m_b_a_set[5] = FALSE; m_b_a_set[6] = FALSE; m_b_a_set[7] = FALSE; + m_b_a_set[8] = FALSE; m_b_a_set[9] = TRUE; m_b_a_set[10] = FALSE; m_b_a_set[11] = FALSE; + m_b_a_set[12] = FALSE; m_b_a_set[13] = FALSE; m_b_a_set[14] = FALSE; m_b_a_set[15] = FALSE; + + /* Second 3x2 matrix. */ + m_b_a_set[16] = TRUE; m_b_a_set[17] = FALSE; m_b_a_set[18] = FALSE; m_b_a_set[19] = FALSE; + m_b_a_set[20] = FALSE; m_b_a_set[21] = TRUE; m_b_a_set[22] = FALSE; m_b_a_set[23] = FALSE; + m_b_a_set[24] = TRUE; m_b_a_set[25] = FALSE; m_b_a_set[26] = FALSE; m_b_a_set[27] = FALSE; + m_b_a_set[28] = FALSE; m_b_a_set[29] = FALSE; m_b_a_set[30] = FALSE; m_b_a_set[31] = FALSE; + + memset(m_b_a_ret, 0, sizeof(m_b_a_ret)); + m_b_a->lpVtbl->SetMatrixArray(m_b_a, (float *)m_b_a_set, 0, 2); + m_b_a->lpVtbl->GetMatrixArray(m_b_a, (float *)m_b_a_ret, 0, 2); + for (i = 0; i < 32; i++) + ok(m_b_a_ret[i] == m_b_a_set[i], "m_b_a_ret[%d] is %d, expected %d.\n", i, m_b_a_ret[i], m_b_a_set[i]); + + /* Test offset. */ + memset(m_b_a_ret, 0, sizeof(m_b_a_ret)); + m_b_a->lpVtbl->SetMatrixArray(m_b_a, (float *)m_b_a_set, 1, 1); + m_b_a->lpVtbl->GetMatrixArray(m_b_a, (float *)m_b_a_ret, 1, 1); + for (i = 0; i < 16; i++) + ok(m_b_a_ret[i] == m_b_a_set[i], "m_b_a_ret[%d] is %d, expected %d. Matrix offset failure.\n", i, m_b_a_ret[i], m_b_a_set[i]); + + effect->lpVtbl->Release(effect); + + refcount = ID3D10Device_Release(device); + ok(!refcount, "Device has %u references left.\n", refcount); +} + START_TEST(effect) { test_effect_constant_buffer_type(); @@ -4640,4 +4846,5 @@ START_TEST(effect) test_effect_state_group_defaults(); test_effect_scalar_variable(); test_effect_vector_variable(); + test_effect_matrix_variable(); }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=65279
Your paranoid android.
=== build (build log) ===
error: patch failed: dlls/d3d10/tests/effect.c:4640 Task: Patch failed to apply
=== debian10 (build log) ===
error: patch failed: dlls/d3d10/tests/effect.c:4640 Task: Patch failed to apply
=== debian10 (build log) ===
error: patch failed: dlls/d3d10/tests/effect.c:4640 Task: Patch failed to apply
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=65272
Your paranoid android.
=== debian10 (build log) ===
../../../wine/dlls/d3d10/effect.c:4776:36: error: ‘union <anonymous>’ has no member named ‘buffer’ ../../../wine/dlls/d3d10/effect.c:4780:24: error: ‘union <anonymous>’ has no member named ‘buffer’ ../../../wine/dlls/d3d10/effect.c:4786:36: error: ‘union <anonymous>’ has no member named ‘buffer’ ../../../wine/dlls/d3d10/effect.c:4812:24: error: ‘union <anonymous>’ has no member named ‘buffer’ Task: The win32 build failed
=== debian10 (build log) ===
../../../wine/dlls/d3d10/effect.c:4776:36: error: ‘union <anonymous>’ has no member named ‘buffer’ ../../../wine/dlls/d3d10/effect.c:4780:24: error: ‘union <anonymous>’ has no member named ‘buffer’ ../../../wine/dlls/d3d10/effect.c:4786:36: error: ‘union <anonymous>’ has no member named ‘buffer’ ../../../wine/dlls/d3d10/effect.c:4812:24: error: ‘union <anonymous>’ has no member named ‘buffer’ Task: The wow64 build failed
Ah, I guess this patch depends upon the earlier three, so I should wait for those to be committed and re-send. My mistake.
On Sun, Feb 16, 2020 at 4:07 PM Marvin testbot@winehq.org wrote:
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=65272
Your paranoid android.
=== debian10 (build log) ===
../../../wine/dlls/d3d10/effect.c:4776:36: error: ‘union <anonymous>’ has no member named ‘buffer’ ../../../wine/dlls/d3d10/effect.c:4780:24: error: ‘union <anonymous>’ has no member named ‘buffer’ ../../../wine/dlls/d3d10/effect.c:4786:36: error: ‘union <anonymous>’ has no member named ‘buffer’ ../../../wine/dlls/d3d10/effect.c:4812:24: error: ‘union <anonymous>’ has no member named ‘buffer’ Task: The win32 build failed
=== debian10 (build log) ===
../../../wine/dlls/d3d10/effect.c:4776:36: error: ‘union <anonymous>’ has no member named ‘buffer’ ../../../wine/dlls/d3d10/effect.c:4780:24: error: ‘union <anonymous>’ has no member named ‘buffer’ ../../../wine/dlls/d3d10/effect.c:4786:36: error: ‘union <anonymous>’ has no member named ‘buffer’ ../../../wine/dlls/d3d10/effect.c:4812:24: error: ‘union <anonymous>’ has no member named ‘buffer’ Task: The wow64 build failed
On Sun, Feb 16, 2020 at 10:01 PM Connor McAdams conmanx360@gmail.com wrote:
Implement SetMatrix/SetMatrixArray and SetMatrixTranspose/SetMatrixTransposeArray methods for the matrix effect variable interface.
Signed-off-by: Connor McAdams conmanx360@gmail.com
dlls/d3d10/d3d10_private.h | 5 ++ dlls/d3d10/effect.c | 107 ++++++++++++++++++++++++++++++++++--- 2 files changed, 104 insertions(+), 8 deletions(-)
diff --git a/dlls/d3d10/d3d10_private.h b/dlls/d3d10/d3d10_private.h index 5c6c7a2d72..2be381f608 100644 --- a/dlls/d3d10/d3d10_private.h +++ b/dlls/d3d10/d3d10_private.h @@ -61,6 +61,11 @@ enum d3d10_effect_object_operation D3D10_EOO_ANONYMOUS_SHADER = 7, };
+struct d3d10_effect_matrix +{
- float m[4][4];
+};
Let's just call it d3d10_matrix. It's not like it has anything specific to effects.
struct d3d10_effect_object { struct d3d10_effect_pass *pass; diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c index 93be257b81..1bc7968499 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c @@ -4967,8 +4967,87 @@ static const struct ID3D10EffectVectorVariableVtbl d3d10_effect_vector_variable_ d3d10_effect_vector_variable_GetFloatVectorArray, };
+static void write_matrix_to_buffer(struct d3d10_effect_variable *variable, float *buf,
struct d3d10_effect_matrix *matrix, BOOL transpose)
+{
- unsigned int row, col;
- if (variable->type->type_class == D3D10_SVC_MATRIX_COLUMNS)
- {
for (col = 0; col < variable->type->column_count; col++)
{
for (row = 0; row < variable->type->row_count; row++)
{
if (transpose)
buf[(col * 4) + row] = matrix->m[col][row];
else
buf[(col * 4) + row] = matrix->m[row][col];
}
}
- }
- else
- {
for (col = 0; col < variable->type->column_count; col++)
{
for (row = 0; row < variable->type->row_count; row++)
{
if (transpose)
buf[(row * 4) + col] = matrix->m[col][row];
else
buf[(row * 4) + col] = matrix->m[row][col];
}
}
- }
+}
So this means matrices are stored as 4-wide rows / columns independently of the matrix dimensions, right? In that case you don't need the outer if / else, you can just pick one and flip the transpose variable if type_class is D3D10_SVC_MATRIX_ROWS / D3D10_SVC_MATRIX_COLUMNS (depending on which side of the "if" you keep).