Implement SetFloat/SetFloatArray, SetInt/SetIntArray, and SetBool/SetBoolArray methods for the scalar effect variable interface.
Signed-off-by: Connor McAdams conmanx360@gmail.com --- dlls/d3d10/effect.c | 186 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 174 insertions(+), 12 deletions(-)
diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c index 3ee9bf7a35..e5de3d3916 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c @@ -4212,8 +4212,151 @@ static const struct ID3D10EffectConstantBufferVtbl d3d10_effect_constant_buffer_ d3d10_effect_constant_buffer_GetTextureBuffer, };
+ +static BOOL get_value_as_bool(void *src_data, D3D10_SHADER_VARIABLE_TYPE src_type) +{ + switch (src_type) + { + case D3D10_SVT_FLOAT: + case D3D10_SVT_INT: + case D3D10_SVT_BOOL: + if (*(DWORD *)src_data) + return -1; + break; + + default: + break; + } + + return FALSE; +} + +static int get_value_as_int(void *src_data, D3D10_SHADER_VARIABLE_TYPE src_type) +{ + switch (src_type) + { + case D3D10_SVT_FLOAT: + return (int)(*(float *)src_data); + + case D3D10_SVT_INT: + return *(int *)src_data; + + case D3D10_SVT_BOOL: + return get_value_as_bool(src_data, src_type); + + default: + return 0; + } +} + +static float get_value_as_float(void *src_data, D3D10_SHADER_VARIABLE_TYPE src_type) +{ + switch (src_type) + { + case D3D10_SVT_FLOAT: + return *(float *)src_data; + + case D3D10_SVT_INT: + return (float)(*(int *)src_data); + + case D3D10_SVT_BOOL: + return (float)get_value_as_bool(src_data, src_type); + + default: + return 0.0f; + } +} + +static void get_vector_as_type(BYTE *dst_data, D3D_SHADER_VARIABLE_TYPE dst_type, + BYTE *src_data, D3D_SHADER_VARIABLE_TYPE src_type, unsigned int count) +{ + unsigned int i; + + for (i = 0; i < count; i++, dst_data += sizeof(DWORD), src_data += sizeof(DWORD)) + { + if (dst_type == src_type) + *(DWORD *)dst_data = *(DWORD *)src_data; + else + { + switch (dst_type) + { + case D3D10_SVT_FLOAT: + *(float *)dst_data = get_value_as_float(src_data, src_type); + break; + + case D3D10_SVT_INT: + *(int *)dst_data = get_value_as_int(src_data, src_type); + break; + + case D3D10_SVT_BOOL: + *(BOOL *)dst_data = get_value_as_bool(src_data, src_type); + break; + + default: + *(DWORD *)dst_data = 0; + break; + } + } + } +} + +static void write_variable_to_buffer(struct d3d10_effect_variable *variable, void *src, + D3D_SHADER_VARIABLE_TYPE src_type) +{ + BYTE *dst = variable->buffer->u.buffer.local_buffer + variable->buffer_offset; + D3D_SHADER_VARIABLE_TYPE dst_type = variable->type->basetype; + + get_vector_as_type(dst, dst_type, src, src_type, variable->type->column_count); + + variable->buffer->u.buffer.changed = TRUE; +} + +static void write_variable_array_to_buffer(struct d3d10_effect_variable *variable, void *src, + D3D_SHADER_VARIABLE_TYPE src_type, unsigned int offset, unsigned int count) +{ + BYTE *dst = variable->buffer->u.buffer.local_buffer + variable->buffer_offset; + BYTE *cur_element = src; + D3D_SHADER_VARIABLE_TYPE dst_type = variable->type->basetype; + unsigned int element_size, i; + + if (!variable->type->element_count) + { + write_variable_to_buffer(variable, src, src_type); + return; + } + + if (offset >= variable->type->element_count) + { + WARN("Application set an offset larger than number of elements.\n"); + return; + } + + if (count > variable->type->element_count - offset) + count = variable->type->element_count - offset; + + element_size = variable->type->elementtype->size_packed; + if (offset) + dst += variable->type->stride * offset; + + for (i = 0; i < count; i++) + { + get_vector_as_type(dst, dst_type, cur_element, src_type, + variable->type->column_count); + + cur_element += element_size; + dst += variable->type->stride; + } + + variable->buffer->u.buffer.changed = TRUE; +} + /* ID3D10EffectVariable methods */
+static inline struct d3d10_effect_variable *impl_from_ID3D10EffectScalarVariable(ID3D10EffectScalarVariable *iface) +{ + return CONTAINING_RECORD(iface, struct d3d10_effect_variable, ID3D10EffectVariable_iface); +} + static BOOL STDMETHODCALLTYPE d3d10_effect_scalar_variable_IsValid(ID3D10EffectScalarVariable *iface) { TRACE("iface %p\n", iface); @@ -4370,9 +4513,12 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_GetRawValue(ID3D10 static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_SetFloat(ID3D10EffectScalarVariable *iface, float value) { - FIXME("iface %p, value %.8e stub!\n", iface, value); + struct d3d10_effect_variable *effect_var = impl_from_ID3D10EffectScalarVariable(iface);
- return E_NOTIMPL; + TRACE("iface %p, value %.8e.\n", iface, value); + write_variable_to_buffer(effect_var, &value, D3D10_SVT_FLOAT); + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_GetFloat(ID3D10EffectScalarVariable *iface, @@ -4383,12 +4529,16 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_GetFloat(ID3D10Eff return E_NOTIMPL; }
+/* Tests show that offset is ignored for scalar variables. */ static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_SetFloatArray(ID3D10EffectScalarVariable *iface, float *values, UINT offset, UINT count) { - FIXME("iface %p, values %p, offset %u, count %u stub!\n", iface, values, offset, count); + struct d3d10_effect_variable *effect_var = impl_from_ID3D10EffectScalarVariable(iface);
- return E_NOTIMPL; + TRACE("iface %p, values %p, offset %u, count %u.\n", iface, values, offset, count); + write_variable_array_to_buffer(effect_var, values, D3D10_SVT_FLOAT, 0, count); + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_GetFloatArray(ID3D10EffectScalarVariable *iface, @@ -4402,9 +4552,12 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_GetFloatArray(ID3D static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_SetInt(ID3D10EffectScalarVariable *iface, int value) { - FIXME("iface %p, value %d stub!\n", iface, value); + struct d3d10_effect_variable *effect_var = impl_from_ID3D10EffectScalarVariable(iface);
- return E_NOTIMPL; + TRACE("iface %p, value %d.\n", iface, value); + write_variable_to_buffer(effect_var, &value, D3D10_SVT_INT); + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_GetInt(ID3D10EffectScalarVariable *iface, @@ -4418,9 +4571,12 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_GetInt(ID3D10Effec static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_SetIntArray(ID3D10EffectScalarVariable *iface, int *values, UINT offset, UINT count) { - FIXME("iface %p, values %p, offset %u, count %u stub!\n", iface, values, offset, count); + struct d3d10_effect_variable *effect_var = impl_from_ID3D10EffectScalarVariable(iface);
- return E_NOTIMPL; + TRACE("iface %p, values %p, offset %u, count %u.\n", iface, values, offset, count); + write_variable_array_to_buffer(effect_var, values, D3D10_SVT_INT, 0, count); + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_GetIntArray(ID3D10EffectScalarVariable *iface, @@ -4434,9 +4590,12 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_GetIntArray(ID3D10 static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_SetBool(ID3D10EffectScalarVariable *iface, BOOL value) { - FIXME("iface %p, value %d stub!\n", iface, value); + struct d3d10_effect_variable *effect_var = impl_from_ID3D10EffectScalarVariable(iface);
- return E_NOTIMPL; + TRACE("iface %p, value %d.\n", iface, value); + write_variable_to_buffer(effect_var, &value, D3D10_SVT_BOOL); + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_GetBool(ID3D10EffectScalarVariable *iface, @@ -4450,9 +4609,12 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_GetBool(ID3D10Effe static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_SetBoolArray(ID3D10EffectScalarVariable *iface, BOOL *values, UINT offset, UINT count) { - FIXME("iface %p, values %p, offset %u, count %u stub!\n", iface, values, offset, count); + struct d3d10_effect_variable *effect_var = impl_from_ID3D10EffectScalarVariable(iface);
- return E_NOTIMPL; + TRACE("iface %p, values %p, offset %u, count %u.\n", iface, values, offset, count); + write_variable_array_to_buffer(effect_var, values, D3D10_SVT_BOOL, 0, count); + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_GetBoolArray(ID3D10EffectScalarVariable *iface,
Implement GetFloat/GetFloatArray, GetInt/GetIntArray, and GetBool/GetBoolArray methods for the scalar effect variable interface.
Signed-off-by: Connor McAdams conmanx360@gmail.com --- dlls/d3d10/effect.c | 88 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 76 insertions(+), 12 deletions(-)
diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c index e5de3d3916..23671ed3f4 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c @@ -4350,6 +4350,52 @@ static void write_variable_array_to_buffer(struct d3d10_effect_variable *variabl variable->buffer->u.buffer.changed = TRUE; }
+static void read_variable_from_buffer(struct d3d10_effect_variable *variable, void *dst, + D3D_SHADER_VARIABLE_TYPE dst_type) +{ + BYTE *src = variable->buffer->u.buffer.local_buffer + variable->buffer_offset; + D3D_SHADER_VARIABLE_TYPE src_type = variable->type->basetype; + + get_vector_as_type(dst, dst_type, src, src_type, variable->type->column_count); +} + +static void read_variable_array_from_buffer(struct d3d10_effect_variable *variable, void *dst, + D3D_SHADER_VARIABLE_TYPE dst_type, unsigned int offset, unsigned int count) +{ + BYTE *src = variable->buffer->u.buffer.local_buffer + variable->buffer_offset; + D3D_SHADER_VARIABLE_TYPE src_type = variable->type->basetype; + BYTE *cur_element = dst; + unsigned int element_size, i; + + if (!variable->type->element_count) + { + read_variable_from_buffer(variable, dst, dst_type); + return; + } + + if (offset >= variable->type->element_count) + { + WARN("Application set an offset larger than number of elements.\n"); + return; + } + + if (count > variable->type->element_count - offset) + count = variable->type->element_count - offset; + + element_size = variable->type->elementtype->size_packed; + if (offset) + src += variable->type->stride * offset; + + for (i = 0; i < count; i++) + { + get_vector_as_type(cur_element, dst_type, src, src_type, + variable->type->column_count); + + cur_element += element_size; + src += variable->type->stride; + } +} + /* ID3D10EffectVariable methods */
static inline struct d3d10_effect_variable *impl_from_ID3D10EffectScalarVariable(ID3D10EffectScalarVariable *iface) @@ -4524,9 +4570,12 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_SetFloat(ID3D10Eff static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_GetFloat(ID3D10EffectScalarVariable *iface, float *value) { - FIXME("iface %p, value %p stub!\n", iface, value); + struct d3d10_effect_variable *effect_var = impl_from_ID3D10EffectScalarVariable(iface);
- return E_NOTIMPL; + TRACE("iface %p, value %p.\n", iface, value); + read_variable_from_buffer(effect_var, value, D3D10_SVT_FLOAT); + + return S_OK; }
/* Tests show that offset is ignored for scalar variables. */ @@ -4544,9 +4593,12 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_SetFloatArray(ID3D static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_GetFloatArray(ID3D10EffectScalarVariable *iface, float *values, UINT offset, UINT count) { - FIXME("iface %p, values %p, offset %u, count %u stub!\n", iface, values, offset, count); + struct d3d10_effect_variable *effect_var = impl_from_ID3D10EffectScalarVariable(iface);
- return E_NOTIMPL; + TRACE("iface %p, values %p, offset %u, count %u.\n", iface, values, offset, count); + read_variable_array_from_buffer(effect_var, values, D3D10_SVT_FLOAT, 0, count); + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_SetInt(ID3D10EffectScalarVariable *iface, @@ -4563,9 +4615,12 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_SetInt(ID3D10Effec static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_GetInt(ID3D10EffectScalarVariable *iface, int *value) { - FIXME("iface %p, value %p stub!\n", iface, value); + struct d3d10_effect_variable *effect_var = impl_from_ID3D10EffectScalarVariable(iface);
- return E_NOTIMPL; + TRACE("iface %p, value %p.\n", iface, value); + read_variable_from_buffer(effect_var, value, D3D10_SVT_INT); + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_SetIntArray(ID3D10EffectScalarVariable *iface, @@ -4582,9 +4637,12 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_SetIntArray(ID3D10 static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_GetIntArray(ID3D10EffectScalarVariable *iface, int *values, UINT offset, UINT count) { - FIXME("iface %p, values %p, offset %u, count %u stub!\n", iface, values, offset, count); + struct d3d10_effect_variable *effect_var = impl_from_ID3D10EffectScalarVariable(iface);
- return E_NOTIMPL; + TRACE("iface %p, values %p, offset %u, count %u.\n", iface, values, offset, count); + read_variable_array_from_buffer(effect_var, values, D3D10_SVT_INT, 0, count); + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_SetBool(ID3D10EffectScalarVariable *iface, @@ -4601,9 +4659,12 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_SetBool(ID3D10Effe static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_GetBool(ID3D10EffectScalarVariable *iface, BOOL *value) { - FIXME("iface %p, value %p stub!\n", iface, value); + struct d3d10_effect_variable *effect_var = impl_from_ID3D10EffectScalarVariable(iface);
- return E_NOTIMPL; + TRACE("iface %p, value %p.\n", iface, value); + read_variable_from_buffer(effect_var, value, D3D10_SVT_BOOL); + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_SetBoolArray(ID3D10EffectScalarVariable *iface, @@ -4620,9 +4681,12 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_SetBoolArray(ID3D1 static HRESULT STDMETHODCALLTYPE d3d10_effect_scalar_variable_GetBoolArray(ID3D10EffectScalarVariable *iface, BOOL *values, UINT offset, UINT count) { - FIXME("iface %p, values %p, offset %u, count %u stub!\n", iface, values, offset, count); + struct d3d10_effect_variable *effect_var = impl_from_ID3D10EffectScalarVariable(iface);
- return E_NOTIMPL; + TRACE("iface %p, values %p, offset %u, count %u.\n", iface, values, offset, count); + read_variable_array_from_buffer(effect_var, values, D3D10_SVT_BOOL, 0, count); + + return S_OK; }
static const struct ID3D10EffectScalarVariableVtbl d3d10_effect_scalar_variable_vtbl =
Implement SetFloatVector/SetFloatVectorArray, SetIntVector/SetIntVectorArray, and SetBoolVector/SetBoolVectorArray methods for the vector effect variable interface.
Signed-off-by: Connor McAdams conmanx360@gmail.com --- dlls/d3d10/effect.c | 47 +++++++++++++++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 12 deletions(-)
diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c index 23671ed3f4..9cc753684c 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c @@ -4734,6 +4734,11 @@ static const struct ID3D10EffectScalarVariableVtbl d3d10_effect_scalar_variable_
/* ID3D10EffectVariable methods */
+static inline struct d3d10_effect_variable *impl_from_ID3D10EffectVectorVariable(ID3D10EffectVectorVariable *iface) +{ + return CONTAINING_RECORD(iface, struct d3d10_effect_variable, ID3D10EffectVariable_iface); +} + static BOOL STDMETHODCALLTYPE d3d10_effect_vector_variable_IsValid(ID3D10EffectVectorVariable *iface) { TRACE("iface %p\n", iface); @@ -4890,25 +4895,34 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_vector_variable_GetRawValue(ID3D10 static HRESULT STDMETHODCALLTYPE d3d10_effect_vector_variable_SetBoolVector(ID3D10EffectVectorVariable *iface, BOOL *value) { - FIXME("iface %p, value %p stub!\n", iface, value); + struct d3d10_effect_variable *effect_var = impl_from_ID3D10EffectVectorVariable(iface);
- return E_NOTIMPL; + TRACE("iface %p, value %p.\n", iface, value); + write_variable_to_buffer(effect_var, value, D3D10_SVT_BOOL); + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d3d10_effect_vector_variable_SetIntVector(ID3D10EffectVectorVariable *iface, int *value) { - FIXME("iface %p, value %p stub!\n", iface, value); + struct d3d10_effect_variable *effect_var = impl_from_ID3D10EffectVectorVariable(iface);
- return E_NOTIMPL; + TRACE("iface %p, value %p.\n", iface, value); + write_variable_to_buffer(effect_var, value, D3D10_SVT_INT); + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d3d10_effect_vector_variable_SetFloatVector(ID3D10EffectVectorVariable *iface, float *value) { - FIXME("iface %p, value %p stub!\n", iface, value); + struct d3d10_effect_variable *effect_var = impl_from_ID3D10EffectVectorVariable(iface);
- return E_NOTIMPL; + TRACE("iface %p, value %p.\n", iface, value); + write_variable_to_buffer(effect_var, value, D3D10_SVT_FLOAT); + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d3d10_effect_vector_variable_GetBoolVector(ID3D10EffectVectorVariable *iface, @@ -4938,25 +4952,34 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_vector_variable_GetFloatVector(ID3 static HRESULT STDMETHODCALLTYPE d3d10_effect_vector_variable_SetBoolVectorArray(ID3D10EffectVectorVariable *iface, BOOL *values, UINT offset, UINT count) { - FIXME("iface %p, values %p, offset %u, count %u stub!\n", iface, values, offset, count); + struct d3d10_effect_variable *effect_var = impl_from_ID3D10EffectVectorVariable(iface);
- return E_NOTIMPL; + TRACE("iface %p, values %p, offset %u, count %u.\n", iface, values, offset, count); + write_variable_array_to_buffer(effect_var, values, D3D10_SVT_BOOL, offset, count); + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d3d10_effect_vector_variable_SetIntVectorArray(ID3D10EffectVectorVariable *iface, int *values, UINT offset, UINT count) { - FIXME("iface %p, values %p, offset %u, count %u stub!\n", iface, values, offset, count); + struct d3d10_effect_variable *effect_var = impl_from_ID3D10EffectVectorVariable(iface);
- return E_NOTIMPL; + TRACE("iface %p, values %p, offset %u, count %u.\n", iface, values, offset, count); + write_variable_array_to_buffer(effect_var, values, D3D10_SVT_INT, offset, count); + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d3d10_effect_vector_variable_SetFloatVectorArray(ID3D10EffectVectorVariable *iface, float *values, UINT offset, UINT count) { - FIXME("iface %p, values %p, offset %u, count %u stub!\n", iface, values, offset, count); + struct d3d10_effect_variable *effect_var = impl_from_ID3D10EffectVectorVariable(iface);
- return E_NOTIMPL; + TRACE("iface %p, values %p, offset %u, count %u.\n", iface, values, offset, count); + write_variable_array_to_buffer(effect_var, values, D3D10_SVT_FLOAT, offset, count); + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d3d10_effect_vector_variable_GetBoolVectorArray(ID3D10EffectVectorVariable *iface,
Implement GetFloatVector/GetFloatVectorArray, GetIntVector/GetIntVectorArray, and GetBoolVector/GetBoolVectorArray methods for the vector effect variable interface.
Signed-off-by: Connor McAdams conmanx360@gmail.com --- dlls/d3d10/effect.c | 42 ++++++++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 12 deletions(-)
diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c index 9cc753684c..39e2f0807e 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c @@ -4928,25 +4928,34 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_vector_variable_SetFloatVector(ID3 static HRESULT STDMETHODCALLTYPE d3d10_effect_vector_variable_GetBoolVector(ID3D10EffectVectorVariable *iface, BOOL *value) { - FIXME("iface %p, value %p stub!\n", iface, value); + struct d3d10_effect_variable *effect_var = impl_from_ID3D10EffectVectorVariable(iface);
- return E_NOTIMPL; + TRACE("iface %p, value %p.\n", iface, value); + read_variable_from_buffer(effect_var, value, D3D10_SVT_BOOL); + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d3d10_effect_vector_variable_GetIntVector(ID3D10EffectVectorVariable *iface, int *value) { - FIXME("iface %p, value %p stub!\n", iface, value); + struct d3d10_effect_variable *effect_var = impl_from_ID3D10EffectVectorVariable(iface);
- return E_NOTIMPL; + TRACE("iface %p, value %p.\n", iface, value); + read_variable_from_buffer(effect_var, value, D3D10_SVT_INT); + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d3d10_effect_vector_variable_GetFloatVector(ID3D10EffectVectorVariable *iface, float *value) { - FIXME("iface %p, value %p stub!\n", iface, value); + struct d3d10_effect_variable *effect_var = impl_from_ID3D10EffectVectorVariable(iface);
- return E_NOTIMPL; + TRACE("iface %p, value %p.\n", iface, value); + read_variable_from_buffer(effect_var, value, D3D10_SVT_FLOAT); + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d3d10_effect_vector_variable_SetBoolVectorArray(ID3D10EffectVectorVariable *iface, @@ -4985,25 +4994,34 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_vector_variable_SetFloatVectorArra static HRESULT STDMETHODCALLTYPE d3d10_effect_vector_variable_GetBoolVectorArray(ID3D10EffectVectorVariable *iface, BOOL *values, UINT offset, UINT count) { - FIXME("iface %p, values %p, offset %u, count %u stub!\n", iface, values, offset, count); + struct d3d10_effect_variable *effect_var = impl_from_ID3D10EffectVectorVariable(iface);
- return E_NOTIMPL; + TRACE("iface %p, values %p, offset %u, count %u.\n", iface, values, offset, count); + read_variable_array_from_buffer(effect_var, values, D3D10_SVT_BOOL, offset, count); + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d3d10_effect_vector_variable_GetIntVectorArray(ID3D10EffectVectorVariable *iface, int *values, UINT offset, UINT count) { - FIXME("iface %p, values %p, offset %u, count %u stub!\n", iface, values, offset, count); + struct d3d10_effect_variable *effect_var = impl_from_ID3D10EffectVectorVariable(iface);
- return E_NOTIMPL; + TRACE("iface %p, values %p, offset %u, count %u.\n", iface, values, offset, count); + read_variable_array_from_buffer(effect_var, values, D3D10_SVT_INT, offset, count); + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d3d10_effect_vector_variable_GetFloatVectorArray(ID3D10EffectVectorVariable *iface, float *values, UINT offset, UINT count) { - FIXME("iface %p, values %p, offset %u, count %u stub!\n", iface, values, offset, count); + struct d3d10_effect_variable *effect_var = impl_from_ID3D10EffectVectorVariable(iface);
- return E_NOTIMPL; + TRACE("iface %p, values %p, offset %u, count %u.\n", iface, values, offset, count); + read_variable_array_from_buffer(effect_var, values, D3D10_SVT_FLOAT, offset, count); + + return S_OK; }
static const struct ID3D10EffectVectorVariableVtbl d3d10_effect_vector_variable_vtbl =
Signed-off-by: Connor McAdams conmanx360@gmail.com --- dlls/d3d10/tests/effect.c | 351 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 351 insertions(+)
diff --git a/dlls/d3d10/tests/effect.c b/dlls/d3d10/tests/effect.c index e2b27cf0c8..765edfa4dd 100644 --- a/dlls/d3d10/tests/effect.c +++ b/dlls/d3d10/tests/effect.c @@ -4273,6 +4273,356 @@ static void test_effect_state_group_defaults(void) ok(!refcount, "Device has %u references left.\n", refcount); }
+/* + * test_effect_scalar_variable + */ +#if 0 +cbuffer cb +{ + float f0, f_a[2]; + int i0, i_a[2]; + bool b0, b_a[2]; +}; +#endif +static DWORD fx_test_scalar_variable[] = +{ + 0x43425844, 0xe4da4aa6, 0x1380ddc5, 0x445edad5, + 0x08581666, 0x00000001, 0x0000020b, 0x00000001, + 0x00000024, 0x30315846, 0x000001df, 0xfeff1001, + 0x00000001, 0x00000006, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x000000d3, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x66006263, + 0x74616f6c, 0x00000700, 0x00000100, 0x00000000, + 0x00000400, 0x00001000, 0x00000400, 0x00090900, + 0x00306600, 0x00000007, 0x00000001, 0x00000002, + 0x00000014, 0x00000010, 0x00000008, 0x00000909, + 0x00615f66, 0x00746e69, 0x0000004c, 0x00000001, + 0x00000000, 0x00000004, 0x00000010, 0x00000004, + 0x00000911, 0x4c003069, 0x01000000, 0x02000000, + 0x14000000, 0x10000000, 0x08000000, 0x11000000, + 0x69000009, 0x6200615f, 0x006c6f6f, 0x0000008f, + 0x00000001, 0x00000000, 0x00000004, 0x00000010, + 0x00000004, 0x00000921, 0x8f003062, 0x01000000, + 0x02000000, 0x14000000, 0x10000000, 0x08000000, + 0x21000000, 0x62000009, 0x0400615f, 0x70000000, + 0x00000000, 0x06000000, 0xff000000, 0x00ffffff, + 0x29000000, 0x0d000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x48000000, + 0x2c000000, 0x00000000, 0x10000000, 0x00000000, + 0x00000000, 0x00000000, 0x6c000000, 0x50000000, + 0x00000000, 0x24000000, 0x00000000, 0x00000000, + 0x00000000, 0x8b000000, 0x6f000000, 0x00000000, + 0x30000000, 0x00000000, 0x00000000, 0x00000000, + 0xb0000000, 0x94000000, 0x00000000, 0x44000000, + 0x00000000, 0x00000000, 0x00000000, 0xcf000000, + 0xb3000000, 0x00000000, 0x50000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, +}; + +static void test_scalar_methods(ID3D10EffectScalarVariable *var, D3D10_SHADER_VARIABLE_TYPE type, + const char *name) +{ + float ret_f, expected_f; + int ret_i, expected_i; + BOOL ret_b, expected_b; + HRESULT hr; + + hr = var->lpVtbl->SetFloat(var, 5.0f); + ok(hr == S_OK, "Var %s, SetFloat failed (%x).\n", name, hr); + + hr = var->lpVtbl->GetFloat(var, &ret_f); + ok(hr == S_OK, "Var %s, GetFloat failed (%x).\n", name, hr); + expected_f = type == D3D10_SVT_BOOL ? -1.0f : 5.0f; + ok(ret_f == expected_f, "Var %s, got unexpected value %.8e.\n", name, ret_f); + + hr = var->lpVtbl->GetInt(var, &ret_i); + ok(hr == S_OK, "Var %s, GetInt failed (%x).\n", name, hr); + expected_i = type == D3D10_SVT_BOOL ? -1 : 5; + ok(ret_i == expected_i, "Var %s, got unexpected value %#x.\n", name, ret_i); + + hr = var->lpVtbl->GetBool(var, &ret_b); + ok(hr == S_OK, "Var %s, GetBool failed (%x).\n", name, hr); + ok(ret_b == -1, "Var %s, got unexpected value %#x.\n", name, ret_b); + + hr = var->lpVtbl->SetInt(var, 2); + ok(hr == S_OK, "Var %s, SetInt failed (%x).\n", name, hr); + + hr = var->lpVtbl->GetFloat(var, &ret_f); + ok(hr == S_OK, "Var %s, GetFloat failed (%x).\n", name, hr); + expected_f = type == D3D10_SVT_BOOL ? -1.0f : 2.0f; + ok(ret_f == expected_f, "Var %s, got unexpected value %.8e.\n", name, ret_f); + + hr = var->lpVtbl->GetInt(var, &ret_i); + ok(hr == S_OK, "Var %s, GetInt failed (%x).\n", name, hr); + expected_i = type == D3D10_SVT_BOOL ? -1 : 2; + ok(ret_i == expected_i, "Var %s, got unexpected value %#x.\n", name, ret_i); + + hr = var->lpVtbl->GetBool(var, &ret_b); + ok(hr == S_OK, "Var %s, GetBool failed (%x).\n", name, hr); + ok(ret_b == -1, "Var %s, got unexpected value %#x.\n", name, ret_b); + + hr = var->lpVtbl->SetBool(var, TRUE); + ok(hr == S_OK, "Var %s, SetBool failed (%x).\n", name, hr); + + hr = var->lpVtbl->GetFloat(var, &ret_f); + ok(hr == S_OK, "Var %s, GetFloat failed (%x).\n", name, hr); + ok(ret_f == -1.0f, "Var %s, got unexpected value %.8e.\n", name, ret_f); + + hr = var->lpVtbl->GetInt(var, &ret_i); + ok(hr == S_OK, "Var %s, GetInt failed (%x).\n", name, hr); + ok(ret_i == -1, "Var %s, got unexpected value %#x.\n", name, ret_i); + + hr = var->lpVtbl->GetBool(var, &ret_b); + ok(hr == S_OK, "Var %s, GetBool failed (%x).\n", name, hr); + expected_b = type == D3D10_SVT_BOOL ? TRUE : -1; + ok(ret_b == expected_b, "Var %s, got unexpected value %#x.\n", name, ret_b); + + hr = var->lpVtbl->SetBool(var, 32); + ok(hr == S_OK, "Var %s, SetBool failed (%x).\n", name, hr); + + hr = var->lpVtbl->GetFloat(var, &ret_f); + ok(hr == S_OK, "Var %s, GetFloat failed (%x).\n", name, hr); + ok(ret_f == -1.0f, "Got unexpected value %.8e.\n", ret_f); + + hr = var->lpVtbl->GetInt(var, &ret_i); + ok(hr == S_OK, "Var %s, GetInt failed (%x).\n", name, hr); + ok(ret_i == -1, "Got unexpected value %#x.\n", ret_i); + + hr = var->lpVtbl->GetBool(var, &ret_b); + ok(hr == S_OK, "Var %s, GetBool failed (%x).\n", name, hr); + expected_b = type == D3D10_SVT_BOOL ? 32 : -1; + ok(ret_b == expected_b, "Var %s, got unexpected value %#x.\n", name, ret_b); +} + +static void test_scalar_array_methods(ID3D10EffectScalarVariable *var, D3D10_SHADER_VARIABLE_TYPE type, + const char *name) +{ + float set_f[2], ret_f[2], expected_f; + int set_i[6], ret_i[6], expected_i, expected_i_a[2]; + BOOL set_b[2], ret_b[2], expected_b, expected_b_a[6]; + unsigned int i; + HRESULT hr; + + set_f[0] = 10.0f; set_f[1] = 20.0f; + hr = var->lpVtbl->SetFloatArray(var, set_f, 0, 2); + ok(hr == S_OK, "Var %s, SetFloatArray failed (%x).\n", name, hr); + + hr = var->lpVtbl->GetFloatArray(var, ret_f, 0, 2); + ok(hr == S_OK, "Var %s, GetFloatArray failed (%x).\n", name, hr); + for (i = 0; i < 2; i++) + { + expected_f = type == D3D10_SVT_BOOL ? -1.0f : set_f[i]; + ok(ret_f[i] == expected_f, "Var %s, got unexpected value %.8e.\n", name, ret_f[i]); + } + + hr = var->lpVtbl->GetIntArray(var, ret_i, 0, 2); + ok(hr == S_OK, "Var %s, GetIntArray failed (%x).\n", name, hr); + for (i = 0; i < 2; i++) + { + expected_i = type == D3D10_SVT_BOOL ? -1 : (int)set_f[i]; + ok(ret_i[i] == expected_i, "Var %s, got unexpected value %#x.\n", name, ret_i[i]); + } + + hr = var->lpVtbl->GetBoolArray(var, ret_b, 0, 2); + ok(hr == S_OK, "Var %s, GetBoolArray failed (%x).\n", name, hr); + for (i = 0; i < 2; i++) + ok(ret_b[i] == -1, "Var %s, got unexpected value %#x.\n", name, ret_b[i]); + + set_i[0] = 5; set_i[1] = 6; + hr = var->lpVtbl->SetIntArray(var, set_i, 0, 2); + ok(hr == S_OK, "Var %s, SetIntArray failed (%x).\n", name, hr); + + hr = var->lpVtbl->GetFloatArray(var, ret_f, 0, 2); + ok(hr == S_OK, "Var %s, GetFloatArray failed (%x).\n", name, hr); + for (i = 0; i < 2; i++) + { + expected_f = type == D3D10_SVT_BOOL ? -1.0f : (float)set_i[i]; + ok(ret_f[i] == expected_f, "Var %s, got unexpected value %.8e.\n", name, ret_f[i]); + } + + hr = var->lpVtbl->GetIntArray(var, ret_i, 0, 2); + ok(hr == S_OK, "Var %s, GetIntArray failed (%x).\n", name, hr); + for (i = 0; i < 2; i++) + { + expected_i = type == D3D10_SVT_BOOL ? -1 : set_i[i]; + ok(ret_i[i] == expected_i, "Var %s, got unexpected value %#x.\n", name, ret_i[i]); + } + + hr = var->lpVtbl->GetBoolArray(var, ret_b, 0, 2); + ok(hr == S_OK, "Var %s, GetBoolArray failed (%x).\n", name, hr); + for (i = 0; i < 2; i++) + ok(ret_b[i] == -1, "Var %s, got unexpected value %#x.\n", name, ret_b[i]); + + set_b[0] = TRUE; set_b[1] = TRUE; + hr = var->lpVtbl->SetBoolArray(var, set_b, 0, 2); + ok(hr == S_OK, "Var %s, SetBoolArray failed (%x).\n", name, hr); + + hr = var->lpVtbl->GetFloatArray(var, ret_f, 0, 2); + ok(hr == S_OK, "Var %s, GetFloatArray failed (%x).\n", name, hr); + for (i = 0; i < 2; i++) + ok(ret_f[i] == -1.0f, "Var %s, got unexpected value %.8e.\n", name, ret_f[i]); + + hr = var->lpVtbl->GetIntArray(var, ret_i, 0, 2); + ok(hr == S_OK, "Var %s, GetIntArray failed (%x).\n", name, hr); + for (i = 0; i < 2; i++) + ok(ret_i[i] == -1, "Var %s, got unexpected value %#x.\n", name, ret_i[i]); + + hr = var->lpVtbl->GetBoolArray(var, ret_b, 0, 2); + ok(hr == S_OK, "Var %s, GetBoolArray failed (%x).\n", name, hr); + for (i = 0; i < 2; i++) + { + expected_b = type == D3D10_SVT_BOOL ? TRUE : -1; + ok(ret_b[i] == expected_b, "Var %s, got unexpected value %#x.\n", name, ret_b[i]); + } + + set_b[0] = 10; set_b[1] = 20; + hr = var->lpVtbl->SetBoolArray(var, set_b, 0, 2); + ok(hr == S_OK, "Var %s, SetBoolArray failed (%x).\n", name, hr); + + hr = var->lpVtbl->GetFloatArray(var, ret_f, 0, 2); + ok(hr == S_OK, "Var %s, GetFloatArray failed (%x).\n", name, hr); + for (i = 0; i < 2; i++) + ok(ret_f[i] == -1.0f, "Var %s, Got unexpected value %.8e.\n", name, ret_f[i]); + + hr = var->lpVtbl->GetIntArray(var, ret_i, 0, 2); + ok(hr == S_OK, "Var %s, GetIntArray failed (%x).\n", name, hr); + for (i = 0; i < 2; i++) + ok(ret_i[i] == -1, "Var %s, got unexpected value %#x.\n", name, ret_i[i]); + + hr = var->lpVtbl->GetBoolArray(var, ret_b, 0, 2); + ok(hr == S_OK, "Var %s, GetBoolArray failed (%x).\n", name, hr); + for (i = 0; i < 2; i++) + { + expected_b = type == D3D10_SVT_BOOL ? set_b[i] : -1; + ok(ret_b[i] == expected_b, "Var %s, got unexpected value %#x.\n", name, ret_b[i]); + } + + /* Array offset tests. Offset argument goes unused for scalar arrays. */ + set_i[0] = 0; set_i[1] = 0; + hr = var->lpVtbl->SetIntArray(var, set_i, 0, 2); + ok(hr == S_OK, "Var %s, SetIntArray failed (%x).\n", name, hr); + + /* After this, if offset is in use, return should be { 0, 5 }. */ + set_i[0] = 5; + hr = var->lpVtbl->SetIntArray(var, set_i, 1, 1); + ok(hr == S_OK, "Var %s, SetIntArray failed (%x).\n", name, hr); + + hr = var->lpVtbl->GetIntArray(var, ret_i, 0, 2); + ok(hr == S_OK, "Var %s, GetIntArray failed (%x).\n", name, hr); + expected_b_a[0] = -1; expected_b_a[1] = 0; + expected_i_a[0] = 5; expected_i_a[1] = 0; + for (i = 0; i < 2; i++) + { + expected_i = type == D3D10_SVT_BOOL ? expected_b_a[i] : expected_i_a[i]; + ok(ret_i[i] == expected_i, "Var %s, got unexpected value %#x.\n", name, ret_i[i]); + } + + /* Test the offset on GetArray methods. If offset was in use, we'd get + * back 5 given that the variable was previously set to { 0, 5 }. */ + hr = var->lpVtbl->GetIntArray(var, ret_i, 1, 1); + ok(hr == S_OK, "Var %s, GetIntArray failed (%x).\n", name, hr); + expected_i = type == D3D10_SVT_BOOL ? -1 : 5; + ok(ret_i[0] == expected_i, "Var %s, got unexpected value %#x.\n", name, ret_i[0]); + + /* Try setting offset larger than number of elements. */ + /* Clear array. */ + set_i[0] = 0; set_i[1] = 0; + hr = var->lpVtbl->SetIntArray(var, set_i, 0, 2); + ok(hr == S_OK, "Var %s, SetIntArray failed (%x).\n", name, hr); + + set_i[0] = 1; + hr = var->lpVtbl->SetIntArray(var, set_i, 6, 1); + ok(hr == S_OK, "Var %s, SetIntArray failed (%x).\n", name, hr); + + /* Since offset goes unused, a larger offset than the number of elements + * in the array should have no effect. */ + hr = var->lpVtbl->GetIntArray(var, ret_i, 0, 1); + ok(hr == S_OK, "Var %s, GetIntArray failed (%x).\n", name, hr); + expected_i = type == D3D10_SVT_BOOL ? -1 : 1; + ok(ret_i[0] == expected_i, "Var %s, got unexpected value %#x.\n", name, ret_i[0]); + + memset(ret_i, 0, sizeof(ret_i)); + hr = var->lpVtbl->GetIntArray(var, ret_i, 6, 1); + ok(hr == S_OK, "Var %s, GetIntArray failed (%x).\n", name, hr); + expected_i = type == D3D10_SVT_BOOL ? -1 : 1; + ok(ret_i[0] == expected_i, "Var %s, got unexpected value %#x.\n", name, ret_i[0]); + +if (0) +{ + /* Windows array setting function has no bounds checking, so this test + * ends up writing over into the adjacent variables in the local buffer. */ + set_i[0] = 1; set_i[1] = 2; set_i[2] = 3; set_i[3] = 4; set_i[4] = 5; set_i[5] = 6; + hr = var->lpVtbl->SetIntArray(var, set_i, 0, 6); + ok(hr == S_OK, "Var %s, SetIntArray failed (%x).\n", name, hr); + + memset(ret_i, 0, sizeof(ret_i)); + hr = var->lpVtbl->GetIntArray(var, ret_i, 0, 6); + ok(hr == S_OK, "Var %s, GetIntArray failed (%x).\n", name, hr); + + expected_i_a[0] = 1; expected_i_a[1] = 2; expected_i_a[2] = 0; expected_i_a[3] = 0; + expected_i_a[4] = 0; expected_i_a[5] = 0; + expected_b_a[0] = -1; expected_b_a[1] = -1; expected_b_a[2] = 0; expected_b_a[3] = 0; + expected_b_a[4] = 0; expected_b_a[5] = 0; + for (i = 0; i < 6; ++i) + { + expected_i = type == D3D10_SVT_BOOL ? expected_b_a[i] : expected_i_a[i]; + ok(ret_i[i] == expected_i, "Var %s, got unexpected value %#x.\n", name, ret_i[i]); + } +} +} + +static void test_effect_scalar_variable(void) +{ + ID3D10Device *device; + ID3D10Effect *effect; + ID3D10EffectVariable *var; + ID3D10EffectType *type; + ID3D10EffectScalarVariable *s_v; + D3D10_EFFECT_TYPE_DESC type_desc; + unsigned int i; + ULONG refcount; + HRESULT hr; + struct + { + const char *name; + D3D_SHADER_VARIABLE_TYPE type; + } tests[] = {{"f0", D3D10_SVT_FLOAT}, {"f_a", D3D10_SVT_FLOAT}, + {"i0", D3D10_SVT_INT}, {"i_a", D3D10_SVT_INT}, + {"b0", D3D10_SVT_BOOL}, {"b_a", D3D10_SVT_BOOL}}; + + if (!(device = create_device())) + { + skip("Failed to create device, skipping tests.\n"); + return; + } + + hr = create_effect(fx_test_scalar_variable, 0, device, NULL, &effect); + ok(SUCCEEDED(hr), "D3D10CreateEffectFromMemory failed (%x)\n", hr); + + /* Check each different scalar type, make sure the variable returned is + * valid, set it to a value, and make sure what we get back is the same + * as what we set it to. */ + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + var = effect->lpVtbl->GetVariableByName(effect, tests[i].name); + type = var->lpVtbl->GetType(var); + hr = type->lpVtbl->GetDesc(type, &type_desc); + ok(SUCCEEDED(hr), "GetDesc failed on variable %s (%x).\n", tests[i].name, hr); + ok(type_desc.Type == tests[i].type, "Got unexpected type on variable %s, (%#x).\n", tests[i].name, type_desc.Type); + s_v = var->lpVtbl->AsScalar(var); + test_scalar_methods(s_v, tests[i].type, tests[i].name); + if (i % 2) + test_scalar_array_methods(s_v, tests[i].type, tests[i].name); + } + + 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(); @@ -4285,4 +4635,5 @@ START_TEST(effect) test_effect_get_variable_by(); test_effect_state_groups(); test_effect_state_group_defaults(); + test_effect_scalar_variable(); }
Signed-off-by: Connor McAdams conmanx360@gmail.com --- dlls/d3d10/tests/effect.c | 396 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 396 insertions(+)
diff --git a/dlls/d3d10/tests/effect.c b/dlls/d3d10/tests/effect.c index 765edfa4dd..7affdb0e4d 100644 --- a/dlls/d3d10/tests/effect.c +++ b/dlls/d3d10/tests/effect.c @@ -4623,6 +4623,401 @@ static void test_effect_scalar_variable(void) ok(!refcount, "Device has %u references left.\n", refcount); }
+/* + * test_effect_vector_variable + */ +#if 0 +cbuffer cb +{ + float4 v_f0, v_f_a[2]; + int3 v_i0, v_i_a[3]; + bool2 v_b0, v_b_a[4]; +}; +#endif +static DWORD fx_test_vector_variable[] = +{ + 0x43425844, 0x581ae0ae, 0xa906b020, 0x26bba03e, + 0x5d7dfba2, 0x00000001, 0x0000021a, 0x00000001, + 0x00000024, 0x30315846, 0x000001ee, 0xfeff1001, + 0x00000001, 0x00000006, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x000000e2, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x66006263, + 0x74616f6c, 0x00070034, 0x00010000, 0x00000000, + 0x00100000, 0x00100000, 0x00100000, 0x210a0000, + 0x5f760000, 0x07003066, 0x01000000, 0x02000000, + 0x20000000, 0x10000000, 0x20000000, 0x0a000000, + 0x76000021, 0x615f665f, 0x746e6900, 0x00510033, + 0x00010000, 0x00000000, 0x000c0000, 0x00100000, + 0x000c0000, 0x19120000, 0x5f760000, 0x51003069, + 0x01000000, 0x03000000, 0x2c000000, 0x10000000, + 0x24000000, 0x12000000, 0x76000019, 0x615f695f, + 0x6f6f6200, 0x9900326c, 0x01000000, 0x00000000, + 0x08000000, 0x10000000, 0x08000000, 0x22000000, + 0x76000011, 0x0030625f, 0x00000099, 0x00000001, + 0x00000004, 0x00000038, 0x00000010, 0x00000020, + 0x00001122, 0x5f625f76, 0x00040061, 0x00c00000, + 0x00000000, 0x00060000, 0xffff0000, 0x0000ffff, + 0x002a0000, 0x000e0000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x004b0000, + 0x002f0000, 0x00000000, 0x00100000, 0x00000000, + 0x00000000, 0x00000000, 0x00720000, 0x00560000, + 0x00000000, 0x00300000, 0x00000000, 0x00000000, + 0x00000000, 0x00930000, 0x00770000, 0x00000000, + 0x00400000, 0x00000000, 0x00000000, 0x00000000, + 0x00bb0000, 0x009f0000, 0x00000000, 0x00700000, + 0x00000000, 0x00000000, 0x00000000, 0x00dc0000, + 0x00c00000, 0x00000000, 0x00800000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, +}; + +static void test_vector_methods(ID3D10EffectVectorVariable *var, D3D10_SHADER_VARIABLE_TYPE type, + const char *name, unsigned int components) +{ + float set_f[4], ret_f[4], expected_f, expected_f_v[4]; + int set_i[4], ret_i[4], expected_i, expected_i_v[4]; + BOOL set_b[4], ret_b[4], expected_b; + unsigned int i; + HRESULT hr; + + set_f[0] = 1.0f; set_f[1] = 2.0f; set_f[2] = 3.0f; set_f[3] = 4.0f; + hr = var->lpVtbl->SetFloatVector(var, set_f); + ok(hr == S_OK, "Var %s, SetFloatVector failed (%x).\n", name, hr); + + hr = var->lpVtbl->GetFloatVector(var, ret_f); + ok(hr == S_OK, "Var %s, GetFloatVector failed (%x).\n", name, hr); + for (i = 0; i < components; i++) + { + expected_f = type == D3D10_SVT_BOOL ? -1.0f : set_f[i]; + ok(ret_f[i] == expected_f, "Var %s, got unexpected value %.8e.\n", name, ret_f[i]); + } + + hr = var->lpVtbl->GetIntVector(var, ret_i); + ok(hr == S_OK, "Var %s, GetIntVector failed (%x).\n", name, hr); + for (i = 0; i < components; i++) + { + expected_i = type == D3D10_SVT_BOOL ? -1 : (int)set_f[i]; + ok(ret_i[i] == expected_i, "Var %s, got unexpected value %#x.\n", name, ret_i[i]); + } + + hr = var->lpVtbl->GetBoolVector(var, ret_b); + ok(hr == S_OK, "Var %s, GetBoolVector failed (%x).\n", name, hr); + for (i = 0; i < components; i++) + ok(ret_b[i] == -1, "Got unexpected value %#x.\n", ret_b[i]); + + set_i[0] = 5; set_i[1] = 6; set_i[2] = 7; set_i[3] = 8; + hr = var->lpVtbl->SetIntVector(var, set_i); + ok(hr == S_OK, "Var %s, SetIntVector failed (%x).\n", name, hr); + + hr = var->lpVtbl->GetFloatVector(var, ret_f); + ok(hr == S_OK, "Var %s, GetFloatVector failed (%x).\n", name, hr); + for (i = 0; i < components; i++) + { + expected_f = type == D3D10_SVT_BOOL ? -1.0f : (float)set_i[i]; + ok(ret_f[i] == expected_f, "Var %s, got unexpected value %.8e.\n", name, ret_f[i]); + } + + hr = var->lpVtbl->GetIntVector(var, ret_i); + ok(hr == S_OK, "Var %s, GetIntVector failed (%x).\n", name, hr); + for (i = 0; i < components; i++) + { + expected_i = type == D3D10_SVT_BOOL ? -1 : set_i[i]; + ok(ret_i[i] == expected_i, "Var %s, got unexpected value %#x.\n", name, ret_i[i]); + } + + hr = var->lpVtbl->GetBoolVector(var, ret_b); + ok(hr == S_OK, "Var %s, GetBoolVector failed (%x).\n", name, hr); + for (i = 0; i < components; i++) + ok(ret_b[i] == -1, "Var %s, got unexpected value %#x.\n", name, ret_b[i]); + + set_b[0] = TRUE; set_b[1] = FALSE; set_b[2] = TRUE; set_b[3] = FALSE; + hr = var->lpVtbl->SetBoolVector(var, set_b); + ok(hr == S_OK, "Var %s, SetBoolVector failed (%x).\n", name, hr); + + hr = var->lpVtbl->GetFloatVector(var, ret_f); + ok(hr == S_OK, "Var %s, GetFloatVector failed (%x).\n", name, hr); + expected_f_v[0] = -1.0f; expected_f_v[1] = 0.0f; expected_f_v[2] = -1.0f; expected_f_v[3] = 0.0f; + for (i = 0; i < components; i++) + ok(ret_f[i] == expected_f_v[i], "Var %s, got unexpected value %.8e.\n", name, ret_f[i]); + + hr = var->lpVtbl->GetIntVector(var, ret_i); + ok(hr == S_OK, "Var %s, GetIntVector failed (%x).\n", name, hr); + expected_i_v[0] = -1; expected_i_v[1] = 0; expected_i_v[2] = -1; expected_i_v[3] = 0; + for (i = 0; i < components; i++) + ok(ret_i[i] == expected_i_v[i], "Var %s, got unexpected value %#x.\n", name, ret_i[i]); + + hr = var->lpVtbl->GetBoolVector(var, ret_b); + ok(hr == S_OK, "Var %s, GetBoolVector failed (%x).\n", name, hr); + for (i = 0; i < components; i++) + { + expected_b = type == D3D10_SVT_BOOL ? set_b[i] : expected_i_v[i]; + ok(ret_b[i] == expected_b, "Var %s, got unexpected value %#x.\n", name, ret_b[i]); + } + + /* See what happens if we use SetBoolVector with a value that isn't TRUE + * or FALSE. */ + set_b[0] = 5; set_b[1] = 10; set_b[2] = 15; set_b[3] = 20; + hr = var->lpVtbl->SetBoolVector(var, set_b); + ok(hr == S_OK, "Var %s, SetBoolVector failed (%x).\n", name, hr); + + hr = var->lpVtbl->GetFloatVector(var, ret_f); + ok(hr == S_OK, "Var %s, GetFloatVector failed (%x).\n", name, hr); + for (i = 0; i < components; i++) + ok(ret_f[i] == -1.0f, "Var %s, got unexpected value %.8e.\n", name, ret_f[i]); + + hr = var->lpVtbl->GetIntVector(var, ret_i); + ok(hr == S_OK, "Var %s, GetIntVector failed (%x).\n", name, hr); + for (i = 0; i < components; i++) + ok(ret_i[i] == -1, "Var %s, got unexpected value %#x.\n", name, ret_i[i]); + + hr = var->lpVtbl->GetBoolVector(var, ret_b); + ok(hr == S_OK, "Var %s, GetBoolVector failed (%x).\n", name, hr); + for (i = 0; i < components; i++) + { + expected_b = type == D3D10_SVT_BOOL ? set_b[i] : -1; + ok(ret_b[i] == expected_b, "Var %s, got unexpected value %#x.\n", name, ret_b[i]); + } +} + +static void test_vector_array_methods(ID3D10EffectVectorVariable *var, D3D10_SHADER_VARIABLE_TYPE type, + const char *name, unsigned int components, unsigned int elements) +{ + float set_f[9], ret_f[9], expected_f, expected_f_a[9]; + int set_i[9], ret_i[9], expected_i, expected_i_a[9]; + BOOL set_b[9], ret_b[9], expected_b; + unsigned int i; + HRESULT hr; + + /* SetFloatVectorArray test. */ + set_f[0] = 1.0f; set_f[1] = 2.0f; set_f[2] = 3.0f; set_f[3] = 4.0f; + set_f[4] = 5.0f; set_f[5] = 6.0f; set_f[6] = 7.0f; set_f[7] = 8.0f; + set_f[8] = 9.0f; + hr = var->lpVtbl->SetFloatVectorArray(var, set_f, 0, elements); + ok(hr == S_OK, "Var %s, SetFloatVectorArray failed (%x).\n", name, hr); + + hr = var->lpVtbl->GetFloatVectorArray(var, ret_f, 0, elements); + ok(hr == S_OK, "Var %s, GetFloatVectorArray failed (%x).\n", name, hr); + for (i = 0; i < components * elements; i++) + { + expected_f = type == D3D10_SVT_BOOL ? -1.0f : set_f[i]; + ok(ret_f[i] == expected_f, "Var %s, got unexpected value %.8e.\n", name, ret_f[i]); + } + + hr = var->lpVtbl->GetIntVectorArray(var, ret_i, 0, elements); + ok(hr == S_OK, "Var %s, GetIntVectorArray failed (%x).\n", name, hr); + for (i = 0; i < components * elements; i++) + { + expected_i = type == D3D10_SVT_BOOL ? -1 : (int)set_f[i]; + ok(ret_i[i] == expected_i, "Var %s, got unexpected value %#x.\n", name, ret_i[i]); + } + + hr = var->lpVtbl->GetBoolVectorArray(var, ret_b, 0, elements); + ok(hr == S_OK, "Var %s, GetBoolVectorArray failed (%x).\n", name, hr); + for (i = 0; i < components * elements; i++) + ok(ret_b[i] == -1, "Var %s, got unexpected value %#x.\n", name, ret_b[i]); + + /* SetIntVectorArray test. */ + set_i[0] = 10; set_i[1] = 11; set_i[2] = 12; set_i[3] = 13; + set_i[4] = 14; set_i[5] = 15; set_i[6] = 16; set_i[7] = 17; + set_i[8] = 18; + hr = var->lpVtbl->SetIntVectorArray(var, set_i, 0, elements); + ok(hr == S_OK, "Var %s, SetIntVectorArray failed (%x).\n", name, hr); + + hr = var->lpVtbl->GetFloatVectorArray(var, ret_f, 0, elements); + ok(hr == S_OK, "Var %s, GetFloatVectorArray failed (%x).\n", name, hr); + for (i = 0; i < components * elements; i++) + { + expected_f = type == D3D10_SVT_BOOL ? -1.0f : (float)set_i[i]; + ok(ret_f[i] == expected_f, "Var %s, got unexpected value %.8e.\n", name, ret_f[i]); + } + + hr = var->lpVtbl->GetIntVectorArray(var, ret_i, 0, elements); + ok(hr == S_OK, "Var %s, GetIntVectorArray failed (%x).\n", name, hr); + for (i = 0; i < components * elements; i++) + { + expected_i = type == D3D10_SVT_BOOL ? -1 : set_i[i]; + ok(ret_i[i] == expected_i, "Var %s, got unexpected value %#x.\n", name, ret_i[i]); + } + + hr = var->lpVtbl->GetBoolVectorArray(var, ret_b, 0, elements); + ok(hr == S_OK, "Var %s, GetBoolVectorArray failed (%x).\n", name, hr); + for (i = 0; i < components * elements; i++) + ok(ret_b[i] == -1, "Var %s, got unexpected value %#x.\n", name, ret_b[i]); + + /* SetBoolVectorArray test. */ + set_b[0] = TRUE; set_b[1] = FALSE; set_b[2] = TRUE; set_b[3] = TRUE; + set_b[4] = TRUE; set_b[5] = FALSE; set_b[6] = FALSE; set_b[7] = TRUE; + set_b[8] = TRUE; + hr = var->lpVtbl->SetBoolVectorArray(var, set_b, 0, elements); + ok(hr == S_OK, "Var %s, SetBoolVectorArray failed (%x).\n", name, hr); + + hr = var->lpVtbl->GetFloatVectorArray(var, ret_f, 0, elements); + ok(hr == S_OK, "Var %s, GetFloatVectorArray failed (%x).\n", name, hr); + expected_f_a[0] = -1.0f; expected_f_a[1] = 0.0f; expected_f_a[2] = -1.0f; expected_f_a[3] = -1.0f; + expected_f_a[4] = -1.0f; expected_f_a[5] = 0.0f; expected_f_a[6] = 0.0f; expected_f_a[7] = -1.0f; + expected_f_a[8] = -1.0f; + for (i = 0; i < components * elements; i++) + ok(ret_f[i] == expected_f_a[i], "Var %s, got unexpected value %.8e.\n", name, ret_f[i]); + + hr = var->lpVtbl->GetIntVectorArray(var, ret_i, 0, elements); + ok(hr == S_OK, "Var %s, GetIntVectorArray failed (%x).\n", name, hr); + expected_i_a[0] = -1; expected_i_a[1] = 0; expected_i_a[2] = -1; expected_i_a[3] = -1; + expected_i_a[4] = -1; expected_i_a[5] = 0; expected_i_a[6] = 0; expected_i_a[7] = -1; + expected_i_a[8] = -1; + for (i = 0; i < components * elements; i++) + ok(ret_i[i] == expected_i_a[i], "Var %s, got unexpected value %#x.\n", name, ret_i[i]); + + hr = var->lpVtbl->GetBoolVectorArray(var, ret_b, 0, elements); + ok(hr == S_OK, "Var %s, GetBoolVectorArray failed (%x).\n", name, hr); + for (i = 0; i < components * elements; i++) + { + expected_b = type == D3D10_SVT_BOOL ? set_b[i] : expected_i_a[i]; + ok(ret_b[i] == expected_b, "Var %s, got unexpected value %#x.\n", name, ret_b[i]); + } + + /* See what happens if we use SetBoolVectorArray with a value that isn't + * TRUE or FALSE. */ + set_b[0] = 5; set_b[1] = 10; set_b[2] = 15; set_b[3] = 20; + set_b[4] = 25; set_b[5] = 30; set_b[6] = 35; set_b[7] = 40; + set_b[8] = 45; + hr = var->lpVtbl->SetBoolVectorArray(var, set_b, 0, elements); + ok(hr == S_OK, "Var %s, SetBoolVectorArray failed (%x).\n", name, hr); + + hr = var->lpVtbl->GetFloatVectorArray(var, ret_f, 0, elements); + ok(hr == S_OK, "Var %s, GetFloatVectorArray failed (%x).\n", name, hr); + for (i = 0; i < components * elements; i++) + ok(ret_f[i] == -1.0f, "Var %s, got unexpected value %.8e.\n", name, ret_f[i]); + + hr = var->lpVtbl->GetIntVectorArray(var, ret_i, 0, elements); + ok(hr == S_OK, "Var %s, GetIntVectorArray failed (%x).\n", name, hr); + for (i = 0; i < components * elements; i++) + ok(ret_i[i] == -1, "Var %s, got unexpected value %#x.\n", name, ret_i[i]); + + hr = var->lpVtbl->GetBoolVectorArray(var, ret_b, 0, elements); + ok(hr == S_OK, "Var %s, GetBoolVectorArray failed (%x).\n", name, hr); + for (i = 0; i < components * elements; i++) + { + expected_b = type == D3D10_SVT_BOOL ? set_b[i] : -1; + ok(ret_b[i] == expected_b, "Var %s, got unexpected value %#x.\n", name, ret_b[i]); + } + + /* According to MSDN, the offset argument goes unused for VectorArray + * methods, same as the ScalarArray methods. However, testing has shown + * this to not be the case. So, test for the correct behavior here. */ + /* Clear the array first. */ + set_b[0] = FALSE; set_b[1] = FALSE; set_b[2] = FALSE; set_b[3] = FALSE; + set_b[4] = FALSE; set_b[5] = FALSE; set_b[6] = FALSE; set_b[7] = FALSE; + set_b[8] = FALSE; + hr = var->lpVtbl->SetBoolVectorArray(var, set_b, 0, elements); + ok(hr == S_OK, "Var %s, SetBoolVectorArray failed (%x).\n", name, hr); + + set_b[0] = TRUE; set_b[1] = TRUE; set_b[2] = TRUE; set_b[3] = TRUE; + hr = var->lpVtbl->SetBoolVectorArray(var, set_b, 1, 1); + + /* If the previous offset of 1 worked, then the first vector value of the + * array should still be false. */ + hr = var->lpVtbl->GetFloatVectorArray(var, ret_f, 0, 1); + ok(hr == S_OK, "Var %s, GetFloatVectorArray failed (%x).\n", name, hr); + for (i = 0; i < components; i++) + ok(ret_f[i] == 0, "Var %s, got unexpected value %.8e.\n", name, ret_f[i]); + + hr = var->lpVtbl->GetIntVectorArray(var, ret_i, 0, 1); + ok(hr == S_OK, "Var %s, GetIntVectorArray failed (%x).\n", name, hr); + for (i = 0; i < components; i++) + ok(ret_i[i] == 0, "Var %s, got unexpected value %#x.\n", name, ret_i[i]); + + hr = var->lpVtbl->GetBoolVectorArray(var, ret_b, 0, 1); + ok(hr == S_OK, "Var %s, GetBoolVectorArray failed (%x).\n", name, hr); + for (i = 0; i < components; i++) + ok(!ret_b[i], "Var %s, got unexpected value %#x.\n", name, ret_b[i]); + + /* Test the GetFloatVectorArray offset argument. If it works, we should + * get a vector with all values set to true. */ + hr = var->lpVtbl->GetFloatVectorArray(var, ret_f, 1, 1); + ok(hr == S_OK, "Var %s, GetFloatVectorArray failed (%x).\n", name, hr); + for (i = 0; i < components; i++) + ok(ret_f[i] == -1.0f, "Var %s, got unexpected value %.8e.\n", name, ret_f[i]); + + hr = var->lpVtbl->GetIntVectorArray(var, ret_i, 1, 1); + ok(hr == S_OK, "Var %s, GetIntVectorArray failed (%x).\n", name, hr); + for (i = 0; i < components; i++) + ok(ret_i[i] == -1, "Var %s, got unexpected value %#x.\n", name, ret_i[i]); + + hr = var->lpVtbl->GetBoolVectorArray(var, ret_b, 1, 1); + ok(hr == S_OK, "Var %s, GetBoolVectorArray failed (%x).\n", name, hr); + for (i = 0; i < components; i++) + { + expected_b = type == D3D10_SVT_BOOL ? TRUE : -1; + ok(ret_b[i] == expected_b, "Var %s, got unexpected value %#x.\n", name, ret_b[i]); + } + +if (0) +{ + /* Windows array setting function has no bounds checking on offset values + * either, so this ends up writing into adjacent variables. */ + hr = var->lpVtbl->SetBoolVectorArray(var, set_b, elements + 1, 1); + ok(hr == S_OK, "Var %s, GetBoolVectorArray failed (%x).\n", name, hr); + + hr = var->lpVtbl->GetBoolVectorArray(var, ret_b, elements + 1, 1); + ok(hr == S_OK, "Var %s, GetBoolVectorArray failed (%x).\n", name, hr); + for (i = 0; i < components; i++) + { + expected_b = type == D3D10_SVT_BOOL ? TRUE : -1; + ok(ret_b[i] == expected_b, "Var %s, got unexpected value %#x.\n", name, ret_b[i]); + } +} +} + +static void test_effect_vector_variable(void) +{ + ID3D10Device *device; + ID3D10Effect *effect; + ID3D10EffectVariable *var; + ID3D10EffectType *type; + ID3D10EffectVectorVariable *v_var; + D3D10_EFFECT_TYPE_DESC type_desc; + unsigned int i; + ULONG refcount; + HRESULT hr; + struct + { + const char *name; + D3D_SHADER_VARIABLE_TYPE type; + unsigned int components; + unsigned int elements; + } tests[] = {{"v_f0", D3D10_SVT_FLOAT, 4, 1}, {"v_f_a", D3D10_SVT_FLOAT, 4, 2}, + {"v_i0", D3D10_SVT_INT, 3, 1}, {"v_i_a", D3D10_SVT_INT, 3, 3}, + {"v_b0", D3D10_SVT_BOOL, 2, 1}, {"v_b_a", D3D10_SVT_BOOL, 2, 4}}; + + if (!(device = create_device())) + { + skip("Failed to create device, skipping tests.\n"); + return; + } + + hr = create_effect(fx_test_vector_variable, 0, device, NULL, &effect); + ok(SUCCEEDED(hr), "D3D10CreateEffectFromMemory failed (%x)\n", hr); + + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + var = effect->lpVtbl->GetVariableByName(effect, tests[i].name); + type = var->lpVtbl->GetType(var); + hr = type->lpVtbl->GetDesc(type, &type_desc); + ok(SUCCEEDED(hr), "GetDesc failed on variable %s (%x).\n", tests[i].name, hr); + ok(type_desc.Type == tests[i].type, "Got unexpected type on variable %s, (%#x).\n", tests[i].name, type_desc.Type); + v_var = var->lpVtbl->AsVector(var); + test_vector_methods(v_var, tests[i].type, tests[i].name, tests[i].components); + if (i % 2) + test_vector_array_methods(v_var, tests[i].type, tests[i].name, tests[i].components, tests[i].elements); + } + + 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(); @@ -4636,4 +5031,5 @@ START_TEST(effect) test_effect_state_groups(); test_effect_state_group_defaults(); test_effect_scalar_variable(); + test_effect_vector_variable(); }