From 185fe9cdebb7c6db09cc7b92f8e69b9633be24e1 Mon Sep 17 00:00:00 2001 From: winesync Date: Mon, 21 Sep 2020 23:03:22 +0200 Subject: [PATCH] [WINESYNC] 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 wine commit id fd06827bca416dfec8835f109834ad0729c996a8 by Alistair Leslie-Hughes --- dll/directx/wine/d3dx9_36/shader.c | 209 ++++++++++++++++++- modules/rostests/winetests/d3dx9_36/shader.c | 49 +++++ sdk/tools/winesync/d3dx9.cfg | 2 +- 3 files changed, 251 insertions(+), 9 deletions(-) diff --git a/dll/directx/wine/d3dx9_36/shader.c b/dll/directx/wine/d3dx9_36/shader.c index 2d0649f3016..8ef4f38af18 100644 --- a/dll/directx/wine/d3dx9_36/shader.c +++ b/dll/directx/wine/d3dx9_36/shader.c @@ -2073,27 +2073,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; diff --git a/modules/rostests/winetests/d3dx9_36/shader.c b/modules/rostests/winetests/d3dx9_36/shader.c index e6326bc4119..e2925faad69 100644 --- a/modules/rostests/winetests/d3dx9_36/shader.c +++ b/modules/rostests/winetests/d3dx9_36/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(); } diff --git a/sdk/tools/winesync/d3dx9.cfg b/sdk/tools/winesync/d3dx9.cfg index 7c849732574..ca2a27ab589 100644 --- a/sdk/tools/winesync/d3dx9.cfg +++ b/sdk/tools/winesync/d3dx9.cfg @@ -15,4 +15,4 @@ files: {include/d3dx9.h: sdk/include/dxsdk/d3dx9.h, include/d3dx9anim.h: sdk/inc include/d3dx9mesh.h: sdk/include/dxsdk/d3dx9mesh.h, include/d3dx9of.h: sdk/include/dxsdk/d3dx9of.h, include/d3dx9shader.h: sdk/include/dxsdk/d3dx9shader.h, include/d3dx9shape.h: sdk/include/dxsdk/d3dx9shape.h, include/d3dx9tex.h: sdk/include/dxsdk/d3dx9tex.h, include/d3dx9xof.h: sdk/include/dxsdk/d3dx9xof.h} -tags: {wine: 0611e27caf5105795cb94e60dec5ff0561e8ec44} +tags: {wine: fd06827bca416dfec8835f109834ad0729c996a8}