MINGW-packages icon indicating copy to clipboard operation
MINGW-packages copied to clipboard

Issues on fxc2

Open driver1998 opened this issue 3 years ago • 16 comments

Currently fxc2 doesn't actually work on all environments because it hard codes to LoadLibrary d3dcompiler_47.dll in the same directory as the exe:

https://github.com/mozilla/fxc2/blob/5ace4c25b63cb5a83b58a3eae3d36256a6022cde/fxc2.cpp#L188

driver1998@desktop CLANG64 ~
$ fxc -Fhout.c -Tps_5_0 -EMain -Vn sample.hlsl
option -Fh (Output File) with arg out.c
option -T (Shader Model/Profile) with arg ps_5_0
option -E (Entry Point) with arg Main
option -Vn (Variable Name) with arg
input file: sample.hlsl
Error: could not load d3dcompiler_47.dll from C:\msys64\clang64\bin\d3dcompiler_47.dll

What should we do about this? Upstream seems to suggest packaging the dll with fxc.exe (And they provided a version), but there will be some other issues:

  • We may risk to force other exes in $MINGW_PREFIX/bin to use the same version of d3dcompiler_47.dll as fxc2 instead of the system one.
  • d3dcompiler_47.dll is not marked as redistributable on ARM64 and is expected to live in system32.

Or maybe patch it to just use the system dll, but are there Windows versions we still support, and don't have this dll built-in?

driver1998 avatar Apr 11 '22 01:04 driver1998

My recollection is that fxc2 was packaged as part of an attempt to get dx12 support in qt to build. I don't recall the outcome of that test, and I don't see anything other than qt5-doc and qt5-static makedepending on it, so maybe the 'test' didn't work out and it was never expanded to the non-static build of qt5?

jeremyd2019 avatar Apr 11 '22 02:04 jeremyd2019

I guess that's why I didn't see any build failures despite fxc2 doesn't work at all...

driver1998 avatar Apr 11 '22 02:04 driver1998

Feel free to try this https://github.com/Biswa96/Junkyard/blob/master/c/HlslComp.c

Biswa96 avatar Apr 11 '22 02:04 Biswa96

I don't think fxc2's code is broken, it does work if I place that dll to /clang64/bin.

driver1998@desktop CLANG64 ~
$ cp /c/windows/system32/d3dcompiler_47.dll /clang64/bin

driver1998@desktop CLANG64 ~
$ fxc -Fhout.c -Tps_2_0 -EMain -Vn sample.hlsl
option -Fh (Output File) with arg out.c
option -T (Shader Model/Profile) with arg ps_2_0
option -E (Entry Point) with arg Main
option -Vn (Variable Name) with arg
input file: sample.hlsl
Calling D3DCompileFromFile(
         sample.hlsl,
        ,
         D3D_COMPILE_STANDARD_FILE_INCLUDE,
         Main,
         ps_2_0,
         0,
         0,
         &output,
         &errors);
Wrote 268 bytes of shader output to out.c

driver1998@desktop CLANG64 ~
$ cat out.c
const signed char Main[] =
{
   0,   2,  -1,  -1,  -2,  -1,
  31,   0,  67,  84,  65,  66,
  28,   0,   0,   0,  79,   0,
   0,   0,   0,   2,  -1,  -1,
   1,   0,   0,   0,  28,   0,
   0,   0,   0,   1,   0,   0,
  72,   0,   0,   0,  48,   0,
   0,   0,   3,   0,   0,   0,
   1,   0,   0,   0,  56,   0,
   0,   0,   0,   0,   0,   0,
  66,  97, 115, 101,  84, 101,
 120,   0,   4,   0,  12,   0,
   1,   0,   1,   0,   1,   0,
   0,   0,   0,   0,   0,   0,
 112, 115,  95,  50,  95,  48,
   0,  77, 105,  99, 114, 111,
 115, 111, 102, 116,  32,  40,
  82,  41,  32,  72,  76,  83,
  76,  32,  83, 104,  97, 100,
 101, 114,  32,  67, 111, 109,
 112, 105, 108, 101, 114,  32,
  49,  48,  46,  49,   0, -85,
  81,   0,   0,   5,   0,   0,
  15, -96,  61,  10,  23,  63,
-102,-103,-103,  62, -82,  71,
 -31,  61,   0,   0,   0,   0,
  31,   0,   0,   2,   0,   0,
   0,-128,   0,   0,   3, -80,
  31,   0,   0,   2,   0,   0,
   0,-112,   0,   8,  15, -96,
  66,   0,   0,   3,   0,   0,
  15,-128,   0,   0, -28, -80,
   0,   8, -28, -96,   5,   0,
   0,   3,   0,   0,   2,-128,
   0,   0,  85,-128,   0,   0,
   0, -96,   4,   0,   0,   4,
   0,   0,   1,-128,   0,   0,
   0,-128,   0,   0,  85, -96,
   0,   0,  85,-128,   4,   0,
   0,   4,   0,   0,  15,-128,
   0,   0, -86,-128,   0,   0,
 -86, -96,   0,   0,   0,-128,
   1,   0,   0,   2,   0,   8,
  15,-128,   0,   0, -28,-128,
  -1,  -1,   0,   0
};

driver1998 avatar Apr 11 '22 02:04 driver1998

So ideally fcx2 should be adapted to try and load the systems one if it's available.

ZachBacon avatar Apr 11 '22 03:04 ZachBacon

Makes me wonder what the 'incorrect' DLL was that required this fix https://github.com/mozilla/fxc2/commit/e00a32fbd3d5814b3f599c8528e37db9c1456803 ?

jeremyd2019 avatar Apr 11 '22 03:04 jeremyd2019

Maybe the wine version? (Keep in mind fxc2 is supposed to be run in wine).

driver1998 avatar Apr 11 '22 03:04 driver1998

Ah, that explains why the comment says "find the WINDOWS dll" but the code is looking in the local directory instead of the Windows directory (or system32 more likely)

jeremyd2019 avatar Apr 11 '22 04:04 jeremyd2019

chances are then we could just carry a patch for us to look for the system dll for this instead of local. Though, couldn't we just modify it, create our own fork to link with d3dcompiler_47 instead of telling it where the dll is located?

ZachBacon avatar Apr 11 '22 07:04 ZachBacon

https://github.com/mozilla/fxc2/pull/3#issuecomment-454787461 kind of sounded like they were looking for someone to fork and take up maintaining/improving it...

jeremyd2019 avatar Apr 11 '22 07:04 jeremyd2019

IIRC d3dcompiler_47.dll is added somewhere between 8.0 and 8.1, we might just as well use the system dll.

driver1998 avatar Apr 11 '22 07:04 driver1998

From https://www.nuget.org/packages/Microsoft.DXSDK.D3DX/9.29.952.8:

It is recommended to use the D3DCompiler API directly using the header, import library, and runtime DLL from the Windows SDK (i.e. "D3DCompiler_47.dll" which is included in Windows 8.1 and Windows 10, and is available for 'application local' deployment for Windows 7 support).

So if we drop Windows 7 and Windows 8.0 we are safe to rely on the system dll being present.

driver1998 avatar Apr 11 '22 07:04 driver1998

So if we drop Windows 7 and Windows 8.0 we are safe to rely on the system dll being present.

Given the current state is that it doesn't work anywhere without manually copying the DLL, reverting (most of) the commit I linked earlier and just using LoadLibrary(d3dcompiler_47.dll) would make it work on 8.1 and newer, and still allow putting the DLL in the same directory if necessary for older versions (or wine).

Is there some convenient way to tell if the program is running on Wine, so it could only use the current directory explicitly there, assuming there was a good reason for them to make that change in the first place there? It looks like checking for "wine_get_version" export from ntdll.

jeremyd2019 avatar Apr 11 '22 14:04 jeremyd2019

For anyone else coming across this thread because they just want to run fxc and have it work, try this:

cp /c/Windows/System32/D3DCompiler_47.dll $MINGW_PREFIX/bin/

This seems to work for me on Windows 11.

DavidEGrayson avatar Feb 27 '23 03:02 DavidEGrayson

I may be late to the party but I think I may a solution. I wrote a program, efxc2 ( https://github.com/JPeterMugaas/efxc2 ) that does not require you to copy a system .dll a MINGW directory. My program is based partly on fxc2 but with some enhancements such the ability to handle more parameters often seen with Microsoft's open source and it also handles both Unix-style and MS-DOS style parameters. It also outputs individual bytes in a header file as unsigned bytes.

I made a pull request at: https://github.com/msys2/MINGW-packages/pull/19970 .

JPeterMugaas avatar Mar 05 '24 06:03 JPeterMugaas

My program, efxc2 is now is merged and a package is available so I wonder if this entire situation needs to be reassessed using that program. I'm hoping that this bug report can be closed in view of this development.

JPeterMugaas avatar Apr 04 '24 13:04 JPeterMugaas