Explorar el Código

feat: 添加D3D几何项目

nicetry12138 hace 1 año
padre
commit
f9fd4024cb

+ 31 - 0
图形学/DirectX学习/src/D3DBox/D3DBox.sln

@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.8.34525.116
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "D3DBox", "D3DBox\D3DBox.vcxproj", "{6EA952F0-104E-4EBA-8AAE-C059F036EB89}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|x64 = Debug|x64
+		Debug|x86 = Debug|x86
+		Release|x64 = Release|x64
+		Release|x86 = Release|x86
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{6EA952F0-104E-4EBA-8AAE-C059F036EB89}.Debug|x64.ActiveCfg = Debug|x64
+		{6EA952F0-104E-4EBA-8AAE-C059F036EB89}.Debug|x64.Build.0 = Debug|x64
+		{6EA952F0-104E-4EBA-8AAE-C059F036EB89}.Debug|x86.ActiveCfg = Debug|Win32
+		{6EA952F0-104E-4EBA-8AAE-C059F036EB89}.Debug|x86.Build.0 = Debug|Win32
+		{6EA952F0-104E-4EBA-8AAE-C059F036EB89}.Release|x64.ActiveCfg = Release|x64
+		{6EA952F0-104E-4EBA-8AAE-C059F036EB89}.Release|x64.Build.0 = Release|x64
+		{6EA952F0-104E-4EBA-8AAE-C059F036EB89}.Release|x86.ActiveCfg = Release|Win32
+		{6EA952F0-104E-4EBA-8AAE-C059F036EB89}.Release|x86.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {39D931CF-6772-4D75-A299-9F3C67F5DC12}
+	EndGlobalSection
+EndGlobal

+ 13 - 0
图形学/DirectX学习/src/D3DBox/D3DBox/D3DBox.cpp

@@ -0,0 +1,13 @@
+// D3DBox.cpp : 定义应用程序的入口点。
+//
+
+#include "D3DBox.h"
+#include "D3dApp.h"
+
+int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
+                     _In_opt_ HINSTANCE hPrevInstance,
+                     _In_ LPWSTR    lpCmdLine,
+                     _In_ int       nCmdShow)
+{
+    return 0;
+}

+ 3 - 0
图形学/DirectX学习/src/D3DBox/D3DBox/D3DBox.h

@@ -0,0 +1,3 @@
+#pragma once
+
+#include "resource.h"

BIN
图形学/DirectX学习/src/D3DBox/D3DBox/D3DBox.ico


BIN
图形学/DirectX学习/src/D3DBox/D3DBox/D3DBox.rc


+ 154 - 0
图形学/DirectX学习/src/D3DBox/D3DBox/D3DBox.vcxproj

@@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <VCProjectVersion>17.0</VCProjectVersion>
+    <Keyword>Win32Proj</Keyword>
+    <ProjectGuid>{6ea952f0-104e-4eba-8aae-c059f036eb89}</ProjectGuid>
+    <RootNamespace>D3DBox</RootNamespace>
+    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v143</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v143</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v143</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v143</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="Shared">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClInclude Include="D3dApp.h" />
+    <ClInclude Include="D3DBox.h" />
+    <ClInclude Include="D3DUtil.h" />
+    <ClInclude Include="d3dx12.h" />
+    <ClInclude Include="DDSTextureLoader.h" />
+    <ClInclude Include="framework.h" />
+    <ClInclude Include="MathHelper.h" />
+    <ClInclude Include="Resource.h" />
+    <ClInclude Include="targetver.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="D3dApp.cpp" />
+    <ClCompile Include="D3DBox.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="D3DBox.rc" />
+  </ItemGroup>
+  <ItemGroup>
+    <Image Include="D3DBox.ico" />
+    <Image Include="small.ico" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>

+ 67 - 0
图形学/DirectX学习/src/D3DBox/D3DBox/D3DBox.vcxproj.filters

@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="源文件">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="头文件">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
+    </Filter>
+    <Filter Include="资源文件">
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="framework.h">
+      <Filter>头文件</Filter>
+    </ClInclude>
+    <ClInclude Include="targetver.h">
+      <Filter>头文件</Filter>
+    </ClInclude>
+    <ClInclude Include="Resource.h">
+      <Filter>头文件</Filter>
+    </ClInclude>
+    <ClInclude Include="D3DBox.h">
+      <Filter>头文件</Filter>
+    </ClInclude>
+    <ClInclude Include="D3dApp.h">
+      <Filter>头文件</Filter>
+    </ClInclude>
+    <ClInclude Include="DDSTextureLoader.h">
+      <Filter>头文件</Filter>
+    </ClInclude>
+    <ClInclude Include="D3DUtil.h">
+      <Filter>头文件</Filter>
+    </ClInclude>
+    <ClInclude Include="MathHelper.h">
+      <Filter>头文件</Filter>
+    </ClInclude>
+    <ClInclude Include="d3dx12.h">
+      <Filter>头文件</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="D3DBox.cpp">
+      <Filter>源文件</Filter>
+    </ClCompile>
+    <ClCompile Include="D3dApp.cpp">
+      <Filter>源文件</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="D3DBox.rc">
+      <Filter>资源文件</Filter>
+    </ResourceCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <Image Include="small.ico">
+      <Filter>资源文件</Filter>
+    </Image>
+    <Image Include="D3DBox.ico">
+      <Filter>资源文件</Filter>
+    </Image>
+  </ItemGroup>
+</Project>

+ 6 - 0
图形学/DirectX学习/src/D3DBox/D3DBox/D3DBox.vcxproj.user

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <ShowAllFiles>false</ShowAllFiles>
+  </PropertyGroup>
+</Project>

+ 288 - 0
图形学/DirectX学习/src/D3DBox/D3DBox/D3DUtil.h

@@ -0,0 +1,288 @@
+//***************************************************************************************
+// d3dUtil.h by Frank Luna (C) 2015 All Rights Reserved.
+//
+// General helper code.
+//***************************************************************************************
+
+#pragma once
+
+#include <windows.h>
+#include <wrl.h>
+#include <dxgi1_4.h>
+#include <d3d12.h>
+#include <D3Dcompiler.h>
+#include <DirectXMath.h>
+#include <DirectXPackedVector.h>
+#include <DirectXColors.h>
+#include <DirectXCollision.h>
+#include <string>
+#include <memory>
+#include <algorithm>
+#include <vector>
+#include <array>
+#include <unordered_map>
+#include <cstdint>
+#include <fstream>
+#include <sstream>
+#include <cassert>
+#include "d3dx12.h"
+#include "DDSTextureLoader.h"
+#include "MathHelper.h"
+
+extern const int gNumFrameResources;
+
+inline void d3dSetDebugName(IDXGIObject* obj, const char* name)
+{
+    if (obj)
+    {
+        obj->SetPrivateData(WKPDID_D3DDebugObjectName, lstrlenA(name), name);
+    }
+}
+inline void d3dSetDebugName(ID3D12Device* obj, const char* name)
+{
+    if (obj)
+    {
+        obj->SetPrivateData(WKPDID_D3DDebugObjectName, lstrlenA(name), name);
+    }
+}
+inline void d3dSetDebugName(ID3D12DeviceChild* obj, const char* name)
+{
+    if (obj)
+    {
+        obj->SetPrivateData(WKPDID_D3DDebugObjectName, lstrlenA(name), name);
+    }
+}
+
+inline std::wstring AnsiToWString(const std::string& str)
+{
+    WCHAR buffer[512];
+    MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, buffer, 512);
+    return std::wstring(buffer);
+}
+
+/*
+#if defined(_DEBUG)
+    #ifndef Assert
+    #define Assert(x, description)                                  \
+    {                                                               \
+        static bool ignoreAssert = false;                           \
+        if(!ignoreAssert && !(x))                                   \
+        {                                                           \
+            Debug::AssertResult result = Debug::ShowAssertDialog(   \
+            (L#x), description, AnsiToWString(__FILE__), __LINE__); \
+        if(result == Debug::AssertIgnore)                           \
+        {                                                           \
+            ignoreAssert = true;                                    \
+        }                                                           \
+                    else if(result == Debug::AssertBreak)           \
+        {                                                           \
+            __debugbreak();                                         \
+        }                                                           \
+        }                                                           \
+    }
+    #endif
+#else
+    #ifndef Assert
+    #define Assert(x, description)
+    #endif
+#endif
+    */
+
+class d3dUtil
+{
+public:
+
+    static bool IsKeyDown(int vkeyCode);
+
+    static std::string ToString(HRESULT hr);
+
+    static UINT CalcConstantBufferByteSize(UINT byteSize)
+    {
+        // Constant buffers must be a multiple of the minimum hardware
+        // allocation size (usually 256 bytes).  So round up to nearest
+        // multiple of 256.  We do this by adding 255 and then masking off
+        // the lower 2 bytes which store all bits < 256.
+        // Example: Suppose byteSize = 300.
+        // (300 + 255) & ~255
+        // 555 & ~255
+        // 0x022B & ~0x00ff
+        // 0x022B & 0xff00
+        // 0x0200
+        // 512
+        return (byteSize + 255) & ~255;
+    }
+
+    static Microsoft::WRL::ComPtr<ID3DBlob> LoadBinary(const std::wstring& filename);
+
+    static Microsoft::WRL::ComPtr<ID3D12Resource> CreateDefaultBuffer(
+        ID3D12Device* device,
+        ID3D12GraphicsCommandList* cmdList,
+        const void* initData,
+        UINT64 byteSize,
+        Microsoft::WRL::ComPtr<ID3D12Resource>& uploadBuffer);
+
+    static Microsoft::WRL::ComPtr<ID3DBlob> CompileShader(
+        const std::wstring& filename,
+        const D3D_SHADER_MACRO* defines,
+        const std::string& entrypoint,
+        const std::string& target);
+};
+
+class DxException
+{
+public:
+    DxException() = default;
+    DxException(HRESULT hr, const std::wstring& functionName, const std::wstring& filename, int lineNumber);
+
+    std::wstring ToString()const;
+
+    HRESULT ErrorCode = S_OK;
+    std::wstring FunctionName;
+    std::wstring Filename;
+    int LineNumber = -1;
+};
+
+// Defines a subrange of geometry in a MeshGeometry.  This is for when multiple
+// geometries are stored in one vertex and index buffer.  It provides the offsets
+// and data needed to draw a subset of geometry stores in the vertex and index 
+// buffers so that we can implement the technique described by Figure 6.3.
+struct SubmeshGeometry
+{
+    UINT IndexCount = 0;
+    UINT StartIndexLocation = 0;
+    INT BaseVertexLocation = 0;
+
+    // Bounding box of the geometry defined by this submesh. 
+    // This is used in later chapters of the book.
+    DirectX::BoundingBox Bounds;
+};
+
+struct MeshGeometry
+{
+    // Give it a name so we can look it up by name.
+    std::string Name;
+
+    // System memory copies.  Use Blobs because the vertex/index format can be generic.
+    // It is up to the client to cast appropriately.  
+    Microsoft::WRL::ComPtr<ID3DBlob> VertexBufferCPU = nullptr;
+    Microsoft::WRL::ComPtr<ID3DBlob> IndexBufferCPU = nullptr;
+
+    Microsoft::WRL::ComPtr<ID3D12Resource> VertexBufferGPU = nullptr;
+    Microsoft::WRL::ComPtr<ID3D12Resource> IndexBufferGPU = nullptr;
+
+    Microsoft::WRL::ComPtr<ID3D12Resource> VertexBufferUploader = nullptr;
+    Microsoft::WRL::ComPtr<ID3D12Resource> IndexBufferUploader = nullptr;
+
+    // Data about the buffers.
+    UINT VertexByteStride = 0;
+    UINT VertexBufferByteSize = 0;
+    DXGI_FORMAT IndexFormat = DXGI_FORMAT_R16_UINT;
+    UINT IndexBufferByteSize = 0;
+
+    // A MeshGeometry may store multiple geometries in one vertex/index buffer.
+    // Use this container to define the Submesh geometries so we can draw
+    // the Submeshes individually.
+    std::unordered_map<std::string, SubmeshGeometry> DrawArgs;
+
+    D3D12_VERTEX_BUFFER_VIEW VertexBufferView()const
+    {
+        D3D12_VERTEX_BUFFER_VIEW vbv;
+        vbv.BufferLocation = VertexBufferGPU->GetGPUVirtualAddress();
+        vbv.StrideInBytes = VertexByteStride;
+        vbv.SizeInBytes = VertexBufferByteSize;
+
+        return vbv;
+    }
+
+    D3D12_INDEX_BUFFER_VIEW IndexBufferView()const
+    {
+        D3D12_INDEX_BUFFER_VIEW ibv;
+        ibv.BufferLocation = IndexBufferGPU->GetGPUVirtualAddress();
+        ibv.Format = IndexFormat;
+        ibv.SizeInBytes = IndexBufferByteSize;
+
+        return ibv;
+    }
+
+    // We can free this memory after we finish upload to the GPU.
+    void DisposeUploaders()
+    {
+        VertexBufferUploader = nullptr;
+        IndexBufferUploader = nullptr;
+    }
+};
+
+struct Light
+{
+    DirectX::XMFLOAT3 Strength = { 0.5f, 0.5f, 0.5f };
+    float FalloffStart = 1.0f;                          // point/spot light only
+    DirectX::XMFLOAT3 Direction = { 0.0f, -1.0f, 0.0f };// directional/spot light only
+    float FalloffEnd = 10.0f;                           // point/spot light only
+    DirectX::XMFLOAT3 Position = { 0.0f, 0.0f, 0.0f };  // point/spot light only
+    float SpotPower = 64.0f;                            // spot light only
+};
+
+#define MaxLights 16
+
+struct MaterialConstants
+{
+    DirectX::XMFLOAT4 DiffuseAlbedo = { 1.0f, 1.0f, 1.0f, 1.0f };
+    DirectX::XMFLOAT3 FresnelR0 = { 0.01f, 0.01f, 0.01f };
+    float Roughness = 0.25f;
+
+    // Used in texture mapping.
+    DirectX::XMFLOAT4X4 MatTransform = MathHelper::Identity4x4();
+};
+
+// Simple struct to represent a material for our demos.  A production 3D engine
+// would likely create a class hierarchy of Materials.
+struct Material
+{
+    // Unique material name for lookup.
+    std::string Name;
+
+    // Index into constant buffer corresponding to this material.
+    int MatCBIndex = -1;
+
+    // Index into SRV heap for diffuse texture.
+    int DiffuseSrvHeapIndex = -1;
+
+    // Index into SRV heap for normal texture.
+    int NormalSrvHeapIndex = -1;
+
+    // Dirty flag indicating the material has changed and we need to update the constant buffer.
+    // Because we have a material constant buffer for each FrameResource, we have to apply the
+    // update to each FrameResource.  Thus, when we modify a material we should set 
+    // NumFramesDirty = gNumFrameResources so that each frame resource gets the update.
+    int NumFramesDirty = gNumFrameResources;
+
+    // Material constant buffer data used for shading.
+    DirectX::XMFLOAT4 DiffuseAlbedo = { 1.0f, 1.0f, 1.0f, 1.0f };
+    DirectX::XMFLOAT3 FresnelR0 = { 0.01f, 0.01f, 0.01f };
+    float Roughness = .25f;
+    DirectX::XMFLOAT4X4 MatTransform = MathHelper::Identity4x4();
+};
+
+struct Texture
+{
+    // Unique material name for lookup.
+    std::string Name;
+
+    std::wstring Filename;
+
+    Microsoft::WRL::ComPtr<ID3D12Resource> Resource = nullptr;
+    Microsoft::WRL::ComPtr<ID3D12Resource> UploadHeap = nullptr;
+};
+
+#ifndef ThrowIfFailed
+#define ThrowIfFailed(x)                                              \
+{                                                                     \
+    HRESULT hr__ = (x);                                               \
+    std::wstring wfn = AnsiToWString(__FILE__);                       \
+    if(FAILED(hr__)) { throw DxException(hr__, L#x, wfn, __LINE__); } \
+}
+#endif
+
+#ifndef ReleaseCom
+#define ReleaseCom(x) { if(x){ x->Release(); x = 0; } }
+#endif

+ 368 - 0
图形学/DirectX学习/src/D3DBox/D3DBox/D3dApp.cpp

@@ -0,0 +1,368 @@
+#include "D3dApp.h"
+#include <Windows.h>
+
+using Microsoft::WRL::ComPtr;
+using namespace std;
+using namespace DirectX;
+
+LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+    // 转发窗口消息
+	return D3DApp::GetApp()->MsgProc(hwnd, msg, wParam, lParam);
+}
+
+D3DApp* D3DApp::mApp = nullptr;
+
+D3DApp::D3DApp(HINSTANCE hInstance)
+{
+	mhAppInst = hInstance;
+
+    // 单例模式 禁止各种方式创建第二个
+	assert(mApp == nullptr);
+    mApp = this;
+}
+
+D3DApp::~D3DApp()
+{
+    if (md3dDevice != nullptr) {
+        FlushCommandQueue();    // 清空 GPU 命令
+    }
+}
+
+D3DApp* D3DApp::GetApp()
+{
+	return mApp;
+}
+
+HINSTANCE D3DApp::AppInst() const
+{
+    return mhAppInst;
+}
+
+HWND D3DApp::MainWnd() const
+{
+    return mhMainWnd;
+}
+
+float D3DApp::AspectRatio() const
+{
+    return mClientWidth * 1.0f / mClientHeight;
+}
+
+bool D3DApp::Get4xMassState()
+{
+    return m4xMsaaState;
+}
+
+void D3DApp::Set4XMassState(bool Value)
+{
+	if (m4xMsaaState != Value)
+	{
+		m4xMsaaState = Value;
+
+		CreateSwapChain();
+		OnResize();
+	}
+}
+
+int D3DApp::Run()
+{
+    return 0;
+}
+
+bool D3DApp::Initialize()
+{
+    if (!InitMainWindow()) {
+        return false;
+    }
+
+    if (!InitDirect3D()) {
+        return false;
+    }
+
+    OnResize();
+
+    return true;
+}
+
+LRESULT D3DApp::MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+    switch (msg)
+    {
+    default:
+        break;
+    }
+    return DefWindowProc(hWnd, msg, wParam, lParam);
+}
+
+void D3DApp::CreateRtvAndDsvDescriptorHeaps()
+{
+	D3D12_DESCRIPTOR_HEAP_DESC rtvHeapDesc;
+	rtvHeapDesc.NumDescriptors = SwapChainBufferCount;
+	rtvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
+	rtvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
+	rtvHeapDesc.NodeMask = 0;
+	ThrowIfFailed(md3dDevice->CreateDescriptorHeap(
+		&rtvHeapDesc, IID_PPV_ARGS(mRtvHeap.GetAddressOf())));
+
+
+	D3D12_DESCRIPTOR_HEAP_DESC dsvHeapDesc;
+	dsvHeapDesc.NumDescriptors = 1;
+	dsvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV;
+	dsvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
+	dsvHeapDesc.NodeMask = 0;
+	ThrowIfFailed(md3dDevice->CreateDescriptorHeap(
+		&dsvHeapDesc, IID_PPV_ARGS(mDsvHeap.GetAddressOf())));
+}
+
+void D3DApp::OnResize()
+{
+}
+
+// 基本流程: 注册、创建、展示、更新
+bool D3DApp::InitMainWindow()
+{
+	WNDCLASS wc;
+	wc.style = CS_HREDRAW | CS_VREDRAW;
+	wc.lpfnWndProc = MainWndProc;
+	wc.cbClsExtra = 0;
+	wc.cbWndExtra = 0;
+	wc.hInstance = mhAppInst;
+	wc.hIcon = LoadIcon(0, IDI_APPLICATION);
+	wc.hCursor = LoadCursor(0, IDC_ARROW);
+	wc.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);
+	wc.lpszMenuName = 0;
+	wc.lpszClassName = L"MainWnd";
+
+	if (!RegisterClass(&wc))
+	{
+		MessageBox(0, L"RegisterClass Failed.", 0, 0);
+		return false;
+	}
+
+	RECT R = { 0, 0, mClientWidth, mClientHeight };
+	AdjustWindowRect(&R, WS_OVERLAPPEDWINDOW, false);
+	int width = R.right - R.left;
+	int height = R.bottom - R.top;
+
+	mhMainWnd = CreateWindow(L"MainWnd", mMainWndCaption.c_str(), 
+		WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, width, height, 0, 0, mhAppInst, 0);
+
+	if (!mhMainWnd) {
+		MessageBox(0, L"RegisterClass Failed.", 0, 0);
+		return false;
+	}
+
+	ShowWindow(mhMainWnd, SW_SHOW);
+	UpdateWindow(mhMainWnd);	// 迫使系统立即处理那些已经在消息队列中的绘制消息,确保窗口首次创建之后,会被立即正确绘制
+
+    return true;
+}
+
+bool D3DApp::InitDirect3D()
+{
+#if defined(DEBUG) || defined(_DEBUG)
+	{
+		ComPtr<ID3D12Debug> debugController;
+		ThrowIfFailed(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController)));
+		debugController->EnableDebugLayer();
+	}
+#endif
+
+	// 创建 DXGI 
+	ThrowIfFailed(CreateDXGIFactory1(IID_PPV_ARGS(&mdxgiFactory)));
+
+	// 获得光栅器
+	HRESULT hardwareResult = D3D12CreateDevice(nullptr, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&md3dDevice));
+	if (FAILED(hardwareResult)) {
+		ComPtr<IDXGIAdapter> pWarpAdapter;
+		ThrowIfFailed(mdxgiFactory->EnumWarpAdapter(IID_PPV_ARGS(&pWarpAdapter)));
+		ThrowIfFailed(D3D12CreateDevice(pWarpAdapter.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&md3dDevice)));
+	}
+
+	// 创建围栏
+	ThrowIfFailed(md3dDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&mFence)));
+
+	// 存储描述符大小
+	mRtvDescriptorSize = md3dDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
+	mDsvDescriptorSize = md3dDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_DSV);
+	mCbvSrvUavDescriptorSize = md3dDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
+
+	// 设置 4x 多重采样 
+	D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS msQualityLevels;
+	msQualityLevels.Format = mBackBufferFormat;
+	msQualityLevels.SampleCount = 4;
+	msQualityLevels.Flags = D3D12_MULTISAMPLE_QUALITY_LEVELS_FLAG_NONE;
+	msQualityLevels.NumQualityLevels = 0;
+	ThrowIfFailed(md3dDevice->CheckFeatureSupport(D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS, &msQualityLevels, sizeof(msQualityLevels)));
+
+	m4xMsaaQuality = msQualityLevels.NumQualityLevels;
+	assert(m4xMsaaQuality > 0 && "Unexpected MSAA quality level.");
+
+#ifdef _DEBUG
+	LogAdapters();
+#endif // _DEBUG
+
+
+	CreateCommandObjects();
+	CreateSwapChain();
+	CreateRtvAndDsvDescriptorHeaps();
+
+    return false;
+}
+
+void D3DApp::CreateCommandObjects()
+{
+	D3D12_COMMAND_QUEUE_DESC queueDesc = {};
+	queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
+	queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
+	ThrowIfFailed(md3dDevice->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&mCommandQueue)));
+
+	ThrowIfFailed(md3dDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&mCommandAllocator)));
+
+	ThrowIfFailed(md3dDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, mCommandAllocator.Get(), nullptr, IID_PPV_ARGS(&mCommandList)));
+
+	mCommandList->Close();
+}
+
+void D3DApp::CreateSwapChain()
+{
+	mSwapChain.Reset();
+
+	DXGI_SWAP_CHAIN_DESC sd;
+	sd.BufferCount = SwapChainBufferCount;
+	sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
+	sd.BufferDesc.Width = mClientWidth;
+	sd.BufferDesc.Height = mClientHeight;
+	sd.BufferDesc.RefreshRate.Denominator = 1;
+	sd.BufferDesc.RefreshRate.Numerator = 60;
+	sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
+	sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
+	sd.BufferDesc.Format = mBackBufferFormat;
+	sd.SampleDesc.Count = m4xMsaaState ? 4 : 1;
+	sd.SampleDesc.Quality = m4xMsaaState ? (m4xMsaaQuality - 1) : 0;
+	sd.OutputWindow = mhMainWnd;
+	sd.Windowed = true;
+	sd.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
+	sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
+
+	ThrowIfFailed(mdxgiFactory->CreateSwapChain(md3dDevice.Get(), &sd, mSwapChain.GetAddressOf()));
+}
+
+void D3DApp::FlushCommandQueue()
+{
+	mCurrentFence++;
+
+	// 发送一个信号到命令队列。当GPU处理到这一点时,它会将围栏对象 mFence 的值设置为 mCurrentFence。这样可以确保所有先前提交的命令都已经被GPU处理完毕
+	mCommandQueue->Signal(mFence.Get(), mCurrentFence);
+
+	if (mFence->GetCompletedValue() < mCurrentFence) {
+		// 创建一个事件对象,这个事件用于等待围栏信号的完成
+		HANDLE eventHandl = CreateEventEx(nullptr, false, false, EVENT_ALL_ACCESS);
+
+		// 为围栏设置一个完成事件。当围栏达到指定的 mCurrentFence 值时,eventHandl 事件会被设置为信号状态
+		ThrowIfFailed(mFence->SetEventOnCompletion(mCurrentFence, eventHandl));
+
+		// 等待事件对象变为信号状态
+		WaitForSingleObject(eventHandl, INFINITE);
+
+		// 关闭事件句柄,释放系统资源
+		CloseHandle(eventHandl);
+	}
+}
+
+ID3D12Resource* D3DApp::CurrentBackBuffer() const
+{
+	return mSwapChainBuffer[mCurrentBackBuffer].Get();
+}
+
+D3D12_CPU_DESCRIPTOR_HANDLE D3DApp::CurrentBackBufferView() const
+{
+	return CD3DX12_CPU_DESCRIPTOR_HANDLE(
+		mRtvHeap->GetCPUDescriptorHandleForHeapStart(),
+		mCurrentBackBuffer,
+		mRtvDescriptorSize);
+}
+
+D3D12_CPU_DESCRIPTOR_HANDLE D3DApp::DepthStencilView() const
+{
+	return mDsvHeap->GetCPUDescriptorHandleForHeapStart();
+}
+
+void D3DApp::CalculateFrameState()
+{
+}
+
+void D3DApp::LogAdapters()
+{
+	UINT i = 0;
+	IDXGIAdapter* adapter = nullptr;
+	std::vector<IDXGIAdapter*> adapterList;
+	while (mdxgiFactory->EnumAdapters(i, &adapter) != DXGI_ERROR_NOT_FOUND)
+	{
+		DXGI_ADAPTER_DESC desc;
+		adapter->GetDesc(&desc);
+
+		std::wstring text = L"*** Adapter";
+		text += desc.Description;
+		text += L"\n";
+
+		OutputDebugString(text.c_str());
+		adapterList.push_back(adapter);
+
+		++i;
+	}
+
+	for (size_t index = 0; index < adapterList.size(); ++index)
+	{
+		LogAdapterOutputs(adapterList[index]);
+		ReleaseCom(adapterList[index]);
+	}
+}
+
+void D3DApp::LogAdapterOutputs(IDXGIAdapter* adapter)
+{
+	UINT i = 0;
+	IDXGIOutput* output = nullptr;
+	while (adapter->EnumOutputs(i, &output) != DXGI_ERROR_NOT_FOUND)
+	{
+		DXGI_OUTPUT_DESC desc;
+		output->GetDesc(&desc);
+
+		std::wstring text = L"***Output: ";
+		text += desc.DeviceName;
+		text += L"\n";
+		OutputDebugString(text.c_str());
+
+		LogOutputDisplayMode(output, mBackBufferFormat);
+
+		ReleaseCom(output);
+
+		++i;
+	}
+}
+
+void D3DApp::LogOutputDisplayMode(IDXGIOutput* output, DXGI_FORMAT format)
+{
+	UINT count = 0;
+	UINT flags = 0;
+
+	// Call with nullptr to get list count.
+	output->GetDisplayModeList(format, flags, &count, nullptr);
+
+	std::vector<DXGI_MODE_DESC> modeList(count);
+	output->GetDisplayModeList(format, flags, &count, &modeList[0]);
+
+	for (auto& x : modeList)
+	{
+		UINT n = x.RefreshRate.Numerator;
+		UINT d = x.RefreshRate.Denominator;
+		std::wstring text =
+			L"Width = " + std::to_wstring(x.Width) + L" " +
+			L"Height = " + std::to_wstring(x.Height) + L" " +
+			L"Refresh = " + std::to_wstring(n) + L"/" + std::to_wstring(d) +
+			L"\n";
+
+		::OutputDebugString(text.c_str());
+	}
+}

+ 123 - 0
图形学/DirectX学习/src/D3DBox/D3DBox/D3dApp.h

@@ -0,0 +1,123 @@
+#pragma once
+
+#if defined(DEBUG) || defined(_DEBUG)
+#define _CRTDBG_MAP_ALLOC
+#include <crtdbg.h>
+#endif
+
+#include "d3dUtil.h"
+//#include "GameTimer.h"
+
+// Link necessary d3d12 libraries.
+#pragma comment(lib,"d3dcompiler.lib")
+#pragma comment(lib, "D3D12.lib")
+#pragma comment(lib, "dxgi.lib")
+
+class GameTimer;
+
+class D3DApp
+{
+protected:
+	D3DApp(HINSTANCE hInstance);
+	D3DApp(const D3DApp& rhs) = delete;
+	D3DApp& operator=(const D3DApp& rhs) = delete;
+	virtual ~D3DApp();
+
+public:
+	static D3DApp* GetApp();
+
+	HINSTANCE	AppInst() const;
+	HWND		MainWnd() const;
+	float		AspectRatio() const;			// 纵横比
+
+	bool		Get4xMassState();				// 是否开启 4xMass 多重采样
+	void		Set4XMassState(bool Value);		// 设置多重采样的开关
+
+	int			Run();							// 初始化完毕之后执行
+
+	virtual bool Initialize();					// 初始化窗口和D3D
+	virtual LRESULT MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);		// 窗口消息触发函数
+
+protected:
+	virtual void CreateRtvAndDsvDescriptorHeaps();	// 创建 RTV 和 DSV 的堆描述符
+	virtual void OnResize();						// 窗口重新设置大小是调用
+	virtual void Update(const GameTimer& gt) = 0;	// 每帧更新逻辑
+	virtual void Draw(const GameTimer& gt) = 0;		// 每帧绘制
+
+	virtual void OnMouseDown(WPARAM btnState, int x, int y) {}	// 鼠标点击事件
+	virtual void OnMouseUp(WPARAM btnState, int x, int y) {}	// 鼠标松开事件
+	virtual void OnMouseMove(WPARAM btnStae, int x, int y) {}	// 鼠标移动事件
+
+protected:
+
+	bool InitMainWindow();							// 初始化窗口
+	bool InitDirect3D();							// 初始化 D3D
+	
+	void CreateCommandObjects();					// 创建命令队列、分配器、列表
+	void CreateSwapChain();							// 创建交换链
+	
+	void FlushCommandQueue();						// 等待清空命令列表命令
+
+	ID3D12Resource* CurrentBackBuffer() const;		// 当前交换链中的后台缓冲区
+	D3D12_CPU_DESCRIPTOR_HANDLE CurrentBackBufferView() const;	// 当前交换链中后台缓冲区视图
+	D3D12_CPU_DESCRIPTOR_HANDLE DepthStencilView() const;		// 当前深度模板视图
+
+	void CalculateFrameState();						// 计算当前帧状态
+	
+	void LogAdapters();								// 输出所有适配器
+	void LogAdapterOutputs(IDXGIAdapter* adapter);	// 输出指定适配器信息
+	void LogOutputDisplayMode(IDXGIOutput* output, DXGI_FORMAT format);	// 根据指定颜色格式输出显卡信息
+
+protected:
+	static D3DApp* mApp;
+
+	HINSTANCE	mhAppInst = nullptr;
+	HWND		mhMainWnd = nullptr;
+	bool		mAppPaused = false;		// 当前程序是否被暂停
+	bool		mMinimized = false;		// 当前程序是否最小化
+	bool		mMaximized = false;		// 当前程序是否最大化
+	bool		mResizing = false;		// 当前程序正在重新设置大小
+	bool		mFullscreenState = false;	// 当前程序是否全屏状态
+
+	bool		m4xMsaaState = false;	// 是否开启4x多重采样
+	UINT		m4xMsaaQuality = 0;		// 多重采样质量
+
+	//GameTimer	mTimer;					// 时间计时器
+
+	Microsoft::WRL::ComPtr<IDXGIFactory4> mdxgiFactory;	// DXGI 工厂
+	Microsoft::WRL::ComPtr<IDXGISwapChain> mSwapChain;	// 交换链
+	Microsoft::WRL::ComPtr<ID3D12Device> md3dDevice;	// 设备
+
+	Microsoft::WRL::ComPtr<ID3D12Fence>	mFence;			// 围栏
+	UINT64 mCurrentFence = 0;							// 围栏序号
+
+
+	Microsoft::WRL::ComPtr<ID3D12CommandQueue>	mCommandQueue;	// 命令队列
+	Microsoft::WRL::ComPtr<ID3D12CommandAllocator> mCommandAllocator;	// 命令内存分配器
+	Microsoft::WRL::ComPtr<ID3D12GraphicsCommandList>	mCommandList;	// 命令列表
+
+	static const int SwapChainBufferCount = 2;			// 渲染缓冲个数 这里表示使用双缓冲
+	int mCurrentBackBuffer = 0;							// 当前后台缓冲的序号
+	
+	Microsoft::WRL::ComPtr<ID3D12Resource> mSwapChainBuffer[SwapChainBufferCount];	// 双缓冲
+	Microsoft::WRL::ComPtr<ID3D12Resource> mDepthStencilBuffer;		// 深度缓冲
+
+	Microsoft::WRL::ComPtr<ID3D12DescriptorHeap> mRtvHeap;	// Render Target View 描述符堆
+	Microsoft::WRL::ComPtr<ID3D12DescriptorHeap> mDsvHeap;	// Depth Stencil View 描述符堆
+
+	D3D12_VIEWPORT mScreenViewport;							// 视口,定义了渲染到屏幕的区域
+	D3D12_RECT mScissorRect;								// 剪裁矩形,定义了在视口内可见的矩形区域
+
+	UINT mRtvDescriptorSize = 0;							// Rtv 描述符大小 不同平台有所不同
+	UINT mDsvDescriptorSize = 0;							// Dsv 描述符大小
+	UINT mCbvSrvUavDescriptorSize = 0;						// Cbv Srv Uav 描述符大小
+
+	std::wstring mMainWndCaption = L"d3d App";							// 主窗口标题
+	D3D_DRIVER_TYPE md3dDriverType = D3D_DRIVER_TYPE_HARDWARE;			// Direct3D 驱动类型,通常是硬件加速
+	DXGI_FORMAT mBackBufferFormat = DXGI_FORMAT_R8G8B8A8_UNORM;			// 后台缓冲区的像素格式
+	DXGI_FORMAT mDepthStencilFormat = DXGI_FORMAT_D24_UNORM_S8_UINT;	// 深度模板缓冲区的格式
+	
+	int mClientWidth = 800;
+	int mClientHeight = 600;
+};
+

+ 172 - 0
图形学/DirectX学习/src/D3DBox/D3DBox/DDSTextureLoader.h

@@ -0,0 +1,172 @@
+//--------------------------------------------------------------------------------------
+// File: DDSTextureLoader.h
+//
+// Functions for loading a DDS texture and creating a Direct3D 11 runtime resource for it
+//
+// Note these functions are useful as a light-weight runtime loader for DDS files. For
+// a full-featured DDS file reader, writer, and texture processing pipeline see
+// the 'Texconv' sample and the 'DirectXTex' library.
+//
+// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
+// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
+// PARTICULAR PURPOSE.
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// http://go.microsoft.com/fwlink/?LinkId=248926
+// http://go.microsoft.com/fwlink/?LinkId=248929
+//--------------------------------------------------------------------------------------
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <wrl.h>
+#include <d3d11_1.h>
+#include "d3dx12.h"
+
+#pragma warning(push)
+#pragma warning(disable : 4005)
+#include <stdint.h>
+
+#pragma warning(pop)
+
+#if defined(_MSC_VER) && (_MSC_VER<1610) && !defined(_In_reads_)
+#define _In_reads_(exp)
+#define _Out_writes_(exp)
+#define _In_reads_bytes_(exp)
+#define _In_reads_opt_(exp)
+#define _Outptr_opt_
+#endif
+
+#ifndef _Use_decl_annotations_
+#define _Use_decl_annotations_
+#endif
+
+namespace DirectX
+{
+	enum DDS_ALPHA_MODE
+	{
+		DDS_ALPHA_MODE_UNKNOWN = 0,
+		DDS_ALPHA_MODE_STRAIGHT = 1,
+		DDS_ALPHA_MODE_PREMULTIPLIED = 2,
+		DDS_ALPHA_MODE_OPAQUE = 3,
+		DDS_ALPHA_MODE_CUSTOM = 4,
+	};
+
+	// Standard version
+	HRESULT CreateDDSTextureFromMemory(_In_ ID3D11Device* d3dDevice,
+		_In_reads_bytes_(ddsDataSize) const uint8_t* ddsData,
+		_In_ size_t ddsDataSize,
+		_Outptr_opt_ ID3D11Resource** texture,
+		_Outptr_opt_ ID3D11ShaderResourceView** textureView,
+		_In_ size_t maxsize = 0,
+		_Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr
+	);
+
+	HRESULT CreateDDSTextureFromMemory12(_In_ ID3D12Device* device,
+		_In_ ID3D12GraphicsCommandList* cmdList,
+		_In_reads_bytes_(ddsDataSize) const uint8_t* ddsData,
+		_In_ size_t ddsDataSize,
+		_Out_ Microsoft::WRL::ComPtr<ID3D12Resource>& texture,
+		_Out_ Microsoft::WRL::ComPtr<ID3D12Resource>& textureUploadHeap,
+		_In_ size_t maxsize = 0,
+		_Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr
+	);
+
+	HRESULT CreateDDSTextureFromFile(_In_ ID3D11Device* d3dDevice,
+		_In_z_ const wchar_t* szFileName,
+		_Outptr_opt_ ID3D11Resource** texture,
+		_Outptr_opt_ ID3D11ShaderResourceView** textureView,
+		_In_ size_t maxsize = 0,
+		_Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr
+	);
+
+	HRESULT CreateDDSTextureFromFile12(_In_ ID3D12Device* device,
+		_In_ ID3D12GraphicsCommandList* cmdList,
+		_In_z_ const wchar_t* szFileName,
+		_Out_ Microsoft::WRL::ComPtr<ID3D12Resource>& texture,
+		_Out_ Microsoft::WRL::ComPtr<ID3D12Resource>& textureUploadHeap,
+		_In_ size_t maxsize = 0,
+		_Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr
+	);
+
+	// Standard version with optional auto-gen mipmap support
+	HRESULT CreateDDSTextureFromMemory(_In_ ID3D11Device* d3dDevice,
+		_In_opt_ ID3D11DeviceContext* d3dContext,
+		_In_reads_bytes_(ddsDataSize) const uint8_t* ddsData,
+		_In_ size_t ddsDataSize,
+		_Outptr_opt_ ID3D11Resource** texture,
+		_Outptr_opt_ ID3D11ShaderResourceView** textureView,
+		_In_ size_t maxsize = 0,
+		_Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr
+	);
+
+	HRESULT CreateDDSTextureFromFile(_In_ ID3D11Device* d3dDevice,
+		_In_opt_ ID3D11DeviceContext* d3dContext,
+		_In_z_ const wchar_t* szFileName,
+		_Outptr_opt_ ID3D11Resource** texture,
+		_Outptr_opt_ ID3D11ShaderResourceView** textureView,
+		_In_ size_t maxsize = 0,
+		_Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr
+	);
+
+	// Extended version
+	HRESULT CreateDDSTextureFromMemoryEx(_In_ ID3D11Device* d3dDevice,
+		_In_reads_bytes_(ddsDataSize) const uint8_t* ddsData,
+		_In_ size_t ddsDataSize,
+		_In_ size_t maxsize,
+		_In_ D3D11_USAGE usage,
+		_In_ unsigned int bindFlags,
+		_In_ unsigned int cpuAccessFlags,
+		_In_ unsigned int miscFlags,
+		_In_ bool forceSRGB,
+		_Outptr_opt_ ID3D11Resource** texture,
+		_Outptr_opt_ ID3D11ShaderResourceView** textureView,
+		_Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr
+	);
+
+	HRESULT CreateDDSTextureFromFileEx(_In_ ID3D11Device* d3dDevice,
+		_In_z_ const wchar_t* szFileName,
+		_In_ size_t maxsize,
+		_In_ D3D11_USAGE usage,
+		_In_ unsigned int bindFlags,
+		_In_ unsigned int cpuAccessFlags,
+		_In_ unsigned int miscFlags,
+		_In_ bool forceSRGB,
+		_Outptr_opt_ ID3D11Resource** texture,
+		_Outptr_opt_ ID3D11ShaderResourceView** textureView,
+		_Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr
+	);
+
+	// Extended version with optional auto-gen mipmap support
+	HRESULT CreateDDSTextureFromMemoryEx(_In_ ID3D11Device* d3dDevice,
+		_In_opt_ ID3D11DeviceContext* d3dContext,
+		_In_reads_bytes_(ddsDataSize) const uint8_t* ddsData,
+		_In_ size_t ddsDataSize,
+		_In_ size_t maxsize,
+		_In_ D3D11_USAGE usage,
+		_In_ unsigned int bindFlags,
+		_In_ unsigned int cpuAccessFlags,
+		_In_ unsigned int miscFlags,
+		_In_ bool forceSRGB,
+		_Outptr_opt_ ID3D11Resource** texture,
+		_Outptr_opt_ ID3D11ShaderResourceView** textureView,
+		_Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr
+	);
+
+	HRESULT CreateDDSTextureFromFileEx(_In_ ID3D11Device* d3dDevice,
+		_In_opt_ ID3D11DeviceContext* d3dContext,
+		_In_z_ const wchar_t* szFileName,
+		_In_ size_t maxsize,
+		_In_ D3D11_USAGE usage,
+		_In_ unsigned int bindFlags,
+		_In_ unsigned int cpuAccessFlags,
+		_In_ unsigned int miscFlags,
+		_In_ bool forceSRGB,
+		_Outptr_opt_ ID3D11Resource** texture,
+		_Outptr_opt_ ID3D11ShaderResourceView** textureView,
+		_Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr
+	);
+}

+ 100 - 0
图形学/DirectX学习/src/D3DBox/D3DBox/MathHelper.h

@@ -0,0 +1,100 @@
+//***************************************************************************************
+// MathHelper.h by Frank Luna (C) 2011 All Rights Reserved.
+//
+// Helper math class.
+//***************************************************************************************
+
+#pragma once
+
+#include <Windows.h>
+#include <DirectXMath.h>
+#include <cstdint>
+
+class MathHelper
+{
+public:
+	// Returns random float in [0, 1).
+	static float RandF()
+	{
+		return (float)(rand()) / (float)RAND_MAX;
+	}
+
+	// Returns random float in [a, b).
+	static float RandF(float a, float b)
+	{
+		return a + RandF() * (b - a);
+	}
+
+	static int Rand(int a, int b)
+	{
+		return a + rand() % ((b - a) + 1);
+	}
+
+	template<typename T>
+	static T Min(const T& a, const T& b)
+	{
+		return a < b ? a : b;
+	}
+
+	template<typename T>
+	static T Max(const T& a, const T& b)
+	{
+		return a > b ? a : b;
+	}
+
+	template<typename T>
+	static T Lerp(const T& a, const T& b, float t)
+	{
+		return a + (b - a) * t;
+	}
+
+	template<typename T>
+	static T Clamp(const T& x, const T& low, const T& high)
+	{
+		return x < low ? low : (x > high ? high : x);
+	}
+
+	// Returns the polar angle of the point (x,y) in [0, 2*PI).
+	static float AngleFromXY(float x, float y);
+
+	static DirectX::XMVECTOR SphericalToCartesian(float radius, float theta, float phi)
+	{
+		return DirectX::XMVectorSet(
+			radius * sinf(phi) * cosf(theta),
+			radius * cosf(phi),
+			radius * sinf(phi) * sinf(theta),
+			1.0f);
+	}
+
+	static DirectX::XMMATRIX InverseTranspose(DirectX::CXMMATRIX M)
+	{
+		// Inverse-transpose is just applied to normals.  So zero out 
+		// translation row so that it doesn't get into our inverse-transpose
+		// calculation--we don't want the inverse-transpose of the translation.
+		DirectX::XMMATRIX A = M;
+		A.r[3] = DirectX::XMVectorSet(0.0f, 0.0f, 0.0f, 1.0f);
+
+		DirectX::XMVECTOR det = DirectX::XMMatrixDeterminant(A);
+		return DirectX::XMMatrixTranspose(DirectX::XMMatrixInverse(&det, A));
+	}
+
+	static DirectX::XMFLOAT4X4 Identity4x4()
+	{
+		static DirectX::XMFLOAT4X4 I(
+			1.0f, 0.0f, 0.0f, 0.0f,
+			0.0f, 1.0f, 0.0f, 0.0f,
+			0.0f, 0.0f, 1.0f, 0.0f,
+			0.0f, 0.0f, 0.0f, 1.0f);
+
+		return I;
+	}
+
+	static DirectX::XMVECTOR RandUnitVec3();
+	static DirectX::XMVECTOR RandHemisphereUnitVec3(DirectX::XMVECTOR n);
+
+	static const float Infinity;
+	static const float Pi;
+
+
+};
+

+ 30 - 0
图形学/DirectX学习/src/D3DBox/D3DBox/Resource.h

@@ -0,0 +1,30 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ 生成的包含文件。
+// 使用者 D3DBox.rc
+
+#define IDS_APP_TITLE			103
+
+#define IDR_MAINFRAME			128
+#define IDD_D3DBOX_DIALOG	102
+#define IDD_ABOUTBOX			103
+#define IDM_ABOUT				104
+#define IDM_EXIT				105
+#define IDI_D3DBOX			107
+#define IDI_SMALL				108
+#define IDC_D3DBOX			109
+#define IDC_MYICON				2
+#ifndef IDC_STATIC
+#define IDC_STATIC				-1
+#endif
+// 新对象的下一组默认值
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+
+#define _APS_NO_MFC					130
+#define _APS_NEXT_RESOURCE_VALUE	129
+#define _APS_NEXT_COMMAND_VALUE		32771
+#define _APS_NEXT_CONTROL_VALUE		1000
+#define _APS_NEXT_SYMED_VALUE		110
+#endif
+#endif

+ 1532 - 0
图形学/DirectX学习/src/D3DBox/D3DBox/d3dx12.h

@@ -0,0 +1,1532 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+//  Copyright (C) Microsoft Corporation.  All Rights Reserved.
+//
+//  File:       d3dx12.h
+//  Content:    D3DX12 utility library
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef __D3DX12_H__
+#define __D3DX12_H__
+
+#include "d3d12.h"
+
+#if defined( __cplusplus )
+
+struct CD3DX12_DEFAULT {};
+extern const DECLSPEC_SELECTANY CD3DX12_DEFAULT D3D12_DEFAULT;
+
+//------------------------------------------------------------------------------------------------
+inline bool operator==(const D3D12_VIEWPORT& l, const D3D12_VIEWPORT& r)
+{
+	return l.TopLeftX == r.TopLeftX && l.TopLeftY == r.TopLeftY && l.Width == r.Width &&
+		l.Height == r.Height && l.MinDepth == r.MinDepth && l.MaxDepth == r.MaxDepth;
+}
+
+//------------------------------------------------------------------------------------------------
+inline bool operator!=(const D3D12_VIEWPORT& l, const D3D12_VIEWPORT& r)
+{
+	return !(l == r);
+}
+
+//------------------------------------------------------------------------------------------------
+struct CD3DX12_RECT : public D3D12_RECT
+{
+	CD3DX12_RECT()
+	{}
+	explicit CD3DX12_RECT(const D3D12_RECT& o) :
+		D3D12_RECT(o)
+	{}
+	explicit CD3DX12_RECT(
+		LONG Left,
+		LONG Top,
+		LONG Right,
+		LONG Bottom)
+	{
+		left = Left;
+		top = Top;
+		right = Right;
+		bottom = Bottom;
+	}
+	~CD3DX12_RECT() {}
+	operator const D3D12_RECT& () const { return *this; }
+};
+
+//------------------------------------------------------------------------------------------------
+struct CD3DX12_BOX : public D3D12_BOX
+{
+	CD3DX12_BOX()
+	{}
+	explicit CD3DX12_BOX(const D3D12_BOX& o) :
+		D3D12_BOX(o)
+	{}
+	explicit CD3DX12_BOX(
+		LONG Left,
+		LONG Right)
+	{
+		left = Left;
+		top = 0;
+		front = 0;
+		right = Right;
+		bottom = 1;
+		back = 1;
+	}
+	explicit CD3DX12_BOX(
+		LONG Left,
+		LONG Top,
+		LONG Right,
+		LONG Bottom)
+	{
+		left = Left;
+		top = Top;
+		front = 0;
+		right = Right;
+		bottom = Bottom;
+		back = 1;
+	}
+	explicit CD3DX12_BOX(
+		LONG Left,
+		LONG Top,
+		LONG Front,
+		LONG Right,
+		LONG Bottom,
+		LONG Back)
+	{
+		left = Left;
+		top = Top;
+		front = Front;
+		right = Right;
+		bottom = Bottom;
+		back = Back;
+	}
+	~CD3DX12_BOX() {}
+	operator const D3D12_BOX& () const { return *this; }
+};
+inline bool operator==(const D3D12_BOX& l, const D3D12_BOX& r)
+{
+	return l.left == r.left && l.top == r.top && l.front == r.front &&
+		l.right == r.right && l.bottom == r.bottom && l.back == r.back;
+}
+inline bool operator!=(const D3D12_BOX& l, const D3D12_BOX& r)
+{
+	return !(l == r);
+}
+
+//------------------------------------------------------------------------------------------------
+struct CD3DX12_DEPTH_STENCIL_DESC : public D3D12_DEPTH_STENCIL_DESC
+{
+	CD3DX12_DEPTH_STENCIL_DESC()
+	{}
+	explicit CD3DX12_DEPTH_STENCIL_DESC(const D3D12_DEPTH_STENCIL_DESC& o) :
+		D3D12_DEPTH_STENCIL_DESC(o)
+	{}
+	explicit CD3DX12_DEPTH_STENCIL_DESC(CD3DX12_DEFAULT)
+	{
+		DepthEnable = TRUE;
+		DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL;
+		DepthFunc = D3D12_COMPARISON_FUNC_LESS;
+		StencilEnable = FALSE;
+		StencilReadMask = D3D12_DEFAULT_STENCIL_READ_MASK;
+		StencilWriteMask = D3D12_DEFAULT_STENCIL_WRITE_MASK;
+		const D3D12_DEPTH_STENCILOP_DESC defaultStencilOp =
+		{ D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_COMPARISON_FUNC_ALWAYS };
+		FrontFace = defaultStencilOp;
+		BackFace = defaultStencilOp;
+	}
+	explicit CD3DX12_DEPTH_STENCIL_DESC(
+		BOOL depthEnable,
+		D3D12_DEPTH_WRITE_MASK depthWriteMask,
+		D3D12_COMPARISON_FUNC depthFunc,
+		BOOL stencilEnable,
+		UINT8 stencilReadMask,
+		UINT8 stencilWriteMask,
+		D3D12_STENCIL_OP frontStencilFailOp,
+		D3D12_STENCIL_OP frontStencilDepthFailOp,
+		D3D12_STENCIL_OP frontStencilPassOp,
+		D3D12_COMPARISON_FUNC frontStencilFunc,
+		D3D12_STENCIL_OP backStencilFailOp,
+		D3D12_STENCIL_OP backStencilDepthFailOp,
+		D3D12_STENCIL_OP backStencilPassOp,
+		D3D12_COMPARISON_FUNC backStencilFunc)
+	{
+		DepthEnable = depthEnable;
+		DepthWriteMask = depthWriteMask;
+		DepthFunc = depthFunc;
+		StencilEnable = stencilEnable;
+		StencilReadMask = stencilReadMask;
+		StencilWriteMask = stencilWriteMask;
+		FrontFace.StencilFailOp = frontStencilFailOp;
+		FrontFace.StencilDepthFailOp = frontStencilDepthFailOp;
+		FrontFace.StencilPassOp = frontStencilPassOp;
+		FrontFace.StencilFunc = frontStencilFunc;
+		BackFace.StencilFailOp = backStencilFailOp;
+		BackFace.StencilDepthFailOp = backStencilDepthFailOp;
+		BackFace.StencilPassOp = backStencilPassOp;
+		BackFace.StencilFunc = backStencilFunc;
+	}
+	~CD3DX12_DEPTH_STENCIL_DESC() {}
+	operator const D3D12_DEPTH_STENCIL_DESC& () const { return *this; }
+};
+
+//------------------------------------------------------------------------------------------------
+struct CD3DX12_BLEND_DESC : public D3D12_BLEND_DESC
+{
+	CD3DX12_BLEND_DESC()
+	{}
+	explicit CD3DX12_BLEND_DESC(const D3D12_BLEND_DESC& o) :
+		D3D12_BLEND_DESC(o)
+	{}
+	explicit CD3DX12_BLEND_DESC(CD3DX12_DEFAULT)
+	{
+		AlphaToCoverageEnable = FALSE;
+		IndependentBlendEnable = FALSE;
+		const D3D12_RENDER_TARGET_BLEND_DESC defaultRenderTargetBlendDesc =
+		{
+			FALSE,FALSE,
+			D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD,
+			D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD,
+			D3D12_LOGIC_OP_NOOP,
+			D3D12_COLOR_WRITE_ENABLE_ALL,
+		};
+		for (UINT i = 0; i < D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i)
+			RenderTarget[i] = defaultRenderTargetBlendDesc;
+	}
+	~CD3DX12_BLEND_DESC() {}
+	operator const D3D12_BLEND_DESC& () const { return *this; }
+};
+
+//------------------------------------------------------------------------------------------------
+struct CD3DX12_RASTERIZER_DESC : public D3D12_RASTERIZER_DESC
+{
+	CD3DX12_RASTERIZER_DESC()
+	{}
+	explicit CD3DX12_RASTERIZER_DESC(const D3D12_RASTERIZER_DESC& o) :
+		D3D12_RASTERIZER_DESC(o)
+	{}
+	explicit CD3DX12_RASTERIZER_DESC(CD3DX12_DEFAULT)
+	{
+		FillMode = D3D12_FILL_MODE_SOLID;
+		CullMode = D3D12_CULL_MODE_BACK;
+		FrontCounterClockwise = FALSE;
+		DepthBias = D3D12_DEFAULT_DEPTH_BIAS;
+		DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP;
+		SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS;
+		DepthClipEnable = TRUE;
+		MultisampleEnable = FALSE;
+		AntialiasedLineEnable = FALSE;
+		ForcedSampleCount = 0;
+		ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF;
+	}
+	explicit CD3DX12_RASTERIZER_DESC(
+		D3D12_FILL_MODE fillMode,
+		D3D12_CULL_MODE cullMode,
+		BOOL frontCounterClockwise,
+		INT depthBias,
+		FLOAT depthBiasClamp,
+		FLOAT slopeScaledDepthBias,
+		BOOL depthClipEnable,
+		BOOL multisampleEnable,
+		BOOL antialiasedLineEnable,
+		UINT forcedSampleCount,
+		D3D12_CONSERVATIVE_RASTERIZATION_MODE conservativeRaster)
+	{
+		FillMode = fillMode;
+		CullMode = cullMode;
+		FrontCounterClockwise = frontCounterClockwise;
+		DepthBias = depthBias;
+		DepthBiasClamp = depthBiasClamp;
+		SlopeScaledDepthBias = slopeScaledDepthBias;
+		DepthClipEnable = depthClipEnable;
+		MultisampleEnable = multisampleEnable;
+		AntialiasedLineEnable = antialiasedLineEnable;
+		ForcedSampleCount = forcedSampleCount;
+		ConservativeRaster = conservativeRaster;
+	}
+	~CD3DX12_RASTERIZER_DESC() {}
+	operator const D3D12_RASTERIZER_DESC& () const { return *this; }
+};
+
+//------------------------------------------------------------------------------------------------
+struct CD3DX12_RESOURCE_ALLOCATION_INFO : public D3D12_RESOURCE_ALLOCATION_INFO
+{
+	CD3DX12_RESOURCE_ALLOCATION_INFO()
+	{}
+	explicit CD3DX12_RESOURCE_ALLOCATION_INFO(const D3D12_RESOURCE_ALLOCATION_INFO& o) :
+		D3D12_RESOURCE_ALLOCATION_INFO(o)
+	{}
+	CD3DX12_RESOURCE_ALLOCATION_INFO(
+		UINT64 size,
+		UINT64 alignment)
+	{
+		SizeInBytes = size;
+		Alignment = alignment;
+	}
+	operator const D3D12_RESOURCE_ALLOCATION_INFO& () const { return *this; }
+};
+
+//------------------------------------------------------------------------------------------------
+struct CD3DX12_HEAP_PROPERTIES : public D3D12_HEAP_PROPERTIES
+{
+	CD3DX12_HEAP_PROPERTIES()
+	{}
+	explicit CD3DX12_HEAP_PROPERTIES(const D3D12_HEAP_PROPERTIES& o) :
+		D3D12_HEAP_PROPERTIES(o)
+	{}
+	CD3DX12_HEAP_PROPERTIES(
+		D3D12_CPU_PAGE_PROPERTY cpuPageProperty,
+		D3D12_MEMORY_POOL memoryPoolPreference,
+		UINT creationNodeMask = 1,
+		UINT nodeMask = 1)
+	{
+		Type = D3D12_HEAP_TYPE_CUSTOM;
+		CPUPageProperty = cpuPageProperty;
+		MemoryPoolPreference = memoryPoolPreference;
+		CreationNodeMask = creationNodeMask;
+		VisibleNodeMask = nodeMask;
+	}
+	explicit CD3DX12_HEAP_PROPERTIES(
+		D3D12_HEAP_TYPE type,
+		UINT creationNodeMask = 1,
+		UINT nodeMask = 1)
+	{
+		Type = type;
+		CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
+		MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
+		CreationNodeMask = creationNodeMask;
+		VisibleNodeMask = nodeMask;
+	}
+	operator const D3D12_HEAP_PROPERTIES& () const { return *this; }
+	bool IsCPUAccessible() const
+	{
+		return Type == D3D12_HEAP_TYPE_UPLOAD || Type == D3D12_HEAP_TYPE_READBACK || (Type == D3D12_HEAP_TYPE_CUSTOM &&
+			(CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE || CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_WRITE_BACK));
+	}
+};
+inline bool operator==(const D3D12_HEAP_PROPERTIES& l, const D3D12_HEAP_PROPERTIES& r)
+{
+	return l.Type == r.Type && l.CPUPageProperty == r.CPUPageProperty &&
+		l.MemoryPoolPreference == r.MemoryPoolPreference &&
+		l.CreationNodeMask == r.CreationNodeMask &&
+		l.VisibleNodeMask == r.VisibleNodeMask;
+}
+inline bool operator!=(const D3D12_HEAP_PROPERTIES& l, const D3D12_HEAP_PROPERTIES& r)
+{
+	return !(l == r);
+}
+
+//------------------------------------------------------------------------------------------------
+struct CD3DX12_HEAP_DESC : public D3D12_HEAP_DESC
+{
+	CD3DX12_HEAP_DESC()
+	{}
+	explicit CD3DX12_HEAP_DESC(const D3D12_HEAP_DESC& o) :
+		D3D12_HEAP_DESC(o)
+	{}
+	CD3DX12_HEAP_DESC(
+		UINT64 size,
+		D3D12_HEAP_PROPERTIES properties,
+		UINT64 alignment = 0,
+		D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE)
+	{
+		SizeInBytes = size;
+		Properties = properties;
+		Alignment = alignment;
+		Flags = flags;
+	}
+	CD3DX12_HEAP_DESC(
+		UINT64 size,
+		D3D12_HEAP_TYPE type,
+		UINT64 alignment = 0,
+		D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE)
+	{
+		SizeInBytes = size;
+		Properties = CD3DX12_HEAP_PROPERTIES(type);
+		Alignment = alignment;
+		Flags = flags;
+	}
+	CD3DX12_HEAP_DESC(
+		UINT64 size,
+		D3D12_CPU_PAGE_PROPERTY cpuPageProperty,
+		D3D12_MEMORY_POOL memoryPoolPreference,
+		UINT64 alignment = 0,
+		D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE)
+	{
+		SizeInBytes = size;
+		Properties = CD3DX12_HEAP_PROPERTIES(cpuPageProperty, memoryPoolPreference);
+		Alignment = alignment;
+		Flags = flags;
+	}
+	CD3DX12_HEAP_DESC(
+		const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo,
+		D3D12_HEAP_PROPERTIES properties,
+		D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE)
+	{
+		SizeInBytes = resAllocInfo.SizeInBytes;
+		Properties = properties;
+		Alignment = resAllocInfo.Alignment;
+		Flags = flags;
+	}
+	CD3DX12_HEAP_DESC(
+		const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo,
+		D3D12_HEAP_TYPE type,
+		D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE)
+	{
+		SizeInBytes = resAllocInfo.SizeInBytes;
+		Properties = CD3DX12_HEAP_PROPERTIES(type);
+		Alignment = resAllocInfo.Alignment;
+		Flags = flags;
+	}
+	CD3DX12_HEAP_DESC(
+		const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo,
+		D3D12_CPU_PAGE_PROPERTY cpuPageProperty,
+		D3D12_MEMORY_POOL memoryPoolPreference,
+		D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE)
+	{
+		SizeInBytes = resAllocInfo.SizeInBytes;
+		Properties = CD3DX12_HEAP_PROPERTIES(cpuPageProperty, memoryPoolPreference);
+		Alignment = resAllocInfo.Alignment;
+		Flags = flags;
+	}
+	operator const D3D12_HEAP_DESC& () const { return *this; }
+	bool IsCPUAccessible() const
+	{
+		return static_cast<const CD3DX12_HEAP_PROPERTIES*>(&Properties)->IsCPUAccessible();
+	}
+};
+inline bool operator==(const D3D12_HEAP_DESC& l, const D3D12_HEAP_DESC& r)
+{
+	return l.SizeInBytes == r.SizeInBytes &&
+		l.Properties == r.Properties &&
+		l.Alignment == r.Alignment &&
+		l.Flags == r.Flags;
+}
+inline bool operator!=(const D3D12_HEAP_DESC& l, const D3D12_HEAP_DESC& r)
+{
+	return !(l == r);
+}
+
+//------------------------------------------------------------------------------------------------
+struct CD3DX12_CLEAR_VALUE : public D3D12_CLEAR_VALUE
+{
+	CD3DX12_CLEAR_VALUE()
+	{}
+	explicit CD3DX12_CLEAR_VALUE(const D3D12_CLEAR_VALUE& o) :
+		D3D12_CLEAR_VALUE(o)
+	{}
+	CD3DX12_CLEAR_VALUE(
+		DXGI_FORMAT format,
+		const FLOAT color[4])
+	{
+		Format = format;
+		memcpy(Color, color, sizeof(Color));
+	}
+	CD3DX12_CLEAR_VALUE(
+		DXGI_FORMAT format,
+		FLOAT depth,
+		UINT8 stencil)
+	{
+		Format = format;
+		/* Use memcpy to preserve NAN values */
+		memcpy(&DepthStencil.Depth, &depth, sizeof(depth));
+		DepthStencil.Stencil = stencil;
+	}
+	operator const D3D12_CLEAR_VALUE& () const { return *this; }
+};
+
+//------------------------------------------------------------------------------------------------
+struct CD3DX12_RANGE : public D3D12_RANGE
+{
+	CD3DX12_RANGE()
+	{}
+	explicit CD3DX12_RANGE(const D3D12_RANGE& o) :
+		D3D12_RANGE(o)
+	{}
+	CD3DX12_RANGE(
+		SIZE_T begin,
+		SIZE_T end)
+	{
+		Begin = begin;
+		End = end;
+	}
+	operator const D3D12_RANGE& () const { return *this; }
+};
+
+//------------------------------------------------------------------------------------------------
+struct CD3DX12_TILED_RESOURCE_COORDINATE : public D3D12_TILED_RESOURCE_COORDINATE
+{
+	CD3DX12_TILED_RESOURCE_COORDINATE()
+	{}
+	explicit CD3DX12_TILED_RESOURCE_COORDINATE(const D3D12_TILED_RESOURCE_COORDINATE& o) :
+		D3D12_TILED_RESOURCE_COORDINATE(o)
+	{}
+	CD3DX12_TILED_RESOURCE_COORDINATE(
+		UINT x,
+		UINT y,
+		UINT z,
+		UINT subresource)
+	{
+		X = x;
+		Y = y;
+		Z = z;
+		Subresource = subresource;
+	}
+	operator const D3D12_TILED_RESOURCE_COORDINATE& () const { return *this; }
+};
+
+//------------------------------------------------------------------------------------------------
+struct CD3DX12_TILE_REGION_SIZE : public D3D12_TILE_REGION_SIZE
+{
+	CD3DX12_TILE_REGION_SIZE()
+	{}
+	explicit CD3DX12_TILE_REGION_SIZE(const D3D12_TILE_REGION_SIZE& o) :
+		D3D12_TILE_REGION_SIZE(o)
+	{}
+	CD3DX12_TILE_REGION_SIZE(
+		UINT numTiles,
+		BOOL useBox,
+		UINT width,
+		UINT16 height,
+		UINT16 depth)
+	{
+		NumTiles = numTiles;
+		UseBox = useBox;
+		Width = width;
+		Height = height;
+		Depth = depth;
+	}
+	operator const D3D12_TILE_REGION_SIZE& () const { return *this; }
+};
+
+//------------------------------------------------------------------------------------------------
+struct CD3DX12_SUBRESOURCE_TILING : public D3D12_SUBRESOURCE_TILING
+{
+	CD3DX12_SUBRESOURCE_TILING()
+	{}
+	explicit CD3DX12_SUBRESOURCE_TILING(const D3D12_SUBRESOURCE_TILING& o) :
+		D3D12_SUBRESOURCE_TILING(o)
+	{}
+	CD3DX12_SUBRESOURCE_TILING(
+		UINT widthInTiles,
+		UINT16 heightInTiles,
+		UINT16 depthInTiles,
+		UINT startTileIndexInOverallResource)
+	{
+		WidthInTiles = widthInTiles;
+		HeightInTiles = heightInTiles;
+		DepthInTiles = depthInTiles;
+		StartTileIndexInOverallResource = startTileIndexInOverallResource;
+	}
+	operator const D3D12_SUBRESOURCE_TILING& () const { return *this; }
+};
+
+//------------------------------------------------------------------------------------------------
+struct CD3DX12_TILE_SHAPE : public D3D12_TILE_SHAPE
+{
+	CD3DX12_TILE_SHAPE()
+	{}
+	explicit CD3DX12_TILE_SHAPE(const D3D12_TILE_SHAPE& o) :
+		D3D12_TILE_SHAPE(o)
+	{}
+	CD3DX12_TILE_SHAPE(
+		UINT widthInTexels,
+		UINT heightInTexels,
+		UINT depthInTexels)
+	{
+		WidthInTexels = widthInTexels;
+		HeightInTexels = heightInTexels;
+		DepthInTexels = depthInTexels;
+	}
+	operator const D3D12_TILE_SHAPE& () const { return *this; }
+};
+
+//------------------------------------------------------------------------------------------------
+struct CD3DX12_RESOURCE_BARRIER : public D3D12_RESOURCE_BARRIER
+{
+	CD3DX12_RESOURCE_BARRIER()
+	{}
+	explicit CD3DX12_RESOURCE_BARRIER(const D3D12_RESOURCE_BARRIER& o) :
+		D3D12_RESOURCE_BARRIER(o)
+	{}
+	static inline CD3DX12_RESOURCE_BARRIER Transition(
+		_In_ ID3D12Resource* pResource,
+		D3D12_RESOURCE_STATES stateBefore,
+		D3D12_RESOURCE_STATES stateAfter,
+		UINT subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
+		D3D12_RESOURCE_BARRIER_FLAGS flags = D3D12_RESOURCE_BARRIER_FLAG_NONE)
+	{
+		CD3DX12_RESOURCE_BARRIER result;
+		ZeroMemory(&result, sizeof(result));
+		D3D12_RESOURCE_BARRIER& barrier = result;
+		result.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
+		result.Flags = flags;
+		barrier.Transition.pResource = pResource;
+		barrier.Transition.StateBefore = stateBefore;
+		barrier.Transition.StateAfter = stateAfter;
+		barrier.Transition.Subresource = subresource;
+		return result;
+	}
+	static inline CD3DX12_RESOURCE_BARRIER Aliasing(
+		_In_ ID3D12Resource* pResourceBefore,
+		_In_ ID3D12Resource* pResourceAfter)
+	{
+		CD3DX12_RESOURCE_BARRIER result;
+		ZeroMemory(&result, sizeof(result));
+		D3D12_RESOURCE_BARRIER& barrier = result;
+		result.Type = D3D12_RESOURCE_BARRIER_TYPE_ALIASING;
+		barrier.Aliasing.pResourceBefore = pResourceBefore;
+		barrier.Aliasing.pResourceAfter = pResourceAfter;
+		return result;
+	}
+	static inline CD3DX12_RESOURCE_BARRIER UAV(
+		_In_ ID3D12Resource* pResource)
+	{
+		CD3DX12_RESOURCE_BARRIER result;
+		ZeroMemory(&result, sizeof(result));
+		D3D12_RESOURCE_BARRIER& barrier = result;
+		result.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV;
+		barrier.UAV.pResource = pResource;
+		return result;
+	}
+	operator const D3D12_RESOURCE_BARRIER& () const { return *this; }
+};
+
+//------------------------------------------------------------------------------------------------
+struct CD3DX12_PACKED_MIP_INFO : public D3D12_PACKED_MIP_INFO
+{
+	CD3DX12_PACKED_MIP_INFO()
+	{}
+	explicit CD3DX12_PACKED_MIP_INFO(const D3D12_PACKED_MIP_INFO& o) :
+		D3D12_PACKED_MIP_INFO(o)
+	{}
+	CD3DX12_PACKED_MIP_INFO(
+		UINT8 numStandardMips,
+		UINT8 numPackedMips,
+		UINT numTilesForPackedMips,
+		UINT startTileIndexInOverallResource)
+	{
+		NumStandardMips = numStandardMips;
+		NumPackedMips = numPackedMips;
+		NumTilesForPackedMips = numTilesForPackedMips;
+		StartTileIndexInOverallResource = startTileIndexInOverallResource;
+	}
+	operator const D3D12_PACKED_MIP_INFO& () const { return *this; }
+};
+
+//------------------------------------------------------------------------------------------------
+struct CD3DX12_SUBRESOURCE_FOOTPRINT : public D3D12_SUBRESOURCE_FOOTPRINT
+{
+	CD3DX12_SUBRESOURCE_FOOTPRINT()
+	{}
+	explicit CD3DX12_SUBRESOURCE_FOOTPRINT(const D3D12_SUBRESOURCE_FOOTPRINT& o) :
+		D3D12_SUBRESOURCE_FOOTPRINT(o)
+	{}
+	CD3DX12_SUBRESOURCE_FOOTPRINT(
+		DXGI_FORMAT format,
+		UINT width,
+		UINT height,
+		UINT depth,
+		UINT rowPitch)
+	{
+		Format = format;
+		Width = width;
+		Height = height;
+		Depth = depth;
+		RowPitch = rowPitch;
+	}
+	explicit CD3DX12_SUBRESOURCE_FOOTPRINT(
+		const D3D12_RESOURCE_DESC& resDesc,
+		UINT rowPitch)
+	{
+		Format = resDesc.Format;
+		Width = UINT(resDesc.Width);
+		Height = resDesc.Height;
+		Depth = (resDesc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D ? resDesc.DepthOrArraySize : 1);
+		RowPitch = rowPitch;
+	}
+	operator const D3D12_SUBRESOURCE_FOOTPRINT& () const { return *this; }
+};
+
+//------------------------------------------------------------------------------------------------
+struct CD3DX12_TEXTURE_COPY_LOCATION : public D3D12_TEXTURE_COPY_LOCATION
+{
+	CD3DX12_TEXTURE_COPY_LOCATION()
+	{}
+	explicit CD3DX12_TEXTURE_COPY_LOCATION(const D3D12_TEXTURE_COPY_LOCATION& o) :
+		D3D12_TEXTURE_COPY_LOCATION(o)
+	{}
+	CD3DX12_TEXTURE_COPY_LOCATION(ID3D12Resource* pRes) { pResource = pRes; }
+	CD3DX12_TEXTURE_COPY_LOCATION(ID3D12Resource* pRes, D3D12_PLACED_SUBRESOURCE_FOOTPRINT const& Footprint)
+	{
+		pResource = pRes;
+		Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
+		PlacedFootprint = Footprint;
+	}
+	CD3DX12_TEXTURE_COPY_LOCATION(ID3D12Resource* pRes, UINT Sub)
+	{
+		pResource = pRes;
+		Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
+		SubresourceIndex = Sub;
+	}
+};
+
+//------------------------------------------------------------------------------------------------
+struct CD3DX12_DESCRIPTOR_RANGE : public D3D12_DESCRIPTOR_RANGE
+{
+	CD3DX12_DESCRIPTOR_RANGE() { }
+	explicit CD3DX12_DESCRIPTOR_RANGE(const D3D12_DESCRIPTOR_RANGE& o) :
+		D3D12_DESCRIPTOR_RANGE(o)
+	{}
+	CD3DX12_DESCRIPTOR_RANGE(
+		D3D12_DESCRIPTOR_RANGE_TYPE rangeType,
+		UINT numDescriptors,
+		UINT baseShaderRegister,
+		UINT registerSpace = 0,
+		UINT offsetInDescriptorsFromTableStart =
+		D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND)
+	{
+		Init(rangeType, numDescriptors, baseShaderRegister, registerSpace, offsetInDescriptorsFromTableStart);
+	}
+
+	inline void Init(
+		D3D12_DESCRIPTOR_RANGE_TYPE rangeType,
+		UINT numDescriptors,
+		UINT baseShaderRegister,
+		UINT registerSpace = 0,
+		UINT offsetInDescriptorsFromTableStart =
+		D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND)
+	{
+		Init(*this, rangeType, numDescriptors, baseShaderRegister, registerSpace, offsetInDescriptorsFromTableStart);
+	}
+
+	static inline void Init(
+		_Out_ D3D12_DESCRIPTOR_RANGE& range,
+		D3D12_DESCRIPTOR_RANGE_TYPE rangeType,
+		UINT numDescriptors,
+		UINT baseShaderRegister,
+		UINT registerSpace = 0,
+		UINT offsetInDescriptorsFromTableStart =
+		D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND)
+	{
+		range.RangeType = rangeType;
+		range.NumDescriptors = numDescriptors;
+		range.BaseShaderRegister = baseShaderRegister;
+		range.RegisterSpace = registerSpace;
+		range.OffsetInDescriptorsFromTableStart = offsetInDescriptorsFromTableStart;
+	}
+};
+
+//------------------------------------------------------------------------------------------------
+struct CD3DX12_ROOT_DESCRIPTOR_TABLE : public D3D12_ROOT_DESCRIPTOR_TABLE
+{
+	CD3DX12_ROOT_DESCRIPTOR_TABLE() {}
+	explicit CD3DX12_ROOT_DESCRIPTOR_TABLE(const D3D12_ROOT_DESCRIPTOR_TABLE& o) :
+		D3D12_ROOT_DESCRIPTOR_TABLE(o)
+	{}
+	CD3DX12_ROOT_DESCRIPTOR_TABLE(
+		UINT numDescriptorRanges,
+		_In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* _pDescriptorRanges)
+	{
+		Init(numDescriptorRanges, _pDescriptorRanges);
+	}
+
+	inline void Init(
+		UINT numDescriptorRanges,
+		_In_reads_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* _pDescriptorRanges)
+	{
+		Init(*this, numDescriptorRanges, _pDescriptorRanges);
+	}
+
+	static inline void Init(
+		_Out_ D3D12_ROOT_DESCRIPTOR_TABLE& rootDescriptorTable,
+		UINT numDescriptorRanges,
+		_In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* _pDescriptorRanges)
+	{
+		rootDescriptorTable.NumDescriptorRanges = numDescriptorRanges;
+		rootDescriptorTable.pDescriptorRanges = _pDescriptorRanges;
+	}
+};
+
+//------------------------------------------------------------------------------------------------
+struct CD3DX12_ROOT_CONSTANTS : public D3D12_ROOT_CONSTANTS
+{
+	CD3DX12_ROOT_CONSTANTS() {}
+	explicit CD3DX12_ROOT_CONSTANTS(const D3D12_ROOT_CONSTANTS& o) :
+		D3D12_ROOT_CONSTANTS(o)
+	{}
+	CD3DX12_ROOT_CONSTANTS(
+		UINT num32BitValues,
+		UINT shaderRegister,
+		UINT registerSpace = 0)
+	{
+		Init(num32BitValues, shaderRegister, registerSpace);
+	}
+
+	inline void Init(
+		UINT num32BitValues,
+		UINT shaderRegister,
+		UINT registerSpace = 0)
+	{
+		Init(*this, num32BitValues, shaderRegister, registerSpace);
+	}
+
+	static inline void Init(
+		_Out_ D3D12_ROOT_CONSTANTS& rootConstants,
+		UINT num32BitValues,
+		UINT shaderRegister,
+		UINT registerSpace = 0)
+	{
+		rootConstants.Num32BitValues = num32BitValues;
+		rootConstants.ShaderRegister = shaderRegister;
+		rootConstants.RegisterSpace = registerSpace;
+	}
+};
+
+//------------------------------------------------------------------------------------------------
+struct CD3DX12_ROOT_DESCRIPTOR : public D3D12_ROOT_DESCRIPTOR
+{
+	CD3DX12_ROOT_DESCRIPTOR() {}
+	explicit CD3DX12_ROOT_DESCRIPTOR(const D3D12_ROOT_DESCRIPTOR& o) :
+		D3D12_ROOT_DESCRIPTOR(o)
+	{}
+	CD3DX12_ROOT_DESCRIPTOR(
+		UINT shaderRegister,
+		UINT registerSpace = 0)
+	{
+		Init(shaderRegister, registerSpace);
+	}
+
+	inline void Init(
+		UINT shaderRegister,
+		UINT registerSpace = 0)
+	{
+		Init(*this, shaderRegister, registerSpace);
+	}
+
+	static inline void Init(_Out_ D3D12_ROOT_DESCRIPTOR& table, UINT shaderRegister, UINT registerSpace = 0)
+	{
+		table.ShaderRegister = shaderRegister;
+		table.RegisterSpace = registerSpace;
+	}
+};
+
+//------------------------------------------------------------------------------------------------
+struct CD3DX12_ROOT_PARAMETER : public D3D12_ROOT_PARAMETER
+{
+	CD3DX12_ROOT_PARAMETER() {}
+	explicit CD3DX12_ROOT_PARAMETER(const D3D12_ROOT_PARAMETER& o) :
+		D3D12_ROOT_PARAMETER(o)
+	{}
+
+	static inline void InitAsDescriptorTable(
+		_Out_ D3D12_ROOT_PARAMETER& rootParam,
+		UINT numDescriptorRanges,
+		_In_reads_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* pDescriptorRanges,
+		D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL)
+	{
+		rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
+		rootParam.ShaderVisibility = visibility;
+		CD3DX12_ROOT_DESCRIPTOR_TABLE::Init(rootParam.DescriptorTable, numDescriptorRanges, pDescriptorRanges);
+	}
+
+	static inline void InitAsConstants(
+		_Out_ D3D12_ROOT_PARAMETER& rootParam,
+		UINT num32BitValues,
+		UINT shaderRegister,
+		UINT registerSpace = 0,
+		D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL)
+	{
+		rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
+		rootParam.ShaderVisibility = visibility;
+		CD3DX12_ROOT_CONSTANTS::Init(rootParam.Constants, num32BitValues, shaderRegister, registerSpace);
+	}
+
+	static inline void InitAsConstantBufferView(
+		_Out_ D3D12_ROOT_PARAMETER& rootParam,
+		UINT shaderRegister,
+		UINT registerSpace = 0,
+		D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL)
+	{
+		rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
+		rootParam.ShaderVisibility = visibility;
+		CD3DX12_ROOT_DESCRIPTOR::Init(rootParam.Descriptor, shaderRegister, registerSpace);
+	}
+
+	static inline void InitAsShaderResourceView(
+		_Out_ D3D12_ROOT_PARAMETER& rootParam,
+		UINT shaderRegister,
+		UINT registerSpace = 0,
+		D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL)
+	{
+		rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_SRV;
+		rootParam.ShaderVisibility = visibility;
+		CD3DX12_ROOT_DESCRIPTOR::Init(rootParam.Descriptor, shaderRegister, registerSpace);
+	}
+
+	static inline void InitAsUnorderedAccessView(
+		_Out_ D3D12_ROOT_PARAMETER& rootParam,
+		UINT shaderRegister,
+		UINT registerSpace = 0,
+		D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL)
+	{
+		rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV;
+		rootParam.ShaderVisibility = visibility;
+		CD3DX12_ROOT_DESCRIPTOR::Init(rootParam.Descriptor, shaderRegister, registerSpace);
+	}
+
+	inline void InitAsDescriptorTable(
+		UINT numDescriptorRanges,
+		_In_reads_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* pDescriptorRanges,
+		D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL)
+	{
+		InitAsDescriptorTable(*this, numDescriptorRanges, pDescriptorRanges, visibility);
+	}
+
+	inline void InitAsConstants(
+		UINT num32BitValues,
+		UINT shaderRegister,
+		UINT registerSpace = 0,
+		D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL)
+	{
+		InitAsConstants(*this, num32BitValues, shaderRegister, registerSpace, visibility);
+	}
+
+	inline void InitAsConstantBufferView(
+		UINT shaderRegister,
+		UINT registerSpace = 0,
+		D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL)
+	{
+		InitAsConstantBufferView(*this, shaderRegister, registerSpace, visibility);
+	}
+
+	inline void InitAsShaderResourceView(
+		UINT shaderRegister,
+		UINT registerSpace = 0,
+		D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL)
+	{
+		InitAsShaderResourceView(*this, shaderRegister, registerSpace, visibility);
+	}
+
+	inline void InitAsUnorderedAccessView(
+		UINT shaderRegister,
+		UINT registerSpace = 0,
+		D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL)
+	{
+		InitAsUnorderedAccessView(*this, shaderRegister, registerSpace, visibility);
+	}
+};
+
+//------------------------------------------------------------------------------------------------
+struct CD3DX12_STATIC_SAMPLER_DESC : public D3D12_STATIC_SAMPLER_DESC
+{
+	CD3DX12_STATIC_SAMPLER_DESC() {}
+	explicit CD3DX12_STATIC_SAMPLER_DESC(const D3D12_STATIC_SAMPLER_DESC& o) :
+		D3D12_STATIC_SAMPLER_DESC(o)
+	{}
+	CD3DX12_STATIC_SAMPLER_DESC(
+		UINT shaderRegister,
+		D3D12_FILTER filter = D3D12_FILTER_ANISOTROPIC,
+		D3D12_TEXTURE_ADDRESS_MODE addressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP,
+		D3D12_TEXTURE_ADDRESS_MODE addressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP,
+		D3D12_TEXTURE_ADDRESS_MODE addressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP,
+		FLOAT mipLODBias = 0,
+		UINT maxAnisotropy = 16,
+		D3D12_COMPARISON_FUNC comparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL,
+		D3D12_STATIC_BORDER_COLOR borderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE,
+		FLOAT minLOD = 0.f,
+		FLOAT maxLOD = D3D12_FLOAT32_MAX,
+		D3D12_SHADER_VISIBILITY shaderVisibility = D3D12_SHADER_VISIBILITY_ALL,
+		UINT registerSpace = 0)
+	{
+		Init(
+			shaderRegister,
+			filter,
+			addressU,
+			addressV,
+			addressW,
+			mipLODBias,
+			maxAnisotropy,
+			comparisonFunc,
+			borderColor,
+			minLOD,
+			maxLOD,
+			shaderVisibility,
+			registerSpace);
+	}
+
+	static inline void Init(
+		_Out_ D3D12_STATIC_SAMPLER_DESC& samplerDesc,
+		UINT shaderRegister,
+		D3D12_FILTER filter = D3D12_FILTER_ANISOTROPIC,
+		D3D12_TEXTURE_ADDRESS_MODE addressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP,
+		D3D12_TEXTURE_ADDRESS_MODE addressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP,
+		D3D12_TEXTURE_ADDRESS_MODE addressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP,
+		FLOAT mipLODBias = 0,
+		UINT maxAnisotropy = 16,
+		D3D12_COMPARISON_FUNC comparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL,
+		D3D12_STATIC_BORDER_COLOR borderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE,
+		FLOAT minLOD = 0.f,
+		FLOAT maxLOD = D3D12_FLOAT32_MAX,
+		D3D12_SHADER_VISIBILITY shaderVisibility = D3D12_SHADER_VISIBILITY_ALL,
+		UINT registerSpace = 0)
+	{
+		samplerDesc.ShaderRegister = shaderRegister;
+		samplerDesc.Filter = filter;
+		samplerDesc.AddressU = addressU;
+		samplerDesc.AddressV = addressV;
+		samplerDesc.AddressW = addressW;
+		samplerDesc.MipLODBias = mipLODBias;
+		samplerDesc.MaxAnisotropy = maxAnisotropy;
+		samplerDesc.ComparisonFunc = comparisonFunc;
+		samplerDesc.BorderColor = borderColor;
+		samplerDesc.MinLOD = minLOD;
+		samplerDesc.MaxLOD = maxLOD;
+		samplerDesc.ShaderVisibility = shaderVisibility;
+		samplerDesc.RegisterSpace = registerSpace;
+	}
+	inline void Init(
+		UINT shaderRegister,
+		D3D12_FILTER filter = D3D12_FILTER_ANISOTROPIC,
+		D3D12_TEXTURE_ADDRESS_MODE addressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP,
+		D3D12_TEXTURE_ADDRESS_MODE addressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP,
+		D3D12_TEXTURE_ADDRESS_MODE addressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP,
+		FLOAT mipLODBias = 0,
+		UINT maxAnisotropy = 16,
+		D3D12_COMPARISON_FUNC comparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL,
+		D3D12_STATIC_BORDER_COLOR borderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE,
+		FLOAT minLOD = 0.f,
+		FLOAT maxLOD = D3D12_FLOAT32_MAX,
+		D3D12_SHADER_VISIBILITY shaderVisibility = D3D12_SHADER_VISIBILITY_ALL,
+		UINT registerSpace = 0)
+	{
+		Init(
+			*this,
+			shaderRegister,
+			filter,
+			addressU,
+			addressV,
+			addressW,
+			mipLODBias,
+			maxAnisotropy,
+			comparisonFunc,
+			borderColor,
+			minLOD,
+			maxLOD,
+			shaderVisibility,
+			registerSpace);
+	}
+
+};
+
+//------------------------------------------------------------------------------------------------
+struct CD3DX12_ROOT_SIGNATURE_DESC : public D3D12_ROOT_SIGNATURE_DESC
+{
+	CD3DX12_ROOT_SIGNATURE_DESC() {}
+	explicit CD3DX12_ROOT_SIGNATURE_DESC(const D3D12_ROOT_SIGNATURE_DESC& o) :
+		D3D12_ROOT_SIGNATURE_DESC(o)
+	{}
+	CD3DX12_ROOT_SIGNATURE_DESC(
+		UINT numParameters,
+		_In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters,
+		UINT numStaticSamplers = 0,
+		_In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = NULL,
+		D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE)
+	{
+		Init(numParameters, _pParameters, numStaticSamplers, _pStaticSamplers, flags);
+	}
+	CD3DX12_ROOT_SIGNATURE_DESC(CD3DX12_DEFAULT)
+	{
+		Init(0, NULL, 0, NULL, D3D12_ROOT_SIGNATURE_FLAG_NONE);
+	}
+
+	inline void Init(
+		UINT numParameters,
+		_In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters,
+		UINT numStaticSamplers = 0,
+		_In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = NULL,
+		D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE)
+	{
+		Init(*this, numParameters, _pParameters, numStaticSamplers, _pStaticSamplers, flags);
+	}
+
+	static inline void Init(
+		_Out_ D3D12_ROOT_SIGNATURE_DESC& desc,
+		UINT numParameters,
+		_In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters,
+		UINT numStaticSamplers = 0,
+		_In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = NULL,
+		D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE)
+	{
+		desc.NumParameters = numParameters;
+		desc.pParameters = _pParameters;
+		desc.NumStaticSamplers = numStaticSamplers;
+		desc.pStaticSamplers = _pStaticSamplers;
+		desc.Flags = flags;
+	}
+};
+
+//------------------------------------------------------------------------------------------------
+struct CD3DX12_CPU_DESCRIPTOR_HANDLE : public D3D12_CPU_DESCRIPTOR_HANDLE
+{
+	CD3DX12_CPU_DESCRIPTOR_HANDLE() {}
+	explicit CD3DX12_CPU_DESCRIPTOR_HANDLE(const D3D12_CPU_DESCRIPTOR_HANDLE& o) :
+		D3D12_CPU_DESCRIPTOR_HANDLE(o)
+	{}
+	CD3DX12_CPU_DESCRIPTOR_HANDLE(CD3DX12_DEFAULT) { ptr = 0; }
+	CD3DX12_CPU_DESCRIPTOR_HANDLE(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE& other, INT offsetScaledByIncrementSize)
+	{
+		InitOffsetted(other, offsetScaledByIncrementSize);
+	}
+	CD3DX12_CPU_DESCRIPTOR_HANDLE(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE& other, INT offsetInDescriptors, UINT descriptorIncrementSize)
+	{
+		InitOffsetted(other, offsetInDescriptors, descriptorIncrementSize);
+	}
+	CD3DX12_CPU_DESCRIPTOR_HANDLE& Offset(INT offsetInDescriptors, UINT descriptorIncrementSize)
+	{
+		ptr += offsetInDescriptors * descriptorIncrementSize;
+		return *this;
+	}
+	CD3DX12_CPU_DESCRIPTOR_HANDLE& Offset(INT offsetScaledByIncrementSize)
+	{
+		ptr += offsetScaledByIncrementSize;
+		return *this;
+	}
+	bool operator==(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE& other)
+	{
+		return (ptr == other.ptr);
+	}
+	bool operator!=(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE& other)
+	{
+		return (ptr != other.ptr);
+	}
+	CD3DX12_CPU_DESCRIPTOR_HANDLE& operator=(const D3D12_CPU_DESCRIPTOR_HANDLE& other)
+	{
+		ptr = other.ptr;
+		return *this;
+	}
+
+	inline void InitOffsetted(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE& base, INT offsetScaledByIncrementSize)
+	{
+		InitOffsetted(*this, base, offsetScaledByIncrementSize);
+	}
+
+	inline void InitOffsetted(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE& base, INT offsetInDescriptors, UINT descriptorIncrementSize)
+	{
+		InitOffsetted(*this, base, offsetInDescriptors, descriptorIncrementSize);
+	}
+
+	static inline void InitOffsetted(_Out_ D3D12_CPU_DESCRIPTOR_HANDLE& handle, _In_ const D3D12_CPU_DESCRIPTOR_HANDLE& base, INT offsetScaledByIncrementSize)
+	{
+		handle.ptr = base.ptr + offsetScaledByIncrementSize;
+	}
+
+	static inline void InitOffsetted(_Out_ D3D12_CPU_DESCRIPTOR_HANDLE& handle, _In_ const D3D12_CPU_DESCRIPTOR_HANDLE& base, INT offsetInDescriptors, UINT descriptorIncrementSize)
+	{
+		handle.ptr = base.ptr + offsetInDescriptors * descriptorIncrementSize;
+	}
+};
+
+//------------------------------------------------------------------------------------------------
+struct CD3DX12_GPU_DESCRIPTOR_HANDLE : public D3D12_GPU_DESCRIPTOR_HANDLE
+{
+	CD3DX12_GPU_DESCRIPTOR_HANDLE() {}
+	explicit CD3DX12_GPU_DESCRIPTOR_HANDLE(const D3D12_GPU_DESCRIPTOR_HANDLE& o) :
+		D3D12_GPU_DESCRIPTOR_HANDLE(o)
+	{}
+	CD3DX12_GPU_DESCRIPTOR_HANDLE(CD3DX12_DEFAULT) { ptr = 0; }
+	CD3DX12_GPU_DESCRIPTOR_HANDLE(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE& other, INT offsetScaledByIncrementSize)
+	{
+		InitOffsetted(other, offsetScaledByIncrementSize);
+	}
+	CD3DX12_GPU_DESCRIPTOR_HANDLE(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE& other, INT offsetInDescriptors, UINT descriptorIncrementSize)
+	{
+		InitOffsetted(other, offsetInDescriptors, descriptorIncrementSize);
+	}
+	CD3DX12_GPU_DESCRIPTOR_HANDLE& Offset(INT offsetInDescriptors, UINT descriptorIncrementSize)
+	{
+		ptr += offsetInDescriptors * descriptorIncrementSize;
+		return *this;
+	}
+	CD3DX12_GPU_DESCRIPTOR_HANDLE& Offset(INT offsetScaledByIncrementSize)
+	{
+		ptr += offsetScaledByIncrementSize;
+		return *this;
+	}
+	inline bool operator==(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE& other)
+	{
+		return (ptr == other.ptr);
+	}
+	inline bool operator!=(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE& other)
+	{
+		return (ptr != other.ptr);
+	}
+	CD3DX12_GPU_DESCRIPTOR_HANDLE& operator=(const D3D12_GPU_DESCRIPTOR_HANDLE& other)
+	{
+		ptr = other.ptr;
+		return *this;
+	}
+
+	inline void InitOffsetted(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE& base, INT offsetScaledByIncrementSize)
+	{
+		InitOffsetted(*this, base, offsetScaledByIncrementSize);
+	}
+
+	inline void InitOffsetted(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE& base, INT offsetInDescriptors, UINT descriptorIncrementSize)
+	{
+		InitOffsetted(*this, base, offsetInDescriptors, descriptorIncrementSize);
+	}
+
+	static inline void InitOffsetted(_Out_ D3D12_GPU_DESCRIPTOR_HANDLE& handle, _In_ const D3D12_GPU_DESCRIPTOR_HANDLE& base, INT offsetScaledByIncrementSize)
+	{
+		handle.ptr = base.ptr + offsetScaledByIncrementSize;
+	}
+
+	static inline void InitOffsetted(_Out_ D3D12_GPU_DESCRIPTOR_HANDLE& handle, _In_ const D3D12_GPU_DESCRIPTOR_HANDLE& base, INT offsetInDescriptors, UINT descriptorIncrementSize)
+	{
+		handle.ptr = base.ptr + offsetInDescriptors * descriptorIncrementSize;
+	}
+};
+
+//------------------------------------------------------------------------------------------------
+inline UINT D3D12CalcSubresource(UINT MipSlice, UINT ArraySlice, UINT PlaneSlice, UINT MipLevels, UINT ArraySize)
+{
+	return MipSlice + ArraySlice * MipLevels + PlaneSlice * MipLevels * ArraySize;
+}
+
+//------------------------------------------------------------------------------------------------
+template <typename T, typename U, typename V>
+inline void D3D12DecomposeSubresource(UINT Subresource, UINT MipLevels, UINT ArraySize, _Out_ T& MipSlice, _Out_ U& ArraySlice, _Out_ V& PlaneSlice)
+{
+	MipSlice = static_cast<T>(Subresource % MipLevels);
+	ArraySlice = static_cast<U>((Subresource / MipLevels) % ArraySize);
+	PlaneSlice = static_cast<V>(Subresource / (MipLevels * ArraySize));
+}
+
+//------------------------------------------------------------------------------------------------
+inline UINT8 D3D12GetFormatPlaneCount(
+	_In_ ID3D12Device* pDevice,
+	DXGI_FORMAT Format
+)
+{
+	D3D12_FEATURE_DATA_FORMAT_INFO formatInfo = { Format };
+	if (FAILED(pDevice->CheckFeatureSupport(D3D12_FEATURE_FORMAT_INFO, &formatInfo, sizeof(formatInfo))))
+	{
+		return 0;
+	}
+	return formatInfo.PlaneCount;
+}
+
+//------------------------------------------------------------------------------------------------
+struct CD3DX12_RESOURCE_DESC : public D3D12_RESOURCE_DESC
+{
+	CD3DX12_RESOURCE_DESC()
+	{}
+	explicit CD3DX12_RESOURCE_DESC(const D3D12_RESOURCE_DESC& o) :
+		D3D12_RESOURCE_DESC(o)
+	{}
+	CD3DX12_RESOURCE_DESC(
+		D3D12_RESOURCE_DIMENSION dimension,
+		UINT64 alignment,
+		UINT64 width,
+		UINT height,
+		UINT16 depthOrArraySize,
+		UINT16 mipLevels,
+		DXGI_FORMAT format,
+		UINT sampleCount,
+		UINT sampleQuality,
+		D3D12_TEXTURE_LAYOUT layout,
+		D3D12_RESOURCE_FLAGS flags)
+	{
+		Dimension = dimension;
+		Alignment = alignment;
+		Width = width;
+		Height = height;
+		DepthOrArraySize = depthOrArraySize;
+		MipLevels = mipLevels;
+		Format = format;
+		SampleDesc.Count = sampleCount;
+		SampleDesc.Quality = sampleQuality;
+		Layout = layout;
+		Flags = flags;
+	}
+	static inline CD3DX12_RESOURCE_DESC Buffer(
+		const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo,
+		D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE)
+	{
+		return CD3DX12_RESOURCE_DESC(D3D12_RESOURCE_DIMENSION_BUFFER, resAllocInfo.Alignment, resAllocInfo.SizeInBytes,
+			1, 1, 1, DXGI_FORMAT_UNKNOWN, 1, 0, D3D12_TEXTURE_LAYOUT_ROW_MAJOR, flags);
+	}
+	static inline CD3DX12_RESOURCE_DESC Buffer(
+		UINT64 width,
+		D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE,
+		UINT64 alignment = 0)
+	{
+		return CD3DX12_RESOURCE_DESC(D3D12_RESOURCE_DIMENSION_BUFFER, alignment, width, 1, 1, 1,
+			DXGI_FORMAT_UNKNOWN, 1, 0, D3D12_TEXTURE_LAYOUT_ROW_MAJOR, flags);
+	}
+	static inline CD3DX12_RESOURCE_DESC Tex1D(
+		DXGI_FORMAT format,
+		UINT64 width,
+		UINT16 arraySize = 1,
+		UINT16 mipLevels = 0,
+		D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE,
+		D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN,
+		UINT64 alignment = 0)
+	{
+		return CD3DX12_RESOURCE_DESC(D3D12_RESOURCE_DIMENSION_TEXTURE1D, alignment, width, 1, arraySize,
+			mipLevels, format, 1, 0, layout, flags);
+	}
+	static inline CD3DX12_RESOURCE_DESC Tex2D(
+		DXGI_FORMAT format,
+		UINT64 width,
+		UINT height,
+		UINT16 arraySize = 1,
+		UINT16 mipLevels = 0,
+		UINT sampleCount = 1,
+		UINT sampleQuality = 0,
+		D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE,
+		D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN,
+		UINT64 alignment = 0)
+	{
+		return CD3DX12_RESOURCE_DESC(D3D12_RESOURCE_DIMENSION_TEXTURE2D, alignment, width, height, arraySize,
+			mipLevels, format, sampleCount, sampleQuality, layout, flags);
+	}
+	static inline CD3DX12_RESOURCE_DESC Tex3D(
+		DXGI_FORMAT format,
+		UINT64 width,
+		UINT height,
+		UINT16 depth,
+		UINT16 mipLevels = 0,
+		D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE,
+		D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN,
+		UINT64 alignment = 0)
+	{
+		return CD3DX12_RESOURCE_DESC(D3D12_RESOURCE_DIMENSION_TEXTURE3D, alignment, width, height, depth,
+			mipLevels, format, 1, 0, layout, flags);
+	}
+	inline UINT16 Depth() const
+	{
+		return (Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D ? DepthOrArraySize : 1);
+	}
+	inline UINT16 ArraySize() const
+	{
+		return (Dimension != D3D12_RESOURCE_DIMENSION_TEXTURE3D ? DepthOrArraySize : 1);
+	}
+	inline UINT8 PlaneCount(_In_ ID3D12Device* pDevice) const
+	{
+		return D3D12GetFormatPlaneCount(pDevice, Format);
+	}
+	inline UINT Subresources(_In_ ID3D12Device* pDevice) const
+	{
+		return MipLevels * ArraySize() * PlaneCount(pDevice);
+	}
+	inline UINT CalcSubresource(UINT MipSlice, UINT ArraySlice, UINT PlaneSlice)
+	{
+		return D3D12CalcSubresource(MipSlice, ArraySlice, PlaneSlice, MipLevels, ArraySize());
+	}
+	operator const D3D12_RESOURCE_DESC& () const { return *this; }
+};
+inline bool operator==(const D3D12_RESOURCE_DESC& l, const D3D12_RESOURCE_DESC& r)
+{
+	return l.Dimension == r.Dimension &&
+		l.Alignment == r.Alignment &&
+		l.Width == r.Width &&
+		l.Height == r.Height &&
+		l.DepthOrArraySize == r.DepthOrArraySize &&
+		l.MipLevels == r.MipLevels &&
+		l.Format == r.Format &&
+		l.SampleDesc.Count == r.SampleDesc.Count &&
+		l.SampleDesc.Quality == r.SampleDesc.Quality &&
+		l.Layout == r.Layout &&
+		l.Flags == r.Flags;
+}
+inline bool operator!=(const D3D12_RESOURCE_DESC& l, const D3D12_RESOURCE_DESC& r)
+{
+	return !(l == r);
+}
+
+//------------------------------------------------------------------------------------------------
+// Row-by-row memcpy
+inline void MemcpySubresource(
+	_In_ const D3D12_MEMCPY_DEST* pDest,
+	_In_ const D3D12_SUBRESOURCE_DATA* pSrc,
+	SIZE_T RowSizeInBytes,
+	UINT NumRows,
+	UINT NumSlices)
+{
+	for (UINT z = 0; z < NumSlices; ++z)
+	{
+		BYTE* pDestSlice = reinterpret_cast<BYTE*>(pDest->pData) + pDest->SlicePitch * z;
+		const BYTE* pSrcSlice = reinterpret_cast<const BYTE*>(pSrc->pData) + pSrc->SlicePitch * z;
+		for (UINT y = 0; y < NumRows; ++y)
+		{
+			memcpy(pDestSlice + pDest->RowPitch * y,
+				pSrcSlice + pSrc->RowPitch * y,
+				RowSizeInBytes);
+		}
+	}
+}
+
+//------------------------------------------------------------------------------------------------
+// Returns required size of a buffer to be used for data upload
+inline UINT64 GetRequiredIntermediateSize(
+	_In_ ID3D12Resource* pDestinationResource,
+	_In_range_(0, D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
+	_In_range_(0, D3D12_REQ_SUBRESOURCES - FirstSubresource) UINT NumSubresources)
+{
+	D3D12_RESOURCE_DESC Desc = pDestinationResource->GetDesc();
+	UINT64 RequiredSize = 0;
+
+	ID3D12Device* pDevice;
+	pDestinationResource->GetDevice(__uuidof(*pDevice), reinterpret_cast<void**>(&pDevice));
+	pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, 0, nullptr, nullptr, nullptr, &RequiredSize);
+	pDevice->Release();
+
+	return RequiredSize;
+}
+
+//------------------------------------------------------------------------------------------------
+// All arrays must be populated (e.g. by calling GetCopyableFootprints)
+inline UINT64 UpdateSubresources(
+	_In_ ID3D12GraphicsCommandList* pCmdList,
+	_In_ ID3D12Resource* pDestinationResource,
+	_In_ ID3D12Resource* pIntermediate,
+	_In_range_(0, D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
+	_In_range_(0, D3D12_REQ_SUBRESOURCES - FirstSubresource) UINT NumSubresources,
+	UINT64 RequiredSize,
+	_In_reads_(NumSubresources) const D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts,
+	_In_reads_(NumSubresources) const UINT* pNumRows,
+	_In_reads_(NumSubresources) const UINT64* pRowSizesInBytes,
+	_In_reads_(NumSubresources) const D3D12_SUBRESOURCE_DATA* pSrcData)
+{
+	// Minor validation
+	D3D12_RESOURCE_DESC IntermediateDesc = pIntermediate->GetDesc();
+	D3D12_RESOURCE_DESC DestinationDesc = pDestinationResource->GetDesc();
+	if (IntermediateDesc.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER ||
+		IntermediateDesc.Width < RequiredSize + pLayouts[0].Offset ||
+		RequiredSize >(SIZE_T) - 1 ||
+		(DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER &&
+			(FirstSubresource != 0 || NumSubresources != 1)))
+	{
+		return 0;
+	}
+
+	BYTE* pData;
+	HRESULT hr = pIntermediate->Map(0, NULL, reinterpret_cast<void**>(&pData));
+	if (FAILED(hr))
+	{
+		return 0;
+	}
+
+	for (UINT i = 0; i < NumSubresources; ++i)
+	{
+		if (pRowSizesInBytes[i] > (SIZE_T)-1) return 0;
+		D3D12_MEMCPY_DEST DestData = { pData + pLayouts[i].Offset, pLayouts[i].Footprint.RowPitch, pLayouts[i].Footprint.RowPitch * pNumRows[i] };
+		MemcpySubresource(&DestData, &pSrcData[i], (SIZE_T)pRowSizesInBytes[i], pNumRows[i], pLayouts[i].Footprint.Depth);
+	}
+	pIntermediate->Unmap(0, NULL);
+
+	if (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER)
+	{
+		CD3DX12_BOX SrcBox(UINT(pLayouts[0].Offset), UINT(pLayouts[0].Offset + pLayouts[0].Footprint.Width));
+		pCmdList->CopyBufferRegion(
+			pDestinationResource, 0, pIntermediate, pLayouts[0].Offset, pLayouts[0].Footprint.Width);
+	}
+	else
+	{
+		for (UINT i = 0; i < NumSubresources; ++i)
+		{
+			CD3DX12_TEXTURE_COPY_LOCATION Dst(pDestinationResource, i + FirstSubresource);
+			CD3DX12_TEXTURE_COPY_LOCATION Src(pIntermediate, pLayouts[i]);
+			pCmdList->CopyTextureRegion(&Dst, 0, 0, 0, &Src, nullptr);
+		}
+	}
+	return RequiredSize;
+}
+
+//------------------------------------------------------------------------------------------------
+// Heap-allocating UpdateSubresources implementation
+inline UINT64 UpdateSubresources(
+	_In_ ID3D12GraphicsCommandList* pCmdList,
+	_In_ ID3D12Resource* pDestinationResource,
+	_In_ ID3D12Resource* pIntermediate,
+	UINT64 IntermediateOffset,
+	_In_range_(0, D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
+	_In_range_(0, D3D12_REQ_SUBRESOURCES - FirstSubresource) UINT NumSubresources,
+	_In_reads_(NumSubresources) D3D12_SUBRESOURCE_DATA* pSrcData)
+{
+	UINT64 RequiredSize = 0;
+	UINT64 MemToAlloc = static_cast<UINT64>(sizeof(D3D12_PLACED_SUBRESOURCE_FOOTPRINT) + sizeof(UINT) + sizeof(UINT64)) * NumSubresources;
+	if (MemToAlloc > SIZE_MAX)
+	{
+		return 0;
+	}
+	void* pMem = HeapAlloc(GetProcessHeap(), 0, static_cast<SIZE_T>(MemToAlloc));
+	if (pMem == NULL)
+	{
+		return 0;
+	}
+	D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts = reinterpret_cast<D3D12_PLACED_SUBRESOURCE_FOOTPRINT*>(pMem);
+	UINT64* pRowSizesInBytes = reinterpret_cast<UINT64*>(pLayouts + NumSubresources);
+	UINT* pNumRows = reinterpret_cast<UINT*>(pRowSizesInBytes + NumSubresources);
+
+	D3D12_RESOURCE_DESC Desc = pDestinationResource->GetDesc();
+	ID3D12Device* pDevice;
+	pDestinationResource->GetDevice(__uuidof(*pDevice), reinterpret_cast<void**>(&pDevice));
+	pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, pLayouts, pNumRows, pRowSizesInBytes, &RequiredSize);
+	pDevice->Release();
+
+	UINT64 Result = UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, pLayouts, pNumRows, pRowSizesInBytes, pSrcData);
+	HeapFree(GetProcessHeap(), 0, pMem);
+	return Result;
+}
+
+//------------------------------------------------------------------------------------------------
+// Stack-allocating UpdateSubresources implementation
+template <UINT MaxSubresources>
+inline UINT64 UpdateSubresources(
+	_In_ ID3D12GraphicsCommandList* pCmdList,
+	_In_ ID3D12Resource* pDestinationResource,
+	_In_ ID3D12Resource* pIntermediate,
+	UINT64 IntermediateOffset,
+	_In_range_(0, MaxSubresources) UINT FirstSubresource,
+	_In_range_(1, MaxSubresources - FirstSubresource) UINT NumSubresources,
+	_In_reads_(NumSubresources) D3D12_SUBRESOURCE_DATA* pSrcData)
+{
+	UINT64 RequiredSize = 0;
+	D3D12_PLACED_SUBRESOURCE_FOOTPRINT Layouts[MaxSubresources];
+	UINT NumRows[MaxSubresources];
+	UINT64 RowSizesInBytes[MaxSubresources];
+
+	D3D12_RESOURCE_DESC Desc = pDestinationResource->GetDesc();
+	ID3D12Device* pDevice;
+	pDestinationResource->GetDevice(__uuidof(*pDevice), reinterpret_cast<void**>(&pDevice));
+	pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, Layouts, NumRows, RowSizesInBytes, &RequiredSize);
+	pDevice->Release();
+
+	return UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, Layouts, NumRows, RowSizesInBytes, pSrcData);
+}
+
+//------------------------------------------------------------------------------------------------
+inline bool D3D12IsLayoutOpaque(D3D12_TEXTURE_LAYOUT Layout)
+{
+	return Layout == D3D12_TEXTURE_LAYOUT_UNKNOWN || Layout == D3D12_TEXTURE_LAYOUT_64KB_UNDEFINED_SWIZZLE;
+}
+
+//------------------------------------------------------------------------------------------------
+inline ID3D12CommandList* const* CommandListCast(ID3D12GraphicsCommandList* const* pp)
+{
+	// This cast is useful for passing strongly typed command list pointers into
+	// ExecuteCommandLists.
+	// This cast is valid as long as the const-ness is respected. D3D12 APIs do
+	// respect the const-ness of their arguments.
+	return reinterpret_cast<ID3D12CommandList* const*>(pp);
+}
+
+
+#endif // defined( __cplusplus )
+
+#endif //__D3DX12_H__
+
+
+

+ 15 - 0
图形学/DirectX学习/src/D3DBox/D3DBox/framework.h

@@ -0,0 +1,15 @@
+// header.h: 标准系统包含文件的包含文件,
+// 或特定于项目的包含文件
+//
+
+#pragma once
+
+#include "targetver.h"
+#define WIN32_LEAN_AND_MEAN             // 从 Windows 头文件中排除极少使用的内容
+// Windows 头文件
+#include <windows.h>
+// C 运行时头文件
+#include <stdlib.h>
+#include <malloc.h>
+#include <memory.h>
+#include <tchar.h>

BIN
图形学/DirectX学习/src/D3DBox/D3DBox/small.ico


+ 6 - 0
图形学/DirectX学习/src/D3DBox/D3DBox/targetver.h

@@ -0,0 +1,6 @@
+#pragma once
+
+// // 包含 SDKDDKVer.h 可定义可用的最高版本的 Windows 平台。
+// 如果希望为之前的 Windows 平台构建应用程序,在包含 SDKDDKVer.h 之前请先包含 WinSDKVer.h 并
+// 将 _WIN32_WINNT 宏设置为想要支持的平台。
+#include <SDKDDKVer.h>