From: Rémi Bernon rbernon@codeweavers.com
Those aren't in the Win10 DLL anymore, but they were in the Win7 and Win8 DLLs. The exports are also in the MinGW runtime, and using a D3DKMT function in a program built with MinGW might pull it from dxgi, so having the exports in the Wine DLL is useful. --- dlls/dxgi/dxgi.spec | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+)
diff --git a/dlls/dxgi/dxgi.spec b/dlls/dxgi/dxgi.spec index 67a345dc376..72578e3662c 100644 --- a/dlls/dxgi/dxgi.spec +++ b/dlls/dxgi/dxgi.spec @@ -1,6 +1,40 @@ @ stdcall CreateDXGIFactory(ptr ptr) @ stdcall CreateDXGIFactory1(ptr ptr) @ stdcall CreateDXGIFactory2(long ptr ptr) +@ stdcall D3DKMTCloseAdapter(ptr) gdi32.D3DKMTCloseAdapter +@ stdcall D3DKMTCreateAllocation(ptr) gdi32.D3DKMTCreateAllocation +@ stdcall D3DKMTCreateContext(ptr) gdi32.D3DKMTCreateContext +@ stdcall D3DKMTCreateDevice(ptr) gdi32.D3DKMTCreateDevice +@ stdcall D3DKMTCreateSynchronizationObject(ptr) gdi32.D3DKMTCreateSynchronizationObject +@ stdcall D3DKMTDestroyAllocation(ptr) gdi32.D3DKMTDestroyAllocation +@ stdcall D3DKMTDestroyContext(ptr) gdi32.D3DKMTDestroyContext +@ stdcall D3DKMTDestroyDevice(ptr) gdi32.D3DKMTDestroyDevice +@ stdcall D3DKMTDestroySynchronizationObject(ptr) gdi32.D3DKMTDestroySynchronizationObject +@ stdcall D3DKMTEscape(ptr) gdi32.D3DKMTEscape +@ stdcall D3DKMTGetContextSchedulingPriority(ptr) gdi32.D3DKMTGetContextSchedulingPriority +@ stdcall D3DKMTGetDeviceState(ptr) gdi32.D3DKMTGetDeviceState +@ stdcall D3DKMTGetDisplayModeList(ptr) gdi32.D3DKMTGetDisplayModeList +@ stdcall D3DKMTGetMultisampleMethodList(ptr) gdi32.D3DKMTGetMultisampleMethodList +@ stdcall D3DKMTGetRuntimeData(ptr) gdi32.D3DKMTGetRuntimeData +@ stdcall D3DKMTGetSharedPrimaryHandle(ptr) gdi32.D3DKMTGetSharedPrimaryHandle +@ stdcall D3DKMTLock(ptr) gdi32.D3DKMTLock +@ stdcall D3DKMTOpenAdapterFromHdc(ptr) gdi32.D3DKMTOpenAdapterFromHdc +@ stdcall D3DKMTOpenResource(ptr) gdi32.D3DKMTOpenResource +@ stdcall D3DKMTPresent(ptr) gdi32.D3DKMTPresent +@ stdcall D3DKMTQueryAdapterInfo(ptr) gdi32.D3DKMTQueryAdapterInfo +@ stdcall D3DKMTQueryAllocationResidency(ptr) gdi32.D3DKMTQueryAllocationResidency +@ stdcall D3DKMTQueryResourceInfo(ptr) gdi32.D3DKMTQueryResourceInfo +@ stdcall D3DKMTRender(ptr) gdi32.D3DKMTRender +@ stdcall D3DKMTSetAllocationPriority(ptr) gdi32.D3DKMTSetAllocationPriority +@ stdcall D3DKMTSetContextSchedulingPriority(ptr) gdi32.D3DKMTSetContextSchedulingPriority +@ stdcall D3DKMTSetDisplayMode(ptr) gdi32.D3DKMTSetDisplayMode +@ stdcall D3DKMTSetDisplayPrivateDriverFormat(ptr) gdi32.D3DKMTSetDisplayPrivateDriverFormat +@ stdcall D3DKMTSetGammaRamp(ptr) gdi32.D3DKMTSetGammaRamp +@ stdcall D3DKMTSetVidPnSourceOwner(ptr) gdi32.D3DKMTSetVidPnSourceOwner +@ stdcall D3DKMTSignalSynchronizationObject(ptr) gdi32.D3DKMTSignalSynchronizationObject +@ stdcall D3DKMTUnlock(ptr) gdi32.D3DKMTUnlock +@ stdcall D3DKMTWaitForSynchronizationObject(ptr) gdi32.D3DKMTWaitForSynchronizationObject +@ stdcall D3DKMTWaitForVerticalBlankEvent(ptr) gdi32.D3DKMTWaitForVerticalBlankEvent @ stdcall DXGID3D10CreateDevice(ptr ptr ptr long ptr long ptr) @ stdcall DXGID3D10RegisterLayers(ptr long) @ stdcall DXGIGetDebugInterface1(long ptr ptr)
From: Rémi Bernon rbernon@codeweavers.com
The list of exports was incorrectly updated, this fixes it to the list that is currently exported on Windows 7 to 10, and forward them all to gdi32.dll. --- dlls/d3d11/d3d11.spec | 60 +++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 31 deletions(-)
diff --git a/dlls/d3d11/d3d11.spec b/dlls/d3d11/d3d11.spec index bb755e2e869..5bee6d0fa73 100644 --- a/dlls/d3d11/d3d11.spec +++ b/dlls/d3d11/d3d11.spec @@ -5,41 +5,39 @@ @ stdcall D3D11CreateDevice(ptr long ptr long ptr long long ptr ptr ptr) @ stdcall D3D11CreateDeviceAndSwapChain(ptr long ptr long ptr long long ptr ptr ptr ptr ptr) @ stdcall D3D11On12CreateDevice(ptr long ptr long ptr long long ptr ptr ptr) -@ stdcall D3DKMTCheckVidPnExclusiveOwnership(ptr) gdi32.D3DKMTCheckVidPnExclusiveOwnership @ stdcall D3DKMTCloseAdapter(ptr) gdi32.D3DKMTCloseAdapter -@ stub D3DKMTCreateAllocation -@ stub D3DKMTCreateContext +@ stdcall D3DKMTCreateAllocation(ptr) gdi32.D3DKMTCreateAllocation +@ stdcall D3DKMTCreateContext(ptr) gdi32.D3DKMTCreateContext @ stdcall D3DKMTCreateDevice(ptr) gdi32.D3DKMTCreateDevice -@ stub D3DKMTCreateSynchronizationObject -@ stub D3DKMTDestroyAllocation -@ stub D3DKMTDestroyContext +@ stdcall D3DKMTCreateSynchronizationObject(ptr) gdi32.D3DKMTCreateSynchronizationObject +@ stdcall D3DKMTDestroyAllocation(ptr) gdi32.D3DKMTDestroyAllocation +@ stdcall D3DKMTDestroyContext(ptr) gdi32.D3DKMTDestroyContext @ stdcall D3DKMTDestroyDevice(ptr) gdi32.D3DKMTDestroyDevice -@ stub D3DKMTDestroySynchronizationObject -@ stub D3DKMTEscape -@ stub D3DKMTGetContextSchedulingPriority -@ stub D3DKMTGetDeviceState -@ stub D3DKMTGetDisplayModeList -@ stub D3DKMTGetMultisampleMethodList -@ stub D3DKMTGetRuntimeData -@ stub D3DKMTGetSharedPrimaryHandle -@ stub D3DKMTLock -@ stdcall D3DKMTOpenAdapterFromGdiDisplayName(ptr) gdi32.D3DKMTOpenAdapterFromGdiDisplayName -@ stub D3DKMTOpenAdapterFromHdc -@ stub D3DKMTOpenResource -@ stub D3DKMTPresent +@ stdcall D3DKMTDestroySynchronizationObject(ptr) gdi32.D3DKMTDestroySynchronizationObject +@ stdcall D3DKMTEscape(ptr) gdi32.D3DKMTEscape +@ stdcall D3DKMTGetContextSchedulingPriority(ptr) gdi32.D3DKMTGetContextSchedulingPriority +@ stdcall D3DKMTGetDeviceState(ptr) gdi32.D3DKMTGetDeviceState +@ stdcall D3DKMTGetDisplayModeList(ptr) gdi32.D3DKMTGetDisplayModeList +@ stdcall D3DKMTGetMultisampleMethodList(ptr) gdi32.D3DKMTGetMultisampleMethodList +@ stdcall D3DKMTGetRuntimeData(ptr) gdi32.D3DKMTGetRuntimeData +@ stdcall D3DKMTGetSharedPrimaryHandle(ptr) gdi32.D3DKMTGetSharedPrimaryHandle +@ stdcall D3DKMTLock(ptr) gdi32.D3DKMTLock +@ stdcall D3DKMTOpenAdapterFromHdc(ptr) gdi32.D3DKMTOpenAdapterFromHdc +@ stdcall D3DKMTOpenResource(ptr) gdi32.D3DKMTOpenResource +@ stdcall D3DKMTPresent(ptr) gdi32.D3DKMTPresent @ stdcall D3DKMTQueryAdapterInfo(ptr) gdi32.D3DKMTQueryAdapterInfo -@ stub D3DKMTQueryAllocationResidency -@ stub D3DKMTQueryResourceInfo -@ stub D3DKMTRender -@ stub D3DKMTSetAllocationPriority -@ stub D3DKMTSetContextSchedulingPriority -@ stub D3DKMTSetDisplayMode -@ stub D3DKMTSetDisplayPrivateDriverFormat -@ stub D3DKMTSetGammaRamp +@ stdcall D3DKMTQueryAllocationResidency(ptr) gdi32.D3DKMTQueryAllocationResidency +@ stdcall D3DKMTQueryResourceInfo(ptr) gdi32.D3DKMTQueryResourceInfo +@ stdcall D3DKMTRender(ptr) gdi32.D3DKMTRender +@ stdcall D3DKMTSetAllocationPriority(ptr) gdi32.D3DKMTSetAllocationPriority +@ stdcall D3DKMTSetContextSchedulingPriority(ptr) gdi32.D3DKMTSetContextSchedulingPriority +@ stdcall D3DKMTSetDisplayMode(ptr) gdi32.D3DKMTSetDisplayMode +@ stdcall D3DKMTSetDisplayPrivateDriverFormat(ptr) gdi32.D3DKMTSetDisplayPrivateDriverFormat +@ stdcall D3DKMTSetGammaRamp(ptr) gdi32.D3DKMTSetGammaRamp @ stdcall D3DKMTSetVidPnSourceOwner(ptr) gdi32.D3DKMTSetVidPnSourceOwner -@ stub D3DKMTSignalSynchronizationObject -@ stub D3DKMTUnlock -@ stub D3DKMTWaitForSynchronizationObject -@ stub D3DKMTWaitForVerticalBlankEvent +@ stdcall D3DKMTSignalSynchronizationObject(ptr) gdi32.D3DKMTSignalSynchronizationObject +@ stdcall D3DKMTUnlock(ptr) gdi32.D3DKMTUnlock +@ stdcall D3DKMTWaitForSynchronizationObject(ptr) gdi32.D3DKMTWaitForSynchronizationObject +@ stdcall D3DKMTWaitForVerticalBlankEvent(ptr) gdi32.D3DKMTWaitForVerticalBlankEvent @ stub OpenAdapter10 @ stub OpenAdapter10_2
Is that forward on Windows? If not, can we use '-import' instead?
I don't know? How do you tell the difference? And actually, why does it matter?
BTW the same needs to be done in DXVK (https://github.com/doitsujin/dxvk/pull/5251), which uses .def file, and I don't know how `-import` would be done with these.
GetProcAddress() will return the same address in 'forwarded to' dll if that is forwarded, and different for other cases (if it has some wrapper). Various hotpatchers and mods love to hook dxgi, d3d11 and basically whatever and often break on forwards which is the thing they usually don't understand (unless it is the same on Windows of course). '-import' will generate an import thunk with hotpatch prolog and jump in the source dll.
I don't know offhand if and how that can be done with .def files, needs a bit of look... worst case that needs manual wrapper. Unless those are the same forwards on Windows of course.
If those are no longer present in Windows, it sounds like MinGW should be fixed instead?
Forwards can be present on Windows. It is just that it is not necessarily that in this specific case?
Windows may have some, e. g., implemented wrapper which we may skip implementing (at once at least) and essentially forward to another .dll, just using import thunk with 'import' instead of the forward.
Note that you only need `-import` if some app is known to depend on the hotpatch prefix, otherwise you can simply link to it directly.
'forward' vs '-import' issues were not due to hotpatch prefix, it is represented differently in the import table and parsing import / export table parts of hotpatchers is what was broken.
On Mon Oct 6 18:44:21 2025 +0000, Jacek Caban wrote:
If those are no longer present in Windows, it sounds like MinGW should be fixed instead?
Even if this is the case, requiring to wait for the toolchain release to be able to use D3DKMT functions in D3D runtimes is a big PITA, so it would be better to have this in the meantime.
On Mon Oct 6 18:44:41 2025 +0000, Rémi Bernon wrote:
Even if this is the case, requiring to wait for the toolchain release to be able to use D3DKMT functions in D3D runtimes is a big PITA, so it would be better to have this in the meantime.
FWIW I don't know that anything does depend on these exports, if that is a big deal for dxvk maybe it can wait, but for Wine it is just a matter of using a better fitting 'spec' file entry.
On Mon Oct 6 18:46:16 2025 +0000, Paul Gofman wrote:
FWIW I don't know that anything does depend on these exports, if that is a big deal for dxvk maybe it can wait, but for Wine it is just a matter of using a better fitting 'spec' file entry.
I don't know, this seems to have raised an unexpectedly high amount of discussion for something that looked pretty straightforward to me, and was meant to fix a simple annoying issue:
When using these D3DKMT functions in DXVK, they get resolved by MinGW to dxgi.dll, and when running an application with DXVK, we crash on a missing / stubbed dxgi export (depending on whether DXVK dxgi or Wine dxgi is used).
Exporting these functions and forwarding them where they are supposed to go, like it seems is (or was) the case on Windows (and the reason MinGW exports them), fixes the issue without having to bother with toolchain updates, fragile link library ordering, or other alternative tricks.
When using these D3DKMT functions in DXVK, they get resolved by MinGW to dxgi.dll,
Sorry, why is it so? If they are not defined in neither Wine nor dxvk's dxgi currently?
On Mon Oct 6 18:55:16 2025 +0000, Paul Gofman wrote:
When using these D3DKMT functions in DXVK, they get resolved by MinGW
to dxgi.dll, Sorry, why is it so? If they are not defined in neither Wine nor dxvk's dxgi currently?
Because MinGW import lib has them.
There are 3 options: forward, -import, and nothing. Forward is different in the export table, and can indeed break some things. Nothing is the default, it simply jumps to the imported entry point. -import is the same but it generates a hot patch prefix before the jump.
Ah yeah, sorry... for what I mean, 'nothing' is good enough I guess, since it is not 'forward' like in the current patch.
On Mon Oct 6 18:56:19 2025 +0000, Rémi Bernon wrote:
Because MinGW import lib has them.
Ok, I quick dumped dxgi and d3d11 exports on Windows dll. DXGI doesn't seem to export any D3DKMT functions at all, is it right to export those from dxgi.dll?
d3d11 does export a bunch, but from the look of winedump doesn't look like they are forwarded. How exactly that is broken now without adding anything? If that is for calling those functions from Wine that should be correctly resolved to gdi I guess? And if that is about calling D3DKMT functions from dxvk, maybe the best bet for now in this case do that with GetProcAddress there? Before we know what does it mean that those functions are dupicated in d3d11 and what those versions are supposed to do.
On Mon Oct 6 19:05:44 2025 +0000, Paul Gofman wrote:
Ok, I quick dumped dxgi and d3d11 exports on Windows dll. DXGI doesn't seem to export any D3DKMT functions at all, is it right to export those from dxgi.dll? d3d11 does export a bunch, but from the look of winedump doesn't look like they are forwarded. How exactly that is broken now without adding anything? If that is for calling those functions from Wine that should be correctly resolved to gdi I guess? And if that is about calling D3DKMT functions from dxvk, maybe the best bet for now in this case do that with GetProcAddress there? Before we know what does it mean that those functions are dupicated in d3d11 and what those versions are supposed to do.
Like described in the patch, dxgi on Windows 10 doesn't export them anymore, but it was on Windows 8.1. And as MinGW import lib has them, and until they get removed from there, and until the toolchain update is widespread enough, it doesn't seem like a huge deal to have them too.
Regarding what these duplicated functions do, I don't think it's interesting at all and I'm not going to spend time looking into this. They are probably just wrappers around the syscalls because they didn't want to pull gdi32 or win32u directly.
It's also IMO inconvenient if all these concerns are now requiring us to use GetProcAddress everywhere, just to make sure we get the gdi32 function. I had this initially to workaround the issue but it's not a nice solution and I would even expect it to be slowing down the adoption of D3DKMT for shared resources in DXVK because there's no good reason to have to do it when linking is supposed to just work.
Then I would like to add that even though this MR adds new dxgi exports, several of the d3d11 D3DKMT forwards were already present before, and they didn't raise the same concerns that were raised here (and even, some exports have been added which were never supposed to be there).
On Mon Oct 6 19:15:01 2025 +0000, Rémi Bernon wrote:
Like described in the patch, dxgi on Windows 10 doesn't export them anymore, but it was on Windows 8.1. And as MinGW import lib has them, and until they get removed from there, and until the toolchain update is widespread enough, it doesn't seem like a huge deal to have them too. Regarding what these duplicated functions do, I don't think it's interesting at all and I'm not going to spend time looking into this. They are probably just wrappers around the syscalls because they didn't want to pull gdi32 or win32u directly. It's also IMO inconvenient if all these concerns are now requiring us to use GetProcAddress everywhere, just to make sure we get the gdi32 function. I had this initially to workaround the issue but it's not a nice solution and I would even expect it to be slowing down the adoption of D3DKMT for shared resources in DXVK because there's no good reason to have to do it when linking is supposed to just work. Then I would like to add that even though this MR adds new dxgi exports, several of the d3d11 D3DKMT forwards were already present before, and they didn't raise the same concerns that were raised here (and even, some exports have been added which were never supposed to be there).
FWIW I only suggested not using forward import in Wine patch if that is not the case on Windows (it probably isn't). Does it not work for some reason?
On Mon Oct 6 19:25:08 2025 +0000, Paul Gofman wrote:
FWIW I only suggested not using forward import in Wine patch if that is not the case on Windows (it probably isn't). Does it not work for some reason?
Yeah it should work, and I would be fine with that but I think it'd be better to do the same thing on both Wine and DXVK side, and I don't know what `.def` forward export do (I'm assuming they do the same as Wine `.spec` forward as it's the same syntax)?
On Mon Oct 6 19:44:35 2025 +0000, Alexandre Julliard wrote:
There are 3 options: forward, -import, and nothing. Forward is different in the export table, and can indeed break some things. Nothing is the default, it simply jumps to the imported entry point. -import is the same but it generates a hot patch prefix before the jump.
I don't understand how you write the "nothing" version though?
`@ stdcall -import D3DKMTCloseAdapter(ptr) gdi32.D3DKMTCloseAdapter` is -import
`@ stdcall D3DKMTCloseAdapter(ptr) gdi32.D3DKMTCloseAdapter` is forward
Then how can we link with gdi32.D3DKMTCloseAdapter and export it directly?
On Mon Oct 6 19:44:35 2025 +0000, Rémi Bernon wrote:
I don't understand how you write the "nothing" version though? `@ stdcall -import D3DKMTCloseAdapter(ptr) gdi32.D3DKMTCloseAdapter` is -import `@ stdcall D3DKMTCloseAdapter(ptr) gdi32.D3DKMTCloseAdapter` is forward Then how can we link with gdi32.D3DKMTCloseAdapter and export it directly?
Simply `@ stdcall D3DKMTCloseAdapter(ptr)`, if gdi32 is imported it will link to it.
On Mon Oct 6 19:45:21 2025 +0000, Alexandre Julliard wrote:
Simply `@ stdcall D3DKMTCloseAdapter(ptr)`, if gdi32 is imported it will link to it.
Hmm... that doesn't seem to work for me, I get undefined reference link errors.
On Mon Oct 6 19:28:05 2025 +0000, Rémi Bernon wrote:
Yeah it should work, and I would be fine with that but I think it'd be better to do the same thing on both Wine and DXVK side, and I don't know what `.def` forward export do (I'm assuming they do the same as Wine `.spec` forward as it's the same syntax)?
AFAICT the functions are exported correctly in the gdi32 mingw import lib, so for DXVK it may be a simple matter of linking to gdi32 first.
On Mon Oct 6 19:50:40 2025 +0000, Alexandre Julliard wrote:
AFAICT the functions are exported correctly in the gdi32 mingw import lib, so for DXVK it may be a simple matter of linking to gdi32 first.
Yes, that's also an option but I think it's fragile, especially as the error, if the order gets later messed up somehow, is then not going to be a link error but a runtime error when the function gets called (say, in dxgi) and not found.
On Mon Oct 6 19:53:50 2025 +0000, Rémi Bernon wrote:
Yes, that's also an option but I think it's fragile, especially as the error, if the order gets later messed up somehow, is then not going to be a link error but a runtime error when the function gets called (say, in dxgi) and not found.
It should be pretty easy to figure out if that happens. I don't think it justifies adding exports that don't exist on Windows.
On Mon Oct 6 20:09:41 2025 +0000, Alexandre Julliard wrote:
It should be pretty easy to figure out if that happens. I don't think it justifies adding exports that don't exist on Windows.
The exports existed on Windows until "recently" for dxgi. The exact same problem happens with d3d11, and these are still exported nowadays, so I don't think it's a huge deal to have both at once when it's just a handful of artificial functions in a .spec file.
This merge request was closed by Rémi Bernon.
On Mon Oct 6 20:13:21 2025 +0000, Rémi Bernon wrote:
The exports existed on Windows until "recently" for dxgi. The exact same problem happens with d3d11, and these are still exported nowadays, so I don't think it's a huge deal to have both at once when it's just a handful of artificial functions in a .spec file.
If they were removed from Windows it means that nothing depends on them.
If Microsoft kept them in d3d11 it means that they may be needed by some apps, and in that case we can have them too.