The DirectX 12 compiler DXC has received a PR about a month ago that adds template support to HLSL.
So you can now do this:

template<int iStartPlane, int iEndPlane>
bool FrustumCull_Box(float3 BoxOrigin)
{
	[unroll]
	for (uint PlaneIndex = iStartPlane; PlaneIndex < iEndPlane; ++PlaneIndex)
	{
		float4 PlaneData = CullPlanes[PlaneIndex];
		float PlaneDistance = dot(PlaneData.xyz, BoxOrigin) - PlaneData.w;
		float PushOut = dot(abs(PlaneData.xyz), BoundsExtent);

		if (PlaneDistance > PushOut)
			return true;
	}

	return false;
}

Which is great since that’s all going to happen at compile time and so the compiler will be able to unroll the loop correctly.
This, coupled with UE4’s shader permutation vectors via FPermutationDomain allows you to skip most of the dynamic branching in your code, which is fantastic!

Here’s what you need to do to make UE4 support HLSL templates:

  1. Install the prerequisites:
    1. Python 3.x
    2. Windows SDK: 10.0.19041.0 or newer recommended, installed via Visual Studio
    3. Windows Driver Kit (WDK) from https://docs.microsoft.com/en-us/windows-hardware/drivers/download-the-wdk
  2. Fork this repo on GitHub: https://github.com/microsoft/DirectXShaderCompiler
  3. Clone its master branch
  4. Pull & merge this PR: https://github.com/microsoft/DirectXShaderCompiler/pull/3533
    1. Here’s a tutorial: https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/checking-out-pull-requests-locally
  5. Go inside the DirectXShaderCompiler directory and run utils\hct\hctshortcut.js, which places a shortcut on your desktop called “HLSL console”
  6. Run HLSL console from your desktop
  7. hctbuild
  8. This builds the debug version of DXC and creates a folder called hlsl.bin next to the downloaded repo folder.
  9. You should see something like “Success – files are available at <SOME_DIR>\hlsl.bin\Debug\bin”
  10. This is good, but we need the Release version since it’s a lot faster!
  11. Open the generated LLVM.sln that’s inside hlsl.bin
  12. Build ALL_BUILD in Release in Visual Studio
  13. Copy hlsl.bin\Release\bin\dxcompiler.dll to:
    1. Engine\Binaries\Win64\
    2. Engine\Binaries\ThirdParty\Windows\DirectX\x64\
  14. If anything goes wrong you can restore the original DLLs by running setup.bat on source-built engines.
  15. Edit Engine\Source\Developer\Windows\ShaderFormatD3D\Private\D3DShaderCompiler.cpp:
    Find the D3DCreateDXCArguments() function and this:

    OutArgs.Add(L"/enable-templates");

    Goes above the line

    if (AutoBindingSpace < UE_ARRAY_COUNT(DigitStrings))

That’s it, you should now be able to compile HLSL shaders with templates in them!

As an added bonus, you can also get Microsoft PIX to recognize templates by replacing its c:\Program Files\Microsoft PIX\2103.16\dxcompiler.dll with the one you’ve just built.

Published

Comments

No Comments

Leave a Reply