d3dx9: Implement D3DXCreateFragmentLinker[Ex]().

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=38086
Signed-off-by: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
Signed-off-by: Matteo Bruni <mbruni@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alistair Leslie-Hughes 2019-11-29 11:57:30 +01:00 committed by Alexandre Julliard
parent b29c7da5f0
commit fd06827bca
2 changed files with 250 additions and 8 deletions

View File

@ -2069,27 +2069,220 @@ HRESULT WINAPI D3DXGetShaderConstantTable(const DWORD *byte_code, ID3DXConstantT
return D3DXGetShaderConstantTableEx(byte_code, 0, constant_table);
}
HRESULT WINAPI D3DXCreateFragmentLinker(IDirect3DDevice9 *device, UINT size, ID3DXFragmentLinker **linker)
struct d3dx9_fragment_linker
{
FIXME("device %p, size %u, linker %p: stub.\n", device, size, linker);
ID3DXFragmentLinker ID3DXFragmentLinker_iface;
LONG ref;
if (linker)
*linker = NULL;
struct IDirect3DDevice9 *device;
DWORD flags;
};
static inline struct d3dx9_fragment_linker *impl_from_ID3DXFragmentLinker(ID3DXFragmentLinker *iface)
{
return CONTAINING_RECORD(iface, struct d3dx9_fragment_linker, ID3DXFragmentLinker_iface);
}
static HRESULT WINAPI d3dx9_fragment_linker_QueryInterface(ID3DXFragmentLinker *iface, REFIID riid, void **out)
{
TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
if (IsEqualGUID(riid, &IID_IUnknown)
|| IsEqualGUID(riid, &IID_ID3DXFragmentLinker))
{
iface->lpVtbl->AddRef(iface);
*out = iface;
return D3D_OK;
}
WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
*out = NULL;
return E_NOINTERFACE;
}
static ULONG WINAPI d3dx9_fragment_linker_AddRef(ID3DXFragmentLinker *iface)
{
struct d3dx9_fragment_linker *linker = impl_from_ID3DXFragmentLinker(iface);
ULONG refcount = InterlockedIncrement(&linker->ref);
TRACE("%p increasing refcount to %u.\n", linker, refcount);
return refcount;
}
static ULONG WINAPI d3dx9_fragment_linker_Release(ID3DXFragmentLinker *iface)
{
struct d3dx9_fragment_linker *linker = impl_from_ID3DXFragmentLinker(iface);
ULONG refcount = InterlockedDecrement(&linker->ref);
TRACE("%p decreasing refcount to %u.\n", linker, refcount);
if (!refcount)
{
IDirect3DDevice9_Release(linker->device);
heap_free(linker);
}
return refcount;
}
static HRESULT WINAPI d3dx9_fragment_linker_GetDevice(ID3DXFragmentLinker *iface, struct IDirect3DDevice9 **device)
{
struct d3dx9_fragment_linker *linker = impl_from_ID3DXFragmentLinker(iface);
TRACE("iface %p, device %p.\n", linker, device);
if (!device)
{
WARN("Invalid argument supplied.\n");
return D3DERR_INVALIDCALL;
}
IDirect3DDevice9_AddRef(linker->device);
*device = linker->device;
TRACE("Returning device %p.\n", *device);
return S_OK;
}
static UINT WINAPI d3dx9_fragment_linker_GetNumberOfFragments(ID3DXFragmentLinker *iface)
{
FIXME("iface %p: stub.\n", iface);
return E_NOTIMPL;
}
HRESULT WINAPI D3DXCreateFragmentLinkerEx(IDirect3DDevice9 *device, UINT size, DWORD flags, ID3DXFragmentLinker **linker)
static D3DXHANDLE WINAPI d3dx9_fragment_linker_GetFragmentHandleByIndex(ID3DXFragmentLinker *iface, UINT index)
{
FIXME("device %p, size %u, flags %#x, linker %p: stub.\n", device, size, flags, linker);
FIXME("iface %p, index %u: stub.\n", iface, index);
if (linker)
*linker = NULL;
return NULL;
}
static D3DXHANDLE WINAPI d3dx9_fragment_linker_GetFragmentHandleByName(ID3DXFragmentLinker *iface,
const char *name)
{
FIXME("iface %p, name %s: stub.\n", iface, debugstr_a(name));
return NULL;
}
static HRESULT WINAPI d3dx9_fragment_linker_GetFragmentDesc(ID3DXFragmentLinker *iface, D3DXHANDLE name,
D3DXFRAGMENT_DESC *desc)
{
FIXME("iface %p, name %p, desc %p: stub.\n", iface, name, desc);
return E_NOTIMPL;
}
static HRESULT WINAPI d3dx9_fragment_linker_AddFragments(ID3DXFragmentLinker *iface, const DWORD *fragments)
{
FIXME("iface %p, fragments %p: stub.\n", iface, fragments);
return E_NOTIMPL;
}
static HRESULT WINAPI d3dx9_fragment_linker_GetAllFragments(ID3DXFragmentLinker *iface, ID3DXBuffer **buffer)
{
FIXME("iface %p, buffer %p: stub.\n", iface, buffer);
return E_NOTIMPL;
}
static HRESULT WINAPI d3dx9_fragment_linker_GetFragment(ID3DXFragmentLinker *iface, D3DXHANDLE name,
ID3DXBuffer **buffer)
{
FIXME("iface %p, name %p, buffer %p: stub.\n", iface, name, buffer);
return E_NOTIMPL;
}
static HRESULT WINAPI d3dx9_fragment_linker_LinkShader(ID3DXFragmentLinker *iface, const char *profile,
DWORD flags, const D3DXHANDLE *handles, UINT fragment_count, ID3DXBuffer **buffer,
ID3DXBuffer **errors)
{
FIXME("iface %p, profile %s, flags %#x, handles %p, fragment_count %u, buffer %p, errors %p: stub.\n",
iface, debugstr_a(profile), flags, handles, fragment_count, buffer, errors);
return E_NOTIMPL;
}
static HRESULT WINAPI d3dx9_fragment_linker_LinkVertexShader(ID3DXFragmentLinker *iface, const char *profile,
DWORD flags, const D3DXHANDLE *handles, UINT fragment_count, IDirect3DVertexShader9 **shader,
ID3DXBuffer **errors)
{
FIXME("iface %p, profile %s, flags %#x, handles %p, fragment_count %u, shader %p, errors %p: stub.\n",
iface, debugstr_a(profile), flags, handles, fragment_count, shader, errors);
return E_NOTIMPL;
}
static HRESULT WINAPI d3dx9_fragment_linker_LinkPixelShader(ID3DXFragmentLinker *iface, const char *profile,
DWORD flags, const D3DXHANDLE *handles, UINT fragment_count, IDirect3DPixelShader9 **shader,
ID3DXBuffer **errors)
{
FIXME("iface %p, profile %s, flags %#x, handles %p, fragment_count %u, shader %p, errors %p: stub.\n",
iface, debugstr_a(profile), flags, handles, fragment_count, shader, errors);
return E_NOTIMPL;
}
static HRESULT WINAPI d3dx9_fragment_linker_ClearCache(ID3DXFragmentLinker *iface)
{
FIXME("iface %p: stub.\n", iface);
return E_NOTIMPL;
}
static const struct ID3DXFragmentLinkerVtbl d3dx9_fragment_linker_vtbl =
{
d3dx9_fragment_linker_QueryInterface,
d3dx9_fragment_linker_AddRef,
d3dx9_fragment_linker_Release,
d3dx9_fragment_linker_GetDevice,
d3dx9_fragment_linker_GetNumberOfFragments,
d3dx9_fragment_linker_GetFragmentHandleByIndex,
d3dx9_fragment_linker_GetFragmentHandleByName,
d3dx9_fragment_linker_GetFragmentDesc,
d3dx9_fragment_linker_AddFragments,
d3dx9_fragment_linker_GetAllFragments,
d3dx9_fragment_linker_GetFragment,
d3dx9_fragment_linker_LinkShader,
d3dx9_fragment_linker_LinkVertexShader,
d3dx9_fragment_linker_LinkPixelShader,
d3dx9_fragment_linker_ClearCache
};
HRESULT WINAPI D3DXCreateFragmentLinkerEx(IDirect3DDevice9 *device, UINT size, DWORD flags,
ID3DXFragmentLinker **linker)
{
struct d3dx9_fragment_linker *object;
TRACE("device %p, size %u, flags %#x, linker %p.\n", device, size, flags, linker);
object = heap_alloc(sizeof(*object));
if (!object)
return E_OUTOFMEMORY;
object->ID3DXFragmentLinker_iface.lpVtbl = &d3dx9_fragment_linker_vtbl;
object->ref = 1;
IDirect3DDevice9_AddRef(device);
object->device = device;
object->flags = flags;
*linker = &object->ID3DXFragmentLinker_iface;
return S_OK;
}
HRESULT WINAPI D3DXCreateFragmentLinker(IDirect3DDevice9 *device, UINT size, ID3DXFragmentLinker **linker)
{
TRACE("device %p, size %u, linker %p.\n", device, size, linker);
return D3DXCreateFragmentLinkerEx(device, size, 0, linker);
}
HRESULT WINAPI D3DXGetShaderSamplers(const DWORD *byte_code, const char **samplers, UINT *count)
{
UINT i, sampler_count = 0;

View File

@ -6575,6 +6575,54 @@ static void test_shader_semantics(void)
}
}
static void test_fragment_linker(void)
{
ID3DXFragmentLinker *linker;
D3DPRESENT_PARAMETERS d3dpp;
IDirect3DDevice9 *device;
IDirect3D9 *d3d;
ULONG refcount;
HWND window;
HRESULT hr;
window = CreateWindowA("static", "d3dx9_test", WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, NULL, NULL, NULL, NULL);
if (!(d3d = Direct3DCreate9(D3D_SDK_VERSION)))
{
skip("Failed to create a D3D object.\n");
DestroyWindow(window);
return;
}
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
D3DCREATE_MIXED_VERTEXPROCESSING, &d3dpp, &device);
if (FAILED(hr))
{
skip("Failed to create a D3D device, hr %#x.\n", hr);
IDirect3D9_Release(d3d);
DestroyWindow(window);
return;
}
hr = D3DXCreateFragmentLinker(device, 1024, &linker);
ok(hr == D3D_OK, "Unexpected hr %#x.\n", hr);
ok(!!linker, "Unexpected linker %p.\n", linker);
linker->lpVtbl->Release(linker);
hr = D3DXCreateFragmentLinkerEx(device, 1024, 0, &linker);
ok(hr == D3D_OK, "Unexpected hr %#x.\n", hr);
ok(!!linker, "Unexpected linker %p.\n", linker);
linker->lpVtbl->Release(linker);
refcount = IDirect3DDevice9_Release(device);
ok(!refcount, "Device has %u references left.\n", refcount);
refcount = IDirect3D9_Release(d3d);
ok(!refcount, "The D3D object has %u references left.\n", refcount);
DestroyWindow(window);
}
START_TEST(shader)
{
test_get_shader_size();
@ -6589,4 +6637,5 @@ START_TEST(shader)
test_registerset();
test_registerset_defaults();
test_shader_semantics();
test_fragment_linker();
}