I'm filling a window with a blank swap chain that's being handled by DirectX 12. While fooling a round a bit with Explicit Multi-Adapter, I came across this weird behaviour...
As shown in pretty much all DX12 demo code in existence so far, I loop through all DXGI adapters that I get using IDXGIFactory4::EnumAdapters1() to find the most suitable (or in my case every) adapter at D3D_FEATURE_LEVEL_11_0 or higher. And as shown in the demos, I discard all adapters that have the DXGI_ADAPTER_FLAG_SOFTWARE like this:
if ((adapterDesc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) != FALSE)
continue; // Check the next adapter.
In my implementation I then dump all compatible adapters into a std::vector to be used later.
If I use a breakpoint to check how everything looks at runtime, I notice my adapter list only contains one adapter after the loop has exited, which is not what I would expect, as I have both an NVIDIA GeForce GT 650M and an Intel HD Graphics 4000.
By breaking during the loop and checking the DXGI_ADAPTER_DESC2 structure for each adapter, I find that the one I get is indeed the GT 650M, so that means my integrated graphics is identifying itself as a software adapter.
This is plausible on its own, but if you look at a picture of an Ivy Bridge die (which is what I have) you see a big area cordoned off as "Processor Graphics", which Intel themselves define like this: "Processor graphics refer to graphics that are physically in the processor package or integrated into the processor silicon." That just screams "hardware adapter" at me.
If I remove the above code block I do indeed get two adapters in my list, but the second one identifies itself as "Microsoft Basic Render Driver" and gives a vendor ID of 0x1414, while Google says that Intel usually returns 0x8086 as its ID. This list doesn't even mention the owner of 0x1414.
And, to make things even more confusing, if I check the Information Center in my Intel HD Graphics Control Panel it says it has a vendor ID of 0x8086!
Before anyone asks: Yes, my drivers should be up-to-date; I updated them as soon as I noticed this. Strangely though, DxDiag gives me an incorrect driver date for the integrated graphics, but does the same (though slightly closer to the truth) for the GT 650M. The discrete GPU driver is of WDDM 2.0, while the integrated graphics driver is of WDDM 1.3, which might be relevant, because I think it should be of 2.0 too. (Might the update have failed?)
The primary reason for the if (adapterDesc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) filter is to avoid selecting the Microsoft Basic Render Driver. This uses the WARP11 software device which does not support DirectX 12.
WARP11 is supported in all versions of Windows with DirectX 11. WARP12 is currently a developer only device (i.e. "Graphics Tools" optional feature-on-demand is installed).
It's probably a bug if your discrete part is returning true for this flag. It might be a bug in your code, a driver bug, or some strange side-effect of Optimus-style selection. WARP / MBR is really the only thing that is expected to return DXGI_ADAPTER_FLAG_SOFTWARE.
You can also exclude MBR via a if ( ( adapterDesc.VendorId == 0x1414 ) && ( adapterDesc.DeviceId == 0x8c ) ) test for well-known VendorID/DeviceID, but I suggest digging your code to understand why you are incorrectly getting DXGI_ADAPTER_FLAG_SOFTWARE returned for hardware devices.
See Anatomy of Direct3D 11 Create Device
Related
I think I know how it should work - only it does not. I have a lenovo laptop with a 860m and an intel integrated card.
I can run my application from outside with both gpu, and everything works fine: the selected gpu will be the adapter with index 0, it has the laptop screen as output, etc.
However if I try to use the adapter with index 1 (if I run the app normally, that is the nvidia, if I run it with the nvidia gpu, that is the intel), IDXGIOutput::EnumOutputs does not find anything, so I can't configure the display settings properly.
I was thinking about simply skipping the configuration, or using the output from the other adapter - but then there is no way to filter out adapters without real output - e.g. my pc has an integrated card too, but it does not have a monitor physically connected, so using that should not be possible.
I also tried to find what exactly the "Run with graphical processor" context menu button does, but I could not find anything.
Goal is to give the user the ability to select adapter inside the application, his/her choices is saved to a config file, and would be used after restart - but I can't find the way to filter the possible adapters.
You likely have a 'heterogenous adapter' system (a.k.a. NVIDIA Optimus or AMD PowerXPress). These solutions have the driver manipulate the default adapter and the device enumeration to control which card is used. You really don't have any programmatic control over this, but you can inject something into your Win32 'classic' desktop application which will encourage the driver to select the discrete part:
// Indicates to hybrid graphics systems to prefer the discrete part by default
extern "C"
{
__declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
}
UPDATE With Windows 10 April 2018 Update (17134) or later, you can use the DXGI 1.6 interface EnumAdapterByGpuPreference. See GitHub for some example usage.
I'm trying too use DirectX desktop duplication API.
I tried running exmaples from
http://www.codeproject.com/Tips/1116253/Desktop-Screen-Capture-on-Windows-via-Windows-Desk
And from
https://code.msdn.microsoft.com/windowsdesktop/Desktop-Duplication-Sample-da4c696a
Both of these are examples of screen capture using DXGI.
I have NVIDIA GeForce GTX 1060 with Windows 10 Pro on the machine. It has Intelâ„¢ Core i7-6700HQ processor.
These examples work perfectly fine when NVIDIA Control Panel > 3D Settings is selected to Auto select processor.
However if I set the setting manually to NVIDIA Graphics Card the samples stop working.
Error occurs at the following line.
//IDXGIOutput1* DxgiOutput1
hr = DxgiOutput1->DuplicateOutput(m_Device, &m_DeskDupl);
Error in hr(HRESULT) is DXGI_ERROR_UNSUPPORTED 0x887A0004
I'm new to DirectX and I don't know the issue here, is DirectX desktop duplication not supported on NVIDIA ?
If that's the case then is there a way to select a particular processor at the start of program so that program can run with any settings ?
#Edit
After looking around I asked the developer (Evgeny Pereguda) of the second sample project on codeproject.com
Here's a link to the discussion
https://www.codeproject.com/Tips/1116253/Desktop-Screen-Capture-on-Windows-via-Windows-Desk?msg=5319978#xx5319978xx
Posting the screenshot of the discussion on codeproject.com in case original link goes down
I also found an answer on stackoverflow which unequivocally suggested that it could not be done with the desktop duplication API referring to support ticket at microsoft's support site https://support.microsoft.com/en-us/help/3019314/error-generated-when-desktop-duplication-api-capable-application-is-ru
Quote from the ticket
This issue occurs because the DDA does not support being run against
the discrete GPU on a Microsoft Hybrid system. By design, the call
fails together with error code DXGI_ERROR_UNSUPPORTED in such a
scenario.
However there are some applications which are efficiently duplicating desktop on windows in both modes (integrated graphics and discrete) on my machine. (https://www.youtube.com/watch?v=bjE6qXd6Itw)
I have looked into the installation folder of the Virtual Desktop on my machine and can see following DLLs of interest
SharpDX.D3DCompiler.dll
SharpDX.Direct2D1.dll
SharpDX.Direct3D10.dll
SharpDX.Direct3D11.dll
SharpDX.Direct3D9.dll
SharpDX.dll
SharpDX.DXGI.dll
SharpDX.Mathematics.dll
Its probably an indication that this application is using DXGI to duplicate desktop, or may be the application is capable of selecting a specific processor before it starts.
Anyway the question remains, is there any other efficient method of duplicating desktop in both modes?
The likely cause is certain internal limitation for Desktop Duplication API, described in Error generated when Desktop Duplication API-capable application is run against discrete GPU:
... when the application tries to duplicate the desktop image against the discrete GPU on a Microsoft Hybrid system, the application may not run correctly, or it may generate one of the following errors:
Failed to create windows swapchain with 0x80070005
CDesktopCaptureDWM: IDXGIOutput1::DuplicateOutput failed: 0x887a0004
The article does not suggest any other workaround except use of a different GPU (without more specific detail as for whether it is at all achievable programmatically):
To work around this issue, run the application on the integrated GPU instead of on the discrete GPU on a Microsoft Hybrid system.
Microsoft introduced a registry value that can be set programmatically to control which GPU an application runs on. Full answer here.
New to CUDA, but have some time spending on computing, and I have geforces at home and tesla (same generation) in the office.
At home I have two gpus installed in the same computer, one is GK110 (compute capability 3.5), the other is GF110 (compute capability 2.0), I perfer to use GK110 for computation task ONLY and GF110 for display UNLESS I tell it to do computation, is there a way to do this through driver setting or I still need to rewrite some of my codes?
Also, if I understand correctly, if the display port of GK110 is not being connected, then the annoying windows timeout detection will not try to reset it even if the computation time is very long?
Btw my CUDA codes are compiled with both compute_35 and compute20, so the codes can be run on both GPUs, however I plan to use features that being exclusive to GK110 so the codes in the future may not being able to run on GF110 at all, and the OS is windows 7.
With a GeForce GTX Titan (or any GeForce product) on Windows, I don't believe there is a way to prevent the GPU from appearing in the system in WDDM mode, which means that windows will build a display driver stack on it, even if the card has no physical display attached to it. So you may be stuck with the windows TDR mechanism. You could try experimenting with it to confirm that. (The windows TDR behavior can be modified via registry hacking).
Regarding steering CUDA tasks to the GTX Titan, the display driver control panel should have a selectable setting for this. It may be in the "Manage 3D settings" area or some other area depending on which driver you have. When you find the appropriate settings area, there will be a selection entitled something like CUDA - GPUs which will probably be set to "All". If you change the "Global Presets" selection to "Base Profile" you should be able to change this CUDA-GPUs setting. Clicking on it should give you a selection of "All" or a set of checkboxes for each GPU detected. If you uncheck the GF110 device and check the GK110 device, then CUDA programs that do not select a particular GPU via cudaSetDevice() should be steered to the GK110 device based on this checkbox selection. You may want to experiment with this as well to confirm.
Other than that, as mentioned in the comments, using a programmatic method, you can always query device properties and then select the device that reports itself as a cc3.5 device.
Is there any good way too get a indication if a computer is capable to run a program/software without any performance problem, using pure JavaScript (Google V8), C++ (Windows, Mac OS & Linux), by requiring as little information as possible from the software creator (like CPU score, GPU score)?
That way can I give my users a good indication whether their computer is good enough to run the software or not, so the user doesn't need to download and install it from the first place if she/he will not be able to run it anyway.
I thinking of something like "score" based indications:
CPU: 230 000 (generic processor score)
GPU: 40 000 (generic GPU score)
+ Network/File I/O read/write requirements
That way can I only calculate those scores on the users computer and then compare them, as long as I'm using the same algorithm, but I have no clue about any such algorithm, whose would be sufficient for real-world software for desktop usage.
I would suggest testing on existence of specific libraries and environment (OS version, video card presence, working sound drivers, DirectX, OpenGL, Gnome, KDE). Assign priorities to these libraries and make comparison using the priorities, e.g. video card presence is more important than KDE presence.
The problem is, even outdated hardware can run most software without issues (just slower), but newest hardware cannot run some software without installing requirements.
For example, I can run Firefox 11 on my Pentium III coppermine (using FreeBSD and X server), but if you install windows XP on the newest hardware with six-core i7 and nVidia GTX 640 it still cannot run DirectX 11 games.
This method requires no assistance from the software creator, but is not 100% accurate.
If you want 90+% accurate information, make the software creator check 5-6 checkboxes before uploading. Example:
My application requires DirectX/OpenGL/3D acceleration
My application requires sound
My application requires Windows Vista or later
My application requires [high bandwith] network connection
then you can test specific applications using information from these checkboxes.
Edit:
I think additional checks could be:
video/audio codecs
pixel/vertex/geometry shader version, GPU physics acceleration (may be crucial for games)
not so much related anymore: processor extensions (SSE2 MMX etc)
third party software such as pdf, flash, etc
system libraries (libpng, libjpeg, svg)
system version (Service Pack number, OS edition (premium professional etc)
window manager (some apps on OSX require X11 for functioning, some apps on Linux work only on KDE, etc)
These are actual requirements I (and many others) have seen when installing different software.
As for old hardware, if the computer satisfies hardware requirements (pixel shader version, processor extensions, etc), then there's a strong reason to believe the software will run on the system (possibly slower, but that's what benchmarks are for if you need them).
For GPUs I do not think getting a score is usable/possible without running some code on the machine to test if the machine is up to spec.
With GPU's this is typically checking what Shader Models it is able to use, and either defaulting to a lower shader model (thus the complexity of the application is of less "quality") or telling them they have no hope of running the code and thus quitting.
I have created 16 Direct3D devices with size approximately 320x200 pixels. I invoke IDirect3DDevice9::Present for each device in a separate thread every 40 ms. On laptops with Windows XP and integrated Intel GMA945 graphics part of devices is not updated if system tooltip or Start menu are shown. IDirect3DDevice9::Present doesn't return any error codes at that moment, in program everything looks fine, but user can see that move on several of devices freezes. What could be a reason for that?
This works fine on Windows 7 with the same hardware and on Windows XP with different hardware, so the problem only with this combination. I should support this since my customers are use this combination of the hardware and OS. MSDN says nothing about that I should create only one D3D device (at least I can't find it) so problem should be elsewhere.
What I'm trying to find is that possibly there's some combination of flags that could solve my problem. At the moment I use the following:
D3DPRESENT_PARAMETERS param = {};
param.Windowed = TRUE;
param.SwapEffect = D3DSWAPEFFECT_DISCARD;
param.hDeviceWindow = GetSafeHwnd();
param.BackBufferCount = 1;
param.BackBufferFormat = D3DFMT_UNKNOWN;
param.BackBufferWidth = m_szDevice.Width;
param.BackBufferHeight = m_szDevice.Height;
param.MultiSampleType = D3DMULTISAMPLE_NONMASKABLE;
param.Flags = D3DPRESENTFLAG_VIDEO;
param.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
param.MultiSampleType = D3DMULTISAMPLE_NONE;
param.MultiSampleQuality = 0;
Don't do that. The device is supposed to map basically 1-to-1 to a GPU. Create one device, and use it to draw to 16 different windows, in whichever way works for you. (Multiple swap chains is the usual approach, afaik)
Creating 16 devices and trying to get them to render in parallel is just asking for trouble.
D3D is designed around the assumption that only one device will be doing serious rendering at any time.
In theory, the difference should only be a matter of performance, but in your case, trying to run 16 devices in parallel on a crappy Intel GPU, it wouldn't surprise me if it causes rendering errors such as you'er seeing.
I've distributed DirectX software for a couple of years and along the way learnt that Intel graphics chipsets have incredibly crap drivers. Once I even saw a driver revision that couldn't render a quad properly. So when you have a problem with an Intel chipset, if you're on the latest driver version, you pretty much have to accept your solution is going to be "start shotgun hacking things until it works".
Sorry to give you a lame answer, but Intel chipsets are not well engineered at all. They're solely there to get something - anything - on the screen, probably for office worker type use. Beyond "does it do aero glass" Intel probably don't give a hoot what it does or how well it works. An alternative "solution" is to distribute your application anyway, state that Intel chipsets are not supported due to glitches in the hardware/driver support, and contact Intel and see if you can get a fix from them.
And people say OpenGL has bad drivers...
First of all, when you say "doesn't return any error codes at that moment", are you running the D3D9 debug version at max debugging level?
Second, everytime you create a new device and it gains focus, the surfaces of all the existing devices are lost. Are you calling reset on all of them after creation?
Other than that, it's like the other answers state: don't create many devices from a single application. Device creation might start throwing errors after 9 or 10 devices, you are really pushing it with 16. Use a single device with multiple swap chains in stead, see for instance this DirectX 8 tutorial.
Intel graphics chips, particularly the integrated GMA ones, have never been known for their capabilities. They can report caps they don't have and later fail, with or without errors codes (had bug reports of this, supposedly supported shader models later failed to compile). It is possible that you're running into a similar problem with their chips/drivers. Does it work on other hardware or with different drivers?
I assume, from having multiple devices, they are windowed? Have you checked the window handles, or tried explicitly passing the handle/viewport when presenting? Do any of the devices get reset?
It is possible the display drivers are not properly repainting the window after the tooltip or start menu are shown (more likely if its a window under the tooltip/menu). Have you checked the window for focus, made sure it gets painted, etc?