Skip to content

Implementation

Chuck Walbourn edited this page Jan 21, 2022 · 15 revisions
DirectXTK

Be sure to read the Implementation page for DirectX Tool Kit for DirectX 11 as those topics also apply to DirectX Tool Kit for DirectX 12:

  • Complier conformance
  • Naming conventions
  • Type usage
  • Unicode
  • Error reporting
  • The pImpl idiom
  • Calling-conventions
  • Default constructors/assignment operators
  • DirectXMath Parameter Conventions

Strongly-typed enum bitmask flags

To provide type-safe bitmask flags, we make use of the DEFINE_ENUM_FLAG_OPERATORS macro (in winnt.h) to make an enum work as you'd expect for bitmask flags based on recommendations in the C+ standard under 17.5.2.1.3 Bitmask types.

The impact to client code is minimal, but mostly means you can't pass a 0 literal and must use the defined default value like WIC_LOADER_DEFAULT.

We generally use enum rather than enum class because it simplifies testing the bitflags. For example, the following works with enum:

if ((myFlags & MYFLAGS_BIT2) != 0)

To do the same thing with a enum class requires:

if ((myFlags & MYFLAGS_BIT2) == MYFLAGS_BIT2)

The EffectFlags are the exception. We use a namespace with constexpr uint32_t value instead. This allows client code to extend the namespace to add their own mask values rather than having to create a different flags bitset.

Direct3D 12 headers have adopted strongly typed enum bitmask flags. If you need a parameter such as D3D12_RESOURCE_FLAGS the proper type is D3D12_RESOURCE_FLAGS.

Direct3D 11 headers do not make use of the strongly type enum bitmask flags. For this reason, if you need a parameter such as D3D11_BIND_FLAG the proper type is unsigned int.

See this blog post.

SAL annotation

The DirectX Toolkit library makes extensive use of SAL2 annotations (_In_, _Outptr_opt_, etc.) which greatly improves the accuracy of the Visual C++ static code analysis (also known as PREFAST). The standard Windows headers #define them all to empty strings if not building with /analyze, so they have no effect on code-generation.

The main thing to note about Direct3D 12 is that the types D3D12_GPU_DESCRIPTOR_HANDLE and D3D12_CPU_DESCRIPTOR_HANDLE are actually implemented as structs, so SAL pointer-style annotation doesn't apply to them (_In_, _In_opt_, etc.).

Root Signatures

Rather than trying to share a single root signature across all shaders in the DirectX Tool Kit, the IEffect::Apply will call both SetGraphicsRootSignature and SetPipelineState as well as other required parameters. The overhead of resetting the root signature is minimal for the greatly improved usability and maintainability of the library.

Another design decision here is to use distinct SetGraphicsRootDescriptorTable entries for each texture and sampler descriptor. While the Direct3D 12 root signature allows you to create ranges for the tables, it means that all such descriptors must be continuous in the heap. Rather than impose this requirement on the application-level API, we use multiple tables.

All shaders have HLSL-described root signatures. While this isn't strictly for PCs since the driver already has to compile the IL into vendor-specific microcode so it can accommodate changes to the root signature, this is a significant performance hit on Xbox One XDK apps.

Samplers

When creating root signatures you have the choice of using static samplers built into the signature, or you must provide a sampler descriptor and set the sampler heap at render time. For SpriteBatch we support both a static-sampler mode and a sampler heap descriptor mode for ease of use, and the fact that this feature only added a couple of shader combinations. For Effects generally, we require sampler heap descriptors which must be set in addition to the texture heap descriptor to render.

Shared Code

The following files are identical between DirectX Tool Kit for DirectX 11 and DirectX Tool Kit for DirectX 12:

Inc\Audio.h
Inc\GamePad.h
Inc\Keyboard.h
Inc\Mouse.h
Inc\SimpleMath.*

Audio\*.h
Audio\*.cpp

Src\AlignedNew.h
Src\Bezier.h
Src\BinaryReader.*
Src\DDS.h
Src\DemandCreate.h
Src\GamePad.cpp
Src\Geometry.*
Src\Keyboard.cpp
Src\LoaderHelpers.h
Src\Mouse.cpp
Src\PlatformHelpers.h
Src\SDKMesh.h
Src\SharedResourcePool.h
Src\SimpleMath.cpp
Src\TeapotData.inc
Src\vbo.h

Src\Shaders\Common.fxh
Src\Shaders\Lighting.fxh
Src\Shaders\PBRCommon.fxh
Src\Shaders\Structures.fxh
Src\Shaders\Utilities.fxh
Src\Shaders\PixelPacking_Velocity.hlsli

Further Reading

Dual-use Coding Techniques for Games
C++ Core Guidelines
DirectX Developer Blog

For Use

  • Universal Windows Platform apps
  • Windows desktop apps
  • Windows 11
  • Windows 10
  • Xbox One
  • Xbox Series X|S

Architecture

  • x86
  • x64
  • ARM64

For Development

  • Visual Studio 2022
  • Visual Studio 2019 (16.11)
  • clang/LLVM v12 - v18
  • MinGW 12.2, 13.2
  • CMake 3.20

Related Projects

DirectX Tool Kit for DirectX 11

DirectXMesh

DirectXTex

DirectXMath

Tools

Test Suite

Model Viewer

Content Exporter

DxCapsViewer

See also

DirectX Landing Page

Clone this wiki locally