From fd06827bca416dfec8835f109834ad0729c996a8 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Fri, 29 Nov 2019 11:57:30 +0100 Subject: [PATCH] d3dx9: Implement D3DXCreateFragmentLinker[Ex](). Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=38086 Signed-off-by: Alistair Leslie-Hughes Signed-off-by: Matteo Bruni Signed-off-by: Alexandre Julliard --- dlls/d3dx9_36/shader.c | 209 +++++++++++++++++++++++++++++++++++++++++-- dlls/d3dx9_36/tests/shader.c | 49 ++++++++++ 2 files changed, 250 insertions(+), 8 deletions(-) diff --git a/dlls/d3dx9_36/shader.c b/dlls/d3dx9_36/shader.c index c59fc791ea7..d7adc18ff6f 100644 --- a/dlls/d3dx9_36/shader.c +++ b/dlls/d3dx9_36/shader.c @@ -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 +{ + ID3DXFragmentLinker ID3DXFragmentLinker_iface; + LONG ref; + + 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; +} + +static D3DXHANDLE WINAPI d3dx9_fragment_linker_GetFragmentHandleByIndex(ID3DXFragmentLinker *iface, UINT index) +{ + FIXME("iface %p, index %u: stub.\n", iface, index); + + 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("device %p, size %u, linker %p: stub.\n", device, size, linker); + 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); - if (linker) - *linker = NULL; + 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; } -HRESULT WINAPI D3DXCreateFragmentLinkerEx(IDirect3DDevice9 *device, UINT size, DWORD flags, ID3DXFragmentLinker **linker) +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("device %p, size %u, flags %#x, linker %p: stub.\n", device, size, flags, linker); + 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; +} - if (linker) - *linker = NULL; +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; diff --git a/dlls/d3dx9_36/tests/shader.c b/dlls/d3dx9_36/tests/shader.c index e6326bc4119..e2925faad69 100644 --- a/dlls/d3dx9_36/tests/shader.c +++ b/dlls/d3dx9_36/tests/shader.c @@ -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(); } -- 2.11.4.GIT