From: Zhiyi Zhang zzhang@codeweavers.com
--- dlls/d3dcompiler_43/compiler.c | 6 -- dlls/d3dcompiler_43/linker.c | 125 +++++++++++++++++++++++++ dlls/d3dcompiler_43/tests/hlsl_d3d11.c | 20 ++++ dlls/d3dcompiler_47/Makefile.in | 1 + 4 files changed, 146 insertions(+), 6 deletions(-) create mode 100644 dlls/d3dcompiler_43/linker.c
diff --git a/dlls/d3dcompiler_43/compiler.c b/dlls/d3dcompiler_43/compiler.c index 58f3e3a4358..f5c259191b4 100644 --- a/dlls/d3dcompiler_43/compiler.c +++ b/dlls/d3dcompiler_43/compiler.c @@ -489,12 +489,6 @@ end: return hr; }
-HRESULT WINAPI D3DCreateLinker(ID3D11Linker **linker) -{ - FIXME("linker %p stub!\n", linker); - return E_NOTIMPL; -} - HRESULT WINAPI D3DLoadModule(const void *data, SIZE_T size, ID3D11Module **module) { FIXME("data %p, size %Iu, module %p stub!\n", data, size, module); diff --git a/dlls/d3dcompiler_43/linker.c b/dlls/d3dcompiler_43/linker.c new file mode 100644 index 00000000000..685a5fb286a --- /dev/null +++ b/dlls/d3dcompiler_43/linker.c @@ -0,0 +1,125 @@ +/* + * Copyright 2025 Zhiyi Zhang for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ +#define COBJMACROS +#include "wine/debug.h" +#include "d3dcompiler_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3dcompiler); + +struct d3d11_linker +{ + ID3D11Linker ID3D11Linker_iface; + LONG refcount; +}; + +static inline struct d3d11_linker *impl_from_ID3D11Linker(ID3D11Linker *iface) +{ + return CONTAINING_RECORD(iface, struct d3d11_linker, ID3D11Linker_iface); +} + +static HRESULT WINAPI d3d11_linker_QueryInterface(ID3D11Linker *iface, REFIID riid, void **object) +{ + struct d3d11_linker *linker = impl_from_ID3D11Linker(iface); + + TRACE("linker %p, riid %s, object %p.\n", linker, debugstr_guid(riid), object); + + if (IsEqualGUID(riid, &IID_ID3D11Linker) + || 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 WINAPI d3d11_linker_AddRef(ID3D11Linker *iface) +{ + struct d3d11_linker *linker = impl_from_ID3D11Linker(iface); + ULONG refcount = InterlockedIncrement(&linker->refcount); + + TRACE("%p increasing refcount to %lu.\n", iface, refcount); + + return refcount; +} + +static ULONG WINAPI d3d11_linker_Release(ID3D11Linker *iface) +{ + struct d3d11_linker *linker = impl_from_ID3D11Linker(iface); + ULONG refcount = InterlockedDecrement(&linker->refcount); + + TRACE("%p decreasing refcount to %lu.\n", iface, refcount); + + if (!refcount) + free(linker); + + return refcount; +} + +static HRESULT WINAPI d3d11_linker_Link(ID3D11Linker *iface, ID3D11ModuleInstance *instance, + LPCSTR instance_name, LPCSTR target_name, UINT flags, ID3DBlob **shader, ID3DBlob **error) +{ + FIXME("iface %p, instance %p, instance_name %s, target_name %s, flags %#x, shader %p, error %p stub!\n", + iface, instance, wine_dbgstr_a(instance_name), wine_dbgstr_a(target_name), flags, shader, error); + return E_NOTIMPL; +} + +static HRESULT WINAPI d3d11_linker_UseLibrary(ID3D11Linker *iface, ID3D11ModuleInstance *instance) +{ + FIXME("iface %p, instance %p stub!\n", iface, instance); + return E_NOTIMPL; +} + +static HRESULT WINAPI d3d11_linker_AddClipPlaneFromCBuffer(ID3D11Linker *iface, UINT buffer_slot, + UINT buffer_entry) +{ + FIXME("iface %p, buffer_slot %u, buffer_entry %u stub!\n", iface, buffer_slot, buffer_entry); + return E_NOTIMPL; +} + +static const struct ID3D11LinkerVtbl d3d11_linker_vtbl = +{ + d3d11_linker_QueryInterface, + d3d11_linker_AddRef, + d3d11_linker_Release, + d3d11_linker_Link, + d3d11_linker_UseLibrary, + d3d11_linker_AddClipPlaneFromCBuffer, +}; + +HRESULT WINAPI D3DCreateLinker(ID3D11Linker **linker) +{ + struct d3d11_linker *object; + + TRACE("linker %p.\n", linker); + + if (!linker) + return E_INVALIDARG; + + if (!(object = calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; + + object->ID3D11Linker_iface.lpVtbl = &d3d11_linker_vtbl; + object->refcount = 1; + + *linker = &object->ID3D11Linker_iface; + return S_OK; +} diff --git a/dlls/d3dcompiler_43/tests/hlsl_d3d11.c b/dlls/d3dcompiler_43/tests/hlsl_d3d11.c index 5f58e6f3d1c..8f1ce3af37d 100644 --- a/dlls/d3dcompiler_43/tests/hlsl_d3d11.c +++ b/dlls/d3dcompiler_43/tests/hlsl_d3d11.c @@ -1164,12 +1164,32 @@ static void test_semantic_reflection(void) } }
+#if D3D_COMPILER_VERSION >= 47 + +static void test_D3DCreateLinker(void) +{ + ID3D11Linker *linker; + HRESULT hr; + + hr = D3DCreateLinker(NULL); + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + + hr = D3DCreateLinker(&linker); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + linker->lpVtbl->Release(linker); +} + +#endif /* D3D_COMPILER_VERSION >= 47 */ + START_TEST(hlsl_d3d11) { HMODULE mod;
test_reflection(); test_semantic_reflection(); +#if D3D_COMPILER_VERSION >= 47 + test_D3DCreateLinker(); +#endif
if (!(mod = LoadLibraryA("d3d11.dll"))) { diff --git a/dlls/d3dcompiler_47/Makefile.in b/dlls/d3dcompiler_47/Makefile.in index a98ca7243c1..ab5da889126 100644 --- a/dlls/d3dcompiler_47/Makefile.in +++ b/dlls/d3dcompiler_47/Makefile.in @@ -14,6 +14,7 @@ SOURCES = \ blob.c \ bytecodewriter.c \ compiler.c \ + linker.c \ reflection.c \ utils.c \ version.rc