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