Nikolay Sivov : d3d10/effect: Fix buffer offsets for members and array elements.

Alexandre Julliard julliard at winehq.org
Wed Oct 27 16:26:01 CDT 2021


Module: wine
Branch: master
Commit: 59b01089a26ea463ff1cd6acd4f877c44da92aa3
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=59b01089a26ea463ff1cd6acd4f877c44da92aa3

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Tue Oct 26 23:25:08 2021 +0200

d3d10/effect: Fix buffer offsets for members and array elements.

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       | 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");




More information about the wine-cvs mailing list