Device took an unreasonable amount of time to execute its commands - directx

I'm porting C code to HLSL (compute shader).
The compiler is crazy with one of the for loops. At runtime, the display device driver detect an unreasonable amount of time to execute the code.
Here is the partial source code with the offending for loop:
P = FloatToAsciiNoExponent(F * Factor, DstBuf, 7);
uint TmpBuf[FTOA_BUFFER_SIZE];
uint BytesWritten = IntToAscii(Exp10, TmpBuf, BASE10);
DstBuf[P++] = 'E';
[fastopt]
for (uint I = 0; I < BytesWritten; I++)
DstBuf[P++] = TmpBuf[I];
At run time, I got the following debug message:
D3D11 ERROR: ID3D11Device::RemoveDevice: Device removal has been
triggered for the following reason (DXGI_ERROR_DEVICE_HUNG: The Device
took an unreasonable amount of time to execute its commands, or the
hardware crashed/hung. As a result, the TDR (Timeout Detection and
Recovery) mechanism has been triggered. The current Device Context was
executing commands when the hang occurred. The application may want to
respawn and fallback to less aggressive use of the display hardware).
EXECUTION ERROR #378: DEVICE_REMOVAL_PROCESS_AT_FAULT]
If I comment out the two for-loop lines, everything is OK (Except of course the final result which lacks his last part).
FloatToAsciiNoExponent() is a function which convert his first argument into a list or ascii code stored in the second argument (an array of uint). The last argument is the numeration base for conversion. It has been validated.
IntToAscii() is a function converting his first argument into a list of ascii code stored in the second argument (an array of uint). It has been validated.
The original C source code I'm porting can be found here: https://searchcode.com/codesearch/view/14753060/
I'm running on Windows 7 and DirectX SDK of June 2010 (The last one running on Windows 7). Windows update has been executed and every update installed. The graphic card is an NVidia Quadro K4200 having 24GB of RAM with driver version 431.02.
Any help appreciated.

With DirectCompute you still need to make sure each instance completes in a reasonable time or you will hit TDR timeouts (~2 seconds).
See Microsoft Docs
With DirectX 11.1 (Windows 8 or later), you can use D3D11_CREATE_DEVICE_DISABLE_GPU_TIMEOUT to give you a bit more time for a long-running DirectCompute shader, but you can make the system unresponsive.
You can install a partial version of DirectX 11.1 on Windows 7 Service Pack 1 via KB2670838
You should also read this blog post for more up-to-date information about the legacy DirectX SDK.
UPDATE Apparently this was actually an HLSL compiler bug with the legacy DirectX SDK. Note that you can and should use the latest Windows 10 SDK HLSL compiler even for DirectX 11 on Windows 7. See this blog post and Microsoft Docs.

Answering myself:
I upgraded my PC to Win10 which includes DirectX12. Now the source code is working as expected. This confirm that the June 2010 compiler is bugged.

Related

Formerly working Matlab Compiler-based DLL suddenly cannot initialize

Update: It turned out that there was something with installing Delphi 10.4 CE that broke my app (thanks, DelphiCoder!); specifically, it was something in the Windows Registry that was broken. After using ProcessMonitor to ensure no Delphi 10.4 (aka 21.0) was being invoked, I ended up cleaning out the registry of all 10.4 references, rebuilding completely (not clear if this was needed or not), and lo and behold, it works again! I'm adding this update in case someone in a similar situation finds this question - remember to back up your registry first and be careful!
Original Post: I created several DLLs with Matlab Compiler 10 years ago, with C wrappers, to make them available with Delphi. Once I got them working, they always worked - until today! The code in the C wrapper initialization function in question is in the code box below; the "Could not initialize library" is printed to the console when I run my Delphi app.
mclmcrInitialize();
if (!mclInitializeApplication(NULL, 0)) {
fprintf(stderr, "Could not initialize application\n");
}
if (!libMyDllInitialize()) {
fprintf(stderr, "Could not initialize library\n");
}
The problem is that this has never happened before, over all the probably 10 years since we first wrote these! My machine has the correct version of the 32-bit 2021a MCR installed, as it has for several years; I've installed this on numerous machines from Windows XP up to Windows 10, The DLLs were last built 5 - 7 years ago; anyway, I don't have access to the Matlab compiler anymore. The only thing that has changed is my app, but not anywhere near where this DLL initialization code is called; also, when the problem first happened, my app was working, then didn't -without any changes. Finally, I went back a few days and rebuilt my app, and it still fails.
So I am really stuck, and need some advanced help in debugging DLL startup issues on Windows. I tried looking in the Windows Event Logger, but nothing appears to show up there. Logs to check? A setting in the Registry that somehow got hosed? Wrong phase of the moon? How does one debug loading/initializing a formerly working DLL when forced to treat it as a black box? Help!
How does one debug loading/initializing a formerly working DLL [...]?
I think there is no definitive answer to your question.
This is how we have gone about debugging the loading/initializing of DLLs and applications and may help you:
We regularly work with systems where we have no source code for the DLLs (and often we don't have any source code for the applications either). We experience DLL conflicts quite regularly. When testing why applications don't start as expected we have found the use of Sysinternal's Process Monitor by Mark Russinovich invaluable.
This will show you system level activity. You can filter for your process and then you will see all file, registry, thread and network activity (although thread and network are quite limited). If the DLL has dependencies then the system tries to find those and so you will be able to discover all dependent DLLs and COM interfaces (by seeing the registry lookups for that interface) that it's looking for. Process Monitor will show if the resource is not found or if access is denied.
Slightly more difficult to discover is if one of the dependencies exists but the export table has changed (so the functions have different signatures or export ordinals). There are ways to check that (by looking at the export and import tables) but generally (if you have access to a working environment) it's enough to check the filesize, timestamp (and the VERSIONINFO resource if there is one) between DLLs.

How to detect Windows 11 using Delphi 10.3.3

I use TOSVersion.ToString function (uses SysUtils) to detect Windows version. However this is what I get in Windows11:
Windows 10 (Version 10.0, Build 21996, 64-bit Edition)
Is there any reliable way to detect Windows 11? I'm using Delphi 10.3.3.
UPDATE: Windows 11 is officially released and I tried again.
Here is what I get:
Windows 10 (Version 10.0, Build 22000, 64-bit Edition)
As Remy pointed out: using the WinAPI you risk of being in some compatibility mode, resulting in getting a version reported that is lower than the actual.
One alternative is to check the file version of expected files, i.e.
%windir%\system32\ntoskrnl.exe or
%windir%\explorer.exe
using GetFileVersionInfo() and VerQueryValue() - the HiWord(dwFileVersionLS)
should be 22000 or higher (according to Windows NT build/release number).
Another is to look in the Registry under HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ at the text values CurrentBuild and CurrentBuildNumber, checking if the highest of both is 22000 or higher.
David already wrote a detailled answer in Checking Windows version on W10 with even more alternatives, although concentrating on the high/low version numbers, not the build. But WMI might help.
(This only works in retrospective with confirmed knowledge.) Check which API exports are available: the idea is that specific functions were introduced with specific Windows releases/versions, so if importing fails for one you know you're on a version below. An outdated example and an outdated list of minimum versions per function will give you an idea. Now you "only" have to find out which new functions are introduced with Windows 11.
Those are all not bulletproof, but you could combine them and then draw conclusions. And after all that you can still try your approach to parse texts instead of relying on numbers only. It also shows how easily you can manipulate your system into reporting different versions as per which method is used.
Official major version number for Windows 11 is 10.
The official build number for the public preview of Windows 11 is
10.0.22000.168
Earlier builds:
10.0.22000.71
10.0.22000.65
10.0.22000.51
Microsoft Windows 11 FAQ
If you want to detect Preview versions, earliest build number was 10.0.22000.51 Windows 11 version history
TOSVersion relies on some hard coded names and logic to return OS name. You will have to implement your own detection, copy and modify TOSVersion record or make wrapper around it, where you can use existing logic for older versions and implement check based on Windows 11 build number to detect Windows 11.
For other general issues and approaches in detecting OS version you can refer to AmigoJack's answer
Except the very weak, atleast for me, solution of considering Windows 10 builds greater than 22000, such as Windows 11, the only solution I found which is actually working is the WMIs Win32_OperatingSystem class - Caption property.
On my dev Win10 machine, it gives the following string: Microsoft Windows 10 Pro.
On my another dev machine, with Win11 installed, the same function gives: Microsoft Windows 11 Pro.
The difference is in string values - "10" vs "11"- but this is at least something far better than the "build greater than" solution.
C# and C++ work well.
The simplest way is to get the version of Kernel32.dll and if Major Version is 10 and Build Version is >= 22000 then you have Windows 11.
See my code here: How can I find the Windows product name in Windows 11?

XInputGetKeyStroke returning ERROR_SUCCESS while controller is unplugged

XInputGetKeyStroke seems to return ERROR_SUCCESS when the specified controller is not plugged in, leaving the supplied XINPUT_KEYSTROKE struct uninitialized:
XINPUT_KEYSTROKE xStroke;
DWORD ret = XInputGetKeyStroke(0, 0, &xStroke);
if (ret == ERROR_SUCCESS)
printf("ERROR_SUCCESS\n");
Am I doing something wrong or is this a bug in XInput? xinput1_3.dll is the version I am using. I am compiling/linking against the headers/libraries in the DirectX 2010 SDK. When the controller is plugged in XInputGetKeyStrokes seems to behave as expected.
I've had the same problem with xinput1_3.dll and from my research it seems it is not implemented. It may be implemented on xinput1_4.dll on Windows 8 but I am unable to test this.
Confirmation that it's not implemented as of 26th April 2014: http://controllermax.com/forums/archive/index.php/t-142531.html
Not the most acceptable of sources but it's all I could find.
Support for XInputGetKeyStroke was added for XInput 1.3 (April 2007), but no Windows driver supports the 'Chatpad' device so it's limited to the controller "button keys".
The source for this function did not change between XInput 1.3 (the last version available down-level on Windows 7 via the legacy DirectX SDK / DirectSetup) and XInput 1.4 (the current version on Windows 8.x), so if there is a bug here it likely repros on XInput 1.4 as well.
This particular API is really only useful on Xbox 360 where the 'Chatpad' might be supported, and due to the down-level story for XInput, you are usually better served using XInput 9.1.0 rather than XInput 1.3 and sticking with the standard XInputGetState methods anyhow. I don't use XInputGetKeyStroke at all for the DirectX Tool Kit GamePad class which is probably a more useful abstraction.
See XINPUT and Windows 8 and DirectX Tool Kit: Now with GamePads
UPDATE: I found the code path that resulted in this condition, and will file a bug, but it's not likely to get fixed for XInput 1.3. One workaround would be to use another function (XInputGetState or XInputGetCapabilities) to check for connected state, and then call XInputGetKeyStroke only if it is connected.

Does calling FastMM4 LogAllocatedBlocksToFile() periodically use up memory space?

I'm hunting an elusive memory problem in a Delphi 5 program, where memory gets randomly overwritten at the customer site. After trying a lot of things with no result so far I now want to use the FastMM4 output from the LogAllocatedBlocksToFile() to find out which objects are allocated immediately before the overwritten area. The program uses a timer to write allocated block information to a new file every 30 minutes. Unfortunately my test run of the program (DEBUG build) crashed after about 23 hours with an EOutOfMemory exception, using allocated memory of 1.83 GB according to MadExcept.
From SysInternals Process Explorer it does look like each call of LogAllocatedBlocksToFile() allocates but does not free memory:
The red spikes in the CPU Usage graph are the LogAllocatedBlocksToFile() calls. I have added calls to LogMemoryManagerStateToFile() immediately before and after, and the data for the last spike (increse of the private bytes from about 183 MB to about 218 MB) looks like this:
55054K Allocated
47911K Overhead
53% Efficiency
and this:
55055K Allocated
47910K Overhead
53% Efficiency
so FastMM4 seems not to be aware of the additional memory the program consumes according to Process Explorer.
I'm using version 4.991 of FastMM4, downloaded today from SourceForge. The test program runs in DEBUG mode, with the following defines set:
FullDebugMode
UseCustomFixedSizeMoveRoutines
UseCustomVariableSizeMoveRoutines
NoDebugInfo
ASMVersion
DetectMMOperationsAfterUninstall
RawStackTraces
LogErrorsToFile
LogMemoryLeakDetailToFile
AlwaysAllocateTopDown
SuppressFreeMemErrorsInsideException
EnableMemoryLeakReporting
HideExpectedLeaksRegisteredByPointer
RequireDebuggerPresenceForLeakReporting
EnableMMX
ForceMMX
EnableBackwardCompatibleMMSharing
UseOutputDebugString
Questions:
Is there any known problem with those functions? Am I not using them properly, are they not intended to be called multiple times in one debugging session? Is there a way to get that memory released again?
Short version:
I have tracked this down to be a version mismatch of the support library FastMM_FullDebugMode.dll.
An older version of the library works with the newer version compiled into the executable. There seems to be no check that versions do match. However, modules don't really work together at run-time.
Long version:
The project originally uses the older version 4.97 of FastMM4, which I have checked in here together with the support library (file version 1.44.0.4, product version 1.42).
While trying to find the bug in the program I have upgraded FastMM4 to version 4.991. I also remember to have copied the new support library (file version 1.61.0.6, product version 1.60) to the build directory. However, some time later I must have deleted it from the directory, or I copied it into the wrong directory to begin with, because two hours ago I checked the modules loaded by the application and found that the app had picked up the old version of the support library from another directory, as it was not in the build directory.
Since copying it there and restarting the app the problem seems to be gone. Memory usage doesn't increase when LogAllocatedBlocksToFile() is called.
Maybe this helps someone, so I answer this instead of deleting the question.
On with debugging...

Performance Object cannot be seen in Windows 7

I wish to register some of status of my application as a performance object, so that I can monitor its performance by utilising the Windows Performance Monitor.
But I had a problem with Windows 7: the performance object cannot be seen in the list of Performance Monitor, even if my application is running.
My code is exactly the same as the Delphi project in this tutorial:
http://www.wehlou.com/Code/perfmon/index.htm
However, the solution provided in this tutorial doesn't work in Windows 7 either.
Such solution works fine in Windows XP and 2003.
I don't know if there are some changes in Windows 7 which makes my performance object missing.
Please help. Thanks a heap in advance.
Is your Windows 7 computer a 64-bits machine? You may have to provide both a 32 and 64 bits version:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa371636(v=vs.85).aspx
The short answer:
Yes you can fix manually the 2 object performance counters (DeltaCount & RawCount) issue under Windows 7 x32. The 2 files generated by PerfMonClient.exe are usable (namely symfile.h and symfile.ini).
Nota: Refer to MSDN for the usage of lodctr.exe.
Prior to that an entry to the registry as follows should created:
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\PerfMonClient\Performance]
"Open"="PerfData_Open"
"Close"="PerfData_Close"
"Collect"="PerfData_Collect"
"Library"=hex(2):25,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,00,\
74,00,25,00,5c,00,53,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,50,\
00,65,00,72,00,66,00,4d,00,6f,00,6e,00,44,00,4c,00,4c,00,2e,00,64,00,6c,00,\
6c,00,00,00
Nota: Library point to %SystemRoot%\System32\PerfMonDLL.dll (location of the performance DLL).
Any attempt to install and/or uninstall them using PerfMonClient.exe App doesn't work even under Windows XP. Forget about that.
Look an feel:
Listing
symfile.h:
#define OBJECT_1 0
#define DEVICE_COUNTER_1 2
#define DEVICE_COUNTER_2 4
symfile.ini:
[info]
drivername=PerfMonClient
symbolfile=symfile.h
[languages]
009=English
[text]
OBJECT_1_009_NAME=PerfMonTest Performance Counters
OBJECT_1_009_HELP=A demo application for your unbridled pleasure
DEVICE_COUNTER_1_009_NAME=RawCount
DEVICE_COUNTER_1_009_HELP=A count of something that goes up and down
DEVICE_COUNTER_2_009_NAME=DeltaCount
DEVICE_COUNTER_2_009_HELP=Something going up all the time, Windows shows difference per time unit

Resources