d3d10/effect: Partially implement D3D10CreateEffectPoolFromMemory().

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-09-16 09:48:09 +03:00 committed by Alexandre Julliard
parent d6359f0bba
commit cec812d861
3 changed files with 237 additions and 39 deletions

View File

@ -257,10 +257,10 @@ struct d3d10_effect_anonymous_shader
};
/* ID3D10Effect */
extern const struct ID3D10EffectVtbl d3d10_effect_vtbl DECLSPEC_HIDDEN;
struct d3d10_effect
{
ID3D10Effect ID3D10Effect_iface;
ID3D10EffectPool ID3D10EffectPool_iface;
LONG refcount;
ID3D10Device *device;

View File

@ -44,6 +44,13 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d10);
#define D3D10_FX10_TYPE_MATRIX_COLUMN_MAJOR_MASK 0x4000
static inline struct d3d10_effect *impl_from_ID3D10EffectPool(ID3D10EffectPool *iface)
{
return CONTAINING_RECORD(iface, struct d3d10_effect, ID3D10EffectPool_iface);
}
static const struct ID3D10EffectVtbl d3d10_effect_pool_effect_vtbl;
static const struct ID3D10EffectTechniqueVtbl d3d10_effect_technique_vtbl;
static const struct ID3D10EffectPassVtbl d3d10_effect_pass_vtbl;
static const struct ID3D10EffectVariableVtbl d3d10_effect_variable_vtbl;
@ -3139,9 +3146,11 @@ static BOOL STDMETHODCALLTYPE d3d10_effect_IsValid(ID3D10Effect *iface)
static BOOL STDMETHODCALLTYPE d3d10_effect_IsPool(ID3D10Effect *iface)
{
FIXME("iface %p stub!\n", iface);
struct d3d10_effect *effect = impl_from_ID3D10Effect(iface);
return FALSE;
TRACE("iface %p.\n", iface);
return effect->ID3D10Effect_iface.lpVtbl == &d3d10_effect_pool_effect_vtbl;
}
static HRESULT STDMETHODCALLTYPE d3d10_effect_GetDevice(ID3D10Effect *iface, ID3D10Device **device)
@ -8361,6 +8370,57 @@ static const struct ID3D10EffectTypeVtbl d3d10_effect_type_vtbl =
d3d10_effect_type_GetMemberSemantic,
};
static HRESULT STDMETHODCALLTYPE d3d10_effect_pool_QueryInterface(ID3D10EffectPool *iface,
REFIID riid, void **object)
{
TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
if (IsEqualGUID(riid, &IID_ID3D10EffectPool) ||
IsEqualGUID(riid, &IID_IUnknown))
{
IUnknown_AddRef(iface);
*object = iface;
return S_OK;
}
WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid));
*object = NULL;
return E_NOINTERFACE;
}
static ULONG STDMETHODCALLTYPE d3d10_effect_pool_AddRef(ID3D10EffectPool *iface)
{
struct d3d10_effect *effect = impl_from_ID3D10EffectPool(iface);
return d3d10_effect_AddRef(&effect->ID3D10Effect_iface);
}
static ULONG STDMETHODCALLTYPE d3d10_effect_pool_Release(ID3D10EffectPool *iface)
{
struct d3d10_effect *effect = impl_from_ID3D10EffectPool(iface);
return d3d10_effect_Release(&effect->ID3D10Effect_iface);
}
static ID3D10Effect * STDMETHODCALLTYPE d3d10_effect_pool_AsEffect(ID3D10EffectPool *iface)
{
struct d3d10_effect *effect = impl_from_ID3D10EffectPool(iface);
TRACE("%p.\n", iface);
return &effect->ID3D10Effect_iface;
}
const struct ID3D10EffectPoolVtbl d3d10_effect_pool_vtbl =
{
/* IUnknown methods */
d3d10_effect_pool_QueryInterface,
d3d10_effect_pool_AddRef,
d3d10_effect_pool_Release,
/* ID3D10EffectPool methods */
d3d10_effect_pool_AsEffect,
};
static int d3d10_effect_type_compare(const void *key, const struct wine_rb_entry *entry)
{
const struct d3d10_effect_type *t = WINE_RB_ENTRY_VALUE(entry, const struct d3d10_effect_type, entry);
@ -8369,23 +8429,18 @@ static int d3d10_effect_type_compare(const void *key, const struct wine_rb_entry
return *id - t->id;
}
HRESULT WINAPI D3D10CreateEffectFromMemory(void *data, SIZE_T data_size, UINT flags,
ID3D10Device *device, ID3D10EffectPool *effect_pool, ID3D10Effect **effect)
static HRESULT d3d10_create_effect(void *data, SIZE_T data_size, ID3D10Device *device,
const ID3D10EffectVtbl *vtbl, struct d3d10_effect **effect)
{
struct d3d10_effect *object;
HRESULT hr;
FIXME("data %p, data_size %lu, flags %#x, device %p, effect_pool %p, effect %p stub!\n",
data, data_size, flags, device, effect_pool, effect);
if (!(object = heap_alloc_zero(sizeof(*object))))
{
ERR("Failed to allocate D3D10 effect object memory\n");
return E_OUTOFMEMORY;
}
wine_rb_init(&object->types, d3d10_effect_type_compare);
object->ID3D10Effect_iface.lpVtbl = &d3d10_effect_vtbl;
object->ID3D10Effect_iface.lpVtbl = vtbl;
object->ID3D10EffectPool_iface.lpVtbl = &d3d10_effect_pool_vtbl;
object->refcount = 1;
ID3D10Device_AddRef(device);
object->device = device;
@ -8398,18 +8453,83 @@ HRESULT WINAPI D3D10CreateEffectFromMemory(void *data, SIZE_T data_size, UINT fl
return hr;
}
*effect = &object->ID3D10Effect_iface;
TRACE("Created effect %p\n", object);
*effect = object;
return S_OK;
}
HRESULT WINAPI D3D10CreateEffectFromMemory(void *data, SIZE_T data_size, UINT flags,
ID3D10Device *device, ID3D10EffectPool *effect_pool, ID3D10Effect **effect)
{
struct d3d10_effect *object;
HRESULT hr;
FIXME("data %p, data_size %lu, flags %#x, device %p, effect_pool %p, effect %p stub!\n",
data, data_size, flags, device, effect_pool, effect);
if (FAILED(hr = d3d10_create_effect(data, data_size, device, &d3d10_effect_vtbl, &object)))
{
WARN("Failed to create an effect, hr %#x.\n", hr);
}
*effect = &object->ID3D10Effect_iface;
TRACE("Created effect %p\n", object);
return hr;
}
static HRESULT STDMETHODCALLTYPE d3d10_effect_pool_effect_QueryInterface(ID3D10Effect *iface,
REFIID riid, void **object)
{
struct d3d10_effect *effect = impl_from_ID3D10Effect(iface);
TRACE("iface %p, riid %s, obj %p.\n", iface, debugstr_guid(riid), object);
return IUnknown_QueryInterface(&effect->ID3D10EffectPool_iface, riid, object);
}
static const struct ID3D10EffectVtbl d3d10_effect_pool_effect_vtbl =
{
/* IUnknown methods */
d3d10_effect_pool_effect_QueryInterface,
d3d10_effect_AddRef,
d3d10_effect_Release,
/* ID3D10Effect methods */
d3d10_effect_IsValid,
d3d10_effect_IsPool,
d3d10_effect_GetDevice,
d3d10_effect_GetDesc,
d3d10_effect_GetConstantBufferByIndex,
d3d10_effect_GetConstantBufferByName,
d3d10_effect_GetVariableByIndex,
d3d10_effect_GetVariableByName,
d3d10_effect_GetVariableBySemantic,
d3d10_effect_GetTechniqueByIndex,
d3d10_effect_GetTechniqueByName,
d3d10_effect_Optimize,
d3d10_effect_IsOptimized,
};
HRESULT WINAPI D3D10CreateEffectPoolFromMemory(void *data, SIZE_T data_size, UINT fx_flags,
ID3D10Device *device, ID3D10EffectPool **effect_pool)
{
FIXME("data %p, data_size %lu, fx_flags %#x, device %p, effect_pool %p stub.\n",
struct d3d10_effect *object;
HRESULT hr;
TRACE("data %p, data_size %lu, fx_flags %#x, device %p, effect_pool %p.\n",
data, data_size, fx_flags, device, effect_pool);
return E_NOTIMPL;
if (FAILED(hr = d3d10_create_effect(data, data_size, device, &d3d10_effect_pool_effect_vtbl,
&object)))
{
WARN("Failed to create an effect, hr %#x.\n", hr);
return hr;
}
*effect_pool = &object->ID3D10EffectPool_iface;
TRACE("Created effect pool %p.\n", object);
return hr;
}

View File

@ -6377,6 +6377,7 @@ static void test_effect_pool(void)
D3D10_EFFECT_DESC desc;
ID3D10Buffer *buffer;
ULONG refcount;
IUnknown *unk;
HRESULT hr;
BOOL ret;
@ -6394,13 +6395,7 @@ todo_wine
ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
hr = create_effect_pool(fx_test_pool, device, &pool);
todo_wine
ok(hr == S_OK, "Failed to create effect pool, hr %#x.\n", hr);
if (FAILED(hr))
{
ID3D10Device_Release(device);
return;
}
refcount = get_refcount(pool);
ok(refcount == 1, "Unexpected refcount %u.\n", refcount);
@ -6412,6 +6407,27 @@ todo_wine
ok(refcount == 2, "Unexpected refcount %u.\n", refcount);
effect->lpVtbl->Release(effect);
hr = pool->lpVtbl->QueryInterface(pool, &IID_IUnknown, (void **)&unk);
todo_wine
ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
if (SUCCEEDED(hr)) IUnknown_Release(unk);
hr = pool->lpVtbl->QueryInterface(pool, &IID_ID3D10Effect, (void **)&unk);
ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
hr = pool->lpVtbl->QueryInterface(pool, &IID_ID3D10EffectPool, (void **)&unk);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
ok(unk == (IUnknown *)pool, "Unexpected pointer.\n");
IUnknown_Release(unk);
hr = effect->lpVtbl->QueryInterface(effect, &IID_IUnknown, (void **)&unk);
todo_wine
ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
if (SUCCEEDED(hr)) IUnknown_Release(unk);
hr = effect->lpVtbl->QueryInterface(effect, &IID_ID3D10Effect, (void **)&unk);
ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
hr = effect->lpVtbl->QueryInterface(effect, &IID_ID3D10EffectPool, (void **)&pool2);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
ok(pool2 == pool, "Unexpected pool pointer.\n");
@ -6434,24 +6450,28 @@ todo_wine
hr = cb->lpVtbl->GetDesc(cb, &var_desc);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
ok(!strcmp(var_desc.Name, "s_cb"), "Unexpected name %s.\n", var_desc.Name);
todo_wine
ok(var_desc.Flags == D3D10_EFFECT_VARIABLE_POOLED, "Unexpected flags %#x.\n", var_desc.Flags);
v = effect->lpVtbl->GetVariableByName(effect, "s_blendstate");
hr = v->lpVtbl->GetDesc(v, &var_desc);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
ok(!strcmp(var_desc.Name, "s_blendstate"), "Unexpected name %s.\n", var_desc.Name);
todo_wine
ok(var_desc.Flags == D3D10_EFFECT_VARIABLE_POOLED, "Unexpected flags %#x.\n", var_desc.Flags);
v = effect->lpVtbl->GetVariableByName(effect, "s_texture");
hr = v->lpVtbl->GetDesc(v, &var_desc);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
ok(!strcmp(var_desc.Name, "s_texture"), "Unexpected name %s.\n", var_desc.Name);
todo_wine
ok(var_desc.Flags == D3D10_EFFECT_VARIABLE_POOLED, "Unexpected flags %#x.\n", var_desc.Flags);
v = effect->lpVtbl->GetVariableByName(effect, "ps");
hr = v->lpVtbl->GetDesc(v, &var_desc);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
ok(!strcmp(var_desc.Name, "ps"), "Unexpected name %s.\n", var_desc.Name);
todo_wine
ok(var_desc.Flags == D3D10_EFFECT_VARIABLE_POOLED, "Unexpected flags %#x.\n", var_desc.Flags);
t = effect->lpVtbl->GetTechniqueByIndex(effect, 0);
@ -6466,11 +6486,31 @@ todo_wine
/* Create standalone effect from the same blob used for pool, */
hr = create_effect(fx_test_pool, D3D10_EFFECT_COMPILE_CHILD_EFFECT, device, NULL, &child_effect);
todo_wine
ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
if (SUCCEEDED(hr)) child_effect->lpVtbl->Release(child_effect);
hr = create_effect(fx_test_pool, 0, device, NULL, &effect2);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
hr = effect2->lpVtbl->QueryInterface(effect2, &IID_IUnknown, (void **)&unk);
todo_wine
ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
if (SUCCEEDED(hr)) IUnknown_Release(unk);
hr = effect2->lpVtbl->QueryInterface(effect2, &IID_ID3D10Effect, (void **)&unk);
todo_wine
ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
if (SUCCEEDED(hr)) IUnknown_Release(unk);
/* For regular effects querying for ID3D10EffectPool is broken */
hr = effect2->lpVtbl->QueryInterface(effect2, &IID_ID3D10EffectPool, (void **)&unk);
todo_wine {
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
ok(unk == (IUnknown *)effect2, "Unexpected pointer.\n");
}
if (SUCCEEDED(hr)) IUnknown_Release(unk);
ret = effect2->lpVtbl->IsPool(effect2);
ok(!ret, "Unexpected pool.\n");
@ -6505,24 +6545,33 @@ todo_wine
ID3D10Device_Release(device3);
cb = child_effect->lpVtbl->GetConstantBufferByName(child_effect, "s_cb");
todo_wine
ok(cb->lpVtbl->IsValid(cb), "Expected valid constant buffer.\n");
hr = cb->lpVtbl->GetConstantBuffer(cb, &buffer);
todo_wine
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
ID3D10Buffer_GetDevice(buffer, &device3);
ok(device3 == device2, "Unexpected device.\n");
ID3D10Device_Release(device3);
ID3D10Buffer_Release(buffer);
if (SUCCEEDED(hr))
{
ID3D10Buffer_GetDevice(buffer, &device3);
ok(device3 == device2, "Unexpected device.\n");
ID3D10Device_Release(device3);
ID3D10Buffer_Release(buffer);
}
child_effect->lpVtbl->Release(child_effect);
pool2->lpVtbl->Release(pool2);
/* When pool is specified, corresponding flag has to be set. */
hr = create_effect(fx_test_pool_child, 0, device, pool, &child_effect);
todo_wine
ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
if (SUCCEEDED(hr)) child_effect->lpVtbl->Release(child_effect);
hr = create_effect(fx_test_pool_child, D3D10_EFFECT_COMPILE_CHILD_EFFECT, device, NULL, &child_effect);
todo_wine
ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
if (SUCCEEDED(hr)) child_effect->lpVtbl->Release(child_effect);
refcount = get_refcount(pool);
ok(refcount == 1, "Unexpected refcount %u.\n", refcount);
@ -6531,15 +6580,19 @@ todo_wine
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
refcount = get_refcount(pool);
todo_wine
ok(refcount == 2, "Unexpected refcount %u.\n", refcount);
hr = child_effect->lpVtbl->GetDesc(child_effect, &desc);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
todo_wine
ok(desc.IsChildEffect, "Unexpected child flag.\n");
ok(desc.ConstantBuffers == 2, "Unexpected buffer count %u.\n", desc.ConstantBuffers);
todo_wine
ok(desc.SharedConstantBuffers == 1, "Unexpected shared buffer count %u.\n",
desc.SharedConstantBuffers);
ok(desc.GlobalVariables == 2, "Unexpected variables count %u.\n", desc.GlobalVariables);
todo_wine
ok(desc.SharedGlobalVariables == 5, "Unexpected shared variables count %u.\n",
desc.SharedGlobalVariables);
@ -6564,12 +6617,17 @@ todo_wine
cb = child_effect->lpVtbl->GetConstantBufferByIndex(child_effect, 2);
ret = cb->lpVtbl->IsValid(cb);
todo_wine
ok(ret, "Unexpected invalid variable.\n");
hr = cb->lpVtbl->GetDesc(cb, &var_desc);
todo_wine
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
ok(!strcmp(var_desc.Name, "s_cb"), "Unexpected name %s.\n", var_desc.Name);
ok(var_desc.Flags == D3D10_EFFECT_VARIABLE_POOLED, "Unexpected flags %#x.\n", var_desc.Flags);
if (SUCCEEDED(hr))
{
ok(!strcmp(var_desc.Name, "s_cb"), "Unexpected name %s.\n", var_desc.Name);
ok(var_desc.Flags == D3D10_EFFECT_VARIABLE_POOLED, "Unexpected flags %#x.\n", var_desc.Flags);
}
/* Pool techniques are not accessible */
t = effect->lpVtbl->GetTechniqueByIndex(effect, 0);
@ -6593,27 +6651,43 @@ todo_wine
v = child_effect->lpVtbl->GetVariableByIndex(child_effect, 2);
hr = v->lpVtbl->GetDesc(v, &var_desc);
todo_wine
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
ok(!strcmp(var_desc.Name, "f1"), "Unexpected name %s.\n", var_desc.Name);
ok(var_desc.Flags == D3D10_EFFECT_VARIABLE_POOLED, "Unexpected flags %#x.\n", var_desc.Flags);
if (SUCCEEDED(hr))
{
ok(!strcmp(var_desc.Name, "f1"), "Unexpected name %s.\n", var_desc.Name);
ok(var_desc.Flags == D3D10_EFFECT_VARIABLE_POOLED, "Unexpected flags %#x.\n", var_desc.Flags);
}
v = child_effect->lpVtbl->GetVariableByIndex(child_effect, 3);
hr = v->lpVtbl->GetDesc(v, &var_desc);
todo_wine
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
ok(!strcmp(var_desc.Name, "f2"), "Unexpected name %s.\n", var_desc.Name);
ok(var_desc.Flags == D3D10_EFFECT_VARIABLE_POOLED, "Unexpected flags %#x.\n", var_desc.Flags);
if (SUCCEEDED(hr))
{
ok(!strcmp(var_desc.Name, "f2"), "Unexpected name %s.\n", var_desc.Name);
ok(var_desc.Flags == D3D10_EFFECT_VARIABLE_POOLED, "Unexpected flags %#x.\n", var_desc.Flags);
}
v = child_effect->lpVtbl->GetVariableByIndex(child_effect, 4);
hr = v->lpVtbl->GetDesc(v, &var_desc);
todo_wine
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
ok(!strcmp(var_desc.Name, "s_blendstate"), "Unexpected name %s.\n", var_desc.Name);
ok(var_desc.Flags == D3D10_EFFECT_VARIABLE_POOLED, "Unexpected flags %#x.\n", var_desc.Flags);
if (SUCCEEDED(hr))
{
ok(!strcmp(var_desc.Name, "s_blendstate"), "Unexpected name %s.\n", var_desc.Name);
ok(var_desc.Flags == D3D10_EFFECT_VARIABLE_POOLED, "Unexpected flags %#x.\n", var_desc.Flags);
}
v = child_effect->lpVtbl->GetVariableByName(child_effect, "s_texture");
hr = v->lpVtbl->GetDesc(v, &var_desc);
todo_wine
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
ok(!strcmp(var_desc.Name, "s_texture"), "Unexpected name %s.\n", var_desc.Name);
ok(var_desc.Flags == D3D10_EFFECT_VARIABLE_POOLED, "Unexpected flags %#x.\n", var_desc.Flags);
if (SUCCEEDED(hr))
{
ok(!strcmp(var_desc.Name, "s_texture"), "Unexpected name %s.\n", var_desc.Name);
ok(var_desc.Flags == D3D10_EFFECT_VARIABLE_POOLED, "Unexpected flags %#x.\n", var_desc.Flags);
}
v = child_effect->lpVtbl->GetVariableBySemantic(child_effect, "COLOR0");
hr = v->lpVtbl->GetDesc(v, &var_desc);
@ -6623,9 +6697,13 @@ todo_wine
v = child_effect->lpVtbl->GetVariableBySemantic(child_effect, "COLOR1");
hr = v->lpVtbl->GetDesc(v, &var_desc);
todo_wine
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
ok(!strcmp(var_desc.Name, "f2"), "Unexpected name %s.\n", var_desc.Name);
ok(var_desc.Flags == D3D10_EFFECT_VARIABLE_POOLED, "Unexpected flags %#x.\n", var_desc.Flags);
if (SUCCEEDED(hr))
{
ok(!strcmp(var_desc.Name, "f2"), "Unexpected name %s.\n", var_desc.Name);
ok(var_desc.Flags == D3D10_EFFECT_VARIABLE_POOLED, "Unexpected flags %#x.\n", var_desc.Flags);
}
child_effect->lpVtbl->Release(child_effect);