d3dx9: Implement recording parameters to parameter block.
Signed-off-by: Paul Gofman <gofmanp@gmail.com> Signed-off-by: Matteo Bruni <mbruni@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
9da70c0758
commit
7d512a1e0e
|
@ -36,6 +36,7 @@ static const char parameter_block_magic_string[4] = {'@', '!', '#', '\xFE'};
|
||||||
#define PARAMETER_FLAG_SHARED 1
|
#define PARAMETER_FLAG_SHARED 1
|
||||||
|
|
||||||
#define INITIAL_POOL_SIZE 16
|
#define INITIAL_POOL_SIZE 16
|
||||||
|
#define INITIAL_PARAM_BLOCK_SIZE 1024
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
|
WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
|
||||||
|
|
||||||
|
@ -153,6 +154,15 @@ struct d3dx_parameter_block
|
||||||
{
|
{
|
||||||
char magic_string[ARRAY_SIZE(parameter_block_magic_string)];
|
char magic_string[ARRAY_SIZE(parameter_block_magic_string)];
|
||||||
struct list entry;
|
struct list entry;
|
||||||
|
size_t size;
|
||||||
|
size_t offset;
|
||||||
|
BYTE *buffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct d3dx_recorded_parameter
|
||||||
|
{
|
||||||
|
struct d3dx_parameter *param;
|
||||||
|
unsigned int bytes;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct d3dx_effect
|
struct d3dx_effect
|
||||||
|
@ -706,11 +716,27 @@ static void free_technique(struct d3dx_technique *technique)
|
||||||
technique->name = NULL;
|
technique->name = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned int get_recorded_parameter_size(const struct d3dx_recorded_parameter *record)
|
||||||
|
{
|
||||||
|
return sizeof(*record) + record->bytes;
|
||||||
|
}
|
||||||
|
|
||||||
static void free_parameter_block(struct d3dx_parameter_block *block)
|
static void free_parameter_block(struct d3dx_parameter_block *block)
|
||||||
{
|
{
|
||||||
|
struct d3dx_recorded_parameter *record;
|
||||||
|
|
||||||
if (!block)
|
if (!block)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
record = (struct d3dx_recorded_parameter *)block->buffer;
|
||||||
|
while ((BYTE *)record < block->buffer + block->offset)
|
||||||
|
{
|
||||||
|
free_parameter_object_data(record->param, record + 1, record->bytes);
|
||||||
|
record = (struct d3dx_recorded_parameter *)((BYTE *)record + get_recorded_parameter_size(record));
|
||||||
|
}
|
||||||
|
assert((BYTE *)record == block->buffer + block->offset);
|
||||||
|
|
||||||
|
heap_free(block->buffer);
|
||||||
heap_free(block);
|
heap_free(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -778,14 +804,12 @@ static void get_vector(struct d3dx_parameter *param, D3DXVECTOR4 *vector)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_vector(struct d3dx_parameter *param, const D3DXVECTOR4 *vector)
|
static void set_vector(struct d3dx_parameter *param, const D3DXVECTOR4 *vector, void *dst_data)
|
||||||
{
|
{
|
||||||
UINT i;
|
UINT i;
|
||||||
|
|
||||||
for (i = 0; i < param->columns; ++i)
|
for (i = 0; i < param->columns; ++i)
|
||||||
{
|
set_number((FLOAT *)dst_data + i, param->type, (FLOAT *)vector + i, D3DXPT_FLOAT);
|
||||||
set_number((FLOAT *)param->data + i, param->type, (FLOAT *)vector + i, D3DXPT_FLOAT);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_matrix(struct d3dx_parameter *param, D3DXMATRIX *matrix, BOOL transpose)
|
static void get_matrix(struct d3dx_parameter *param, D3DXMATRIX *matrix, BOOL transpose)
|
||||||
|
@ -806,31 +830,33 @@ static void get_matrix(struct d3dx_parameter *param, D3DXMATRIX *matrix, BOOL tr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_matrix(struct d3dx_parameter *param, const D3DXMATRIX *matrix)
|
static void set_matrix(struct d3dx_parameter *param, const D3DXMATRIX *matrix, void *dst_data)
|
||||||
{
|
{
|
||||||
UINT i, k;
|
UINT i, k;
|
||||||
|
|
||||||
if (param->type == D3DXPT_FLOAT)
|
if (param->type == D3DXPT_FLOAT)
|
||||||
{
|
{
|
||||||
if (param->columns == 4)
|
if (param->columns == 4)
|
||||||
memcpy(param->data, matrix->u.m, param->rows * 4 * sizeof(float));
|
{
|
||||||
|
memcpy(dst_data, matrix->u.m, param->rows * 4 * sizeof(float));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
for (i = 0; i < param->rows; ++i)
|
for (i = 0; i < param->rows; ++i)
|
||||||
memcpy((float *)param->data + i * param->columns, matrix->u.m + i, param->columns * sizeof(float));
|
memcpy((float *)dst_data + i * param->columns, matrix->u.m + i, param->columns * sizeof(float));
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < param->rows; ++i)
|
for (i = 0; i < param->rows; ++i)
|
||||||
{
|
{
|
||||||
for (k = 0; k < param->columns; ++k)
|
for (k = 0; k < param->columns; ++k)
|
||||||
{
|
set_number((FLOAT *)dst_data + i * param->columns + k, param->type,
|
||||||
set_number((FLOAT *)param->data + i * param->columns + k, param->type,
|
|
||||||
&matrix->u.m[i][k], D3DXPT_FLOAT);
|
&matrix->u.m[i][k], D3DXPT_FLOAT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static void set_matrix_transpose(struct d3dx_parameter *param, const D3DXMATRIX *matrix)
|
static void set_matrix_transpose(struct d3dx_parameter *param, const D3DXMATRIX *matrix, void *dst_data)
|
||||||
{
|
{
|
||||||
UINT i, k;
|
UINT i, k;
|
||||||
|
|
||||||
|
@ -838,7 +864,7 @@ static void set_matrix_transpose(struct d3dx_parameter *param, const D3DXMATRIX
|
||||||
{
|
{
|
||||||
for (k = 0; k < param->columns; ++k)
|
for (k = 0; k < param->columns; ++k)
|
||||||
{
|
{
|
||||||
set_number((FLOAT *)param->data + i * param->columns + k, param->type,
|
set_number((FLOAT *)dst_data + i * param->columns + k, param->type,
|
||||||
&matrix->u.m[k][i], D3DXPT_FLOAT);
|
&matrix->u.m[k][i], D3DXPT_FLOAT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -857,7 +883,8 @@ static HRESULT set_string(char **param_data, const char *string)
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT set_value(struct d3dx_parameter *param, const void *data, unsigned int bytes)
|
static HRESULT set_value(struct d3dx_parameter *param, const void *data, unsigned int bytes,
|
||||||
|
void *dst_data)
|
||||||
{
|
{
|
||||||
unsigned int i, count;
|
unsigned int i, count;
|
||||||
|
|
||||||
|
@ -873,7 +900,7 @@ static HRESULT set_value(struct d3dx_parameter *param, const void *data, unsigne
|
||||||
case D3DXPT_TEXTURECUBE:
|
case D3DXPT_TEXTURECUBE:
|
||||||
for (i = 0; i < count; ++i)
|
for (i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
IUnknown *old_texture = ((IUnknown **)param->data)[i];
|
IUnknown *old_texture = ((IUnknown **)dst_data)[i];
|
||||||
IUnknown *new_texture = ((IUnknown **)data)[i];
|
IUnknown *new_texture = ((IUnknown **)data)[i];
|
||||||
|
|
||||||
if (new_texture == old_texture)
|
if (new_texture == old_texture)
|
||||||
|
@ -890,7 +917,7 @@ static HRESULT set_value(struct d3dx_parameter *param, const void *data, unsigne
|
||||||
case D3DXPT_INT:
|
case D3DXPT_INT:
|
||||||
case D3DXPT_FLOAT:
|
case D3DXPT_FLOAT:
|
||||||
TRACE("Copy %u bytes.\n", bytes);
|
TRACE("Copy %u bytes.\n", bytes);
|
||||||
memcpy(param->data, data, bytes);
|
memcpy(dst_data, data, bytes);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case D3DXPT_STRING:
|
case D3DXPT_STRING:
|
||||||
|
@ -898,7 +925,7 @@ static HRESULT set_value(struct d3dx_parameter *param, const void *data, unsigne
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
for (i = 0; i < count; ++i)
|
for (i = 0; i < count; ++i)
|
||||||
if (FAILED(hr = set_string(&((char **)param->data)[i], ((const char **)data)[i])))
|
if (FAILED(hr = set_string(&((char **)dst_data)[i], ((const char **)data)[i])))
|
||||||
return hr;
|
return hr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1248,6 +1275,43 @@ static ULONG64 next_effect_update_version(struct d3dx_effect *effect)
|
||||||
return next_update_version(get_version_counter_ptr(effect));
|
return next_update_version(get_version_counter_ptr(effect));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void *record_parameter(struct d3dx_effect *effect, struct d3dx_parameter *param, unsigned int bytes)
|
||||||
|
{
|
||||||
|
struct d3dx_parameter_block *block = effect->current_parameter_block;
|
||||||
|
struct d3dx_recorded_parameter new_record, *record;
|
||||||
|
unsigned int new_size, alloc_size;
|
||||||
|
|
||||||
|
new_record.param = param;
|
||||||
|
new_record.bytes = bytes;
|
||||||
|
new_size = block->offset + get_recorded_parameter_size(&new_record);
|
||||||
|
|
||||||
|
if (new_size > block->size)
|
||||||
|
{
|
||||||
|
BYTE *new_alloc;
|
||||||
|
|
||||||
|
alloc_size = max(block->size * 2, max(new_size, INITIAL_PARAM_BLOCK_SIZE));
|
||||||
|
if (block->size)
|
||||||
|
new_alloc = heap_realloc(block->buffer, alloc_size);
|
||||||
|
else
|
||||||
|
new_alloc = heap_alloc(alloc_size);
|
||||||
|
|
||||||
|
if (!new_alloc)
|
||||||
|
{
|
||||||
|
ERR("Out of memory.\n");
|
||||||
|
return param->data;
|
||||||
|
}
|
||||||
|
/* Data update functions may want to free some references upon setting value. */
|
||||||
|
memset(new_alloc + block->size, 0, alloc_size - block->size);
|
||||||
|
|
||||||
|
block->size = alloc_size;
|
||||||
|
block->buffer = new_alloc;
|
||||||
|
}
|
||||||
|
record = (struct d3dx_recorded_parameter *)(block->buffer + block->offset);
|
||||||
|
*record = new_record;
|
||||||
|
block->offset = new_size;
|
||||||
|
return record + 1;
|
||||||
|
}
|
||||||
|
|
||||||
static void set_dirty(struct d3dx_parameter *param)
|
static void set_dirty(struct d3dx_parameter *param)
|
||||||
{
|
{
|
||||||
struct d3dx_shared_data *shared_data;
|
struct d3dx_shared_data *shared_data;
|
||||||
|
@ -1260,6 +1324,17 @@ static void set_dirty(struct d3dx_parameter *param)
|
||||||
top_param->update_version = new_update_version;
|
top_param->update_version = new_update_version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void *param_get_data_and_dirtify(struct d3dx_effect *effect, struct d3dx_parameter *param,
|
||||||
|
unsigned int bytes, BOOL value_changed)
|
||||||
|
{
|
||||||
|
assert(bytes <= param->bytes);
|
||||||
|
|
||||||
|
if (value_changed && !effect->current_parameter_block)
|
||||||
|
set_dirty(param);
|
||||||
|
|
||||||
|
return effect->current_parameter_block ? record_parameter(effect, param, bytes) : param->data;
|
||||||
|
}
|
||||||
|
|
||||||
static void d3dx9_set_light_parameter(enum LIGHT_TYPE op, D3DLIGHT9 *light, void *value)
|
static void d3dx9_set_light_parameter(enum LIGHT_TYPE op, D3DLIGHT9 *light, void *value)
|
||||||
{
|
{
|
||||||
static const struct
|
static const struct
|
||||||
|
@ -2364,10 +2439,7 @@ static HRESULT WINAPI d3dx_effect_SetValue(ID3DXEffect *iface, D3DXHANDLE parame
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data && param->bytes <= bytes)
|
if (data && param->bytes <= bytes)
|
||||||
{
|
return set_value(param, data, bytes, param_get_data_and_dirtify(effect, param, param->bytes, TRUE));
|
||||||
set_dirty(param);
|
|
||||||
return set_value(param, data, bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
WARN("Invalid argument specified.\n");
|
WARN("Invalid argument specified.\n");
|
||||||
|
|
||||||
|
@ -2448,8 +2520,8 @@ static HRESULT WINAPI d3dx_effect_SetBool(ID3DXEffect *iface, D3DXHANDLE paramet
|
||||||
|
|
||||||
if (param && !param->element_count && param->rows == 1 && param->columns == 1)
|
if (param && !param->element_count && param->rows == 1 && param->columns == 1)
|
||||||
{
|
{
|
||||||
set_number(param->data, param->type, &b, D3DXPT_BOOL);
|
set_number(param_get_data_and_dirtify(effect, param, sizeof(int), TRUE),
|
||||||
set_dirty(param);
|
param->type, &b, D3DXPT_BOOL);
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2481,6 +2553,7 @@ static HRESULT WINAPI d3dx_effect_SetBoolArray(ID3DXEffect *iface, D3DXHANDLE pa
|
||||||
{
|
{
|
||||||
struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
|
struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
|
||||||
struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
|
struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
|
||||||
|
DWORD *data;
|
||||||
|
|
||||||
TRACE("iface %p, parameter %p, b %p, count %u.\n", iface, parameter, b, count);
|
TRACE("iface %p, parameter %p, b %p, count %u.\n", iface, parameter, b, count);
|
||||||
|
|
||||||
|
@ -2495,12 +2568,12 @@ static HRESULT WINAPI d3dx_effect_SetBoolArray(ID3DXEffect *iface, D3DXHANDLE pa
|
||||||
case D3DXPC_SCALAR:
|
case D3DXPC_SCALAR:
|
||||||
case D3DXPC_VECTOR:
|
case D3DXPC_VECTOR:
|
||||||
case D3DXPC_MATRIX_ROWS:
|
case D3DXPC_MATRIX_ROWS:
|
||||||
|
data = param_get_data_and_dirtify(effect, param, size * sizeof(int), TRUE);
|
||||||
for (i = 0; i < size; ++i)
|
for (i = 0; i < size; ++i)
|
||||||
{
|
{
|
||||||
/* don't crop the input, use D3DXPT_INT instead of D3DXPT_BOOL */
|
/* don't crop the input, use D3DXPT_INT instead of D3DXPT_BOOL */
|
||||||
set_number((DWORD *)param->data + i, param->type, &b[i], D3DXPT_INT);
|
set_number(data + i, param->type, &b[i], D3DXPT_INT);
|
||||||
}
|
}
|
||||||
set_dirty(param);
|
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
|
|
||||||
case D3DXPC_OBJECT:
|
case D3DXPC_OBJECT:
|
||||||
|
@ -2558,9 +2631,8 @@ static HRESULT WINAPI d3dx_effect_SetInt(ID3DXEffect *iface, D3DXHANDLE paramete
|
||||||
DWORD value;
|
DWORD value;
|
||||||
|
|
||||||
set_number(&value, param->type, &n, D3DXPT_INT);
|
set_number(&value, param->type, &n, D3DXPT_INT);
|
||||||
if (value != *(DWORD *)param->data)
|
*(DWORD *)param_get_data_and_dirtify(effect, param, sizeof(int),
|
||||||
set_dirty(param);
|
value != *(DWORD *)param->data) = value;
|
||||||
*(DWORD *)param->data = value;
|
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2569,14 +2641,19 @@ static HRESULT WINAPI d3dx_effect_SetInt(ID3DXEffect *iface, D3DXHANDLE paramete
|
||||||
&& ((param->class == D3DXPC_VECTOR && param->columns != 2)
|
&& ((param->class == D3DXPC_VECTOR && param->columns != 2)
|
||||||
|| (param->class == D3DXPC_MATRIX_ROWS && param->rows != 2 && param->columns == 1)))
|
|| (param->class == D3DXPC_MATRIX_ROWS && param->rows != 2 && param->columns == 1)))
|
||||||
{
|
{
|
||||||
|
float *data;
|
||||||
|
|
||||||
TRACE("Vector fixup.\n");
|
TRACE("Vector fixup.\n");
|
||||||
|
|
||||||
*(float *)param->data = ((n & 0xff0000) >> 16) * INT_FLOAT_MULTI_INVERSE;
|
data = param_get_data_and_dirtify(effect, param,
|
||||||
((float *)param->data)[1] = ((n & 0xff00) >> 8) * INT_FLOAT_MULTI_INVERSE;
|
min(4, param->rows * param->columns) * sizeof(float), TRUE);
|
||||||
((float *)param->data)[2] = (n & 0xff) * INT_FLOAT_MULTI_INVERSE;
|
|
||||||
|
data[0] = ((n & 0xff0000) >> 16) * INT_FLOAT_MULTI_INVERSE;
|
||||||
|
data[1] = ((n & 0xff00) >> 8) * INT_FLOAT_MULTI_INVERSE;
|
||||||
|
data[2] = (n & 0xff) * INT_FLOAT_MULTI_INVERSE;
|
||||||
if (param->rows * param->columns > 3)
|
if (param->rows * param->columns > 3)
|
||||||
((float *)param->data)[3] = ((n & 0xff000000) >> 24) * INT_FLOAT_MULTI_INVERSE;
|
data[3] = ((n & 0xff000000) >> 24) * INT_FLOAT_MULTI_INVERSE;
|
||||||
set_dirty(param);
|
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2628,6 +2705,7 @@ static HRESULT WINAPI d3dx_effect_SetIntArray(ID3DXEffect *iface, D3DXHANDLE par
|
||||||
{
|
{
|
||||||
struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
|
struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
|
||||||
struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
|
struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
|
||||||
|
DWORD *data;
|
||||||
|
|
||||||
TRACE("iface %p, parameter %p, n %p, count %u.\n", iface, parameter, n, count);
|
TRACE("iface %p, parameter %p, n %p, count %u.\n", iface, parameter, n, count);
|
||||||
|
|
||||||
|
@ -2642,9 +2720,9 @@ static HRESULT WINAPI d3dx_effect_SetIntArray(ID3DXEffect *iface, D3DXHANDLE par
|
||||||
case D3DXPC_SCALAR:
|
case D3DXPC_SCALAR:
|
||||||
case D3DXPC_VECTOR:
|
case D3DXPC_VECTOR:
|
||||||
case D3DXPC_MATRIX_ROWS:
|
case D3DXPC_MATRIX_ROWS:
|
||||||
|
data = param_get_data_and_dirtify(effect, param, size * sizeof(int), TRUE);
|
||||||
for (i = 0; i < size; ++i)
|
for (i = 0; i < size; ++i)
|
||||||
set_number((DWORD *)param->data + i, param->type, &n[i], D3DXPT_INT);
|
set_number(data + i, param->type, &n[i], D3DXPT_INT);
|
||||||
set_dirty(param);
|
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
|
|
||||||
case D3DXPC_OBJECT:
|
case D3DXPC_OBJECT:
|
||||||
|
@ -2698,9 +2776,8 @@ static HRESULT WINAPI d3dx_effect_SetFloat(ID3DXEffect *iface, D3DXHANDLE parame
|
||||||
DWORD value;
|
DWORD value;
|
||||||
|
|
||||||
set_number(&value, param->type, &f, D3DXPT_FLOAT);
|
set_number(&value, param->type, &f, D3DXPT_FLOAT);
|
||||||
if (value != *(DWORD *)param->data)
|
*(DWORD *)param_get_data_and_dirtify(effect, param, sizeof(float),
|
||||||
set_dirty(param);
|
value != *(DWORD *)param->data) = value;
|
||||||
*(DWORD *)param->data = value;
|
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2733,6 +2810,7 @@ static HRESULT WINAPI d3dx_effect_SetFloatArray(ID3DXEffect *iface, D3DXHANDLE p
|
||||||
{
|
{
|
||||||
struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
|
struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
|
||||||
struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
|
struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
|
||||||
|
DWORD *data;
|
||||||
|
|
||||||
TRACE("iface %p, parameter %p, f %p, count %u.\n", iface, parameter, f, count);
|
TRACE("iface %p, parameter %p, f %p, count %u.\n", iface, parameter, f, count);
|
||||||
|
|
||||||
|
@ -2747,9 +2825,9 @@ static HRESULT WINAPI d3dx_effect_SetFloatArray(ID3DXEffect *iface, D3DXHANDLE p
|
||||||
case D3DXPC_SCALAR:
|
case D3DXPC_SCALAR:
|
||||||
case D3DXPC_VECTOR:
|
case D3DXPC_VECTOR:
|
||||||
case D3DXPC_MATRIX_ROWS:
|
case D3DXPC_MATRIX_ROWS:
|
||||||
|
data = param_get_data_and_dirtify(effect, param, size * sizeof(float), TRUE);
|
||||||
for (i = 0; i < size; ++i)
|
for (i = 0; i < size; ++i)
|
||||||
set_number((DWORD *)param->data + i, param->type, &f[i], D3DXPT_FLOAT);
|
set_number(data + i, param->type, &f[i], D3DXPT_FLOAT);
|
||||||
set_dirty(param);
|
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
|
|
||||||
case D3DXPC_OBJECT:
|
case D3DXPC_OBJECT:
|
||||||
|
@ -2806,7 +2884,6 @@ static HRESULT WINAPI d3dx_effect_SetVector(ID3DXEffect *iface, D3DXHANDLE param
|
||||||
{
|
{
|
||||||
case D3DXPC_SCALAR:
|
case D3DXPC_SCALAR:
|
||||||
case D3DXPC_VECTOR:
|
case D3DXPC_VECTOR:
|
||||||
set_dirty(param);
|
|
||||||
if (param->type == D3DXPT_INT && param->bytes == 4)
|
if (param->type == D3DXPT_INT && param->bytes == 4)
|
||||||
{
|
{
|
||||||
DWORD tmp;
|
DWORD tmp;
|
||||||
|
@ -2817,16 +2894,17 @@ static HRESULT WINAPI d3dx_effect_SetVector(ID3DXEffect *iface, D3DXHANDLE param
|
||||||
tmp += ((DWORD)(max(min(vector->x, 1.0f), 0.0f) * INT_FLOAT_MULTI)) << 16;
|
tmp += ((DWORD)(max(min(vector->x, 1.0f), 0.0f) * INT_FLOAT_MULTI)) << 16;
|
||||||
tmp += ((DWORD)(max(min(vector->w, 1.0f), 0.0f) * INT_FLOAT_MULTI)) << 24;
|
tmp += ((DWORD)(max(min(vector->w, 1.0f), 0.0f) * INT_FLOAT_MULTI)) << 24;
|
||||||
|
|
||||||
*(int *)param->data = tmp;
|
*(int *)param_get_data_and_dirtify(effect, param, sizeof(int), TRUE) = tmp;
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
}
|
}
|
||||||
if (param->type == D3DXPT_FLOAT)
|
if (param->type == D3DXPT_FLOAT)
|
||||||
{
|
{
|
||||||
memcpy(param->data, vector, param->columns * sizeof(float));
|
memcpy(param_get_data_and_dirtify(effect, param, param->columns * sizeof(float), TRUE),
|
||||||
|
vector, param->columns * sizeof(float));
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
set_vector(param, vector);
|
set_vector(param, vector, param_get_data_and_dirtify(effect, param, param->columns * sizeof(float), TRUE));
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
|
|
||||||
case D3DXPC_MATRIX_ROWS:
|
case D3DXPC_MATRIX_ROWS:
|
||||||
|
@ -2899,26 +2977,33 @@ static HRESULT WINAPI d3dx_effect_SetVectorArray(ID3DXEffect *iface, D3DXHANDLE
|
||||||
if (param && param->element_count && param->element_count >= count)
|
if (param && param->element_count && param->element_count >= count)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
BYTE *data;
|
||||||
|
|
||||||
TRACE("Class %s.\n", debug_d3dxparameter_class(param->class));
|
TRACE("Class %s.\n", debug_d3dxparameter_class(param->class));
|
||||||
|
|
||||||
switch (param->class)
|
switch (param->class)
|
||||||
{
|
{
|
||||||
case D3DXPC_VECTOR:
|
case D3DXPC_VECTOR:
|
||||||
set_dirty(param);
|
data = param_get_data_and_dirtify(effect, param, count * param->columns * sizeof(float), TRUE);
|
||||||
|
|
||||||
if (param->type == D3DXPT_FLOAT)
|
if (param->type == D3DXPT_FLOAT)
|
||||||
{
|
{
|
||||||
if (param->columns == 4)
|
if (param->columns == 4)
|
||||||
memcpy(param->data, vector, count * 4 * sizeof(float));
|
{
|
||||||
|
memcpy(data, vector, count * 4 * sizeof(float));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
for (i = 0; i < count; ++i)
|
for (i = 0; i < count; ++i)
|
||||||
memcpy((float *)param->data + param->columns * i, vector + i,
|
memcpy((float *)data + param->columns * i, vector + i,
|
||||||
param->columns * sizeof(float));
|
param->columns * sizeof(float));
|
||||||
|
}
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < count; ++i)
|
for (i = 0; i < count; ++i)
|
||||||
set_vector(¶m->members[i], &vector[i]);
|
set_vector(¶m->members[i], &vector[i], data + i * param->columns * sizeof(float));
|
||||||
|
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
|
|
||||||
case D3DXPC_SCALAR:
|
case D3DXPC_SCALAR:
|
||||||
|
@ -2993,8 +3078,8 @@ static HRESULT WINAPI d3dx_effect_SetMatrix(ID3DXEffect *iface, D3DXHANDLE param
|
||||||
switch (param->class)
|
switch (param->class)
|
||||||
{
|
{
|
||||||
case D3DXPC_MATRIX_ROWS:
|
case D3DXPC_MATRIX_ROWS:
|
||||||
set_matrix(param, matrix);
|
set_matrix(param, matrix, param_get_data_and_dirtify(effect, param,
|
||||||
set_dirty(param);
|
param->rows * param->columns * sizeof(float), TRUE));
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
|
|
||||||
case D3DXPC_SCALAR:
|
case D3DXPC_SCALAR:
|
||||||
|
@ -3059,15 +3144,20 @@ static HRESULT WINAPI d3dx_effect_SetMatrixArray(ID3DXEffect *iface, D3DXHANDLE
|
||||||
if (param && param->element_count >= count)
|
if (param && param->element_count >= count)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
BYTE *data;
|
||||||
|
|
||||||
TRACE("Class %s.\n", debug_d3dxparameter_class(param->class));
|
TRACE("Class %s.\n", debug_d3dxparameter_class(param->class));
|
||||||
|
|
||||||
switch (param->class)
|
switch (param->class)
|
||||||
{
|
{
|
||||||
case D3DXPC_MATRIX_ROWS:
|
case D3DXPC_MATRIX_ROWS:
|
||||||
set_dirty(param);
|
data = param_get_data_and_dirtify(effect, param, count * param->rows
|
||||||
|
* param->columns * sizeof(float), TRUE);
|
||||||
|
|
||||||
for (i = 0; i < count; ++i)
|
for (i = 0; i < count; ++i)
|
||||||
set_matrix(¶m->members[i], &matrix[i]);
|
set_matrix(¶m->members[i], &matrix[i],
|
||||||
|
data + i * param->rows * param->columns * sizeof(float));
|
||||||
|
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
|
|
||||||
case D3DXPC_SCALAR:
|
case D3DXPC_SCALAR:
|
||||||
|
@ -3139,13 +3229,18 @@ static HRESULT WINAPI d3dx_effect_SetMatrixPointerArray(ID3DXEffect *iface, D3DX
|
||||||
if (param && count <= param->element_count)
|
if (param && count <= param->element_count)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
BYTE *data;
|
||||||
|
|
||||||
switch (param->class)
|
switch (param->class)
|
||||||
{
|
{
|
||||||
case D3DXPC_MATRIX_ROWS:
|
case D3DXPC_MATRIX_ROWS:
|
||||||
set_dirty(param);
|
data = param_get_data_and_dirtify(effect, param, count * param->rows
|
||||||
|
* param->columns * sizeof(float), TRUE);
|
||||||
|
|
||||||
for (i = 0; i < count; ++i)
|
for (i = 0; i < count; ++i)
|
||||||
set_matrix(¶m->members[i], matrix[i]);
|
set_matrix(¶m->members[i], matrix[i], data + i * param->rows
|
||||||
|
* param->columns * sizeof(float));
|
||||||
|
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
|
|
||||||
case D3DXPC_SCALAR:
|
case D3DXPC_SCALAR:
|
||||||
|
@ -3219,8 +3314,8 @@ static HRESULT WINAPI d3dx_effect_SetMatrixTranspose(ID3DXEffect *iface, D3DXHAN
|
||||||
switch (param->class)
|
switch (param->class)
|
||||||
{
|
{
|
||||||
case D3DXPC_MATRIX_ROWS:
|
case D3DXPC_MATRIX_ROWS:
|
||||||
set_dirty(param);
|
set_matrix_transpose(param, matrix, param_get_data_and_dirtify(effect, param,
|
||||||
set_matrix_transpose(param, matrix);
|
param->rows * param->columns * sizeof(float), TRUE));
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
|
|
||||||
case D3DXPC_SCALAR:
|
case D3DXPC_SCALAR:
|
||||||
|
@ -3289,15 +3384,20 @@ static HRESULT WINAPI d3dx_effect_SetMatrixTransposeArray(ID3DXEffect *iface, D3
|
||||||
if (param && param->element_count >= count)
|
if (param && param->element_count >= count)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
BYTE *data;
|
||||||
|
|
||||||
TRACE("Class %s.\n", debug_d3dxparameter_class(param->class));
|
TRACE("Class %s.\n", debug_d3dxparameter_class(param->class));
|
||||||
|
|
||||||
switch (param->class)
|
switch (param->class)
|
||||||
{
|
{
|
||||||
case D3DXPC_MATRIX_ROWS:
|
case D3DXPC_MATRIX_ROWS:
|
||||||
set_dirty(param);
|
data = param_get_data_and_dirtify(effect, param, count * param->rows
|
||||||
|
* param->columns * sizeof(float), TRUE);
|
||||||
|
|
||||||
for (i = 0; i < count; ++i)
|
for (i = 0; i < count; ++i)
|
||||||
set_matrix_transpose(¶m->members[i], &matrix[i]);
|
set_matrix_transpose(¶m->members[i], &matrix[i], data
|
||||||
|
+ i * param->rows * param->columns * sizeof(float));
|
||||||
|
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
|
|
||||||
case D3DXPC_SCALAR:
|
case D3DXPC_SCALAR:
|
||||||
|
@ -3369,13 +3469,18 @@ static HRESULT WINAPI d3dx_effect_SetMatrixTransposePointerArray(ID3DXEffect *if
|
||||||
if (param && count <= param->element_count)
|
if (param && count <= param->element_count)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
BYTE *data;
|
||||||
|
|
||||||
switch (param->class)
|
switch (param->class)
|
||||||
{
|
{
|
||||||
case D3DXPC_MATRIX_ROWS:
|
case D3DXPC_MATRIX_ROWS:
|
||||||
set_dirty(param);
|
data = param_get_data_and_dirtify(effect, param, count * param->rows
|
||||||
|
* param->columns * sizeof(float), TRUE);
|
||||||
|
|
||||||
for (i = 0; i < count; ++i)
|
for (i = 0; i < count; ++i)
|
||||||
set_matrix_transpose(¶m->members[i], matrix[i]);
|
set_matrix_transpose(¶m->members[i], matrix[i], data
|
||||||
|
+ i * param->rows * param->columns * sizeof(float));
|
||||||
|
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
|
|
||||||
case D3DXPC_SCALAR:
|
case D3DXPC_SCALAR:
|
||||||
|
@ -3442,10 +3547,7 @@ static HRESULT WINAPI d3dx_effect_SetString(ID3DXEffect *iface, D3DXHANDLE param
|
||||||
TRACE("iface %p, parameter %p, string %s.\n", iface, parameter, debugstr_a(string));
|
TRACE("iface %p, parameter %p, string %s.\n", iface, parameter, debugstr_a(string));
|
||||||
|
|
||||||
if (param && param->type == D3DXPT_STRING)
|
if (param && param->type == D3DXPT_STRING)
|
||||||
{
|
return set_string(param_get_data_and_dirtify(effect, param, sizeof(void *), TRUE), string);
|
||||||
set_dirty(param);
|
|
||||||
return set_string(param->data, string);
|
|
||||||
}
|
|
||||||
|
|
||||||
WARN("Parameter not found.\n");
|
WARN("Parameter not found.\n");
|
||||||
|
|
||||||
|
@ -3484,7 +3586,11 @@ static HRESULT WINAPI d3dx_effect_SetTexture(ID3DXEffect *iface, D3DXHANDLE para
|
||||||
|| param->type == D3DXPT_TEXTURE2D || param->type == D3DXPT_TEXTURE3D
|
|| param->type == D3DXPT_TEXTURE2D || param->type == D3DXPT_TEXTURE3D
|
||||||
|| param->type == D3DXPT_TEXTURECUBE))
|
|| param->type == D3DXPT_TEXTURECUBE))
|
||||||
{
|
{
|
||||||
IDirect3DBaseTexture9 *old_texture = *(IDirect3DBaseTexture9 **)param->data;
|
IDirect3DBaseTexture9 **data = param_get_data_and_dirtify(effect, param,
|
||||||
|
sizeof(void *), texture != *(IDirect3DBaseTexture9 **)param->data);
|
||||||
|
IDirect3DBaseTexture9 *old_texture = *data;
|
||||||
|
|
||||||
|
*data = texture;
|
||||||
|
|
||||||
if (texture == old_texture)
|
if (texture == old_texture)
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
|
@ -3494,9 +3600,6 @@ static HRESULT WINAPI d3dx_effect_SetTexture(ID3DXEffect *iface, D3DXHANDLE para
|
||||||
if (old_texture)
|
if (old_texture)
|
||||||
IDirect3DBaseTexture9_Release(old_texture);
|
IDirect3DBaseTexture9_Release(old_texture);
|
||||||
|
|
||||||
*(IDirect3DBaseTexture9 **)param->data = texture;
|
|
||||||
set_dirty(param);
|
|
||||||
|
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4137,6 +4240,10 @@ static D3DXHANDLE WINAPI d3dx_effect_EndParameterBlock(ID3DXEffect *iface)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
ret = effect->current_parameter_block;
|
ret = effect->current_parameter_block;
|
||||||
|
|
||||||
|
ret->buffer = heap_realloc(ret->buffer, ret->offset);
|
||||||
|
ret->size = ret->offset;
|
||||||
|
|
||||||
effect->current_parameter_block = NULL;
|
effect->current_parameter_block = NULL;
|
||||||
list_add_tail(&effect->parameter_block_list, &ret->entry);
|
list_add_tail(&effect->parameter_block_list, &ret->entry);
|
||||||
return (D3DXHANDLE)ret;
|
return (D3DXHANDLE)ret;
|
||||||
|
|
|
@ -8020,12 +8020,12 @@ static void test_effect_parameter_block(void)
|
||||||
IDirect3DTexture9 *texture, *tex_test;
|
IDirect3DTexture9 *texture, *tex_test;
|
||||||
D3DXHANDLE block, block2, handle;
|
D3DXHANDLE block, block2, handle;
|
||||||
ID3DXEffect *effect, *effect2;
|
ID3DXEffect *effect, *effect2;
|
||||||
|
D3DXMATRIX mat, mat_arr[2];
|
||||||
IDirect3DDevice9 *device;
|
IDirect3DDevice9 *device;
|
||||||
ID3DXEffectPool *pool;
|
ID3DXEffectPool *pool;
|
||||||
float float_array[4];
|
float float_array[4];
|
||||||
float float_value;
|
float float_value;
|
||||||
IDirect3D9 *d3d;
|
IDirect3D9 *d3d;
|
||||||
D3DXMATRIX mat;
|
|
||||||
ULONG refcount;
|
ULONG refcount;
|
||||||
HWND window;
|
HWND window;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
@ -8115,9 +8115,7 @@ static void test_effect_parameter_block(void)
|
||||||
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
||||||
|
|
||||||
hr = effect->lpVtbl->GetTexture(effect, "tex1", (IDirect3DBaseTexture9 **)&tex_test);
|
hr = effect->lpVtbl->GetTexture(effect, "tex1", (IDirect3DBaseTexture9 **)&tex_test);
|
||||||
todo_wine ok(hr == D3D_OK && !tex_test, "Got unexpected hr %#x, tex_test %p.\n", hr, tex_test);
|
ok(hr == D3D_OK && !tex_test, "Got unexpected hr %#x, tex_test %p.\n", hr, tex_test);
|
||||||
if (tex_test)
|
|
||||||
IDirect3DTexture9_Release(tex_test);
|
|
||||||
|
|
||||||
/* Child parameters and array members are recorded separately (the whole
|
/* Child parameters and array members are recorded separately (the whole
|
||||||
* parameter is not updated when parameter block is applied). */
|
* parameter is not updated when parameter block is applied). */
|
||||||
|
@ -8126,13 +8124,13 @@ static void test_effect_parameter_block(void)
|
||||||
hr = effect->lpVtbl->SetFloat(effect, "ts1[0].fv", 28.0f);
|
hr = effect->lpVtbl->SetFloat(effect, "ts1[0].fv", 28.0f);
|
||||||
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
||||||
hr = effect->lpVtbl->GetFloat(effect, "ts1[0].fv", &float_value);
|
hr = effect->lpVtbl->GetFloat(effect, "ts1[0].fv", &float_value);
|
||||||
todo_wine ok(hr == D3D_OK && float_value == 12.0, "Got unexpected hr %#x, float_value %g.\n", hr, float_value);
|
ok(hr == D3D_OK && float_value == 12.0, "Got unexpected hr %#x, float_value %g.\n", hr, float_value);
|
||||||
|
|
||||||
float_array[0] = -29.0f;
|
float_array[0] = -29.0f;
|
||||||
hr = effect->lpVtbl->SetFloatArray(effect, "ts1[0].v2", float_array, 1);
|
hr = effect->lpVtbl->SetFloatArray(effect, "ts1[0].v2", float_array, 1);
|
||||||
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
||||||
hr = effect->lpVtbl->GetFloatArray(effect, "ts1[0].v2", float_array, 1);
|
hr = effect->lpVtbl->GetFloatArray(effect, "ts1[0].v2", float_array, 1);
|
||||||
todo_wine ok(hr == D3D_OK && float_array[0] == 13.0, "Got unexpected hr %#x, float_array[0] %g.\n",
|
ok(hr == D3D_OK && float_array[0] == 13.0, "Got unexpected hr %#x, float_array[0] %g.\n",
|
||||||
hr, float_array[0]);
|
hr, float_array[0]);
|
||||||
|
|
||||||
memset(&mat, 0, sizeof(mat));
|
memset(&mat, 0, sizeof(mat));
|
||||||
|
@ -8140,13 +8138,13 @@ static void test_effect_parameter_block(void)
|
||||||
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
||||||
hr = effect->lpVtbl->GetMatrix(effect, "m3x2row", &mat);
|
hr = effect->lpVtbl->GetMatrix(effect, "m3x2row", &mat);
|
||||||
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
||||||
todo_wine ok(!memcmp(&mat, &effect_orig_mat, sizeof(mat)), "Got unexpected matrix.\n");
|
ok(!memcmp(&mat, &effect_orig_mat, sizeof(mat)), "Got unexpected matrix.\n");
|
||||||
|
|
||||||
hr = effect->lpVtbl->SetMatrix(effect, "m3x2column", &test_mat);
|
hr = effect->lpVtbl->SetMatrix(effect, "m3x2column", &test_mat);
|
||||||
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
||||||
hr = effect->lpVtbl->GetMatrix(effect, "m3x2column", &mat);
|
hr = effect->lpVtbl->GetMatrix(effect, "m3x2column", &mat);
|
||||||
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
||||||
todo_wine ok(!memcmp(&mat, &effect_orig_mat, sizeof(mat)), "Got unexpected matrix.\n");
|
ok(!memcmp(&mat, &effect_orig_mat, sizeof(mat)), "Got unexpected matrix.\n");
|
||||||
|
|
||||||
/* Setting shared parameter through effect2 is not recorded to effect
|
/* Setting shared parameter through effect2 is not recorded to effect
|
||||||
* parameter block. */
|
* parameter block. */
|
||||||
|
@ -8321,6 +8319,30 @@ static void test_effect_parameter_block(void)
|
||||||
refcount = pool->lpVtbl->Release(pool);
|
refcount = pool->lpVtbl->Release(pool);
|
||||||
ok(!refcount, "Got unexpected refcount %u.\n", refcount);
|
ok(!refcount, "Got unexpected refcount %u.\n", refcount);
|
||||||
|
|
||||||
|
hr = D3DXCreateEffect(device, test_effect_parameter_value_blob_float, sizeof(test_effect_parameter_value_blob_float),
|
||||||
|
NULL, NULL, 0, NULL, &effect, NULL);
|
||||||
|
hr = effect->lpVtbl->BeginParameterBlock(effect);
|
||||||
|
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
||||||
|
mat_arr[0] = mat_arr[1] = test_mat;
|
||||||
|
hr = effect->lpVtbl->SetMatrixArray(effect, "f33_2", mat_arr, 2);
|
||||||
|
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
||||||
|
block = effect->lpVtbl->EndParameterBlock(effect);
|
||||||
|
ok(!!block, "Got unexpected block %p.\n", block);
|
||||||
|
|
||||||
|
memset(mat_arr, 0, sizeof(mat_arr));
|
||||||
|
hr = effect->lpVtbl->SetMatrixArray(effect, "f33_2", mat_arr, 2);
|
||||||
|
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
||||||
|
hr = effect->lpVtbl->ApplyParameterBlock(effect, block);
|
||||||
|
todo_wine ok(hr == D3D_OK, "Got result %#x.\n", hr);
|
||||||
|
|
||||||
|
hr = effect->lpVtbl->GetMatrixArray(effect, "f33_2", mat_arr, 2);
|
||||||
|
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
||||||
|
todo_wine ok(!memcmp(&mat_arr[0], &test_mat, sizeof(test_mat))
|
||||||
|
&& !memcmp(&mat_arr[1], &test_mat, sizeof(test_mat)), "Got unexpected matrix array.\n");
|
||||||
|
|
||||||
|
refcount = effect->lpVtbl->Release(effect);
|
||||||
|
ok(!refcount, "Got unexpected refcount %u.\n", refcount);
|
||||||
|
|
||||||
refcount = IDirect3DDevice9_Release(device);
|
refcount = IDirect3DDevice9_Release(device);
|
||||||
ok(!refcount, "Device has %u references left.\n", refcount);
|
ok(!refcount, "Device has %u references left.\n", refcount);
|
||||||
IDirect3D9_Release(d3d);
|
IDirect3D9_Release(d3d);
|
||||||
|
|
Loading…
Reference in New Issue