Nikolay Sivov : d3d10/effect: Implement GetRawValue().
Alexandre Julliard
julliard at winehq.org
Wed Oct 27 16:26:02 CDT 2021
Module: wine
Branch: master
Commit: 3f598171bedfb4203ca54344f5a2498d4922f650
URL: https://source.winehq.org/git/wine.git/?a=commit;h=3f598171bedfb4203ca54344f5a2498d4922f650
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Tue Oct 26 23:25:15 2021 +0200
d3d10/effect: Implement GetRawValue().
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Matteo Bruni <mbruni at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
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 b4a2f448ad0..9f652680747 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();
}
More information about the wine-cvs
mailing list