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

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Matteo Bruni <mbruni@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2021-10-26 23:25:08 +02:00 committed by Alexandre Julliard
parent c702e19903
commit 59b01089a2
2 changed files with 54 additions and 5 deletions

View File

@ -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)

View File

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