Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for D3D11.4 and DXGI1.6 #864

Closed
matt77hias opened this issue Feb 7, 2018 · 7 comments
Closed

Add support for D3D11.4 and DXGI1.6 #864

matt77hias opened this issue Feb 7, 2018 · 7 comments
Labels
Feature An improvement or feature Unresolved Waiting for a fix or implementation

Comments

@matt77hias
Copy link

Problem:

  • Connection established to FPS [PID 4692] (No API detected)

Setup:

  • OS: Windows 10 64-bit
  • RenderLab: v0.91 x64 Release
  • Application: MAGE x64 Release

Steps to reproduce with RenderDoc:

  1. Execute renderdocui.exe
  2. Menu select: File > Capture Log
  3. Capture Executable window: add path to executable FPS.exe
  4. Capture Executable window: press Launch button

Diagnostic Log File:

RDOC 017644: [13:28:34]             core.cpp( 318) - Log     - RenderDoc v0.91 x64 Release (2d8b2cf818746b6a2add54e2fef449398816a40c) loaded in replay application
RDOC 010256: [13:28:34]             core.cpp( 318) - Log     - RenderDoc v0.91 x64 Release (2d8b2cf818746b6a2add54e2fef449398816a40c) loaded in replay application
RDOC 017644: [13:28:36]     entry_points.cpp( 619) - Warning - adbExePath not set, attempting to call 'adb' in working env
RDOC 017644: [13:28:36]     entry_points.cpp( 591) - Log     - COMMAND: adb devices
RDOC 017644: [13:28:36]    win32_process.cpp( 458) - Log     - Running process adb
RDOC 017644: [13:28:36]    win32_process.cpp( 475) - Warning - Process adb could not be loaded.
RDOC 017644: [13:28:36]    win32_process.cpp( 916) - Warning - Couldn't launch process 'adb'
RDOC 017644: [13:28:51]    win32_process.cpp( 458) - Log     - Running process C:\Users\Matthias\Documents\Visual Studio 2017\Projects\MAGE\MAGE\FPS\bin\x64\Release\FPS.exe
RDOC 017644: [13:28:51]    win32_process.cpp( 518) - Log     - Injecting renderdoc into process 12264
RDOC 017644: [13:28:53]    win32_process.cpp( 259) - Warning - CreateToolhelp32Snapshot(12264) -> 0x00000018
RDOC 012264: [13:28:51]             core.cpp( 318) - Log     - RenderDoc v0.91 x64 Release (2d8b2cf818746b6a2add54e2fef449398816a40c) capturing application
RDOC 012264: [13:28:53]   win32_libentry.cpp(  67) - Log     - Loading into C:\Users\Matthias\Documents\Visual Studio 2017\Projects\MAGE\MAGE\FPS\bin\x64\Release\FPS.exe
RDOC 012264: [13:28:53]     dxgi_wrapped.cpp( 742) - Warning - Querying IDXGIAdapter for interface: GUID {3c8d99d1-4fbf-4181-a82c-af66bf7bd24e}
RDOC 012264: [13:28:53]     dxgi_wrapped.cpp( 178) - Warning - Querying IDXGIObject for interface: GUID {3c8d99d1-4fbf-4181-a82c-af66bf7bd24e}
RDOC 012264: [13:28:53]     dxgi_wrapped.cpp( 742) - Warning - Querying IDXGIAdapter for interface: GUID {3c8d99d1-4fbf-4181-a82c-af66bf7bd24e}
RDOC 012264: [13:28:53]     dxgi_wrapped.cpp( 178) - Warning - Querying IDXGIObject for interface: GUID {3c8d99d1-4fbf-4181-a82c-af66bf7bd24e}
RDOC 012264: [13:28:53]     dxgi_wrapped.cpp( 742) - Warning - Querying IDXGIAdapter for interface: GUID {3c8d99d1-4fbf-4181-a82c-af66bf7bd24e}
RDOC 012264: [13:28:53]     dxgi_wrapped.cpp( 178) - Warning - Querying IDXGIObject for interface: GUID {3c8d99d1-4fbf-4181-a82c-af66bf7bd24e}
RDOC 017644: [13:28:53]   target_control.cpp( 412) - Log     - Got remote handshake: FPS () [12264]
RDOC 012264: [13:28:54]     d3d11_device.cpp( 866) - Warning - Querying ID3D11Device for interface: GUID {8ffde202-a0e7-45df-9e01-e837801b5ea0}
RDOC 012264: [13:28:54]     dxgi_wrapped.cpp( 178) - Warning - Querying IDXGIObject for interface: GUID {8ffde202-a0e7-45df-9e01-e837801b5ea0}
RDOC 012264: [13:28:54]    d3d11_context.cpp(1672) - Warning - Querying ID3D11DeviceContext for interface: GUID {917600da-f58c-4c33-98d8-3e15b390fa24}
RDOC 012264: [13:28:54]     dxgi_wrapped.cpp( 178) - Warning - Querying IDXGIObject for interface: GUID {917600da-f58c-4c33-98d8-3e15b390fa24}
RDOC 017644: [13:28:58]    win32_network.cpp( 178) - Warning - recv: 10054
@baldurk
Copy link
Owner

baldurk commented Feb 7, 2018

Ah I think the problem is maybe this GUID: {3c8d99d1-4fbf-4181-a82c-af66bf7bd24e} that corresponds to IDXGIAdapter4, which I don't yet support (it's new in DXGI 1.6 it seems).

Similarly these GUIDs: {8ffde202-a0e7-45df-9e01-e837801b5ea0} and {917600da-f58c-4c33-98d8-3e15b390fa24} correspond to ID3D11Device5 and ID3D11DeviceContext4 which is also new in D3D11.4, and I only support up to D3D11.3 currently. In each case you'll be returned a non-hooked interface which probably causes the problems.

I'm not sure how hard it will be to add support for these new interfaces, I'll check. In the meantime if you don't need to use the newest DXGI/D3D interfaces could you test as a workaround only using DXGI 1.5 / D3D11.3 (or lower than that if you don't need any features from those new versions) ?

@baldurk baldurk added Bug A crash, misbehaviour, or other problem Unresolved Waiting for a fix or implementation labels Feb 7, 2018
@matt77hias
Copy link
Author

Since, I switched from Windows 8.1 to Windows 10, I indeed use:

#include <d3d11_4.h> // ID3D11Device5, ID3D11DeviceContext4
#include <DXGI1_6.h> // IDXGISwapChain4, IDXGIAdapter4 and IDXGIOutput6

I do not know by hard if I use new features of these interfaces not present in the previous versions, but the main reason I did this is to use the latest overriden version of a member method, since nearly all member methods of for example ID3D11Device and ID3D11DeviceContext are virtual and could be potentially reimplemented each time a new version is added (though msdn is vague and only mentions additions to the older interfaces).

I will check the version that still used Windows 8.1.

@baldurk
Copy link
Owner

baldurk commented Feb 7, 2018

I don't think that's how the COM implementation works. You won't pay any cost for calling ID3D11DeviceContext::PSSetShader through a ID3D11DeviceContext vs through a ID3D11DeviceContext5. It's always a virtual function call and it will call directly to whatever concrete function the object actually implements. There's only one such implementation for whichever D3D runtime version you're using.

i.e. in a newer D3D runtime the same object will implement ID3D11DeviceContext5, ID3D11DeviceContext4, ID3D11DeviceContext3, and so on up to ID3D11DeviceContext, and the interface you use just determines how much of the exposed functionality you can call. There's no layering that happens of each interface on top of the other.

MSDN mentions new versions only making additions because if each interface isn't a strict superset of the last one and you changed functions that were in older interfaces, then you could no longer access ID3D11DeviceContext functions through the same pointer to the concrete object implementing ID3D11DeviceContext5 say and you'd need a different vtable for every interface.

@matt77hias
Copy link
Author

Thanks for the explanation. But since msdn mentions that ID3D11DeviceContextN inherits from ID3D11DeviceContextN-1, etc. I thought, the internal implementation of the D3D runtime could have been changed and optimized between versions by reimplementing the object. (I will consider using a typedef to use the minimal required interface.)

My latest Windows 8.1 version which uses older interfaces runs fine :)

@baldurk
Copy link
Owner

baldurk commented Feb 7, 2018

I'm glad you got it working then! If you don't mind I'll rename this bug to clarify that it's about D3D11.4 and DXGI 1.6 support, and tag it appropriately. This won't be in scope for the v1.0 release coming up, but I will look at it after that point.


My understanding is that the inherited interfaces are just implemented the same way as would inherit virtual classes in C++. There's a single vtable for all of the interfaces, and the new functions in later interfaces are just added on as extra elements at the end.

So while I'm sure you are right that the D3D runtime will be changed and optimized between versions, you will always have the latest runtime version no matter which interface you access through.

For example you could have an implementation CWin8D3D11DeviceContext (arbitrary example) which only inherits from ID3D11DeviceContext2. The vtable for all device context interfaces up to 2 will point to the same functions, so even if you call ID3D11DeviceContext::PSSetShader through the original interface, the vtable will point to the implementation in CWin8D3D11DeviceContext.

If you then run on windows 10 and you get an implementation CWin10D3D11DeviceContext then the vtable will point to the new runtime implementation for all functions including the original ID3D11DeviceContext::PSSetShader. There's only ever one d3d11.dll and if it gets updated then all the interfaces are updated. This way Microsoft can apply fixes and improvements and have them work even for old games that have shipped and are not updating to use newer interfaces.

This is the same as if you have your own virtual class - the vtable guarantees that the virtual function calls go to whichever implementation is actually used by the underlying object, so don't have to down-cast a base pointer you have to get the most derived implementation.

This isn't necessarily guaranteed, but it would be very counter-productive for D3D to implement it any other way. You can also check this by comparing the pointer you get for ID3D11DeviceContextN vs N-1 or anything - you'll find that it's the same (perhaps plus or minus a few bytes), meaning that it still points to the same vtable. You can even inspect the vtable itself and find that the function pointers are identical.

@baldurk baldurk changed the title "API is not detected" for D3D11 application Add support f or D3D11.4 and DXGI1.6 Feb 7, 2018
@baldurk baldurk added Feature An improvement or feature and removed Bug A crash, misbehaviour, or other problem labels Feb 7, 2018
@baldurk baldurk changed the title Add support f or D3D11.4 and DXGI1.6 Add support for D3D11.4 and DXGI1.6 Feb 7, 2018
@matt77hias
Copy link
Author

If you don't mind I'll rename this bug to clarify that it's about D3D11.4 and DXGI 1.6 support, and tag it appropriately.

No problem.

There's only ever one d3d11.dll and if it gets updated then all the interfaces are updated. This way Microsoft can apply fixes and improvements and have them work even for old games that have shipped and are not updating to use newer interfaces.

Oh, I had completely forgotten the header<>source separation. Indeed, no matter which header to whatever version of an interface you include, the linked D3D library will be the same. And even if new headers to newer interfaces are added, and old implementations gets optimized, you still link against the most recent (and only) D3D library on your system containing these optimizations.

baldurk added a commit that referenced this issue May 24, 2018
* This is just a pass-through implementation as fences do not have to be
  serialised.
@baldurk
Copy link
Owner

baldurk commented May 24, 2018

This ended up being mostly just a pass-through implementation as nothing ended up needing serialisation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature An improvement or feature Unresolved Waiting for a fix or implementation
Projects
None yet
Development

No branches or pull requests

2 participants