Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d3d10/effect.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c index 3b4050460a0..7590bba6317 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c @@ -8551,6 +8551,7 @@ HRESULT WINAPI D3D10CreateEffectFromMemory(void *data, SIZE_T data_size, UINT fl if (FAILED(hr = d3d10_create_effect(data, data_size, device, pool, 0, &object))) { WARN("Failed to create an effect, hr %#x.\n", hr); + return hr; }
*effect = &object->ID3D10Effect_iface;
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com ---
dlls/d3d10/effect.c | 24 ++++++++++++++++++++++-- dlls/d3d10/tests/effect.c | 35 ++++++++++++++++++++++++++++++++--- 2 files changed, 54 insertions(+), 5 deletions(-)
diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c index 7590bba6317..3ceb1a1fbb3 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c @@ -21,6 +21,7 @@ #include "d3d10_private.h"
#include <float.h> +#include <stdint.h>
WINE_DEFAULT_DEBUG_CHANNEL(d3d10);
@@ -2075,10 +2076,25 @@ static HRESULT parse_fx10_technique(const char *data, size_t data_size, return S_OK; }
+static void d3d10_effect_variable_update_buffer_offsets(struct d3d10_effect_variable *v, + unsigned int offset) +{ + unsigned int i; + + for (i = 0; i < v->type->member_count; ++i) + d3d10_effect_variable_update_buffer_offsets(&v->members[i], offset); + + for (i = 0; i < v->type->element_count; ++i) + d3d10_effect_variable_update_buffer_offsets(&v->elements[i], offset); + + v->buffer_offset += offset; +} + 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; HRESULT hr;
if (FAILED(hr = parse_fx10_variable_head(data, data_size, ptr, v))) @@ -2094,8 +2110,8 @@ static HRESULT parse_fx10_numeric_variable(const char *data, size_t data_size, } TRACE("Variable semantic: %s.\n", debugstr_a(v->semantic));
- read_dword(ptr, &v->buffer_offset); - TRACE("Variable offset in buffer: %#x.\n", v->buffer_offset); + read_dword(ptr, &buffer_offset); + TRACE("Variable offset in buffer: %#x.\n", buffer_offset);
read_dword(ptr, &default_value_offset);
@@ -2104,6 +2120,10 @@ static HRESULT parse_fx10_numeric_variable(const char *data, size_t data_size,
v->flag |= flags;
+ /* At this point storage offsets for members and array elements are relative to containing + variable. Update them by moving to correct offset within a buffer. */ + d3d10_effect_variable_update_buffer_offsets(v, buffer_offset); + if (local) { if (default_value_offset) diff --git a/dlls/d3d10/tests/effect.c b/dlls/d3d10/tests/effect.c index bd5392fcd16..2844386ef51 100644 --- a/dlls/d3d10/tests/effect.c +++ b/dlls/d3d10/tests/effect.c @@ -5126,16 +5126,17 @@ static void test_effect_scalar_variable(void) {"i_a", D3D10_SVT_INT, TRUE}, {"b_a", D3D10_SVT_BOOL, TRUE}, }; + ID3D10EffectScalarVariable *s_v, *s_v2; + ID3D10EffectVariable *var, *var2; D3D10_EFFECT_TYPE_DESC type_desc; D3D10_EFFECT_DESC effect_desc; - ID3D10EffectScalarVariable *s_v; - ID3D10EffectVariable *var; ID3D10EffectType *type; ID3D10Device *device; ID3D10Effect *effect; unsigned int i; ULONG refcount; HRESULT hr; + float f;
if (!(device = create_device())) { @@ -5176,6 +5177,22 @@ static void test_effect_scalar_variable(void) test_scalar_array_methods(s_v, tests[i].type, tests[i].name); }
+ /* Verify that offsets are working correctly between array elements and adjacent data. */ + var = effect->lpVtbl->GetVariableByName(effect, "f0"); + s_v = var->lpVtbl->AsScalar(var); + hr = s_v->lpVtbl->SetFloat(s_v, 1.0f); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + var2 = effect->lpVtbl->GetVariableByName(effect, "f_a"); + var2 = var2->lpVtbl->GetElement(var2, 0); + s_v2 = var->lpVtbl->AsScalar(var2); + hr = s_v2->lpVtbl->SetFloat(s_v2, 2.0f); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = s_v->lpVtbl->GetFloat(s_v, &f); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(f == 1.0f, "Unexpected value %f.\n", f); + effect->lpVtbl->Release(effect);
refcount = ID3D10Device_Release(device); @@ -7310,10 +7327,11 @@ static DWORD fx_test_default_variable_value[] =
static void test_effect_default_variable_value(void) { + D3D10_EFFECT_VARIABLE_DESC var_desc; ID3D10EffectVectorVariable *vector; ID3D10EffectScalarVariable *scalar; + ID3D10EffectVariable *v, *v2; float float_v[4], float_s; - ID3D10EffectVariable *v; ID3D10Effect *effect; ID3D10Device *device; int int_v[2], int_s; @@ -7373,6 +7391,17 @@ todo_wine 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); + ok(var_desc.BufferOffset == 32, "Unexpected offset %u.\n", var_desc.BufferOffset); + v2 = v->lpVtbl->GetElement(v, 0); + hr = v2->lpVtbl->GetDesc(v2, &var_desc); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(var_desc.BufferOffset == 32, "Unexpected offset %u.\n", var_desc.BufferOffset); + v2 = v->lpVtbl->GetElement(v, 1); + hr = v2->lpVtbl->GetDesc(v2, &var_desc); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(var_desc.BufferOffset == 48, "Unexpected offset %u.\n", var_desc.BufferOffset);
float_s = 0.0f; v = effect->lpVtbl->GetVariableByName(effect, "f");
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com ---
This is necessary to handle default values. Buffer should be available before variables are processed, and after that d3d object is created fully initialized.
dlls/d3d10/effect.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-)
diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c index 3ceb1a1fbb3..dcfb09211bb 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c @@ -2346,7 +2346,7 @@ static HRESULT parse_fx10_object_variable(const char *data, size_t data_size, return S_OK; }
-static HRESULT create_variable_buffer(struct d3d10_effect_variable *v) +static HRESULT create_buffer_object(struct d3d10_effect_variable *v) { D3D10_BUFFER_DESC buffer_desc; D3D10_SUBRESOURCE_DATA subresource_data; @@ -2354,13 +2354,7 @@ static HRESULT create_variable_buffer(struct d3d10_effect_variable *v) ID3D10Device *device = v->effect->device; HRESULT hr;
- if (!(v->u.buffer.local_buffer = heap_alloc_zero(v->type->size_unpacked))) - { - ERR("Failed to allocate local constant buffer memory.\n"); - return E_OUTOFMEMORY; - } - - buffer_desc.ByteWidth = v->type->size_unpacked; + buffer_desc.ByteWidth = v->data_size; buffer_desc.Usage = D3D10_USAGE_DEFAULT; buffer_desc.CPUAccessFlags = 0; buffer_desc.MiscFlags = 0; @@ -2490,6 +2484,12 @@ static HRESULT parse_fx10_buffer(const char *data, size_t data_size, const char return E_OUTOFMEMORY; }
+ if (local && !(l->u.buffer.local_buffer = heap_alloc_zero(l->data_size))) + { + ERR("Failed to allocate local constant buffer memory.\n"); + return E_OUTOFMEMORY; + } + for (i = 0; i < l->type->member_count; ++i) { struct d3d10_effect_variable *v = &l->members[i]; @@ -2579,10 +2579,13 @@ static HRESULT parse_fx10_buffer(const char *data, size_t data_size, const char TRACE("\tBasetype: %s.\n", debug_d3d10_shader_variable_type(l->type->basetype)); TRACE("\tTypeclass: %s.\n", debug_d3d10_shader_variable_class(l->type->type_class));
- if (local && l->type->size_unpacked) + if (local && l->data_size) { - if (FAILED(hr = create_variable_buffer(l))) + if (FAILED(hr = create_buffer_object(l))) + { + WARN("Failed to create a buffer object, hr %#x.\n", hr); return hr; + } }
if (l->explicit_bind_point != ~0u)
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d3d10/effect.c | 40 +++++++++++++++++++++++++++++++++++++-- dlls/d3d10/tests/effect.c | 36 +++++++++++++++++++++++++++-------- 2 files changed, 66 insertions(+), 10 deletions(-)
diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c index dcfb09211bb..b11dfc9489a 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c @@ -4488,6 +4488,11 @@ static const struct ID3D10EffectVariableVtbl d3d10_effect_variable_vtbl = };
/* ID3D10EffectVariable methods */ +static inline struct d3d10_effect_variable *impl_from_ID3D10EffectConstantBuffer(ID3D10EffectConstantBuffer *iface) +{ + return CONTAINING_RECORD(iface, struct d3d10_effect_variable, ID3D10EffectVariable_iface); +} + static BOOL STDMETHODCALLTYPE d3d10_effect_constant_buffer_IsValid(ID3D10EffectConstantBuffer *iface) { TRACE("iface %p\n", iface); @@ -4649,9 +4654,26 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_constant_buffer_SetConstantBuffer( static HRESULT STDMETHODCALLTYPE d3d10_effect_constant_buffer_GetConstantBuffer(ID3D10EffectConstantBuffer *iface, ID3D10Buffer **buffer) { - FIXME("iface %p, buffer %p stub!\n", iface, buffer); + struct d3d10_effect_variable *v = impl_from_ID3D10EffectConstantBuffer(iface);
- return E_NOTIMPL; + TRACE("iface %p, buffer %p.\n", iface, buffer); + + if (!iface->lpVtbl->IsValid(iface)) + { + WARN("Null variable specified\n"); + return E_FAIL; + } + + if (v->type->basetype != D3D10_SVT_CBUFFER) + { + WARN("Wrong variable type %s.\n", debug_d3d10_shader_variable_type(v->type->basetype)); + return D3DERR_INVALIDCALL; + } + + *buffer = v->u.buffer.buffer; + ID3D10Buffer_AddRef(*buffer); + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d3d10_effect_constant_buffer_SetTextureBuffer(ID3D10EffectConstantBuffer *iface, @@ -4665,8 +4687,22 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_constant_buffer_SetTextureBuffer(I static HRESULT STDMETHODCALLTYPE d3d10_effect_constant_buffer_GetTextureBuffer(ID3D10EffectConstantBuffer *iface, ID3D10ShaderResourceView **view) { + struct d3d10_effect_variable *v = impl_from_ID3D10EffectConstantBuffer(iface); + FIXME("iface %p, view %p stub!\n", iface, view);
+ if (!iface->lpVtbl->IsValid(iface)) + { + WARN("Null variable specified\n"); + return E_FAIL; + } + + if (v->type->basetype != D3D10_SVT_TBUFFER) + { + WARN("Wrong variable type %s.\n", debug_d3d10_shader_variable_type(v->type->basetype)); + return D3DERR_INVALIDCALL; + } + return E_NOTIMPL; }
diff --git a/dlls/d3d10/tests/effect.c b/dlls/d3d10/tests/effect.c index 2844386ef51..ab3cdc71d9c 100644 --- a/dlls/d3d10/tests/effect.c +++ b/dlls/d3d10/tests/effect.c @@ -101,9 +101,12 @@ static void test_effect_constant_buffer_type(void) ID3D10EffectType *type, *type2, *null_type; D3D10_EFFECT_VARIABLE_DESC var_desc; D3D10_EFFECT_TYPE_DESC type_desc; + D3D10_BUFFER_DESC buffer_desc; + ID3D10ShaderResourceView *srv; ID3D10EffectVariable *v; D3D10_EFFECT_DESC desc; ID3D10Device *device; + ID3D10Buffer *buffer; ULONG refcount; HRESULT hr; LPCSTR string; @@ -155,6 +158,20 @@ static void test_effect_constant_buffer_type(void) ok(type_desc.UnpackedSize == 0x10, "UnpackedSize is %#x, expected 0x10\n", type_desc.UnpackedSize); ok(type_desc.Stride == 0x10, "Stride is %#x, expected 0x10\n", type_desc.Stride);
+ hr = constantbuffer->lpVtbl->GetConstantBuffer(constantbuffer, &buffer); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ID3D10Buffer_GetDesc(buffer, &buffer_desc); + ok(buffer_desc.ByteWidth == type_desc.UnpackedSize, "Unexpected buffer size %u.\n", buffer_desc.ByteWidth); + ok(!buffer_desc.Usage, "Unexpected buffer usage %u.\n", buffer_desc.Usage); + ok(buffer_desc.BindFlags == D3D10_BIND_CONSTANT_BUFFER, "Unexpected bind flags %#x.\n", + buffer_desc.BindFlags); + ok(!buffer_desc.CPUAccessFlags, "Unexpected CPU access flags %#x.\n", buffer_desc.CPUAccessFlags); + ok(!buffer_desc.MiscFlags, "Unexpected misc flags %#x.\n", buffer_desc.MiscFlags); + ID3D10Buffer_Release(buffer); + + hr = constantbuffer->lpVtbl->GetTextureBuffer(constantbuffer, &srv); + ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#x.\n", hr); + string = type->lpVtbl->GetMemberName(type, 0); ok(strcmp(string, "f1") == 0, "GetMemberName is "%s", expected "f1"\n", string);
@@ -244,6 +261,13 @@ static void test_effect_constant_buffer_type(void) ok(var_desc.BufferOffset == 0x20, "Unexpected buffer offset %#x.\n", var_desc.BufferOffset); ok(var_desc.ExplicitBindPoint == 0x20, "Unexpected bind point %#x.\n", var_desc.ExplicitBindPoint);
+ /* Invalid buffer variable */ + constantbuffer = effect->lpVtbl->GetConstantBufferByIndex(effect, 100); + hr = constantbuffer->lpVtbl->GetConstantBuffer(constantbuffer, &buffer); + ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr); + hr = constantbuffer->lpVtbl->GetTextureBuffer(constantbuffer, &srv); + ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr); + effect->lpVtbl->Release(effect);
refcount = ID3D10Device_Release(device); @@ -7160,15 +7184,11 @@ todo_wine { ok(cb->lpVtbl->IsValid(cb), "Expected valid constant buffer.\n");
hr = cb->lpVtbl->GetConstantBuffer(cb, &buffer); -todo_wine ok(hr == S_OK, "Unexpected hr %#x.\n", hr); - if (SUCCEEDED(hr)) - { - ID3D10Buffer_GetDevice(buffer, &device3); - ok(device3 == device2, "Unexpected device.\n"); - ID3D10Device_Release(device3); - ID3D10Buffer_Release(buffer); - } + ID3D10Buffer_GetDevice(buffer, &device3); + ok(device3 == device2, "Unexpected device.\n"); + ID3D10Device_Release(device3); + ID3D10Buffer_Release(buffer);
child_effect->lpVtbl->Release(child_effect); pool2->lpVtbl->Release(pool2);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d3d10/effect.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c index b11dfc9489a..a1754853e11 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c @@ -4495,9 +4495,11 @@ static inline struct d3d10_effect_variable *impl_from_ID3D10EffectConstantBuffer
static BOOL STDMETHODCALLTYPE d3d10_effect_constant_buffer_IsValid(ID3D10EffectConstantBuffer *iface) { - TRACE("iface %p\n", iface); + struct d3d10_effect_variable *v = impl_from_ID3D10EffectConstantBuffer(iface); + + TRACE("iface %p.\n", iface);
- return (struct d3d10_effect_variable *)iface != &null_local_buffer; + return v != &null_local_buffer; }
static struct ID3D10EffectType * STDMETHODCALLTYPE d3d10_effect_constant_buffer_GetType(ID3D10EffectConstantBuffer *iface)
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d3d10/tests/effect.c | 142 +++++++++++++++++++++++++++++++++++--- 1 file changed, 132 insertions(+), 10 deletions(-)
diff --git a/dlls/d3d10/tests/effect.c b/dlls/d3d10/tests/effect.c index ab3cdc71d9c..4d853c64baa 100644 --- a/dlls/d3d10/tests/effect.c +++ b/dlls/d3d10/tests/effect.c @@ -7321,12 +7321,25 @@ float1 f1 = {1}; int i = 10; int i2[2] = {9,12}; float f = 0.2f; + +struct test +{ + bool b1; + float f2; + bool b2; +}; +test s1 = { true, -0.2f, false }; + +matrix <uint, 2, 3> m1 = { 1, 2, 3, 4, 5, 6 }; +row_major matrix <uint, 2, 3> m2 = { 1, 2, 3, 4, 5, 6 }; +row_major matrix <bool, 2, 3> m3 = { true, false, true, false, true, false }; +float2x2 m4 = { 1.0f, 2.0f, 3.0f, 4.0f }; #endif static DWORD fx_test_default_variable_value[] = { - 0x43425844, 0xe57b41f2, 0x98392802, 0xed3d94b4, 0xc4074c4f, 0x00000001, 0x00000248, 0x00000001, - 0x00000024, 0x30315846, 0x0000021c, 0xfeff1001, 0x00000001, 0x00000006, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000110, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x43425844, 0x3673286d, 0xd7bb3432, 0xb571508a, 0x5d70cc01, 0x00000001, 0x00000448, 0x00000001, + 0x00000024, 0x30315846, 0x0000041c, 0xfeff1001, 0x00000001, 0x0000000b, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000284, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x6f6c4724, 0x736c6162, 0x6f6c6600, 0x00347461, 0x0000000d, 0x00000001, 0x00000000, 0x00000010, 0x00000010, 0x00000010, 0x0000210a, 0x00003466, 0x003f8000, 0x00400000, 0x00404000, 0x66408000, 0x74616f6c, @@ -7336,12 +7349,28 @@ static DWORD fx_test_default_variable_value[] = 0x04000000, 0x10000000, 0x04000000, 0x11000000, 0x69000009, 0x00000a00, 0x00009b00, 0x00000100, 0x00000200, 0x00001400, 0x00001000, 0x00000800, 0x00091100, 0x00326900, 0x00000009, 0x0000000c, 0x616f6c66, 0x00e80074, 0x00010000, 0x00000000, 0x00040000, 0x00100000, 0x00040000, 0x09090000, - 0x00660000, 0x3e4ccccd, 0x00000004, 0x00000040, 0x00000000, 0x00000006, 0xffffffff, 0x00000000, - 0x00000030, 0x00000014, 0x00000000, 0x00000000, 0x00000033, 0x00000000, 0x00000000, 0x00000066, - 0x0000004a, 0x00000000, 0x00000010, 0x00000069, 0x00000000, 0x00000000, 0x00000094, 0x00000078, - 0x00000000, 0x00000018, 0x00000097, 0x00000000, 0x00000000, 0x000000bb, 0x0000009f, 0x00000000, - 0x0000001c, 0x000000bd, 0x00000000, 0x00000000, 0x000000dd, 0x000000c1, 0x00000000, 0x00000020, - 0x000000e0, 0x00000000, 0x00000000, 0x0000010a, 0x000000ee, 0x00000000, 0x00000034, 0x0000010c, + 0x00660000, 0x3e4ccccd, 0x74736574, 0x00316200, 0x6c6f6f62, 0x00011800, 0x00000100, 0x00000000, + 0x00000400, 0x00001000, 0x00000400, 0x00092100, 0x00326200, 0x00000110, 0x00000003, 0x00000000, + 0x0000000c, 0x00000010, 0x0000000c, 0x00000003, 0x00000115, 0x00000000, 0x00000000, 0x0000011d, + 0x00000066, 0x00000000, 0x00000004, 0x000000ee, 0x00000139, 0x00000000, 0x00000008, 0x0000011d, + 0x01003173, 0xcd000000, 0x00be4ccc, 0x75000000, 0x32746e69, 0x97003378, 0x01000001, 0x00000000, + 0x28000000, 0x30000000, 0x18000000, 0x1b000000, 0x6d00005a, 0x00010031, 0x00020000, 0x00030000, + 0x00040000, 0x00050000, 0x00060000, 0x01970000, 0x00010000, 0x00000000, 0x001c0000, 0x00200000, + 0x00180000, 0x1a1b0000, 0x326d0000, 0x00000100, 0x00000200, 0x00000300, 0x00000400, 0x00000500, + 0x00000600, 0x6f6f6200, 0x3378326c, 0x00020d00, 0x00000100, 0x00000000, 0x00001c00, 0x00002000, + 0x00001800, 0x001a2300, 0x00336d00, 0x00000001, 0x00000000, 0x00000001, 0x00000000, 0x00000001, + 0x00000000, 0x616f6c66, 0x32783274, 0x00024c00, 0x00000100, 0x00000000, 0x00001800, 0x00002000, + 0x00001000, 0x00520b00, 0x00346d00, 0x3f800000, 0x40000000, 0x40400000, 0x40800000, 0x00000004, + 0x000000e0, 0x00000000, 0x0000000b, 0xffffffff, 0x00000000, 0x00000030, 0x00000014, 0x00000000, + 0x00000000, 0x00000033, 0x00000000, 0x00000000, 0x00000066, 0x0000004a, 0x00000000, 0x00000010, + 0x00000069, 0x00000000, 0x00000000, 0x00000094, 0x00000078, 0x00000000, 0x00000018, 0x00000097, + 0x00000000, 0x00000000, 0x000000bb, 0x0000009f, 0x00000000, 0x0000001c, 0x000000bd, 0x00000000, + 0x00000000, 0x000000dd, 0x000000c1, 0x00000000, 0x00000020, 0x000000e0, 0x00000000, 0x00000000, + 0x0000010a, 0x000000ee, 0x00000000, 0x00000034, 0x0000010c, 0x00000000, 0x00000000, 0x00000188, + 0x0000013c, 0x00000000, 0x00000040, 0x0000018b, 0x00000000, 0x00000000, 0x000001bb, 0x0000019f, + 0x00000000, 0x00000050, 0x000001be, 0x00000000, 0x00000000, 0x000001f2, 0x000001d6, 0x00000000, + 0x00000080, 0x000001f5, 0x00000000, 0x00000000, 0x00000231, 0x00000215, 0x00000000, 0x000000a0, + 0x00000234, 0x00000000, 0x00000000, 0x00000271, 0x00000255, 0x00000000, 0x000000c0, 0x00000274, 0x00000000, 0x00000000, };
@@ -7350,13 +7379,16 @@ static void test_effect_default_variable_value(void) D3D10_EFFECT_VARIABLE_DESC var_desc; ID3D10EffectVectorVariable *vector; ID3D10EffectScalarVariable *scalar; - ID3D10EffectVariable *v, *v2; + ID3D10EffectMatrixVariable *matrix; + struct d3d10_matrix m_set, m_ret; + ID3D10EffectVariable *v, *v2, *m; float float_v[4], float_s; ID3D10Effect *effect; ID3D10Device *device; int int_v[2], int_s; ULONG refcount; HRESULT hr; + BOOL ret;
if (!(device = create_device())) { @@ -7431,6 +7463,96 @@ todo_wine todo_wine ok(float_s == 0.2f, "Unexpected value %.8e.\n", float_s);
+ /* Matrix */ + v = effect->lpVtbl->GetVariableByName(effect, "m1"); + matrix = v->lpVtbl->AsMatrix(v); + ok(matrix->lpVtbl->IsValid(matrix), "Expected valid matrix.\n"); + memset(&m_ret, 0, sizeof(m_ret)); + hr = matrix->lpVtbl->GetMatrix(matrix, &m_ret.m[0][0]); + 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); + ok(matrix->lpVtbl->IsValid(matrix), "Expected valid matrix.\n"); + memset(&m_ret, 0, sizeof(m_ret)); + hr = matrix->lpVtbl->GetMatrix(matrix, &m_ret.m[0][0]); + 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"); + memset(&m_ret, 0, sizeof(m_ret)); + hr = matrix->lpVtbl->GetMatrix(matrix, &m_ret.m[0][0]); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + memset(&m_set, 0, sizeof(m_set)); + *(unsigned int *)&m_set.m[0][0] = 1; + *(unsigned int *)&m_set.m[0][1] = 0; + *(unsigned int *)&m_set.m[0][2] = 1; + *(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"); + + v = effect->lpVtbl->GetVariableByName(effect, "m4"); + matrix = v->lpVtbl->AsMatrix(v); + ok(matrix->lpVtbl->IsValid(matrix), "Expected valid matrix.\n"); + memset(&m_ret, 0, sizeof(m_ret)); + hr = matrix->lpVtbl->GetMatrix(matrix, &m_ret.m[0][0]); + 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"); + + m = v->lpVtbl->GetMemberByName(v, "b1"); + ok(m->lpVtbl->IsValid(m), "Expected valid variable.\n"); + 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"); + ok(m->lpVtbl->IsValid(m), "Expected valid variable.\n"); + 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"); + ok(m->lpVtbl->IsValid(m), "Expected valid variable.\n"); + scalar = m->lpVtbl->AsScalar(m); + hr = scalar->lpVtbl->GetBool(scalar, &ret); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(!ret, "Unexpected value.\n"); + effect->lpVtbl->Release(effect);
refcount = ID3D10Device_Release(device);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- 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 a1754853e11..691e40a2217 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 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 (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 *v) +{ + unsigned int element_count = max(v->type->element_count, 1), i, m; + + v = d3d10_array_get_element(v, 0); + + for (i = 0; i < element_count; ++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; + } + v++; + } +} + 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");
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com ---
There is no bounds checks on Windows as far as I can tell.
dlls/d3d10/effect.c | 26 +++++++++- dlls/d3d10/tests/effect.c | 104 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+), 2 deletions(-)
diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c index 691e40a2217..3bca6290ed3 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c @@ -4522,9 +4522,31 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_variable_SetRawValue(ID3D10EffectV static HRESULT STDMETHODCALLTYPE d3d10_effect_variable_GetRawValue(ID3D10EffectVariable *iface, void *data, UINT offset, UINT count) { - FIXME("iface %p, data %p, offset %u, count %u stub!\n", iface, data, offset, count); + struct d3d10_effect_variable *v = impl_from_ID3D10EffectVariable(iface); + BOOL is_buffer; + BYTE *src;
- return E_NOTIMPL; + TRACE("iface %p, data %p, offset %u, count %u.\n", iface, data, offset, count); + + if (!iface->lpVtbl->IsValid(iface)) + { + WARN("Invalid variable.\n"); + return E_FAIL; + } + + is_buffer = v->type->basetype == D3D10_SVT_CBUFFER || v->type->basetype == D3D10_SVT_TBUFFER; + + if (v->type->type_class == D3D10_SVC_OBJECT && !is_buffer) + { + WARN("Not supported on object variables of type %s.\n", + debug_d3d10_shader_variable_type(v->type->basetype)); + return D3DERR_INVALIDCALL; + } + + src = is_buffer ? v->u.buffer.local_buffer : v->buffer->u.buffer.local_buffer + v->buffer_offset; + memcpy(data, src + offset, count); + + return S_OK; }
static const struct ID3D10EffectVariableVtbl d3d10_effect_variable_vtbl = diff --git a/dlls/d3d10/tests/effect.c b/dlls/d3d10/tests/effect.c index ae4db49f283..a8a64a6ed0d 100644 --- a/dlls/d3d10/tests/effect.c +++ b/dlls/d3d10/tests/effect.c @@ -7535,6 +7535,109 @@ static void test_effect_default_variable_value(void) ok(!refcount, "Device has %u references left.\n", refcount); }
+static void test_effect_raw_value(void) +{ + ID3D10EffectConstantBuffer *cb; + ID3D10EffectVariable *v; + ID3D10Effect *effect; + ID3D10Device *device; + unsigned int i; + ULONG refcount; + int i_v[10]; + HRESULT hr; + float f; + + if (!(device = create_device())) + { + skip("Failed to create device, skipping tests.\n"); + return; + } + + hr = create_effect(fx_test_default_variable_value, 0, device, NULL, &effect); + ok(SUCCEEDED(hr), "Failed to create an effect, hr %#x.\n", hr); + + /* Read 1 float at a time, from float4 vector. */ + v = effect->lpVtbl->GetVariableByName(effect, "f4"); + for (i = 0; i < 4; ++i) + { + hr = v->lpVtbl->GetRawValue(v, &f, sizeof(f) * i, sizeof(f)); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(f == i + 1.0f, "Unexpected value %f.\n", f); + } + /* Offset outside of variable storage, returns adjacent memory contents. */ + hr = v->lpVtbl->GetRawValue(v, &f, 16, sizeof(f)); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(f == 1.0f, "Unexpected value %f.\n", f); + hr = v->lpVtbl->GetRawValue(v, &f, 20, sizeof(f)); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(f == 2.0f, "Unexpected value %f.\n", f); + + /* Array */ + v = effect->lpVtbl->GetVariableByName(effect, "i2"); + ok(v->lpVtbl->IsValid(v), "Expected valid variable.\n"); + hr = v->lpVtbl->GetRawValue(v, i_v, 0, 8 * sizeof(float)); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(i_v[0] == 9, "Unexpected value %d.\n", i_v[0]); + ok(i_v[1] == 0, "Unexpected value %d.\n", i_v[1]); + ok(i_v[2] == 0, "Unexpected value %d.\n", i_v[2]); + ok(i_v[3] == 0, "Unexpected value %d.\n", i_v[3]); + ok(i_v[4] == 12, "Unexpected value %d.\n", i_v[4]); + + hr = v->lpVtbl->GetRawValue(v, &f, 20, sizeof(f)); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(f == 0.2f, "Unexpected value %f.\n", f); + + /* Matrix */ + v = effect->lpVtbl->GetVariableByName(effect, "m1"); + hr = v->lpVtbl->GetRawValue(v, i_v, 0, sizeof(i_v)); + ok(i_v[0] == 1, "Unexpected value %d.\n", i_v[0]); + ok(i_v[1] == 4, "Unexpected value %d.\n", i_v[1]); + ok(i_v[2] == 0, "Unexpected value %d.\n", i_v[2]); + ok(i_v[3] == 0, "Unexpected value %d.\n", i_v[3]); + ok(i_v[4] == 2, "Unexpected value %d.\n", i_v[4]); + ok(i_v[5] == 5, "Unexpected value %d.\n", i_v[5]); + ok(i_v[6] == 0, "Unexpected value %d.\n", i_v[6]); + ok(i_v[7] == 0, "Unexpected value %d.\n", i_v[7]); + ok(i_v[8] == 3, "Unexpected value %d.\n", i_v[8]); + ok(i_v[9] == 6, "Unexpected value %d.\n", i_v[9]); + + v = effect->lpVtbl->GetVariableByName(effect, "m2"); + hr = v->lpVtbl->GetRawValue(v, i_v, 0, 7 * sizeof(i_v[0])); + ok(i_v[0] == 1, "Unexpected value %d.\n", i_v[0]); + ok(i_v[1] == 2, "Unexpected value %d.\n", i_v[1]); + ok(i_v[2] == 3, "Unexpected value %d.\n", i_v[2]); + ok(i_v[3] == 0, "Unexpected value %d.\n", i_v[3]); + ok(i_v[4] == 4, "Unexpected value %d.\n", i_v[4]); + ok(i_v[5] == 5, "Unexpected value %d.\n", i_v[5]); + ok(i_v[6] == 6, "Unexpected value %d.\n", i_v[6]); + + /* Read from constant buffer directly. */ + cb = effect->lpVtbl->GetConstantBufferByIndex(effect, 0); + + for (i = 0; i < 4; ++i) + { + hr = cb->lpVtbl->GetRawValue(cb, &f, sizeof(f) * i, sizeof(f)); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(f == i + 1.0f, "Unexpected value %f.\n", f); + } + hr = cb->lpVtbl->GetRawValue(cb, &f, 16, sizeof(f)); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(f == 1.0f, "Unexpected value %f.\n", f); + hr = cb->lpVtbl->GetRawValue(cb, &f, 20, sizeof(f)); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(f == 2.0f, "Unexpected value %f.\n", f); + + /* Invalid variable */ + v = effect->lpVtbl->GetVariableByName(effect, "invalid"); + hr = v->lpVtbl->GetRawValue(v, &f, 0, sizeof(f)); + ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr); + + 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(); @@ -7557,4 +7660,5 @@ START_TEST(effect) test_effect_shader_object(); test_effect_pool(); test_effect_default_variable_value(); + test_effect_raw_value(); }
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d3d10/effect.c | 41 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-)
diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c index 3bca6290ed3..573a404cda9 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c @@ -4514,9 +4514,36 @@ static struct ID3D10EffectSamplerVariable * STDMETHODCALLTYPE d3d10_effect_varia static HRESULT STDMETHODCALLTYPE d3d10_effect_variable_SetRawValue(ID3D10EffectVariable *iface, void *data, UINT offset, UINT count) { - FIXME("iface %p, data %p, offset %u, count %u stub!\n", iface, data, offset, count); + struct d3d10_effect_variable *v = impl_from_ID3D10EffectVariable(iface); + BOOL is_buffer;
- return E_NOTIMPL; + TRACE("iface %p, data %p, offset %u, count %u.\n", iface, data, offset, count); + + if (!iface->lpVtbl->IsValid(iface)) + { + WARN("Invalid variable.\n"); + return E_FAIL; + } + + is_buffer = v->type->basetype == D3D10_SVT_CBUFFER || v->type->basetype == D3D10_SVT_TBUFFER; + + if (v->type->type_class == D3D10_SVC_OBJECT && !is_buffer) + { + WARN("Not supported on object variables of type %s.\n", + debug_d3d10_shader_variable_type(v->type->basetype)); + return D3DERR_INVALIDCALL; + } + + if (!is_buffer) + { + offset += v->buffer_offset; + v = v->buffer; + } + + memcpy(v->u.buffer.local_buffer + offset, data, count); + v->u.buffer.changed = TRUE; + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d3d10_effect_variable_GetRawValue(ID3D10EffectVariable *iface, @@ -4524,7 +4551,6 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_variable_GetRawValue(ID3D10EffectV { struct d3d10_effect_variable *v = impl_from_ID3D10EffectVariable(iface); BOOL is_buffer; - BYTE *src;
TRACE("iface %p, data %p, offset %u, count %u.\n", iface, data, offset, count);
@@ -4543,8 +4569,13 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_variable_GetRawValue(ID3D10EffectV return D3DERR_INVALIDCALL; }
- src = is_buffer ? v->u.buffer.local_buffer : v->buffer->u.buffer.local_buffer + v->buffer_offset; - memcpy(data, src + offset, count); + if (!is_buffer) + { + offset += v->buffer_offset; + v = v->buffer; + } + + memcpy(data, v->u.buffer.local_buffer + offset, count);
return S_OK; }