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