aboutsummaryrefslogtreecommitdiff
path: root/demo/DemoAppD3D12
diff options
context:
space:
mode:
Diffstat (limited to 'demo/DemoAppD3D12')
-rw-r--r--demo/DemoAppD3D12/DemoAppD3D12.vcxproj269
-rw-r--r--demo/DemoAppD3D12/DemoAppD3D12.vcxproj.filters71
-rw-r--r--demo/DemoAppD3D12/NvFlowInteropD3D12.cpp105
-rw-r--r--demo/DemoAppD3D12/appD3D12Ctx.cpp1097
-rw-r--r--demo/DemoAppD3D12/appD3D12Ctx.h113
-rw-r--r--demo/DemoAppD3D12/computeContextD3D12.cpp759
-rw-r--r--demo/DemoAppD3D12/computeContextD3D12.h52
-rw-r--r--demo/DemoAppD3D12/imguiGraphD3D12.cpp662
-rw-r--r--demo/DemoAppD3D12/imguiGraphD3D12.h48
-rw-r--r--demo/DemoAppD3D12/imguiInteropD3D12.cpp60
-rw-r--r--demo/DemoAppD3D12/imguiPS.hlsl.h195
-rw-r--r--demo/DemoAppD3D12/imguiVS.hlsl.h246
-rw-r--r--demo/DemoAppD3D12/meshD3D12.cpp576
-rw-r--r--demo/DemoAppD3D12/meshD3D12.h19
-rw-r--r--demo/DemoAppD3D12/meshInteropD3D12.cpp38
-rw-r--r--demo/DemoAppD3D12/meshPS.hlsl.h205
-rw-r--r--demo/DemoAppD3D12/meshVS.hlsl.h223
17 files changed, 4738 insertions, 0 deletions
diff --git a/demo/DemoAppD3D12/DemoAppD3D12.vcxproj b/demo/DemoAppD3D12/DemoAppD3D12.vcxproj
new file mode 100644
index 0000000..9ddc20a
--- /dev/null
+++ b/demo/DemoAppD3D12/DemoAppD3D12.vcxproj
@@ -0,0 +1,269 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" 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 Condition="'$(Platform)'=='Win32'">
+ <PlatformName>win32</PlatformName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Platform)'=='x64'">
+ <PlatformName>win64</PlatformName>
+ </PropertyGroup>
+ <ItemGroup>
+ <ClCompile Include="appD3D12Ctx.cpp" />
+ <ClCompile Include="computeContextD3D12.cpp" />
+ <ClCompile Include="imguiGraphD3D12.cpp" />
+ <ClCompile Include="imguiInteropD3D12.cpp" />
+ <ClCompile Include="meshD3D12.cpp" />
+ <ClCompile Include="meshInteropD3D12.cpp" />
+ <ClCompile Include="NvFlowInteropD3D12.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="appD3D12Ctx.h" />
+ <ClInclude Include="computeContextD3D12.h" />
+ <ClInclude Include="imguiGraphD3D12.h" />
+ <ClInclude Include="meshD3D12.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <FxCompile Include="..\Shaders\imguiPS.hlsl">
+ <ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Pixel</ShaderType>
+ <ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Pixel</ShaderType>
+ <ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Pixel</ShaderType>
+ <ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Pixel</ShaderType>
+ </FxCompile>
+ <FxCompile Include="..\Shaders\imguiVS.hlsl">
+ <ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Vertex</ShaderType>
+ <ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Vertex</ShaderType>
+ <ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Vertex</ShaderType>
+ <ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Vertex</ShaderType>
+ </FxCompile>
+ <FxCompile Include="..\Shaders\meshPS.hlsl">
+ <ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Pixel</ShaderType>
+ <ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Pixel</ShaderType>
+ <ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Pixel</ShaderType>
+ <ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Pixel</ShaderType>
+ </FxCompile>
+ <FxCompile Include="..\Shaders\meshVS.hlsl">
+ <ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Vertex</ShaderType>
+ <ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Vertex</ShaderType>
+ <ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Vertex</ShaderType>
+ <ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Vertex</ShaderType>
+ </FxCompile>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{BCBFA7E1-C9CE-4326-A5E3-3A93416BBD90}</ProjectGuid>
+ <RootNamespace>DemoAppD3D12</RootNamespace>
+ <WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v140</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ <UseOfMfc>Static</UseOfMfc>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v140</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ <UseOfMfc>Static</UseOfMfc>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v140</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ <UseOfMfc>Static</UseOfMfc>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v140</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ <UseOfMfc>Static</UseOfMfc>
+ </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" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <OutDir>$(SolutionDir)bin\$(PlatformName)\</OutDir>
+ <IntDir>interm\$(Configuration)_$(PlatformName)\</IntDir>
+ <IncludePath>$(SolutionDir)\include;$(SolutionDir)\NvFlowContextD3D12;$(SolutionDir)\NvFlow;$(SolutionDir)\NvFlowContext;$(SolutionDir)external\SDL2\include;$(VC_IncludePath);$(WindowsSDK_IncludePath)</IncludePath>
+ <LibraryPath>$(SolutionDir)lib\win64;$(SolutionDir)external\SDL2\lib\x64;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64</LibraryPath>
+ <TargetName>$(ProjectName)$(Configuration)_$(PlatformName)</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <OutDir>$(SolutionDir)bin\$(PlatformName)\</OutDir>
+ <IntDir>interm\$(Configuration)_$(PlatformName)\</IntDir>
+ <IncludePath>$(SolutionDir)\include;$(SolutionDir)\NvFlowContextD3D12;$(SolutionDir)\NvFlow;$(SolutionDir)\NvFlowContext;$(SolutionDir)external\SDL2\include;$(VC_IncludePath);$(WindowsSDK_IncludePath)</IncludePath>
+ <LibraryPath>$(SolutionDir)lib\win64;$(SolutionDir)external\SDL2\lib\x64;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64</LibraryPath>
+ <TargetName>$(ProjectName)$(Configuration)_$(PlatformName)</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <IncludePath>$(SolutionDir)\include;$(SolutionDir)\NvFlowContextD3D12;$(SolutionDir)\NvFlow;$(SolutionDir)\NvFlowContext;$(SolutionDir)external\SDL2\include;$(VC_IncludePath);$(WindowsSDK_IncludePath)</IncludePath>
+ <LibraryPath>$(SolutionDir)lib\win32;$(SolutionDir)external\SDL2\lib\x86;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86</LibraryPath>
+ <OutDir>$(SolutionDir)bin\$(PlatformName)\</OutDir>
+ <IntDir>interm\$(Configuration)_$(PlatformName)\</IntDir>
+ <TargetName>$(ProjectName)$(Configuration)_$(PlatformName)</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <IncludePath>$(SolutionDir)\include;$(SolutionDir)\NvFlowContextD3D12;$(SolutionDir)\NvFlow;$(SolutionDir)\NvFlowContext;$(SolutionDir)external\SDL2\include;$(VC_IncludePath);$(WindowsSDK_IncludePath)</IncludePath>
+ <LibraryPath>$(SolutionDir)lib\win32;$(SolutionDir)external\SDL2\lib\x86;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86</LibraryPath>
+ <OutDir>$(SolutionDir)bin\$(PlatformName)\</OutDir>
+ <IntDir>interm\$(Configuration)_$(PlatformName)\</IntDir>
+ <TargetName>$(ProjectName)$(Configuration)_$(PlatformName)</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <SDLCheck>true</SDLCheck>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalDependencies>NvFlowLib$(Configuration)_$(PlatformName).lib;SDL2.lib;SDL2main.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ <FxCompile>
+ <EntryPointName>%(Filename)</EntryPointName>
+ </FxCompile>
+ <FxCompile>
+ <ShaderModel>5.0</ShaderModel>
+ </FxCompile>
+ <FxCompile>
+ <VariableName>
+ </VariableName>
+ </FxCompile>
+ <FxCompile>
+ <HeaderFileOutput>$(ProjectDir)%(Filename).hlsl.h</HeaderFileOutput>
+ </FxCompile>
+ <FxCompile>
+ <ObjectFileOutput />
+ </FxCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <SDLCheck>true</SDLCheck>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalDependencies>NvFlowLib$(Configuration)_$(PlatformName).lib;SDL2.lib;SDL2main.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ <FxCompile>
+ <EntryPointName>%(Filename)</EntryPointName>
+ </FxCompile>
+ <FxCompile>
+ <ShaderModel>5.0</ShaderModel>
+ </FxCompile>
+ <FxCompile>
+ <VariableName>
+ </VariableName>
+ </FxCompile>
+ <FxCompile>
+ <HeaderFileOutput>$(ProjectDir)%(Filename).hlsl.h</HeaderFileOutput>
+ </FxCompile>
+ <FxCompile>
+ <ObjectFileOutput />
+ </FxCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <SDLCheck>true</SDLCheck>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <AdditionalDependencies>NvFlowLib$(Configuration)_$(PlatformName).lib;SDL2.lib;SDL2main.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ <FxCompile>
+ <EntryPointName>%(Filename)</EntryPointName>
+ </FxCompile>
+ <FxCompile>
+ <ShaderModel>5.0</ShaderModel>
+ </FxCompile>
+ <FxCompile>
+ <VariableName>
+ </VariableName>
+ </FxCompile>
+ <FxCompile>
+ <HeaderFileOutput>$(ProjectDir)%(Filename).hlsl.h</HeaderFileOutput>
+ </FxCompile>
+ <FxCompile>
+ <ObjectFileOutput />
+ </FxCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <SDLCheck>true</SDLCheck>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <AdditionalDependencies>NvFlowLib$(Configuration)_$(PlatformName).lib;SDL2.lib;SDL2main.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ <FxCompile>
+ <EntryPointName>%(Filename)</EntryPointName>
+ </FxCompile>
+ <FxCompile>
+ <ShaderModel>5.0</ShaderModel>
+ </FxCompile>
+ <FxCompile>
+ <VariableName>
+ </VariableName>
+ </FxCompile>
+ <FxCompile>
+ <HeaderFileOutput>$(ProjectDir)%(Filename).hlsl.h</HeaderFileOutput>
+ </FxCompile>
+ <FxCompile>
+ <ObjectFileOutput />
+ </FxCompile>
+ </ItemDefinitionGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/demo/DemoAppD3D12/DemoAppD3D12.vcxproj.filters b/demo/DemoAppD3D12/DemoAppD3D12.vcxproj.filters
new file mode 100644
index 0000000..fcb8c61
--- /dev/null
+++ b/demo/DemoAppD3D12/DemoAppD3D12.vcxproj.filters
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <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>
+ <Filter Include="Shaders">
+ <UniqueIdentifier>{154d623a-ffac-4ddd-a878-c4dc912a750d}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="appD3D12Ctx.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="imguiGraphD3D12.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="meshD3D12.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="NvFlowInteropD3D12.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="meshInteropD3D12.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="imguiInteropD3D12.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="computeContextD3D12.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="appD3D12Ctx.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="imguiGraphD3D12.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="meshD3D12.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="computeContextD3D12.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <FxCompile Include="..\Shaders\imguiPS.hlsl">
+ <Filter>Shaders</Filter>
+ </FxCompile>
+ <FxCompile Include="..\Shaders\imguiVS.hlsl">
+ <Filter>Shaders</Filter>
+ </FxCompile>
+ <FxCompile Include="..\Shaders\meshPS.hlsl">
+ <Filter>Shaders</Filter>
+ </FxCompile>
+ <FxCompile Include="..\Shaders\meshVS.hlsl">
+ <Filter>Shaders</Filter>
+ </FxCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/demo/DemoAppD3D12/NvFlowInteropD3D12.cpp b/demo/DemoAppD3D12/NvFlowInteropD3D12.cpp
new file mode 100644
index 0000000..ce79bcc
--- /dev/null
+++ b/demo/DemoAppD3D12/NvFlowInteropD3D12.cpp
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved.
+ *
+ * NVIDIA CORPORATION and its licensors retain all intellectual property
+ * and proprietary rights in and to this software, related documentation
+ * and any modifications thereto. Any use, reproduction, disclosure or
+ * distribution of this software and related documentation without an express
+ * license agreement from NVIDIA CORPORATION is strictly prohibited.
+ */
+
+#include <d3d12.h>
+
+#include "../DemoApp/NvFlowInterop.h"
+
+#include "NvFlowContextD3D12.h"
+#include "appD3D12Ctx.h"
+
+NvFlowDescriptorReserveHandleD3D12 NvFlowInteropReserveDescriptors(void* userdata, NvFlowUint numDescriptors, NvFlowUint64 lastFenceCompleted, NvFlowUint64 nextFenceValue)
+{
+ auto appctx = static_cast<AppGraphCtx*>(userdata);
+ auto srcHandle = appctx->m_dynamicHeapCbvSrvUav.reserveDescriptors(numDescriptors, lastFenceCompleted, nextFenceValue);
+ NvFlowDescriptorReserveHandleD3D12 handle = {};
+ handle.heap = srcHandle.heap;
+ handle.descriptorSize = srcHandle.descriptorSize;
+ handle.cpuHandle = srcHandle.cpuHandle;
+ handle.gpuHandle = srcHandle.gpuHandle;
+ return handle;
+}
+
+void NvFlowInteropUpdateContextDesc(NvFlowContextDescD3D12* desc, AppGraphCtx* appctx)
+{
+ desc->device = appctx->m_device;
+ desc->commandQueue = appctx->m_commandQueue;
+ desc->commandQueueFence = appctx->m_fence;
+ desc->commandList = appctx->m_commandList;
+ desc->lastFenceCompleted = appctx->m_lastFenceComplete;
+ desc->nextFenceValue = appctx->m_thisFrameFenceID;
+
+ desc->dynamicHeapCbvSrvUav.userdata = appctx;
+ desc->dynamicHeapCbvSrvUav.reserveDescriptors = NvFlowInteropReserveDescriptors;
+}
+
+NvFlowContext* NvFlowInteropCreateContext(AppGraphCtx* appctx)
+{
+ NvFlowContextDescD3D12 desc = {};
+ NvFlowInteropUpdateContextDesc(&desc, appctx);
+ return NvFlowCreateContextD3D12(NV_FLOW_VERSION, &desc);
+}
+
+NvFlowDepthStencilView* NvFlowInteropCreateDepthStencilView(AppGraphCtx* appctx, NvFlowContext* flowctx)
+{
+ NvFlowDepthStencilViewDescD3D12 desc = {};
+ desc.dsvHandle = appctx->m_current_dsvHandle;
+ desc.dsvDesc = appctx->m_current_dsvDesc;
+ desc.srvHandle = appctx->m_current_depth_srvHandle;
+ desc.srvDesc = appctx->m_current_depth_srvDesc;
+ desc.resource = appctx->m_depthStencil;
+ desc.currentState = D3D12_RESOURCE_STATE_DEPTH_WRITE;
+ desc.viewport = appctx->m_viewport;
+ return NvFlowCreateDepthStencilViewD3D12(flowctx, &desc);
+}
+
+NvFlowRenderTargetView* NvFlowInteropCreateRenderTargetView(AppGraphCtx* appctx, NvFlowContext* flowctx)
+{
+ NvFlowRenderTargetViewDescD3D12 desc = {};
+ desc.rtvHandle = appctx->m_current_rtvHandle;
+ desc.rtvDesc = appctx->m_current_rtvDesc;
+ desc.resource = appctx->m_current_renderTarget;
+ desc.currentState = D3D12_RESOURCE_STATE_RENDER_TARGET;
+ desc.viewport = appctx->m_viewport;
+ desc.scissor = appctx->m_scissorRect;
+ return NvFlowCreateRenderTargetViewD3D12(flowctx, &desc);
+}
+
+void NvFlowInteropUpdateContext(NvFlowContext* context, AppGraphCtx* appctx)
+{
+ NvFlowContextDescD3D12 desc = {};
+ NvFlowInteropUpdateContextDesc(&desc, appctx);
+ NvFlowUpdateContextD3D12(context, &desc);
+}
+
+void NvFlowInteropUpdateDepthStencilView(NvFlowDepthStencilView* view, AppGraphCtx* appctx, NvFlowContext* flowctx)
+{
+ NvFlowDepthStencilViewDescD3D12 desc = {};
+ desc.dsvHandle = appctx->m_current_dsvHandle;
+ desc.dsvDesc = appctx->m_current_dsvDesc;
+ desc.srvHandle = appctx->m_current_depth_srvHandle;
+ desc.srvDesc = appctx->m_current_depth_srvDesc;
+ desc.resource = appctx->m_depthStencil;
+ desc.currentState = D3D12_RESOURCE_STATE_DEPTH_WRITE;
+ desc.viewport = appctx->m_viewport;
+ NvFlowUpdateDepthStencilViewD3D12(flowctx, view, &desc);
+}
+
+void NvFlowInteropUpdateRenderTargetView(NvFlowRenderTargetView* view, AppGraphCtx* appctx, NvFlowContext* flowctx)
+{
+ NvFlowRenderTargetViewDescD3D12 desc = {};
+ desc.rtvHandle = appctx->m_current_rtvHandle;
+ desc.rtvDesc = appctx->m_current_rtvDesc;
+ desc.resource = appctx->m_current_renderTarget;
+ desc.currentState = D3D12_RESOURCE_STATE_RENDER_TARGET;
+ desc.viewport = appctx->m_viewport;
+ desc.scissor = appctx->m_scissorRect;
+ NvFlowUpdateRenderTargetViewD3D12(flowctx, view, &desc);
+} \ No newline at end of file
diff --git a/demo/DemoAppD3D12/appD3D12Ctx.cpp b/demo/DemoAppD3D12/appD3D12Ctx.cpp
new file mode 100644
index 0000000..8d1d7ff
--- /dev/null
+++ b/demo/DemoAppD3D12/appD3D12Ctx.cpp
@@ -0,0 +1,1097 @@
+/*
+ * Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved.
+ *
+ * NVIDIA CORPORATION and its licensors retain all intellectual property
+ * and proprietary rights in and to this software, related documentation
+ * and any modifications thereto. Any use, reproduction, disclosure or
+ * distribution of this software and related documentation without an express
+ * license agreement from NVIDIA CORPORATION is strictly prohibited.
+ */
+
+//direct3d headers
+#include <d3d12.h>
+#include <dxgi1_4.h>
+
+// include the Direct3D Library file
+#pragma comment (lib, "d3d12.lib")
+#pragma comment (lib, "DXGI.lib")
+
+#include "appD3D12Ctx.h"
+
+#include <stdio.h>
+
+#include <SDL.h>
+#include <SDL_video.h>
+#include <SDL_syswm.h>
+
+namespace
+{
+ // COM object release utilities
+ template <class T>
+ void inline COMRelease(T& t)
+ {
+ if (t) t->Release();
+ t = nullptr;
+ }
+
+ template <class T>
+ void inline COMRelease(T& t, UINT arraySize)
+ {
+ for (UINT i = 0; i < arraySize; i++)
+ {
+ if (t[i]) t[i]->Release();
+ t[i] = nullptr;
+ }
+ }
+}
+
+AppGraphProfiler* appGraphCreateProfiler(AppGraphCtx* ctx);
+void appGraphProfilerFrameBegin(AppGraphProfiler* profiler);
+void appGraphProfilerFrameEnd(AppGraphProfiler* profiler);
+void appGraphProfilerEnable(AppGraphProfiler* profiler, bool enabled);
+void appGraphProfilerBegin(AppGraphProfiler* profiler, const char* label);
+void appGraphProfilerEnd(AppGraphProfiler* profiler, const char* label);
+bool appGraphProfilerGet(AppGraphProfiler* profiler, const char** plabel, float* cpuTime, float* gpuTime, int index);
+void appGraphReleaseProfiler(AppGraphProfiler* profiler);
+
+void AppGraphCtxInitRenderTarget(AppGraphCtx* context, SDL_Window* window, bool fullscreen);
+
+AppGraphCtx::AppGraphCtx()
+{
+ m_profiler = appGraphCreateProfiler(this);
+}
+
+AppGraphCtx::~AppGraphCtx()
+{
+ AppGraphCtxReleaseRenderTarget(this);
+
+ COMRelease(m_device);
+ COMRelease(m_commandQueue);
+ COMRelease(m_rtvHeap);
+ COMRelease(m_dsvHeap);
+ COMRelease(m_depthSrvHeap);
+ COMRelease(m_commandAllocators, m_frameCount);
+
+ COMRelease(m_fence);
+ CloseHandle(m_fenceEvent);
+
+ COMRelease(m_commandList);
+
+ m_dynamicHeapCbvSrvUav.release();
+
+ appGraphReleaseProfiler(m_profiler);
+ m_profiler = nullptr;
+}
+
+AppGraphCtx* AppGraphCtxCreate(int deviceID)
+{
+ AppGraphCtx* context = new AppGraphCtx;
+
+ HRESULT hr = S_OK;
+
+#if defined(_DEBUG)
+ // Enable the D3D12 debug layer.
+ {
+ ID3D12Debug* debugController;
+ if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController))))
+ {
+ debugController->EnableDebugLayer();
+ }
+ COMRelease(debugController);
+ }
+#endif
+
+ UINT debugFlags = 0;
+#ifdef _DEBUG
+ debugFlags |= DXGI_CREATE_FACTORY_DEBUG;
+#endif
+
+ // enumerate devices
+ IDXGIFactory4* pFactory = NULL;
+ CreateDXGIFactory2(debugFlags, IID_PPV_ARGS(&pFactory));
+ IDXGIAdapter1* pAdapterTemp = NULL;
+ IDXGIAdapter1* pAdapter = NULL;
+ DXGI_ADAPTER_DESC1 adapterDesc;
+ int adapterIdx = 0;
+ while (S_OK == pFactory->EnumAdapters1(adapterIdx, &pAdapterTemp))
+ {
+ pAdapterTemp->GetDesc1(&adapterDesc);
+
+ context->m_dedicatedVideoMemory = (size_t)adapterDesc.DedicatedVideoMemory;
+
+ if (deviceID == adapterIdx)
+ {
+ pAdapter = pAdapterTemp;
+ break;
+ }
+ else
+ {
+ pAdapterTemp->Release();
+ }
+ adapterIdx++;
+ }
+
+ // create device
+ if (hr = D3D12CreateDevice(pAdapter, D3D_FEATURE_LEVEL_11_0, __uuidof(ID3D12Device), (void**)&context->m_device))
+ {
+ delete context;
+ return nullptr;
+ }
+
+ // to disable annoying warning
+#if 0
+ context->m_device->SetStablePowerState(TRUE);
+#endif
+
+ // create command queue
+ {
+ D3D12_COMMAND_QUEUE_DESC desc;
+ desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
+ desc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL;
+ desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
+ desc.NodeMask = 0;
+
+ if (hr = context->m_device->CreateCommandQueue(&desc, IID_PPV_ARGS(&context->m_commandQueue)))
+ {
+ delete context;
+ return nullptr;
+ }
+ }
+
+ // cleanup adapter and factory
+ COMRelease(pAdapter);
+ COMRelease(pFactory);
+
+ // create RTV descriptor heap
+ {
+ D3D12_DESCRIPTOR_HEAP_DESC desc = {};
+ desc.NumDescriptors = context->m_renderTargetCount;
+ desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
+ desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
+ if (hr = context->m_device->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&context->m_rtvHeap)))
+ {
+ delete context;
+ return nullptr;
+ }
+ context->m_rtvDescriptorSize = context->m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
+ }
+
+ // create DSV descriptor heap
+ {
+ D3D12_DESCRIPTOR_HEAP_DESC desc = {};
+ desc.NumDescriptors = 1;
+ desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV;
+ desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
+ if (hr = context->m_device->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&context->m_dsvHeap)))
+ {
+ delete context;
+ return nullptr;
+ }
+ }
+
+ // create depth SRV descriptor heap
+ {
+ D3D12_DESCRIPTOR_HEAP_DESC desc = {};
+ desc.NumDescriptors = 1;
+ desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
+ desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
+ if (hr = context->m_device->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&context->m_depthSrvHeap)))
+ {
+ delete context;
+ return nullptr;
+ }
+ }
+
+ // Create per frame resources
+ {
+ for (UINT idx = 0; idx < context->m_frameCount; idx++)
+ {
+ if (hr = context->m_device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&context->m_commandAllocators[idx])))
+ {
+ delete context;
+ return nullptr;
+ }
+ }
+ }
+
+ // create dynamic heap
+ {
+ context->m_dynamicHeapCbvSrvUav.init(context->m_device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 256u * 1024u);
+ }
+
+ // Create command list and close it
+ {
+ if (hr = context->m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT,
+ context->m_commandAllocators[context->m_frameIndex], nullptr, IID_PPV_ARGS(&context->m_commandList))
+ )
+ {
+ delete context;
+ return nullptr;
+ }
+ context->m_commandList->Close();
+ }
+
+ // create synchronization objects
+ {
+ if (hr = context->m_device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&context->m_fence)))
+ {
+ delete context;
+ return nullptr;
+ }
+
+ context->m_fenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
+ if (context->m_fenceEvent == nullptr)
+ {
+ delete context;
+ return nullptr;
+ }
+ }
+
+ return context;
+}
+
+bool AppGraphCtxUpdateSize(AppGraphCtx* context, SDL_Window* window, bool fullscreen)
+{
+ // TODO: fix iflip fullscreen support
+ fullscreen = false;
+
+ bool sizeChanged = false;
+
+ // sync with window
+ {
+ HWND hWnd = nullptr;
+ // get Windows handle to this SDL window
+ SDL_SysWMinfo winInfo;
+ SDL_VERSION(&winInfo.version);
+ if (SDL_GetWindowWMInfo(window, &winInfo))
+ {
+ if (winInfo.subsystem == SDL_SYSWM_WINDOWS)
+ {
+ hWnd = winInfo.info.win.window;
+ }
+ }
+ context->m_hWnd = hWnd;
+ context->m_fullscreen = fullscreen;
+
+ HRESULT hr = S_OK;
+
+ RECT rc;
+ GetClientRect(context->m_hWnd, &rc);
+ UINT width = rc.right - rc.left;
+ UINT height = rc.bottom - rc.top;
+
+ if (context->m_winW != width || context->m_winH != height)
+ {
+ context->m_winW = width;
+ context->m_winH = height;
+ sizeChanged = true;
+ context->m_valid = (context->m_winW != 0 && context->m_winH != 0);
+ }
+ }
+
+ if (sizeChanged)
+ {
+ AppGraphCtxReleaseRenderTarget(context);
+ }
+ if (sizeChanged && context->m_valid)
+ {
+ AppGraphCtxInitRenderTarget(context, window, fullscreen);
+ }
+
+ return context->m_valid;
+}
+
+void AppGraphCtxInitRenderTarget(AppGraphCtx* context, SDL_Window* window, bool fullscreen)
+{
+ HWND hWnd = nullptr;
+ // get Windows handle to this SDL window
+ SDL_SysWMinfo winInfo;
+ SDL_VERSION(&winInfo.version);
+ if (SDL_GetWindowWMInfo(window, &winInfo))
+ {
+ if (winInfo.subsystem == SDL_SYSWM_WINDOWS)
+ {
+ hWnd = winInfo.info.win.window;
+ }
+ }
+ context->m_hWnd = hWnd;
+ context->m_fullscreen = fullscreen;
+
+ HRESULT hr = S_OK;
+
+ UINT debugFlags = 0;
+#ifdef _DEBUG
+ debugFlags |= DXGI_CREATE_FACTORY_DEBUG;
+#endif
+
+ // enumerate devices
+ IDXGIFactory4* pFactory = NULL;
+ CreateDXGIFactory2(debugFlags, IID_PPV_ARGS(&pFactory));
+
+ // create the swap chain
+ for (int i = 0; i < 2; i++)
+ {
+ DXGI_SWAP_CHAIN_DESC desc;
+ ZeroMemory(&desc, sizeof(desc));
+ desc.BufferCount = context->m_renderTargetCount;
+ desc.BufferDesc.Width = context->m_winW;
+ desc.BufferDesc.Height = context->m_winH;
+ desc.BufferDesc.Format = context->m_rtv_format; // DXGI_FORMAT_R8G8B8A8_UNORM;
+ desc.BufferDesc.RefreshRate.Numerator = 0;
+ desc.BufferDesc.RefreshRate.Denominator = 0;
+ desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
+ desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
+ desc.OutputWindow = context->m_hWnd;
+ desc.SampleDesc.Count = 1;
+ desc.SampleDesc.Quality = 0;
+ desc.Windowed = TRUE; // m_fullscreen ? FALSE : TRUE;
+ desc.Flags = context->m_fullscreen ? 0u : DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT;
+
+ context->m_current_rtvDesc.Format = context->m_rtv_format;
+ context->m_current_rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
+ context->m_current_rtvDesc.Texture2D.MipSlice = 0u;
+ context->m_current_rtvDesc.Texture2D.PlaneSlice = 0u;
+
+ if (hr = pFactory->CreateSwapChain(context->m_commandQueue, &desc, (IDXGISwapChain**)&context->m_swapChain))
+ {
+ COMRelease(context->m_swapChain);
+ context->m_fullscreen = false;
+ continue;
+ }
+
+ if (!context->m_fullscreen)
+ {
+ context->m_swapChainWaitableObject = context->m_swapChain->GetFrameLatencyWaitableObject();
+ context->m_swapChain->SetMaximumFrameLatency(context->m_renderTargetCount - 2);
+ }
+ else
+ {
+ hr = context->m_swapChain->SetFullscreenState(true, nullptr);
+ if (hr != S_OK)
+ {
+ COMRelease(context->m_swapChain);
+ context->m_fullscreen = false;
+ continue;
+ }
+ DXGI_SWAP_CHAIN_DESC desc = {};
+ context->m_swapChain->GetDesc(&desc);
+ context->m_swapChain->ResizeBuffers(context->m_renderTargetCount, context->m_winW, context->m_winH, desc.BufferDesc.Format, desc.Flags);
+ }
+
+ context->m_frameIndex = context->m_swapChain->GetCurrentBackBufferIndex();
+ break;
+ }
+
+ // configure scissor and viewport
+ {
+ context->m_viewport.Width = float(context->m_winW);
+ context->m_viewport.Height = float(context->m_winH);
+ context->m_viewport.MaxDepth = 1.f;
+
+ context->m_scissorRect.right = context->m_winW;
+ context->m_scissorRect.bottom = context->m_winH;
+ }
+
+ COMRelease(pFactory);
+
+ // create per render target resources
+ {
+ D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = context->m_rtvHeap->GetCPUDescriptorHandleForHeapStart();
+
+ for (UINT idx = 0; idx < context->m_renderTargetCount; idx++)
+ {
+ if (hr = context->m_swapChain->GetBuffer(idx, IID_PPV_ARGS(&context->m_renderTargets[idx])))
+ {
+ return;
+ }
+ context->m_device->CreateRenderTargetView(context->m_renderTargets[idx], nullptr, rtvHandle);
+ rtvHandle.ptr += context->m_rtvDescriptorSize;
+ }
+ }
+
+ // create the depth stencil
+ {
+ D3D12_HEAP_PROPERTIES heapProps = {};
+ heapProps.Type = D3D12_HEAP_TYPE_DEFAULT;
+ heapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
+ heapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
+ heapProps.CreationNodeMask = 0u;
+ heapProps.VisibleNodeMask = 0u;
+
+ D3D12_RESOURCE_DESC texDesc = {};
+ texDesc.MipLevels = 1u;
+ texDesc.Format = context->m_depth_format; // DXGI_FORMAT_R32_TYPELESS; // DXGI_FORMAT_R24G8_TYPELESS
+ texDesc.Width = context->m_winW;
+ texDesc.Height = context->m_winH;
+ texDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL /*| D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE*/;
+ texDesc.DepthOrArraySize = 1u;
+ texDesc.SampleDesc.Count = 1u;
+ texDesc.SampleDesc.Quality = 0u;
+ texDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
+
+ D3D12_CLEAR_VALUE clearValue;
+ clearValue.Format = context->m_dsv_format; // DXGI_FORMAT_D32_FLOAT;
+ clearValue.DepthStencil.Depth = 1.f;
+ clearValue.DepthStencil.Stencil = 0;
+
+ if (hr = context->m_device->CreateCommittedResource(
+ &heapProps,
+ D3D12_HEAP_FLAG_NONE,
+ &texDesc,
+ D3D12_RESOURCE_STATE_DEPTH_WRITE,
+ &clearValue,
+ IID_PPV_ARGS(&context->m_depthStencil)
+ ))
+ {
+ return;
+ }
+
+ // create the depth stencil view
+ D3D12_DEPTH_STENCIL_VIEW_DESC viewDesc = {};
+ viewDesc.Format = context->m_dsv_format; // DXGI_FORMAT_D32_FLOAT;
+ viewDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
+ viewDesc.Flags = D3D12_DSV_FLAG_NONE;
+ viewDesc.Texture2D.MipSlice = 0;
+
+ context->m_current_dsvDesc = viewDesc;
+
+ context->m_device->CreateDepthStencilView(context->m_depthStencil, &viewDesc, context->m_dsvHeap->GetCPUDescriptorHandleForHeapStart());
+
+ // create the depth SRV
+ D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
+ srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
+ srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
+ srvDesc.Format = context->m_depth_srv_format; // DXGI_FORMAT_R32_FLOAT;
+ srvDesc.Texture2D.MipLevels = 1;
+ srvDesc.Texture2D.MostDetailedMip = 0;
+ srvDesc.Texture2D.ResourceMinLODClamp = 0.f;
+
+ context->m_current_depth_srvDesc = srvDesc;
+
+ D3D12_CPU_DESCRIPTOR_HANDLE srvHandle = context->m_depthSrvHeap->GetCPUDescriptorHandleForHeapStart();
+ context->m_device->CreateShaderResourceView(context->m_depthStencil, &srvDesc, srvHandle);
+ }
+}
+
+void AppGraphCtxReleaseRenderTarget(AppGraphCtx* context)
+{
+ if (context->m_swapChain == nullptr)
+ {
+ return;
+ }
+
+ // need to make sure the pipeline is flushed
+ for (UINT i = 0; i < context->m_frameCount; i++)
+ {
+ // check dependencies
+ UINT64 fenceCompleted = context->m_fence->GetCompletedValue();
+ if (fenceCompleted < context->m_fenceValues[i])
+ {
+ context->m_fence->SetEventOnCompletion(context->m_fenceValues[i], context->m_fenceEvent);
+ WaitForSingleObjectEx(context->m_fenceEvent, INFINITE, FALSE);
+ }
+ }
+
+ BOOL bFullscreen = FALSE;
+ context->m_swapChain->GetFullscreenState(&bFullscreen, nullptr);
+ if (bFullscreen == TRUE) context->m_swapChain->SetFullscreenState(FALSE, nullptr);
+
+ COMRelease(context->m_swapChain);
+ COMRelease(context->m_renderTargets, context->m_renderTargetCount);
+ COMRelease(context->m_depthStencil);
+
+ context->m_valid = false;
+ context->m_winW = 0u;
+ context->m_winH = 0u;
+}
+
+void AppGraphCtxRelease(AppGraphCtx* context)
+{
+ if (context == nullptr) return;
+
+ delete context;
+}
+
+void AppGraphCtxFrameStart(AppGraphCtx* context, float clearColor[4])
+{
+ // Get back render target index
+ context->m_renderTargetIndex = context->m_swapChain->GetCurrentBackBufferIndex();
+
+ // check dependencies
+ UINT64 fenceCompleted = context->m_fence->GetCompletedValue();
+ if (fenceCompleted < context->m_fenceValues[context->m_frameIndex])
+ {
+ context->m_fence->SetEventOnCompletion(context->m_fenceValues[context->m_frameIndex], context->m_fenceEvent);
+ WaitForSingleObjectEx(context->m_fenceEvent, INFINITE, FALSE);
+ }
+
+ // The fence ID associated with completion of this frame
+ context->m_thisFrameFenceID = context->m_frameID + 1;
+ context->m_lastFenceComplete = context->m_fence->GetCompletedValue();
+
+ // reset this frame's command allocator
+ context->m_commandAllocators[context->m_frameIndex]->Reset();
+
+ // reset command list with this frame's allocator
+ context->m_commandList->Reset(context->m_commandAllocators[context->m_frameIndex], nullptr);
+
+ appGraphProfilerFrameBegin(context->m_profiler);
+
+ context->m_commandList->RSSetViewports(1, &context->m_viewport);
+ context->m_commandList->RSSetScissorRects(1, &context->m_scissorRect);
+
+ D3D12_RESOURCE_BARRIER barrier = {};
+ barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
+ barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
+ barrier.Transition.pResource = context->m_renderTargets[context->m_renderTargetIndex];
+ barrier.Transition.Subresource = 0u;
+ barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT;
+ barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET;
+ context->m_commandList->ResourceBarrier(1, &barrier);
+
+ D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = context->m_rtvHeap->GetCPUDescriptorHandleForHeapStart();
+ rtvHandle.ptr += context->m_renderTargetIndex * context->m_rtvDescriptorSize;
+
+ D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = context->m_dsvHeap->GetCPUDescriptorHandleForHeapStart();
+ context->m_commandList->OMSetRenderTargets(1, &rtvHandle, FALSE, &dsvHandle);
+
+ context->m_commandList->ClearRenderTargetView(rtvHandle, clearColor, 0, nullptr);
+ context->m_commandList->ClearDepthStencilView(dsvHandle, D3D12_CLEAR_FLAG_DEPTH, 1.f, 0, 0, nullptr);
+
+ /// to simplify interop implementation
+ context->m_current_renderTarget = context->m_renderTargets[context->m_renderTargetIndex];
+ context->m_current_rtvHandle = rtvHandle;
+ context->m_current_dsvHandle = dsvHandle;
+ context->m_current_depth_srvHandle = context->m_depthSrvHeap->GetCPUDescriptorHandleForHeapStart();
+}
+
+void AppGraphCtxFramePresent(AppGraphCtx* context, bool fullsync)
+{
+ D3D12_RESOURCE_BARRIER barrier = {};
+ barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
+ barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
+ barrier.Transition.pResource = context->m_renderTargets[context->m_renderTargetIndex];
+ barrier.Transition.Subresource = 0u;
+ barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET;
+ barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT;
+ context->m_commandList->ResourceBarrier(1, &barrier);
+
+ context->m_commandList->Close();
+
+ // submit command list
+ ID3D12CommandList* cmdLists[] = { context->m_commandList };
+ context->m_commandQueue->ExecuteCommandLists(1, cmdLists);
+
+ // check if now is good time to present
+ bool shouldPresent = context->m_fullscreen ? true : WaitForSingleObjectEx(context->m_swapChainWaitableObject, 0, TRUE) != WAIT_TIMEOUT;
+ if (shouldPresent)
+ {
+ context->m_swapChain->Present(0, 0);
+ context->m_renderTargetID++;
+ }
+
+ appGraphProfilerFrameEnd(context->m_profiler);
+
+ // signal for this frame id
+ context->m_frameID++;
+ context->m_fenceValues[context->m_frameIndex] = context->m_frameID;
+ context->m_commandQueue->Signal(context->m_fence, context->m_frameID);
+
+ // increment frame index after signal
+ context->m_frameIndex = (context->m_frameIndex + 1) % context->m_frameCount;
+
+ if (fullsync)
+ {
+ // check dependencies
+ for (int frameIndex = 0; frameIndex < context->m_frameCount; frameIndex++)
+ {
+ UINT64 fenceCompleted = context->m_fence->GetCompletedValue();
+ if (fenceCompleted < context->m_fenceValues[frameIndex])
+ {
+ context->m_fence->SetEventOnCompletion(context->m_fenceValues[frameIndex], context->m_fenceEvent);
+ WaitForSingleObjectEx(context->m_fenceEvent, INFINITE, FALSE);
+ }
+ }
+ }
+}
+
+void AppGraphCtxWaitForFrames(AppGraphCtx* context, unsigned int maxFramesInFlight)
+{
+ unsigned int framesActive = maxFramesInFlight;
+ while (framesActive >= maxFramesInFlight)
+ {
+ // reset count each cycle, and get latest fence value
+ framesActive = 0u;
+ UINT64 fenceCompleted = context->m_fence->GetCompletedValue();
+
+ // determine how many frames are in flight
+ for (int frameIndex = 0; frameIndex < context->m_frameCount; frameIndex++)
+ {
+ if (fenceCompleted < context->m_fenceValues[frameIndex])
+ {
+ framesActive++;
+ }
+ }
+
+ if (framesActive >= maxFramesInFlight)
+ {
+ // find the active frame with the lowest fence ID
+ UINT64 minFenceID = 0;
+ unsigned int minFrameIdx = 0;
+ for (int frameIndex = 0; frameIndex < context->m_frameCount; frameIndex++)
+ {
+ if (fenceCompleted < context->m_fenceValues[frameIndex])
+ {
+ if (minFenceID == 0)
+ {
+ minFenceID = context->m_fenceValues[frameIndex];
+ minFrameIdx = frameIndex;
+ }
+ else if (context->m_fenceValues[frameIndex] < minFenceID)
+ {
+ minFenceID = context->m_fenceValues[frameIndex];
+ minFrameIdx = frameIndex;
+ }
+ }
+ }
+ // Wait for min frame
+ {
+ unsigned int frameIndex = minFrameIdx;
+ fenceCompleted = context->m_fence->GetCompletedValue();
+ if (fenceCompleted < context->m_fenceValues[frameIndex])
+ {
+ context->m_fence->SetEventOnCompletion(context->m_fenceValues[frameIndex], context->m_fenceEvent);
+ WaitForSingleObjectEx(context->m_fenceEvent, INFINITE, FALSE);
+ }
+ }
+ }
+ }
+}
+
+void AppGraphCtxProfileEnable(AppGraphCtx* context, bool enabled)
+{
+ appGraphProfilerEnable(context->m_profiler, enabled);
+}
+
+void AppGraphCtxProfileBegin(AppGraphCtx* context, const char* label)
+{
+ appGraphProfilerBegin(context->m_profiler, label);
+}
+
+void AppGraphCtxProfileEnd(AppGraphCtx* context, const char* label)
+{
+ appGraphProfilerEnd(context->m_profiler, label);
+}
+
+bool AppGraphCtxProfileGet(AppGraphCtx* context, const char** plabel, float* cpuTime, float* gpuTime, int index)
+{
+ return appGraphProfilerGet(context->m_profiler, plabel, cpuTime, gpuTime, index);
+}
+
+// ******************************* Dynamic descriptor heap ******************************
+
+void AppDynamicDescriptorHeapD3D12::init(ID3D12Device* device, D3D12_DESCRIPTOR_HEAP_TYPE heapType, UINT minHeapSize)
+{
+ m_device = device;
+ m_heapSize = minHeapSize;
+ m_startSlot = 0u;
+ m_descriptorSize = m_device->GetDescriptorHandleIncrementSize(heapType);
+
+ D3D12_DESCRIPTOR_HEAP_DESC desc = {};
+ desc.NumDescriptors = m_heapSize;
+ desc.Type = heapType;
+ desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
+ m_device->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&m_heap));
+}
+
+void AppDynamicDescriptorHeapD3D12::release()
+{
+ m_device = nullptr;
+ COMRelease(m_heap);
+ m_descriptorSize = 0u;
+ m_startSlot = 0u;
+ m_heapSize = 0u;
+}
+
+AppDescriptorReserveHandleD3D12 AppDynamicDescriptorHeapD3D12::reserveDescriptors(UINT numDescriptors, UINT64 lastFenceCompleted, UINT64 nextFenceValue)
+{
+ UINT endSlot = m_startSlot + numDescriptors;
+ if (endSlot >= m_heapSize)
+ {
+ m_startSlot = 0u;
+ endSlot = numDescriptors;
+ }
+ D3D12_CPU_DESCRIPTOR_HANDLE cpuHandle;
+ D3D12_GPU_DESCRIPTOR_HANDLE gpuHandle;
+ cpuHandle = m_heap->GetCPUDescriptorHandleForHeapStart();
+ cpuHandle.ptr += m_startSlot * m_descriptorSize;
+ gpuHandle = m_heap->GetGPUDescriptorHandleForHeapStart();
+ gpuHandle.ptr += m_startSlot * m_descriptorSize;
+
+ // advance start slot
+ m_startSlot = endSlot;
+
+ AppDescriptorReserveHandleD3D12 handle = {};
+ handle.heap = m_heap;
+ handle.descriptorSize = m_descriptorSize;
+ handle.cpuHandle = cpuHandle;
+ handle.gpuHandle = gpuHandle;
+ return handle;
+}
+
+// ******************************* Profiler *********************************
+
+namespace
+{
+ struct TimerCPU
+ {
+ LARGE_INTEGER oldCount;
+ LARGE_INTEGER count;
+ LARGE_INTEGER freq;
+ TimerCPU()
+ {
+ QueryPerformanceCounter(&count);
+ QueryPerformanceFrequency(&freq);
+ oldCount = count;
+ }
+ double getDeltaTime()
+ {
+ QueryPerformanceCounter(&count);
+ double dt = double(count.QuadPart - oldCount.QuadPart) / double(freq.QuadPart);
+ oldCount = count;
+ return dt;
+ }
+ };
+
+ struct TimerGPU
+ {
+ ID3D12QueryHeap* m_queryHeap = nullptr;
+ ID3D12Resource* m_queryReadback = nullptr;
+ UINT64 m_queryFrequency = 0;
+ UINT64 m_queryReadbackFenceVal = ~0llu;
+
+ TimerGPU() {}
+ ~TimerGPU()
+ {
+ COMRelease(m_queryHeap);
+ COMRelease(m_queryReadback);
+ }
+ };
+
+ struct Timer
+ {
+ TimerCPU m_cpu;
+ TimerGPU m_gpu;
+
+ const char* m_label = nullptr;
+ float m_cpuTime = 0.f;
+ float m_gpuTime = 0.f;
+
+ Timer() {}
+ ~Timer() {}
+ };
+
+ struct TimerValue
+ {
+ const char* m_label = nullptr;
+ float m_cpuTime = 0.f;
+ float m_gpuTime = 0.f;
+
+ struct Stat
+ {
+ float m_time = 0.f;
+ float m_maxTime = 0.f;
+ float m_maxTimeAge = 0.f;
+
+ float m_smoothTime = 0.f;
+ float m_smoothTimeSum = 0.f;
+ float m_smoothTimeCount = 0.f;
+
+ Stat() {}
+ void push(float time)
+ {
+ m_time = time;
+
+ if (m_time > m_maxTime)
+ {
+ m_maxTime = m_time;
+ m_maxTimeAge = 0.f;
+ }
+
+ if (fabsf(m_time - m_maxTime) < 0.25f * m_maxTime)
+ {
+ m_smoothTimeSum += m_time;
+ m_smoothTimeCount += 1.f;
+ m_smoothTimeSum *= 0.98f;
+ m_smoothTimeCount *= 0.98f;
+ m_smoothTime = m_smoothTimeSum / m_smoothTimeCount;
+ }
+ }
+
+ float pull(float frameTime)
+ {
+ m_maxTimeAge += frameTime;
+
+ if (m_maxTimeAge > 1.f)
+ {
+ m_maxTimeAge = 0.f;
+ m_maxTime = m_time;
+ m_smoothTimeSum = 0.f;
+ m_smoothTimeCount = 0.f;
+ }
+ return m_smoothTime;
+ }
+ };
+
+ Stat m_cpu;
+ Stat m_gpu;
+
+ void push(float cpuTime, float gpuTime)
+ {
+ m_cpu.push(cpuTime);
+ m_gpu.push(gpuTime);
+ }
+
+ void pull(float frameTime)
+ {
+ m_cpuTime = m_cpu.pull(frameTime);
+ m_gpuTime = m_gpu.pull(frameTime);
+ }
+ };
+
+ struct HeapPropsReadback : public D3D12_HEAP_PROPERTIES
+ {
+ HeapPropsReadback()
+ {
+ Type = D3D12_HEAP_TYPE_READBACK;
+ CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
+ MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
+ CreationNodeMask = 0u;
+ VisibleNodeMask = 0u;
+ }
+ };
+ struct ResourceDescBuffer : public D3D12_RESOURCE_DESC
+ {
+ ResourceDescBuffer(UINT64 size)
+ {
+ Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
+ Alignment = 0u;
+ Width = size;
+ Height = 1u;
+ DepthOrArraySize = 1u;
+ MipLevels = 1;
+ Format = DXGI_FORMAT_UNKNOWN;
+ SampleDesc.Count = 1u;
+ SampleDesc.Quality = 0u;
+ Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
+ Flags = D3D12_RESOURCE_FLAG_NONE;
+ }
+ };
+}
+
+struct AppGraphProfiler
+{
+ AppGraphCtx* m_context;
+
+ int m_state = 0;
+ bool m_enabled = false;
+
+ TimerCPU m_frameTimer;
+ float m_frameTime = 0.f;
+
+ static const int m_timersCap = 64;
+ Timer m_timers[m_timersCap];
+ int m_timersSize = 0;
+
+ TimerValue m_timerValues[m_timersCap];
+ int m_timerValuesSize = 0;
+
+ AppGraphProfiler(AppGraphCtx* context);
+ ~AppGraphProfiler();
+};
+
+AppGraphProfiler::AppGraphProfiler(AppGraphCtx* context) : m_context(context)
+{
+}
+
+AppGraphProfiler::~AppGraphProfiler()
+{
+}
+
+AppGraphProfiler* appGraphCreateProfiler(AppGraphCtx* ctx)
+{
+ return new AppGraphProfiler(ctx);
+}
+
+void appGraphReleaseProfiler(AppGraphProfiler* profiler)
+{
+ delete profiler;
+}
+
+void appGraphProfilerFrameBegin(AppGraphProfiler* p)
+{
+ p->m_frameTime = (float)p->m_frameTimer.getDeltaTime();
+
+ if (p->m_state == 0 && p->m_enabled)
+ {
+ p->m_timersSize = 0;
+
+ p->m_state = 1;
+ }
+}
+
+void appGraphProfilerFrameEnd(AppGraphProfiler* p)
+{
+ if (p->m_state == 1)
+ {
+ p->m_state = 2;
+ }
+}
+
+void appGraphProfilerEnable(AppGraphProfiler* p, bool enabled)
+{
+ p->m_enabled = enabled;
+}
+
+void appGraphProfilerBegin(AppGraphProfiler* p, const char* label)
+{
+ if (p->m_state == 1 && p->m_timersSize < p->m_timersCap)
+ {
+ auto& timer = p->m_timers[p->m_timersSize++];
+ timer.m_label = label;
+ timer.m_cpu.getDeltaTime();
+
+ auto device = p->m_context->m_device;
+
+ if (timer.m_gpu.m_queryHeap == nullptr)
+ {
+ D3D12_QUERY_HEAP_DESC queryDesc = {};
+ queryDesc.Type = D3D12_QUERY_HEAP_TYPE_TIMESTAMP;
+ queryDesc.Count = 2;
+ queryDesc.NodeMask = 0;
+
+ device->CreateQueryHeap(&queryDesc, IID_PPV_ARGS(&timer.m_gpu.m_queryHeap));
+
+ HeapPropsReadback readbackProps;
+ ResourceDescBuffer resDesc(2 * sizeof(UINT64));
+ resDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
+
+ device->CreateCommittedResource(&readbackProps, D3D12_HEAP_FLAG_NONE,
+ &resDesc, D3D12_RESOURCE_STATE_COPY_DEST,
+ nullptr, IID_PPV_ARGS(&timer.m_gpu.m_queryReadback));
+ }
+
+ p->m_context->m_commandQueue->GetTimestampFrequency(&timer.m_gpu.m_queryFrequency);
+
+ p->m_context->m_commandList->EndQuery(timer.m_gpu.m_queryHeap, D3D12_QUERY_TYPE_TIMESTAMP, 0);
+ }
+}
+
+void appGraphProfilerEnd(AppGraphProfiler* p, const char* label)
+{
+ if (p->m_state == 1)
+ {
+ Timer* timer = nullptr;
+ for (int i = 0; i < p->m_timersSize; i++)
+ {
+ if (strcmp(p->m_timers[i].m_label, label) == 0)
+ {
+ timer = &p->m_timers[i];
+ break;
+ }
+ }
+ if (timer)
+ {
+ p->m_context->m_commandList->EndQuery(timer->m_gpu.m_queryHeap, D3D12_QUERY_TYPE_TIMESTAMP, 1);
+
+ p->m_context->m_commandList->ResolveQueryData(timer->m_gpu.m_queryHeap, D3D12_QUERY_TYPE_TIMESTAMP, 0, 2, timer->m_gpu.m_queryReadback, 0u);
+
+ timer->m_gpu.m_queryReadbackFenceVal = p->m_context->m_thisFrameFenceID;
+
+ timer->m_cpuTime = (float)timer->m_cpu.getDeltaTime();
+ }
+ }
+}
+
+bool appGraphProfilerFlush(AppGraphProfiler* p)
+{
+ if (p->m_state == 2)
+ {
+ for (int i = 0; i < p->m_timersSize; i++)
+ {
+ Timer& timer = p->m_timers[i];
+
+ if (timer.m_gpu.m_queryReadbackFenceVal > p->m_context->m_lastFenceComplete)
+ {
+ return false;
+ }
+
+ UINT64 tsBegin, tsEnd;
+ {
+ void* data;
+ // Read range is nullptr, meaning full read access
+ D3D12_RANGE readRange;
+ readRange.Begin = 0u;
+ readRange.End = 2 * sizeof(UINT64);
+ timer.m_gpu.m_queryReadback->Map(0u, &readRange, &data);
+ if (data)
+ {
+ auto mapped = (UINT64*)data;
+ tsBegin = mapped[0];
+ tsEnd = mapped[1];
+
+ D3D12_RANGE writeRange{};
+ timer.m_gpu.m_queryReadback->Unmap(0u, &writeRange);
+ }
+ }
+
+ timer.m_gpuTime = float(tsEnd - tsBegin) / float(timer.m_gpu.m_queryFrequency);
+
+ // update TimerValue
+ int j = 0;
+ for (; j < p->m_timerValuesSize; j++)
+ {
+ TimerValue& value = p->m_timerValues[j];
+ if (strcmp(value.m_label, timer.m_label) == 0)
+ {
+ value.push(timer.m_cpuTime, timer.m_gpuTime);
+ break;
+ }
+ }
+ if (j >= p->m_timerValuesSize && p->m_timerValuesSize < p->m_timersCap)
+ {
+ TimerValue& value = p->m_timerValues[p->m_timerValuesSize++];
+ value.m_label = timer.m_label;
+ value.push(timer.m_cpuTime, timer.m_gpuTime);
+ }
+ }
+
+ p->m_state = 0;
+ }
+ return false;
+}
+
+bool appGraphProfilerGet(AppGraphProfiler* p, const char** plabel, float* cpuTime, float* gpuTime, int index)
+{
+ appGraphProfilerFlush(p);
+ {
+ if (index < p->m_timerValuesSize)
+ {
+ TimerValue& timer = p->m_timerValues[index];
+
+ timer.pull(p->m_frameTime);
+
+ if (plabel) *plabel = timer.m_label;
+ if (cpuTime) *cpuTime = timer.m_cpuTime;
+ if (gpuTime) *gpuTime = timer.m_gpuTime;
+
+ return true;
+ }
+ }
+ return false;
+}
+
+size_t AppGraphCtxDedicatedVideoMemory(AppGraphCtx* context)
+{
+ return context->m_dedicatedVideoMemory;
+} \ No newline at end of file
diff --git a/demo/DemoAppD3D12/appD3D12Ctx.h b/demo/DemoAppD3D12/appD3D12Ctx.h
new file mode 100644
index 0000000..f6d2ba3
--- /dev/null
+++ b/demo/DemoAppD3D12/appD3D12Ctx.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved.
+ *
+ * NVIDIA CORPORATION and its licensors retain all intellectual property
+ * and proprietary rights in and to this software, related documentation
+ * and any modifications thereto. Any use, reproduction, disclosure or
+ * distribution of this software and related documentation without an express
+ * license agreement from NVIDIA CORPORATION is strictly prohibited.
+ */
+
+#ifndef APP_D3D12_CTX_H
+#define APP_D3D12_CTX_H
+
+#include "../DemoApp/appGraphCtx.h"
+
+struct IDXGISwapChain3;
+
+struct AppGraphProfiler;
+
+struct AppDescriptorReserveHandleD3D12
+{
+ ID3D12DescriptorHeap* heap;
+ UINT descriptorSize;
+ D3D12_CPU_DESCRIPTOR_HANDLE cpuHandle;
+ D3D12_GPU_DESCRIPTOR_HANDLE gpuHandle;
+};
+
+struct AppDynamicDescriptorHeapD3D12
+{
+ ID3D12Device* m_device = nullptr;
+ ID3D12DescriptorHeap* m_heap = nullptr;
+ UINT m_descriptorSize = 0u;
+ UINT m_startSlot = 0u;
+ UINT m_heapSize = 0u;
+
+ void init(ID3D12Device* device, D3D12_DESCRIPTOR_HEAP_TYPE heapType, UINT minHeapSize);
+ void release();
+ AppDescriptorReserveHandleD3D12 reserveDescriptors(UINT numDescriptors, UINT64 lastFenceCompleted, UINT64 nextFenceValue);
+
+ AppDynamicDescriptorHeapD3D12() {}
+ ~AppDynamicDescriptorHeapD3D12() { release(); }
+};
+
+struct AppGraphCtx
+{
+ HWND m_hWnd = nullptr;
+
+ int m_winW = 0;
+ int m_winH = 0;
+ bool m_fullscreen = false;
+ bool m_valid = false;
+
+ size_t m_dedicatedVideoMemory = 0u;
+
+ // D3D12 non-replicated objects
+ D3D12_VIEWPORT m_viewport = {};
+ D3D12_RECT m_scissorRect = {};
+ ID3D12Device* m_device = nullptr;
+ ID3D12CommandQueue* m_commandQueue = nullptr;
+
+ // D3D12 render target pipeline
+ static const UINT m_renderTargetCount = 6u;
+ UINT m_renderTargetIndex = 0u;
+ UINT64 m_renderTargetID = 0u;
+ IDXGISwapChain3* m_swapChain = nullptr;
+ HANDLE m_swapChainWaitableObject = nullptr;
+ ID3D12DescriptorHeap* m_rtvHeap = nullptr;
+ UINT m_rtvDescriptorSize = 0u;
+ ID3D12Resource* m_renderTargets[m_renderTargetCount] = {};
+
+ ID3D12Resource* m_depthStencil = nullptr;
+ ID3D12DescriptorHeap* m_dsvHeap = nullptr;
+ ID3D12DescriptorHeap* m_depthSrvHeap = nullptr;
+
+ // D3D12 frame pipeline objects
+ static const UINT m_frameCount = 8u;
+ UINT m_frameIndex = 0u;
+ UINT64 m_frameID = 0u;
+ ID3D12CommandAllocator* m_commandAllocators[m_frameCount] = {};
+
+ // D3D12 synchronization objects
+ ID3D12Fence* m_fence = nullptr;
+ HANDLE m_fenceEvent = 0u;
+ UINT64 m_fenceValues[m_frameCount] = {};
+
+ // fence values for library synchronization
+ UINT64 m_lastFenceComplete = 1u;
+ UINT64 m_thisFrameFenceID = 2u;
+
+ // D3D12 per asset objects
+ ID3D12GraphicsCommandList* m_commandList = nullptr;
+ ID3D12Resource* m_current_renderTarget = nullptr;
+ D3D12_CPU_DESCRIPTOR_HANDLE m_current_rtvHandle;
+ D3D12_RENDER_TARGET_VIEW_DESC m_current_rtvDesc;
+ D3D12_CPU_DESCRIPTOR_HANDLE m_current_dsvHandle;
+ D3D12_DEPTH_STENCIL_VIEW_DESC m_current_dsvDesc;
+ D3D12_CPU_DESCRIPTOR_HANDLE m_current_depth_srvHandle;
+ D3D12_SHADER_RESOURCE_VIEW_DESC m_current_depth_srvDesc;
+
+ DXGI_FORMAT m_rtv_format = DXGI_FORMAT_R8G8B8A8_UNORM;
+ DXGI_FORMAT m_dsv_format = DXGI_FORMAT_D32_FLOAT;
+ DXGI_FORMAT m_depth_srv_format = DXGI_FORMAT_R32_FLOAT;
+ DXGI_FORMAT m_depth_format = DXGI_FORMAT_R32_TYPELESS;
+
+ AppDynamicDescriptorHeapD3D12 m_dynamicHeapCbvSrvUav;
+
+ AppGraphProfiler* m_profiler = nullptr;
+
+ AppGraphCtx();
+ ~AppGraphCtx();
+};
+
+#endif \ No newline at end of file
diff --git a/demo/DemoAppD3D12/computeContextD3D12.cpp b/demo/DemoAppD3D12/computeContextD3D12.cpp
new file mode 100644
index 0000000..f6cf26e
--- /dev/null
+++ b/demo/DemoAppD3D12/computeContextD3D12.cpp
@@ -0,0 +1,759 @@
+/*
+* Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved.
+*
+* NVIDIA CORPORATION and its licensors retain all intellectual property
+* and proprietary rights in and to this software, related documentation
+* and any modifications thereto. Any use, reproduction, disclosure or
+* distribution of this software and related documentation without an express
+* license agreement from NVIDIA CORPORATION is strictly prohibited.
+*/
+
+#include <d3d12.h>
+
+#include "computeContextD3D12.h"
+
+#include <vector>
+
+// ************************** Compute Context Implementation ******************
+
+typedef unsigned int ComputeUint;
+typedef unsigned long long ComputeUint64;
+
+namespace
+{
+ template<class T>
+ struct VectorCached
+ {
+ std::vector<T> m_data;
+
+ ComputeUint m_size = 0u;
+
+ ComputeUint allocateBack()
+ {
+ m_size++;
+ m_data.resize(m_size);
+ return m_size - 1;
+ }
+
+ T& operator[](unsigned int idx)
+ {
+ return m_data[idx];
+ }
+ };
+
+ template <class BufferData>
+ struct VersionedBuffer
+ {
+ BufferData* map(ComputeUint64 lastFenceCompleted, ComputeUint64 nextFenceValue);
+ void unmap(ComputeUint64 lastFenceCompleted, ComputeUint64 nextFenceValue);
+
+ struct Buffer
+ {
+ ComputeUint64 releaseFenceValue = ~0llu;
+ BufferData bufferData;
+
+ Buffer() : bufferData() {}
+ };
+
+ VectorCached<Buffer> m_buffers;
+ ComputeUint m_frontIdx = 0u;
+ ComputeUint m_mappedIdx = 0u;
+
+ BufferData* front();
+
+ ComputeUint64 currentFrame = 0u;
+
+ VersionedBuffer();
+ ~VersionedBuffer();
+ };
+
+ template <class BufferData>
+ VersionedBuffer<BufferData>::VersionedBuffer()
+ {
+ }
+
+ template <class BufferData>
+ VersionedBuffer<BufferData>::~VersionedBuffer()
+ {
+ }
+
+ template <class BufferData>
+ BufferData* VersionedBuffer<BufferData>::front()
+ {
+ return &m_buffers[m_frontIdx].bufferData;
+ }
+
+ template <class BufferData>
+ BufferData* VersionedBuffer<BufferData>::map(ComputeUint64 lastFenceCompleted, ComputeUint64 nextFenceValue)
+ {
+ // search for available buffer
+ ComputeUint numBuffers = m_buffers.m_size;
+ ComputeUint index = m_frontIdx + 1;
+ for (; index < numBuffers; index++)
+ {
+ if (m_buffers[index].releaseFenceValue <= lastFenceCompleted)
+ {
+ break;
+ }
+ }
+ if (index == numBuffers)
+ {
+ for (index = 0u; index < m_frontIdx; index++)
+ {
+ if (m_buffers[index].releaseFenceValue <= lastFenceCompleted)
+ {
+ break;
+ }
+ }
+ }
+ if (index == m_frontIdx || numBuffers == 0u)
+ {
+ index = m_buffers.allocateBack();
+ }
+ m_mappedIdx = index;
+ return &m_buffers[index].bufferData;
+ }
+
+ template <class BufferData>
+ void VersionedBuffer<BufferData>::unmap(ComputeUint64 lastFenceCompleted, ComputeUint64 nextFenceValue)
+ {
+ // mark front obsolete
+ if (m_frontIdx != m_mappedIdx) m_buffers[m_frontIdx].releaseFenceValue = nextFenceValue;
+ // set new front
+ m_frontIdx = m_mappedIdx;
+ }
+}
+
+namespace
+{
+ struct HeapPropsUpload : public D3D12_HEAP_PROPERTIES
+ {
+ HeapPropsUpload()
+ {
+ Type = D3D12_HEAP_TYPE_UPLOAD;
+ CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
+ MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
+ CreationNodeMask = 0u;
+ VisibleNodeMask = 0u;
+ }
+ };
+ struct ResourceDescBuffer : public D3D12_RESOURCE_DESC
+ {
+ ResourceDescBuffer(UINT64 size)
+ {
+ Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
+ Alignment = 0u;
+ Width = size;
+ Height = 1u;
+ DepthOrArraySize = 1u;
+ MipLevels = 1;
+ Format = DXGI_FORMAT_UNKNOWN;
+ SampleDesc.Count = 1u;
+ SampleDesc.Quality = 0u;
+ Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
+ Flags = D3D12_RESOURCE_FLAG_NONE;
+ }
+ };
+ struct DescriptorRange : public D3D12_DESCRIPTOR_RANGE
+ {
+ void init(D3D12_DESCRIPTOR_RANGE_TYPE type, UINT baseRegister, UINT numDescriptors)
+ {
+ RangeType = type;
+ NumDescriptors = numDescriptors;
+ BaseShaderRegister = baseRegister;
+ RegisterSpace = 0u;
+ OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
+ }
+ };
+ struct RootParameter : public D3D12_ROOT_PARAMETER
+ {
+ void initRootConstant(D3D12_SHADER_VISIBILITY visibility, UINT shaderReg)
+ {
+ ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
+ Descriptor.ShaderRegister = shaderReg;
+ Descriptor.RegisterSpace = 0u;
+ ShaderVisibility = visibility;
+ }
+ void initTable(D3D12_DESCRIPTOR_RANGE* range, D3D12_SHADER_VISIBILITY visibility)
+ {
+ ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
+ DescriptorTable.NumDescriptorRanges = 1;
+ DescriptorTable.pDescriptorRanges = range;
+ ShaderVisibility = visibility;
+ }
+ };
+ struct StaticSamplerDesc : public D3D12_STATIC_SAMPLER_DESC
+ {
+ void init(UINT shaderRegister, D3D12_FILTER filter, D3D12_TEXTURE_ADDRESS_MODE addressMode)
+ {
+ Filter = filter;
+ AddressU = addressMode;
+ AddressV = addressMode;
+ AddressW = addressMode;
+ MipLODBias = 0;
+ MaxAnisotropy = 0;
+ ComparisonFunc = D3D12_COMPARISON_FUNC_NEVER;
+ BorderColor = D3D12_STATIC_BORDER_COLOR_TRANSPARENT_BLACK;
+ MinLOD = 0.f;
+ MaxLOD = D3D12_FLOAT32_MAX;
+ ShaderRegister = shaderRegister;
+ RegisterSpace = 0;
+ ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
+ }
+ };
+ struct ComputeRootSignature
+ {
+ static const int numRanges = 2;
+ static const int numParams = 3; //4;
+ static const int numSamplers = 6;
+
+ DescriptorRange ranges[numRanges];
+ RootParameter params[numParams];
+ StaticSamplerDesc samplers[numSamplers];
+ D3D12_ROOT_SIGNATURE_DESC desc;
+
+ ComputeRootSignature()
+ {
+ ranges[0].init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 0u, ComputeDispatchMaxResources);
+ ranges[1].init(D3D12_DESCRIPTOR_RANGE_TYPE_UAV, 0u, ComputeDispatchMaxResourcesRW);
+
+ params[0].initRootConstant(D3D12_SHADER_VISIBILITY_ALL, 0u);
+ params[1].initTable(&ranges[0], D3D12_SHADER_VISIBILITY_ALL);
+ params[2].initTable(&ranges[1], D3D12_SHADER_VISIBILITY_ALL);
+ //params[3].initRootConstant(D3D12_SHADER_VISIBILITY_ALL, 1u);
+
+ samplers[0].init(0, D3D12_FILTER_MIN_MAG_LINEAR_MIP_POINT, D3D12_TEXTURE_ADDRESS_MODE_BORDER);
+ samplers[1].init(1, D3D12_FILTER_MIN_MAG_MIP_POINT, D3D12_TEXTURE_ADDRESS_MODE_BORDER);
+ samplers[2].init(2, D3D12_FILTER_MIN_MAG_LINEAR_MIP_POINT, D3D12_TEXTURE_ADDRESS_MODE_WRAP);
+ samplers[3].init(3, D3D12_FILTER_MIN_MAG_MIP_POINT, D3D12_TEXTURE_ADDRESS_MODE_WRAP);
+ samplers[4].init(4, D3D12_FILTER_MIN_MAG_LINEAR_MIP_POINT, D3D12_TEXTURE_ADDRESS_MODE_CLAMP);
+ samplers[5].init(5, D3D12_FILTER_MIN_MAG_MIP_POINT, D3D12_TEXTURE_ADDRESS_MODE_CLAMP);
+
+ desc.NumParameters = numParams;
+ desc.pParameters = params;
+ desc.NumStaticSamplers = numSamplers;
+ desc.pStaticSamplers = samplers;
+ desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
+ }
+ };
+};
+
+template <class T>
+void inline COMRelease(T& t)
+{
+ if (t) t->Release();
+ t = nullptr;
+}
+
+struct ComputeContextUserData
+{
+ virtual void Release() = 0;
+};
+
+struct ComputeContext
+{
+ ComputeContextDesc m_desc = {};
+
+ ID3D12RootSignature* m_rootSignatureCompute = nullptr;
+ ID3D12DescriptorHeap* m_nullHeap = nullptr;
+ D3D12_CPU_DESCRIPTOR_HANDLE m_nullUAV;
+ D3D12_CPU_DESCRIPTOR_HANDLE m_nullSRV;
+
+ ComputeContextUserData* m_computeUserdata = nullptr;
+
+ ComputeContext(const ComputeContextDesc* desc)
+ {
+ m_desc = *desc;
+
+ auto createRootSignature = [&](D3D12_ROOT_SIGNATURE_DESC* desc, ID3D12RootSignature** root)
+ {
+ ID3DBlob* signature = nullptr;
+ ID3DBlob* error = nullptr;
+ HRESULT hr = S_OK;
+ if (hr = D3D12SerializeRootSignature(desc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error))
+ {
+ return hr;
+ }
+ if (hr = m_desc.device->CreateRootSignature(0u, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(root)))
+ {
+ return hr;
+ }
+ COMRelease(signature);
+ COMRelease(error);
+ return HRESULT(0);
+ };
+ {
+ ComputeRootSignature desc;
+ createRootSignature(&desc.desc, &m_rootSignatureCompute);
+ }
+
+ // create CPU descriptor heap
+ {
+ D3D12_DESCRIPTOR_HEAP_DESC desc = {};
+ desc.NumDescriptors = 2u;
+ desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
+ desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
+ m_desc.device->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&m_nullHeap));
+ }
+
+ // create null UAV
+ {
+ D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc = {};
+ uavDesc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
+ uavDesc.Format = DXGI_FORMAT_R32_UINT;
+ uavDesc.Buffer.FirstElement = 0u;
+ uavDesc.Buffer.NumElements = 256u;
+
+ m_nullUAV = m_nullHeap->GetCPUDescriptorHandleForHeapStart();
+ m_desc.device->CreateUnorderedAccessView(nullptr, nullptr, &uavDesc, m_nullUAV);
+ }
+
+ // create null SRV
+ {
+ D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
+ srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
+ srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
+ srvDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
+ srvDesc.Texture2D.MipLevels = 1;
+ srvDesc.Texture2D.MostDetailedMip = 0;
+ srvDesc.Texture2D.ResourceMinLODClamp = 0.0f;
+
+ m_nullSRV = m_nullHeap->GetCPUDescriptorHandleForHeapStart();
+ m_nullSRV.ptr += m_desc.device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
+ m_desc.device->CreateShaderResourceView(nullptr, &srvDesc, m_nullSRV);
+ }
+ }
+ ~ComputeContext()
+ {
+ COMRelease(m_rootSignatureCompute);
+ COMRelease(m_nullHeap);
+ COMRelease(m_computeUserdata);
+ }
+};
+
+struct ComputeShader
+{
+ ID3D12PipelineState* m_shader = nullptr;
+ ComputeShader(ID3D12PipelineState* shader)
+ {
+ m_shader = shader;
+ }
+ ~ComputeShader()
+ {
+ COMRelease(m_shader);
+ }
+};
+
+struct ComputeConstantBuffer
+{
+ ComputeConstantBufferDesc m_desc = {};
+
+ struct BufferData
+ {
+ ID3D12Resource* m_buffer = nullptr;
+ void* m_mappedData = nullptr;
+
+ BufferData() {}
+ };
+ VersionedBuffer<BufferData> m_buffers;
+
+ ComputeConstantBuffer(ComputeContext* context, const ComputeConstantBufferDesc* desc)
+ {
+ m_desc = *desc;
+
+ // map and unmap to trigger initial allocation
+ ComputeConstantBufferMap(context, this);
+ ComputeConstantBufferUnmap(context, this);
+ }
+ ~ComputeConstantBuffer()
+ {
+ for (ComputeUint i = 0; i < m_buffers.m_buffers.m_size; i++)
+ {
+ COMRelease(m_buffers.m_buffers[i].bufferData.m_buffer);
+ }
+ }
+};
+
+struct ComputeResource
+{
+protected:
+ D3D12_CPU_DESCRIPTOR_HANDLE m_srv;
+ ID3D12Resource* m_resource;
+ D3D12_RESOURCE_STATES* m_currentState;
+public:
+ void update(const ComputeResourceDesc* desc)
+ {
+ m_srv = desc->srv;
+ m_resource = desc->resource;
+ m_currentState = desc->currentState;
+ }
+
+ ComputeResource(const ComputeResourceDesc* desc)
+ {
+ update(desc);
+ }
+
+ D3D12_CPU_DESCRIPTOR_HANDLE SRV()
+ {
+ return m_srv;
+ }
+
+ ID3D12Resource* resource()
+ {
+ return m_resource;
+ }
+
+ D3D12_RESOURCE_STATES* currentState()
+ {
+ return m_currentState;
+ }
+};
+
+struct ComputeResourceRW : public ComputeResource
+{
+protected:
+ D3D12_CPU_DESCRIPTOR_HANDLE m_uav;
+public:
+ void update(const ComputeResourceRWDesc* descRW)
+ {
+ m_uav = descRW->uav;
+ ComputeResource::update(&descRW->resource);
+ }
+
+ ComputeResourceRW(const ComputeResourceRWDesc* descRW) :
+ ComputeResource(&descRW->resource)
+ {
+ m_uav = descRW->uav;
+ }
+
+ D3D12_CPU_DESCRIPTOR_HANDLE UAV()
+ {
+ return m_uav;
+ }
+};
+
+// ************* API functions ****************
+
+ComputeContext* ComputeContextCreate(ComputeContextDesc* desc)
+{
+ return new ComputeContext(desc);
+}
+
+void ComputeContextUpdate(ComputeContext* context, ComputeContextDesc* desc)
+{
+ context->m_desc = *desc;
+}
+
+void ComputeContextRelease(ComputeContext* context)
+{
+ delete context;
+}
+
+ComputeShader* ComputeShaderCreate(ComputeContext* context, const ComputeShaderDesc* desc)
+{
+ ID3D12PipelineState* computeShader = nullptr;
+
+ D3D12_COMPUTE_PIPELINE_STATE_DESC psoDesc = {};
+ psoDesc.pRootSignature = context->m_rootSignatureCompute;
+ psoDesc.CS.pShaderBytecode = desc->cs;
+ psoDesc.CS.BytecodeLength = desc->cs_length;
+
+ context->m_desc.device->CreateComputePipelineState(&psoDesc, IID_PPV_ARGS(&computeShader));
+
+ return new ComputeShader(computeShader);
+}
+
+void ComputeShaderRelease(ComputeShader* shader)
+{
+ delete shader;
+}
+
+ComputeConstantBuffer* ComputeConstantBufferCreate(ComputeContext* context, const ComputeConstantBufferDesc* desc)
+{
+ return new ComputeConstantBuffer(context, desc);
+}
+
+void ComputeConstantBufferRelease(ComputeConstantBuffer* constantBuffer)
+{
+ delete constantBuffer;
+}
+
+void* ComputeConstantBufferMap(ComputeContext* context, ComputeConstantBuffer* constantBuffer)
+{
+ auto bufferData = constantBuffer->m_buffers.map(context->m_desc.lastFenceCompleted, context->m_desc.nextFenceValue);
+
+ if (bufferData->m_buffer == nullptr)
+ {
+ HeapPropsUpload heapProps;
+ ResourceDescBuffer resDesc(constantBuffer->m_desc.sizeInBytes);
+
+ context->m_desc.device->CreateCommittedResource(&heapProps, D3D12_HEAP_FLAG_NONE,
+ &resDesc, D3D12_RESOURCE_STATE_GENERIC_READ,
+ nullptr, IID_PPV_ARGS(&bufferData->m_buffer));
+
+ UINT8* pdata = nullptr;
+ D3D12_RANGE readRange = {};
+ bufferData->m_buffer->Map(0, &readRange, (void**)&pdata);
+
+ bufferData->m_mappedData = pdata;
+ }
+ return bufferData->m_mappedData;
+}
+
+void ComputeConstantBufferUnmap(ComputeContext* context, ComputeConstantBuffer* constantBuffer)
+{
+ constantBuffer->m_buffers.unmap(context->m_desc.lastFenceCompleted, context->m_desc.nextFenceValue);
+}
+
+ComputeResource* ComputeResourceCreate(ComputeContext* context, const ComputeResourceDesc* desc)
+{
+ return new ComputeResource(desc);
+}
+
+void ComputeResourceUpdate(ComputeContext* context, ComputeResource* resource, const ComputeResourceDesc* desc)
+{
+ resource->update(desc);
+}
+
+void ComputeResourceRelease(ComputeResource* resource)
+{
+ delete resource;
+}
+
+ComputeResourceRW* ComputeResourceRWCreate(ComputeContext* context, const ComputeResourceRWDesc* desc)
+{
+ return new ComputeResourceRW(desc);
+}
+
+void ComputeResourceRWUpdate(ComputeContext* context, ComputeResourceRW* resourceRW, const ComputeResourceRWDesc* desc)
+{
+ resourceRW->update(desc);
+}
+
+void ComputeResourceRWRelease(ComputeResourceRW* resourceRW)
+{
+ delete resourceRW;
+}
+
+ComputeResource* ComputeResourceRWGetResource(ComputeResourceRW* resourceRW)
+{
+ return static_cast<ComputeResource*>(resourceRW);
+}
+
+void ComputeContextDispatch(ComputeContext* context, const ComputeDispatchParams* params)
+{
+ auto& commandList = context->m_desc.commandList;
+
+ commandList->SetComputeRootSignature(context->m_rootSignatureCompute);
+ if (params->shader) commandList->SetPipelineState(params->shader->m_shader);
+
+ auto handles = context->m_desc.dynamicHeapCbvSrvUav.reserveDescriptors(context->m_desc.dynamicHeapCbvSrvUav.userdata,
+ ComputeDispatchMaxResources + ComputeDispatchMaxResourcesRW,
+ context->m_desc.lastFenceCompleted, context->m_desc.nextFenceValue
+ );
+
+ commandList->SetDescriptorHeaps(1u, &handles.heap);
+
+ for (ComputeUint i = 0u; i < ComputeDispatchMaxResources; i++)
+ {
+ auto r = params->resources[i];
+ D3D12_CPU_DESCRIPTOR_HANDLE srcHandle = r ? r->SRV() : context->m_nullSRV;
+ context->m_desc.device->CopyDescriptorsSimple(1u, handles.cpuHandle, srcHandle, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
+ handles.cpuHandle.ptr += handles.descriptorSize;
+ }
+ for (ComputeUint i = 0u; i < ComputeDispatchMaxResourcesRW; i++)
+ {
+ auto rw = params->resourcesRW[i];
+ D3D12_CPU_DESCRIPTOR_HANDLE srcHandle = rw ? rw->UAV() : context->m_nullUAV;
+ context->m_desc.device->CopyDescriptorsSimple(1u, handles.cpuHandle, srcHandle, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
+ handles.cpuHandle.ptr += handles.descriptorSize;
+ }
+
+ commandList->SetComputeRootDescriptorTable(1u, handles.gpuHandle);
+ handles.gpuHandle.ptr += handles.descriptorSize * ComputeDispatchMaxResources;
+ commandList->SetComputeRootDescriptorTable(2u, handles.gpuHandle);
+
+ if (params->constantBuffer)
+ {
+ auto cbv = params->constantBuffer->m_buffers.front()->m_buffer;
+ commandList->SetComputeRootConstantBufferView(0u, cbv->GetGPUVirtualAddress());
+ }
+
+ ComputeUint barrierIdx = 0u;
+ D3D12_RESOURCE_BARRIER barrier[ComputeDispatchMaxResources + ComputeDispatchMaxResourcesRW];
+ for (ComputeUint i = 0u; i < ComputeDispatchMaxResources; i++)
+ {
+ auto r = params->resources[i];
+ if (r)
+ {
+ if (!((*r->currentState()) & D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE))
+ {
+ D3D12_RESOURCE_BARRIER& bar = barrier[barrierIdx++];
+ bar.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
+ bar.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
+ bar.Transition.pResource = r->resource();
+ bar.Transition.Subresource = 0u;
+ bar.Transition.StateBefore = *r->currentState();
+ bar.Transition.StateAfter = D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE;
+
+ *r->currentState() = D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE;
+ }
+ }
+ }
+ for (ComputeUint i = 0u; i < ComputeDispatchMaxResourcesRW; i++)
+ {
+ auto rw = params->resourcesRW[i];
+ if (rw)
+ {
+ if ((*rw->currentState()) == D3D12_RESOURCE_STATE_UNORDERED_ACCESS)
+ {
+ D3D12_RESOURCE_BARRIER& bar = barrier[barrierIdx++];
+ bar.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV;
+ bar.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
+ bar.UAV.pResource = rw->resource();
+ }
+ else
+ {
+ D3D12_RESOURCE_BARRIER& bar = barrier[barrierIdx++];
+ bar.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
+ bar.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
+ bar.Transition.pResource = rw->resource();
+ bar.Transition.Subresource = 0u;
+ bar.Transition.StateBefore = *rw->currentState();
+ bar.Transition.StateAfter = D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
+
+ *rw->currentState() = D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
+ }
+ }
+ }
+
+ commandList->ResourceBarrier(barrierIdx, barrier);
+
+ commandList->Dispatch(params->gridDim[0], params->gridDim[1], params->gridDim[2]);
+}
+
+// ******************************* NvFlow Interoperation ****************************************
+
+#include "NvFlow.h"
+#include "NvFlowContextD3D12.h"
+
+struct ComputeContextUserDataNvFlow : public ComputeContextUserData
+{
+ NvFlowDynamicDescriptorHeapD3D12 flowHeap = {};
+
+ void Release() override
+ {
+ delete this;
+ }
+};
+
+ComputeDescriptorReserveHandleD3D12 ComputeReserveDescriptors(void* userdata, UINT numDescriptors, UINT64 lastFenceCompleted, UINT64 nextFenceValue)
+{
+ auto data = static_cast<ComputeContextUserDataNvFlow*>(userdata);
+ auto srcHandle = data->flowHeap.reserveDescriptors(data->flowHeap.userdata, numDescriptors, lastFenceCompleted, nextFenceValue);
+ ComputeDescriptorReserveHandleD3D12 handle = {};
+ handle.heap = srcHandle.heap;
+ handle.descriptorSize = srcHandle.descriptorSize;
+ handle.cpuHandle = srcHandle.cpuHandle;
+ handle.gpuHandle = srcHandle.gpuHandle;
+ return handle;
+}
+
+ComputeContext* ComputeContextNvFlowContextCreate(NvFlowContext* flowContext)
+{
+ ComputeContextDesc desc = {};
+ NvFlowContextDescD3D12 srcDesc = {};
+ NvFlowUpdateContextDescD3D12(flowContext, &srcDesc);
+
+ desc.device = srcDesc.device;
+ desc.commandQueue = srcDesc.commandQueue;
+ desc.commandQueueFence = srcDesc.commandQueueFence;
+ desc.commandList = srcDesc.commandList;
+ desc.lastFenceCompleted = srcDesc.lastFenceCompleted;
+ desc.nextFenceValue = srcDesc.nextFenceValue;
+
+ auto computeUserdata = new ComputeContextUserDataNvFlow;
+ computeUserdata->flowHeap.userdata = srcDesc.dynamicHeapCbvSrvUav.userdata;
+ computeUserdata->flowHeap.reserveDescriptors = srcDesc.dynamicHeapCbvSrvUav.reserveDescriptors;
+
+ desc.dynamicHeapCbvSrvUav.userdata = computeUserdata;
+ desc.dynamicHeapCbvSrvUav.reserveDescriptors = ComputeReserveDescriptors;
+
+ auto computeContext = ComputeContextCreate(&desc);
+
+ computeContext->m_computeUserdata = computeUserdata;
+
+ return computeContext;
+}
+
+void ComputeContextNvFlowContextUpdate(ComputeContext* computeContext, NvFlowContext* flowContext)
+{
+ ComputeContextDesc desc = {};
+ NvFlowContextDescD3D12 srcDesc = {};
+ NvFlowUpdateContextDescD3D12(flowContext, &srcDesc);
+
+ desc.device = srcDesc.device;
+ desc.commandQueue = srcDesc.commandQueue;
+ desc.commandQueueFence = srcDesc.commandQueueFence;
+ desc.commandList = srcDesc.commandList;
+ desc.lastFenceCompleted = srcDesc.lastFenceCompleted;
+ desc.nextFenceValue = srcDesc.nextFenceValue;
+
+ auto computeUserdata = static_cast<ComputeContextUserDataNvFlow*>(computeContext->m_computeUserdata);
+ computeUserdata->flowHeap.userdata = srcDesc.dynamicHeapCbvSrvUav.userdata;
+ computeUserdata->flowHeap.reserveDescriptors = srcDesc.dynamicHeapCbvSrvUav.reserveDescriptors;
+
+ desc.dynamicHeapCbvSrvUav.userdata = computeUserdata;
+ desc.dynamicHeapCbvSrvUav.reserveDescriptors = ComputeReserveDescriptors;
+
+ ComputeContextUpdate(computeContext, &desc);
+}
+
+inline void updateComputeResourceDesc(NvFlowResourceViewDescD3D12* flowViewDesc, ComputeResourceDesc* desc)
+{
+ desc->srv = flowViewDesc->srvHandle;
+ desc->resource = flowViewDesc->resource;
+ desc->currentState = flowViewDesc->currentState;
+}
+
+ComputeResource* ComputeResourceNvFlowCreate(ComputeContext* context, NvFlowContext* flowContext, NvFlowResource* flowResource)
+{
+ NvFlowResourceViewDescD3D12 flowViewDesc = {};
+ NvFlowUpdateResourceViewDescD3D12(flowContext, flowResource, &flowViewDesc);
+ ComputeResourceDesc desc = {};
+ updateComputeResourceDesc(&flowViewDesc, &desc);
+ return ComputeResourceCreate(context, &desc);
+}
+
+void ComputeResourceNvFlowUpdate(ComputeContext* context, ComputeResource* resource, NvFlowContext* flowContext, NvFlowResource* flowResource)
+{
+ NvFlowResourceViewDescD3D12 flowViewDesc = {};
+ NvFlowUpdateResourceViewDescD3D12(flowContext, flowResource, &flowViewDesc);
+ ComputeResourceDesc desc = {};
+ updateComputeResourceDesc(&flowViewDesc, &desc);
+ ComputeResourceUpdate(context, resource, &desc);
+}
+
+inline void updateComputeResourceRWDesc(NvFlowResourceRWViewDescD3D12* flowViewDesc, ComputeResourceRWDesc* desc)
+{
+ updateComputeResourceDesc(&flowViewDesc->resourceView, &desc->resource);
+ desc->uav = flowViewDesc->uavHandle;
+}
+
+ComputeResourceRW* ComputeResourceRWNvFlowCreate(ComputeContext* context, NvFlowContext* flowContext, NvFlowResourceRW* flowResourceRW)
+{
+ NvFlowResourceRWViewDescD3D12 flowViewDesc = {};
+ NvFlowUpdateResourceRWViewDescD3D12(flowContext, flowResourceRW, &flowViewDesc);
+ ComputeResourceRWDesc desc = {};
+ updateComputeResourceRWDesc(&flowViewDesc, &desc);
+ return ComputeResourceRWCreate(context, &desc);
+}
+
+void ComputeResourceRWNvFlowUpdate(ComputeContext* context, ComputeResourceRW* resourceRW, NvFlowContext* flowContext, NvFlowResourceRW* flowResourceRW)
+{
+ NvFlowResourceRWViewDescD3D12 flowViewDesc = {};
+ NvFlowUpdateResourceRWViewDescD3D12(flowContext, flowResourceRW, &flowViewDesc);
+ ComputeResourceRWDesc desc = {};
+ updateComputeResourceRWDesc(&flowViewDesc, &desc);
+ ComputeResourceRWUpdate(context, resourceRW, &desc);
+} \ No newline at end of file
diff --git a/demo/DemoAppD3D12/computeContextD3D12.h b/demo/DemoAppD3D12/computeContextD3D12.h
new file mode 100644
index 0000000..0acb489
--- /dev/null
+++ b/demo/DemoAppD3D12/computeContextD3D12.h
@@ -0,0 +1,52 @@
+/*
+* Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved.
+*
+* NVIDIA CORPORATION and its licensors retain all intellectual property
+* and proprietary rights in and to this software, related documentation
+* and any modifications thereto. Any use, reproduction, disclosure or
+* distribution of this software and related documentation without an express
+* license agreement from NVIDIA CORPORATION is strictly prohibited.
+*/
+
+#pragma once
+
+#include "../DemoApp/computeContext.h"
+
+struct ComputeDescriptorReserveHandleD3D12
+{
+ ID3D12DescriptorHeap* heap;
+ UINT descriptorSize;
+ D3D12_CPU_DESCRIPTOR_HANDLE cpuHandle;
+ D3D12_GPU_DESCRIPTOR_HANDLE gpuHandle;
+};
+
+struct ComputeDynamicDescriptorHeapD3D12
+{
+ void* userdata;
+ ComputeDescriptorReserveHandleD3D12(*reserveDescriptors)(void* userdata, UINT numDescriptors, UINT64 lastFenceCompleted, UINT64 nextFenceValue);
+};
+
+struct ComputeContextDesc
+{
+ ID3D12Device* device;
+ ID3D12CommandQueue* commandQueue;
+ ID3D12Fence* commandQueueFence;
+ ID3D12GraphicsCommandList* commandList;
+ UINT64 lastFenceCompleted;
+ UINT64 nextFenceValue;
+
+ ComputeDynamicDescriptorHeapD3D12 dynamicHeapCbvSrvUav;
+};
+
+struct ComputeResourceDesc
+{
+ D3D12_CPU_DESCRIPTOR_HANDLE srv;
+ ID3D12Resource* resource;
+ D3D12_RESOURCE_STATES* currentState;
+};
+
+struct ComputeResourceRWDesc
+{
+ ComputeResourceDesc resource;
+ D3D12_CPU_DESCRIPTOR_HANDLE uav;
+}; \ No newline at end of file
diff --git a/demo/DemoAppD3D12/imguiGraphD3D12.cpp b/demo/DemoAppD3D12/imguiGraphD3D12.cpp
new file mode 100644
index 0000000..9b5f74a
--- /dev/null
+++ b/demo/DemoAppD3D12/imguiGraphD3D12.cpp
@@ -0,0 +1,662 @@
+/*
+ * Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved.
+ *
+ * NVIDIA CORPORATION and its licensors retain all intellectual property
+ * and proprietary rights in and to this software, related documentation
+ * and any modifications thereto. Any use, reproduction, disclosure or
+ * distribution of this software and related documentation without an express
+ * license agreement from NVIDIA CORPORATION is strictly prohibited.
+ */
+
+//direct3d headers
+#include <d3d12.h>
+
+#include "imguiGraphD3D12.h"
+
+#include "imguiVS.hlsl.h"
+#include "imguiPS.hlsl.h"
+
+namespace
+{
+ template <class T>
+ void inline COMRelease(T& t)
+ {
+ if (t) t->Release();
+ t = nullptr;
+ }
+}
+
+namespace
+{
+ ImguiGraphDesc m_desc = {};
+
+ struct Vertex
+ {
+ float x, y;
+ float u, v;
+ uint8_t rgba[4];
+ };
+
+ ID3D12RootSignature* m_rootSignature = nullptr;
+ ID3D12PipelineState* m_pipelineState = nullptr;
+ ID3D12Resource* m_constantBuffer = nullptr;
+ UINT8* m_constantBufferData = nullptr;
+ ID3D12Resource* m_vertexBuffer = nullptr;
+ Vertex* m_vertexBufferData = nullptr;
+ D3D12_VERTEX_BUFFER_VIEW m_vertexBufferView = {};
+
+ struct Scissor
+ {
+ int beginIdx;
+ int stopIdx;
+ int x;
+ int y;
+ int width;
+ int height;
+ };
+ Scissor m_stateScissor = {};
+
+ ID3D12Resource* m_textureUploadHeap = nullptr;
+ ID3D12Resource* m_texture = nullptr;
+
+ ID3D12DescriptorHeap* m_srvUavHeapCPU = nullptr;
+ ID3D12DescriptorHeap* m_srvUavHeapGPU = nullptr;
+
+ Vertex m_stateVert;
+ uint32_t m_stateVertIdx = 0u;
+
+ struct Params
+ {
+ float projection[16];
+
+ float padding[64 - 16];
+ };
+ static const int frameCount = 4;
+ int frameIndex = 0;
+}
+
+void imguiGraphContextInit(const ImguiGraphDesc* desc)
+{
+ m_desc = *desc;
+
+ // create the root signature
+ {
+ D3D12_DESCRIPTOR_RANGE ranges[1];
+ ranges[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
+ ranges[0].NumDescriptors = 1u;
+ ranges[0].BaseShaderRegister = 0u;
+ ranges[0].RegisterSpace = 0u;
+ ranges[0].OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
+
+ D3D12_ROOT_PARAMETER params[2];
+ params[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
+ params[0].Descriptor.ShaderRegister = 0u;
+ params[0].Descriptor.RegisterSpace = 0u;
+ params[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
+ params[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
+ params[1].DescriptorTable.NumDescriptorRanges = 1;
+ params[1].DescriptorTable.pDescriptorRanges = ranges;
+ params[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
+
+ D3D12_STATIC_SAMPLER_DESC sampler = {};
+ sampler.Filter = D3D12_FILTER_MIN_MAG_LINEAR_MIP_POINT;
+ sampler.AddressU = D3D12_TEXTURE_ADDRESS_MODE_BORDER;
+ sampler.AddressV = D3D12_TEXTURE_ADDRESS_MODE_BORDER;
+ sampler.AddressW = D3D12_TEXTURE_ADDRESS_MODE_BORDER;
+ sampler.MipLODBias = 0;
+ sampler.MaxAnisotropy = 0;
+ sampler.ComparisonFunc = D3D12_COMPARISON_FUNC_NEVER;
+ sampler.BorderColor = D3D12_STATIC_BORDER_COLOR_TRANSPARENT_BLACK;
+ sampler.MinLOD = 0.f;
+ sampler.MaxLOD = D3D12_FLOAT32_MAX;
+ sampler.ShaderRegister = 0;
+ sampler.RegisterSpace = 0;
+ sampler.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
+
+ D3D12_ROOT_SIGNATURE_DESC desc;
+ desc.NumParameters = 2;
+ desc.pParameters = params;
+ desc.NumStaticSamplers = 1u;
+ desc.pStaticSamplers = &sampler;
+ desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT;
+
+ ID3DBlob* signature = nullptr;
+ ID3DBlob* error = nullptr;
+ HRESULT hr = S_OK;
+ if (hr = D3D12SerializeRootSignature(&desc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error))
+ {
+ return;
+ }
+ if (hr = m_desc.device->CreateRootSignature(0u, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&m_rootSignature)))
+ {
+ return;
+ }
+ COMRelease(signature);
+ COMRelease(error);
+ }
+
+ // create the pipeline state object
+ {
+ D3D12_INPUT_ELEMENT_DESC inputElementDescs[] =
+ {
+ { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
+ { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
+ { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
+ };
+
+ const bool wireFrame = false;
+
+ D3D12_RASTERIZER_DESC rasterDesc;
+ if (wireFrame)
+ {
+ rasterDesc.FillMode = D3D12_FILL_MODE_WIREFRAME;
+ rasterDesc.CullMode = D3D12_CULL_MODE_NONE;
+ }
+ else
+ {
+ rasterDesc.FillMode = D3D12_FILL_MODE_SOLID;
+ rasterDesc.CullMode = D3D12_CULL_MODE_BACK;
+ }
+ rasterDesc.FrontCounterClockwise = TRUE; // FALSE;
+ rasterDesc.DepthBias = D3D12_DEFAULT_DEPTH_BIAS;
+ rasterDesc.DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP;
+ rasterDesc.SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS;
+ rasterDesc.DepthClipEnable = TRUE;
+ rasterDesc.MultisampleEnable = FALSE;
+ rasterDesc.AntialiasedLineEnable = FALSE;
+ rasterDesc.ForcedSampleCount = 0;
+ rasterDesc.ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF;
+
+ D3D12_BLEND_DESC blendDesc;
+ blendDesc.AlphaToCoverageEnable = FALSE;
+ blendDesc.IndependentBlendEnable = FALSE;
+ {
+ const D3D12_RENDER_TARGET_BLEND_DESC defaultRenderTargetBlendDesc =
+ {
+ TRUE,FALSE,
+ D3D12_BLEND_SRC_ALPHA, D3D12_BLEND_INV_SRC_ALPHA, D3D12_BLEND_OP_ADD,
+ D3D12_BLEND_SRC_ALPHA, D3D12_BLEND_INV_SRC_ALPHA, D3D12_BLEND_OP_ADD,
+ D3D12_LOGIC_OP_NOOP,
+ D3D12_COLOR_WRITE_ENABLE_ALL,
+ };
+ for (UINT i = 0; i < D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i)
+ blendDesc.RenderTarget[i] = defaultRenderTargetBlendDesc;
+ }
+
+ D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {};
+ psoDesc.InputLayout.NumElements = 3;
+ psoDesc.InputLayout.pInputElementDescs = inputElementDescs;
+ psoDesc.pRootSignature = m_rootSignature;
+ psoDesc.VS.pShaderBytecode = g_imguiVS;
+ psoDesc.VS.BytecodeLength = sizeof(g_imguiVS);
+ psoDesc.PS.pShaderBytecode = g_imguiPS;
+ psoDesc.PS.BytecodeLength = sizeof(g_imguiPS);
+ psoDesc.RasterizerState = rasterDesc;
+ psoDesc.BlendState = blendDesc;
+ psoDesc.DepthStencilState.DepthEnable = FALSE;
+ psoDesc.DepthStencilState.StencilEnable = FALSE;
+ psoDesc.SampleMask = UINT_MAX;
+ psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
+ psoDesc.NumRenderTargets = 1;
+ psoDesc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM;
+ psoDesc.SampleDesc.Count = 1;
+ HRESULT hr = S_OK;
+ if (hr = m_desc.device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&m_pipelineState)))
+ {
+ return;
+ }
+ }
+
+ // create a constant buffer
+ {
+ Params params = {
+ 1.f, 0.f, 0.f, 0.f,
+ 0.f, 1.f, 0.f, 0.f,
+ 0.f, 0.f, 1.f, 0.f,
+ 0.f, 0.f, 0.f, 1.f
+ };
+
+ HRESULT hr = S_OK;
+
+ D3D12_HEAP_PROPERTIES heapProps = {};
+ heapProps.Type = D3D12_HEAP_TYPE_UPLOAD;
+ heapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
+ heapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
+ heapProps.CreationNodeMask = 0u;
+ heapProps.VisibleNodeMask = 0u;
+
+ D3D12_RESOURCE_DESC desc = {};
+ desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
+ desc.Alignment = 0u;
+ desc.Width = frameCount*sizeof(params);
+ desc.Height = 1u;
+ desc.DepthOrArraySize = 1u;
+ desc.MipLevels = 1;
+ desc.Format = DXGI_FORMAT_UNKNOWN;
+ desc.SampleDesc.Count = 1u;
+ desc.SampleDesc.Quality = 0u;
+ desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
+ desc.Flags = D3D12_RESOURCE_FLAG_NONE;
+
+ if (hr = m_desc.device->CreateCommittedResource(&heapProps, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_GENERIC_READ,
+ nullptr, IID_PPV_ARGS(&m_constantBuffer)))
+ {
+ return;
+ }
+
+ UINT8* pdata;
+ D3D12_RANGE readRange = {};
+ if (hr = m_constantBuffer->Map(0, &readRange, (void**)&pdata))
+ {
+ return;
+ }
+ else
+ {
+ memcpy(pdata, &params, sizeof(params));
+ m_constantBufferData = pdata;
+ //m_constantBuffer->Unmap(0, nullptr); // leave mapped
+ }
+ }
+
+ // create a vertex buffer
+ {
+ HRESULT hr = S_OK;
+
+ UINT bufferSize = (UINT)(m_desc.maxVertices * frameCount) * sizeof(Vertex);
+
+ D3D12_HEAP_PROPERTIES heapProps = {};
+ heapProps.Type = D3D12_HEAP_TYPE_UPLOAD;
+ heapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
+ heapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
+ heapProps.CreationNodeMask = 0u;
+ heapProps.VisibleNodeMask = 0u;
+
+ D3D12_RESOURCE_DESC desc = {};
+ desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
+ desc.Alignment = 0u;
+ desc.Width = bufferSize;
+ desc.Height = 1u;
+ desc.DepthOrArraySize = 1u;
+ desc.MipLevels = 1;
+ desc.Format = DXGI_FORMAT_UNKNOWN;
+ desc.SampleDesc.Count = 1u;
+ desc.SampleDesc.Quality = 0u;
+ desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
+ desc.Flags = D3D12_RESOURCE_FLAG_NONE;
+
+ if (hr = m_desc.device->CreateCommittedResource(&heapProps, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_GENERIC_READ,
+ nullptr, IID_PPV_ARGS(&m_vertexBuffer)))
+ {
+ return;
+ }
+
+ UINT8* pdata;
+ D3D12_RANGE readRange = {};
+ if (hr = m_vertexBuffer->Map(0, &readRange, (void**)&pdata))
+ {
+ return;
+ }
+ else
+ {
+ m_vertexBufferData = (Vertex*)pdata;
+ //m_vertexBufferUpload->Unmap(0, nullptr);
+ }
+
+ m_vertexBufferView.BufferLocation = m_vertexBuffer->GetGPUVirtualAddress();
+ m_vertexBufferView.StrideInBytes = sizeof(Vertex);
+ m_vertexBufferView.SizeInBytes = bufferSize;
+ }
+}
+
+void imguiGraphContextUpdate(const ImguiGraphDesc* desc)
+{
+ m_desc = *desc;
+}
+
+void imguiGraphContextDestroy()
+{
+ COMRelease(m_rootSignature);
+ COMRelease(m_pipelineState);
+ COMRelease(m_constantBuffer);
+ COMRelease(m_vertexBuffer);
+}
+
+void imguiGraphRecordBegin()
+{
+ frameIndex = (frameIndex + 1) % frameCount;
+
+ Params params = {
+ 2.f / float(m_desc.winW), 0.f, 0.f, -1.f,
+ 0.f, 2.f / float(m_desc.winH), 0.f, -1.f,
+ 0.f, 0.f, 1.f, 0.f,
+ 0.f, 0.f, 0.f, 1.f
+ };
+
+ memcpy(m_constantBufferData + frameIndex*sizeof(Params), &params, sizeof(Params));
+
+ // clear state
+ m_stateVert = Vertex{ 0.f, 0.f, -1.f, -1.f, 0,0,0,0 };
+ m_stateVertIdx = 0u;
+
+ m_stateScissor = Scissor { 0, 0, 0, 0, m_desc.winW, m_desc.winH };
+
+ // configure for triangle renderering
+ ID3D12GraphicsCommandList* commandList = m_desc.commandList;
+
+ D3D12_CPU_DESCRIPTOR_HANDLE srvHandleCPU;
+ D3D12_GPU_DESCRIPTOR_HANDLE srvHandleGPU;
+ ID3D12DescriptorHeap* heap = nullptr;
+ if (m_desc.dynamicHeapCbvSrvUav.reserveDescriptors)
+ {
+ auto handle = m_desc.dynamicHeapCbvSrvUav.reserveDescriptors(m_desc.dynamicHeapCbvSrvUav.userdata,
+ 1u, m_desc.lastFenceCompleted, m_desc.nextFenceValue);
+ heap = handle.heap;
+ srvHandleCPU = handle.cpuHandle;
+ srvHandleGPU = handle.gpuHandle;
+ }
+ else
+ {
+ if (m_srvUavHeapGPU == nullptr)
+ {
+ D3D12_DESCRIPTOR_HEAP_DESC srvHeapDesc = {};
+ srvHeapDesc.NumDescriptors = 1;
+ srvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
+ srvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
+ m_desc.device->CreateDescriptorHeap(&srvHeapDesc, IID_PPV_ARGS(&m_srvUavHeapGPU));
+ }
+ heap = m_srvUavHeapGPU;
+ srvHandleCPU = m_srvUavHeapGPU->GetCPUDescriptorHandleForHeapStart();
+ srvHandleGPU = m_srvUavHeapGPU->GetGPUDescriptorHandleForHeapStart();
+ }
+
+ commandList->SetDescriptorHeaps(1, &heap);
+
+ m_desc.device->CopyDescriptorsSimple(1u, srvHandleCPU, m_srvUavHeapCPU->GetCPUDescriptorHandleForHeapStart(), D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
+
+ commandList->SetGraphicsRootSignature(m_rootSignature);
+ commandList->SetPipelineState(m_pipelineState);
+
+ D3D12_GPU_VIRTUAL_ADDRESS cbvHandle = m_constantBuffer->GetGPUVirtualAddress();
+ commandList->SetGraphicsRootConstantBufferView(0, cbvHandle + frameIndex * sizeof(Params));
+
+ commandList->SetGraphicsRootDescriptorTable(1, srvHandleGPU);
+
+ commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
+ commandList->IASetVertexBuffers(0, 1, &m_vertexBufferView);
+}
+
+static void imguiGraphFlush()
+{
+ ID3D12GraphicsCommandList* commandList = m_desc.commandList;
+
+ Scissor& p = m_stateScissor;
+ if (p.beginIdx < p.stopIdx)
+ {
+ int winH = m_desc.winH;
+ D3D12_RECT rect;
+ rect.left = p.x;
+ rect.right = p.x + p.width;
+ rect.top = (winH) - (p.y + p.height);
+ rect.bottom = (winH) - (p.y);
+ commandList->RSSetScissorRects(1, &rect);
+
+ UINT vertexCount = (p.stopIdx - p.beginIdx);
+ UINT startIndex = p.beginIdx + frameIndex * m_desc.maxVertices;
+ commandList->DrawInstanced(vertexCount, 1, startIndex, 0);
+ }
+}
+
+void imguiGraphRecordEnd()
+{
+ ID3D12GraphicsCommandList* commandList = m_desc.commandList;
+
+ // no need to hold onto this
+ COMRelease(m_textureUploadHeap);
+
+ // restore scissor
+ Scissor& p = m_stateScissor;
+ int winH = m_desc.winH;
+ D3D12_RECT rect;
+ rect.left = p.x;
+ rect.right = p.x + p.width;
+ rect.top = (winH) - (p.y + p.height);
+ rect.bottom = (winH) - (p.y);
+ commandList->RSSetScissorRects(1, &rect);
+}
+
+void imguiGraphEnableScissor(int x, int y, int width, int height)
+{
+ // mark end of last region
+ m_stateScissor.stopIdx = m_stateVertIdx;
+
+ imguiGraphFlush();
+
+ m_stateScissor.beginIdx = m_stateVertIdx;
+ m_stateScissor.stopIdx = m_stateVertIdx;
+ m_stateScissor.x = x;
+ m_stateScissor.y = y;
+ m_stateScissor.width = width;
+ m_stateScissor.height = height;
+}
+
+void imguiGraphDisableScissor()
+{
+ if (m_stateVertIdx == 0) return;
+
+ // mark end of last region
+ m_stateScissor.stopIdx = m_stateVertIdx;
+
+ imguiGraphFlush();
+
+ m_stateScissor.beginIdx = m_stateVertIdx;
+ m_stateScissor.stopIdx = m_stateVertIdx;
+ m_stateScissor.x = 0;
+ m_stateScissor.y = 0;
+ m_stateScissor.width = m_desc.winW;
+ m_stateScissor.height = m_desc.winH;
+}
+
+void imguiGraphVertex2f(float x, float y)
+{
+ float v[2] = { x,y };
+ imguiGraphVertex2fv(v);
+}
+
+void imguiGraphVertex2fv(const float* v)
+{
+ // update state
+ m_stateVert.x = v[0];
+ m_stateVert.y = v[1];
+
+ Vertex* vdata = &m_vertexBufferData[frameIndex * m_desc.maxVertices];
+
+ // push vertex
+ if ((m_stateVertIdx) < m_desc.maxVertices)
+ {
+ vdata[m_stateVertIdx++] = m_stateVert;
+ }
+}
+
+void imguiGraphTexCoord2f(float u, float v)
+{
+ m_stateVert.u = u;
+ m_stateVert.v = v;
+}
+
+void imguiGraphColor4ub(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha)
+{
+ m_stateVert.rgba[0] = red;
+ m_stateVert.rgba[1] = green;
+ m_stateVert.rgba[2] = blue;
+ m_stateVert.rgba[3] = alpha;
+}
+
+void imguiGraphColor4ubv(const uint8_t* v)
+{
+ m_stateVert.rgba[0] = v[0];
+ m_stateVert.rgba[1] = v[1];
+ m_stateVert.rgba[2] = v[2];
+ m_stateVert.rgba[3] = v[3];
+}
+
+void imguiGraphFontTextureEnable()
+{
+
+}
+
+void imguiGraphFontTextureDisable()
+{
+ m_stateVert.u = -1.f;
+ m_stateVert.v = -1.f;
+}
+
+void imguiGraphFontTextureInit(unsigned char* data)
+{
+ ID3D12GraphicsCommandList* commandList = m_desc.commandList;
+
+ // Create the texture
+ {
+ UINT width = 512;
+ UINT height = 512;
+
+ D3D12_HEAP_PROPERTIES heapProps = {};
+ heapProps.Type = D3D12_HEAP_TYPE_DEFAULT;
+ heapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
+ heapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
+ heapProps.CreationNodeMask = 0u;
+ heapProps.VisibleNodeMask = 0u;
+
+ D3D12_RESOURCE_DESC texDesc = {};
+ texDesc.MipLevels = 1u;
+ texDesc.Format = DXGI_FORMAT_R8_UNORM;
+ texDesc.Width = width;
+ texDesc.Height = height;
+ texDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
+ texDesc.DepthOrArraySize = 1u;
+ texDesc.SampleDesc.Count = 1u;
+ texDesc.SampleDesc.Quality = 0u;
+ texDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
+
+ if (m_desc.device->CreateCommittedResource(
+ &heapProps,
+ D3D12_HEAP_FLAG_NONE,
+ &texDesc,
+ D3D12_RESOURCE_STATE_COPY_DEST,
+ nullptr,
+ IID_PPV_ARGS(&m_texture)
+ ))
+ {
+ return;
+ }
+
+ // get footprint information
+ D3D12_PLACED_SUBRESOURCE_FOOTPRINT footprint = {};
+ UINT64 uploadHeapSize = 0u;
+ m_desc.device->GetCopyableFootprints(&texDesc, 0u, 1u, 0u, &footprint, nullptr, nullptr, &uploadHeapSize);
+
+ heapProps.Type = D3D12_HEAP_TYPE_UPLOAD;
+ D3D12_RESOURCE_DESC bufferDesc = texDesc;
+ bufferDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
+ bufferDesc.Alignment = 0u;
+ bufferDesc.Width = uploadHeapSize;
+ bufferDesc.Height = 1u;
+ bufferDesc.DepthOrArraySize = 1u;
+ bufferDesc.MipLevels = 1;
+ bufferDesc.Format = DXGI_FORMAT_UNKNOWN;
+ bufferDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
+ bufferDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
+
+ if (m_desc.device->CreateCommittedResource(
+ &heapProps,
+ D3D12_HEAP_FLAG_NONE,
+ &bufferDesc,
+ D3D12_RESOURCE_STATE_GENERIC_READ,
+ nullptr,
+ IID_PPV_ARGS(&m_textureUploadHeap)
+ ))
+ {
+ return;
+ }
+
+ // map upload heap, and convert rgb bitmap to rgba
+ UINT8* pdata;
+ D3D12_RANGE readRange = {};
+ if (m_textureUploadHeap->Map(0, &readRange, (void**)&pdata))
+ {
+ return;
+ }
+ else
+ {
+ UINT8* dst = pdata;
+ UINT elements = width*height;
+ UINT8* src = data;
+ for (UINT j = 0; j < height; j++)
+ {
+ for (UINT i = 0; i < width; i++)
+ {
+ UINT idx = j * (footprint.Footprint.RowPitch) + i;
+
+ UINT8 a = src[j * width + i];
+ dst[idx] = a;
+ }
+ }
+
+ m_textureUploadHeap->Unmap(0, nullptr);
+ }
+
+ // add copy from upload heap to default heap to command list
+ D3D12_TEXTURE_COPY_LOCATION dstCopy = {};
+ D3D12_TEXTURE_COPY_LOCATION srcCopy = {};
+ dstCopy.pResource = m_texture;
+ dstCopy.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
+ dstCopy.SubresourceIndex = 0u;
+ srcCopy.pResource = m_textureUploadHeap;
+ srcCopy.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
+ srcCopy.PlacedFootprint = footprint;
+ commandList->CopyTextureRegion(&dstCopy, 0, 0, 0, &srcCopy, nullptr);
+
+ D3D12_RESOURCE_BARRIER barrier[1] = {};
+ auto textureBarrier = [&barrier](UINT idx, ID3D12Resource* texture)
+ {
+ barrier[idx].Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
+ barrier[idx].Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
+ barrier[idx].Transition.pResource = texture;
+ barrier[idx].Transition.Subresource = 0u;
+ barrier[idx].Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST;
+ barrier[idx].Transition.StateAfter = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
+ };
+ textureBarrier(0, m_texture);
+ commandList->ResourceBarrier(1, barrier);
+
+ // create an SRV heap and descriptor for the texture
+ D3D12_DESCRIPTOR_HEAP_DESC srvHeapDesc = {};
+ srvHeapDesc.NumDescriptors = 1;
+ srvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
+ srvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
+ if (m_desc.device->CreateDescriptorHeap(&srvHeapDesc, IID_PPV_ARGS(&m_srvUavHeapCPU)))
+ {
+ return;
+ }
+
+ D3D12_CPU_DESCRIPTOR_HANDLE srvUavHandle = m_srvUavHeapCPU->GetCPUDescriptorHandleForHeapStart();
+
+ D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
+ srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
+ srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
+ srvDesc.Format = texDesc.Format;
+ srvDesc.Texture2D.MipLevels = 1;
+ srvDesc.Texture2D.MostDetailedMip = 0;
+ srvDesc.Texture2D.ResourceMinLODClamp = 0.f;
+
+ m_desc.device->CreateShaderResourceView(m_texture, &srvDesc, srvUavHandle);
+ }
+
+}
+
+void imguiGraphFontTextureRelease()
+{
+ COMRelease(m_texture);
+ COMRelease(m_textureUploadHeap);
+ COMRelease(m_srvUavHeapCPU);
+ COMRelease(m_srvUavHeapGPU);
+} \ No newline at end of file
diff --git a/demo/DemoAppD3D12/imguiGraphD3D12.h b/demo/DemoAppD3D12/imguiGraphD3D12.h
new file mode 100644
index 0000000..7eeb538
--- /dev/null
+++ b/demo/DemoAppD3D12/imguiGraphD3D12.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved.
+ *
+ * NVIDIA CORPORATION and its licensors retain all intellectual property
+ * and proprietary rights in and to this software, related documentation
+ * and any modifications thereto. Any use, reproduction, disclosure or
+ * distribution of this software and related documentation without an express
+ * license agreement from NVIDIA CORPORATION is strictly prohibited.
+ */
+
+#ifndef IMGUI_GRAPH_D3D12_H
+#define IMGUI_GRAPH_D3D12_H
+
+#include <stdint.h>
+
+#include "../DemoApp/imguiGraph.h"
+
+struct ImguiDescriptorReserveHandleD3D12
+{
+ ID3D12DescriptorHeap* heap;
+ UINT descriptorSize;
+ D3D12_CPU_DESCRIPTOR_HANDLE cpuHandle;
+ D3D12_GPU_DESCRIPTOR_HANDLE gpuHandle;
+};
+
+struct ImguiDynamicDescriptorHeapD3D12
+{
+ void* userdata;
+ ImguiDescriptorReserveHandleD3D12(*reserveDescriptors)(void* userdata, UINT numDescriptors, UINT64 lastFenceCompleted, UINT64 nextFenceValue);
+};
+
+struct ImguiGraphDesc
+{
+ ID3D12Device* device = nullptr;
+ ID3D12GraphicsCommandList* commandList = nullptr;
+ UINT64 lastFenceCompleted;
+ UINT64 nextFenceValue;
+ int winW;
+ int winH;
+
+ uint32_t maxVertices = 64 * 4096u;
+
+ ImguiDynamicDescriptorHeapD3D12 dynamicHeapCbvSrvUav = {};
+
+ ImguiGraphDesc() {}
+};
+
+#endif \ No newline at end of file
diff --git a/demo/DemoAppD3D12/imguiInteropD3D12.cpp b/demo/DemoAppD3D12/imguiInteropD3D12.cpp
new file mode 100644
index 0000000..322e1b5
--- /dev/null
+++ b/demo/DemoAppD3D12/imguiInteropD3D12.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved.
+ *
+ * NVIDIA CORPORATION and its licensors retain all intellectual property
+ * and proprietary rights in and to this software, related documentation
+ * and any modifications thereto. Any use, reproduction, disclosure or
+ * distribution of this software and related documentation without an express
+ * license agreement from NVIDIA CORPORATION is strictly prohibited.
+ */
+
+ //direct3d headers
+#include <d3d12.h>
+
+// include the Direct3D Library file
+#pragma comment (lib, "d3d12.lib")
+
+#include "../DemoApp/imguiInterop.h"
+
+#include "appD3D12Ctx.h"
+#include "imguiGraphD3D12.h"
+
+ImguiDescriptorReserveHandleD3D12 imguiInteropReserveDescriptors(void* userdata, UINT numDescriptors, UINT64 lastFenceCompleted, UINT64 nextFenceValue)
+{
+ auto appctx = static_cast<AppGraphCtx*>(userdata);
+ auto srcHandle = appctx->m_dynamicHeapCbvSrvUav.reserveDescriptors(numDescriptors, lastFenceCompleted, nextFenceValue);
+ ImguiDescriptorReserveHandleD3D12 handle = {};
+ handle.heap = srcHandle.heap;
+ handle.descriptorSize = srcHandle.descriptorSize;
+ handle.cpuHandle = srcHandle.cpuHandle;
+ handle.gpuHandle = srcHandle.gpuHandle;
+ return handle;
+}
+
+void imguiInteropUpdateDesc(ImguiGraphDesc& desc, AppGraphCtx* appctx)
+{
+ desc.device = appctx->m_device;
+ desc.commandList = appctx->m_commandList;
+ desc.lastFenceCompleted = appctx->m_lastFenceComplete;
+ desc.nextFenceValue = appctx->m_thisFrameFenceID;
+ desc.winW = appctx->m_winW;
+ desc.winH = appctx->m_winH;
+ desc.dynamicHeapCbvSrvUav.userdata = appctx;
+ desc.dynamicHeapCbvSrvUav.reserveDescriptors = imguiInteropReserveDescriptors;
+}
+
+bool imguiInteropGraphInit(imguiGraphInit_t func, const char* fontpath, AppGraphCtx* appctx)
+{
+ ImguiGraphDesc desc;
+ imguiInteropUpdateDesc(desc, appctx);
+
+ return func(fontpath, &desc);
+}
+
+void imguiInteropGraphUpdate(imguiGraphUpdate_t func, AppGraphCtx* appctx)
+{
+ ImguiGraphDesc desc;
+ imguiInteropUpdateDesc(desc, appctx);
+
+ return func(&desc);
+} \ No newline at end of file
diff --git a/demo/DemoAppD3D12/imguiPS.hlsl.h b/demo/DemoAppD3D12/imguiPS.hlsl.h
new file mode 100644
index 0000000..d6fb74c
--- /dev/null
+++ b/demo/DemoAppD3D12/imguiPS.hlsl.h
@@ -0,0 +1,195 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// texSampler sampler NA NA s0 1
+// tex texture float 2d t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// TEXCOORD 0 xy 1 NONE float xy
+// COLOR 0 xyzw 2 NONE float xyzw
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_5_0
+dcl_globalFlags refactoringAllowed
+dcl_sampler s0, mode_default
+dcl_resource_texture2d (float,float,float,float) t0
+dcl_input_ps linear v1.xy
+dcl_input_ps linear v2.xyzw
+dcl_output o0.xyzw
+dcl_temps 1
+ge r0.x, v1.x, l(0.000000)
+if_nz r0.x
+ sample_l_indexable(texture2d)(float,float,float,float) r0.x, v1.xyxx, t0.xyzw, s0, l(0.000000)
+ mul r0.x, r0.x, v2.w
+else
+ mov r0.x, v2.w
+endif
+mov r0.yzw, v2.xxyz
+mov o0.xyzw, r0.yzwx
+ret
+// Approximately 10 instruction slots used
+#endif
+
+const BYTE g_imguiPS[] =
+{
+ 68, 88, 66, 67, 254, 30,
+ 194, 112, 35, 29, 114, 31,
+ 28, 188, 13, 85, 22, 84,
+ 219, 9, 1, 0, 0, 0,
+ 80, 3, 0, 0, 5, 0,
+ 0, 0, 52, 0, 0, 0,
+ 240, 0, 0, 0, 100, 1,
+ 0, 0, 152, 1, 0, 0,
+ 180, 2, 0, 0, 82, 68,
+ 69, 70, 180, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 2, 0, 0, 0,
+ 60, 0, 0, 0, 0, 5,
+ 255, 255, 0, 1, 0, 0,
+ 139, 0, 0, 0, 82, 68,
+ 49, 49, 60, 0, 0, 0,
+ 24, 0, 0, 0, 32, 0,
+ 0, 0, 40, 0, 0, 0,
+ 36, 0, 0, 0, 12, 0,
+ 0, 0, 0, 0, 0, 0,
+ 124, 0, 0, 0, 3, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 1, 0,
+ 0, 0, 135, 0, 0, 0,
+ 2, 0, 0, 0, 5, 0,
+ 0, 0, 4, 0, 0, 0,
+ 255, 255, 255, 255, 0, 0,
+ 0, 0, 1, 0, 0, 0,
+ 1, 0, 0, 0, 116, 101,
+ 120, 83, 97, 109, 112, 108,
+ 101, 114, 0, 116, 101, 120,
+ 0, 77, 105, 99, 114, 111,
+ 115, 111, 102, 116, 32, 40,
+ 82, 41, 32, 72, 76, 83,
+ 76, 32, 83, 104, 97, 100,
+ 101, 114, 32, 67, 111, 109,
+ 112, 105, 108, 101, 114, 32,
+ 49, 48, 46, 49, 0, 171,
+ 73, 83, 71, 78, 108, 0,
+ 0, 0, 3, 0, 0, 0,
+ 8, 0, 0, 0, 80, 0,
+ 0, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 3, 0,
+ 0, 0, 0, 0, 0, 0,
+ 15, 0, 0, 0, 92, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 3, 0,
+ 0, 0, 1, 0, 0, 0,
+ 3, 3, 0, 0, 101, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 3, 0,
+ 0, 0, 2, 0, 0, 0,
+ 15, 15, 0, 0, 83, 86,
+ 95, 80, 79, 83, 73, 84,
+ 73, 79, 78, 0, 84, 69,
+ 88, 67, 79, 79, 82, 68,
+ 0, 67, 79, 76, 79, 82,
+ 0, 171, 79, 83, 71, 78,
+ 44, 0, 0, 0, 1, 0,
+ 0, 0, 8, 0, 0, 0,
+ 32, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 3, 0, 0, 0, 0, 0,
+ 0, 0, 15, 0, 0, 0,
+ 83, 86, 95, 84, 65, 82,
+ 71, 69, 84, 0, 171, 171,
+ 83, 72, 69, 88, 20, 1,
+ 0, 0, 80, 0, 0, 0,
+ 69, 0, 0, 0, 106, 8,
+ 0, 1, 90, 0, 0, 3,
+ 0, 96, 16, 0, 0, 0,
+ 0, 0, 88, 24, 0, 4,
+ 0, 112, 16, 0, 0, 0,
+ 0, 0, 85, 85, 0, 0,
+ 98, 16, 0, 3, 50, 16,
+ 16, 0, 1, 0, 0, 0,
+ 98, 16, 0, 3, 242, 16,
+ 16, 0, 2, 0, 0, 0,
+ 101, 0, 0, 3, 242, 32,
+ 16, 0, 0, 0, 0, 0,
+ 104, 0, 0, 2, 1, 0,
+ 0, 0, 29, 0, 0, 7,
+ 18, 0, 16, 0, 0, 0,
+ 0, 0, 10, 16, 16, 0,
+ 1, 0, 0, 0, 1, 64,
+ 0, 0, 0, 0, 0, 0,
+ 31, 0, 4, 3, 10, 0,
+ 16, 0, 0, 0, 0, 0,
+ 72, 0, 0, 141, 194, 0,
+ 0, 128, 67, 85, 21, 0,
+ 18, 0, 16, 0, 0, 0,
+ 0, 0, 70, 16, 16, 0,
+ 1, 0, 0, 0, 70, 126,
+ 16, 0, 0, 0, 0, 0,
+ 0, 96, 16, 0, 0, 0,
+ 0, 0, 1, 64, 0, 0,
+ 0, 0, 0, 0, 56, 0,
+ 0, 7, 18, 0, 16, 0,
+ 0, 0, 0, 0, 10, 0,
+ 16, 0, 0, 0, 0, 0,
+ 58, 16, 16, 0, 2, 0,
+ 0, 0, 18, 0, 0, 1,
+ 54, 0, 0, 5, 18, 0,
+ 16, 0, 0, 0, 0, 0,
+ 58, 16, 16, 0, 2, 0,
+ 0, 0, 21, 0, 0, 1,
+ 54, 0, 0, 5, 226, 0,
+ 16, 0, 0, 0, 0, 0,
+ 6, 25, 16, 0, 2, 0,
+ 0, 0, 54, 0, 0, 5,
+ 242, 32, 16, 0, 0, 0,
+ 0, 0, 150, 3, 16, 0,
+ 0, 0, 0, 0, 62, 0,
+ 0, 1, 83, 84, 65, 84,
+ 148, 0, 0, 0, 10, 0,
+ 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 0, 3, 0,
+ 0, 0, 2, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 2, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 3, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0
+};
diff --git a/demo/DemoAppD3D12/imguiVS.hlsl.h b/demo/DemoAppD3D12/imguiVS.hlsl.h
new file mode 100644
index 0000000..6c7ed54
--- /dev/null
+++ b/demo/DemoAppD3D12/imguiVS.hlsl.h
@@ -0,0 +1,246 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Buffer Definitions:
+//
+// cbuffer params
+// {
+//
+// float4x4 transform; // Offset: 0 Size: 64
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// params cbuffer NA NA cb0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// POSITION 0 xy 0 NONE float xy
+// TEXCOORD 0 xy 1 NONE float xy
+// COLOR 0 xyzw 2 NONE float xyzw
+// SV_InstanceID 0 x 3 INSTID uint
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float xyzw
+// TEXCOORD 0 xy 1 NONE float xy
+// COLOR 0 xyzw 2 NONE float xyzw
+//
+vs_5_0
+dcl_globalFlags refactoringAllowed
+dcl_constantbuffer CB0[4], immediateIndexed
+dcl_input v0.xy
+dcl_input v1.xy
+dcl_input v2.xyzw
+dcl_output_siv o0.xyzw, position
+dcl_output o1.xy
+dcl_output o2.xyzw
+dcl_temps 1
+mov r0.xy, v0.xyxx
+mov r0.z, l(1.000000)
+dp3 o0.x, r0.xyzx, cb0[0].xywx
+dp3 o0.y, r0.xyzx, cb0[1].xywx
+dp3 o0.z, r0.xyzx, cb0[2].xywx
+dp3 o0.w, r0.xyzx, cb0[3].xywx
+mov o1.xy, v1.xyxx
+mov o2.xyzw, v2.xyzw
+ret
+// Approximately 9 instruction slots used
+#endif
+
+const BYTE g_imguiVS[] =
+{
+ 68, 88, 66, 67, 6, 20,
+ 203, 172, 109, 190, 55, 177,
+ 9, 228, 94, 38, 104, 254,
+ 183, 14, 1, 0, 0, 0,
+ 52, 4, 0, 0, 5, 0,
+ 0, 0, 52, 0, 0, 0,
+ 64, 1, 0, 0, 216, 1,
+ 0, 0, 76, 2, 0, 0,
+ 152, 3, 0, 0, 82, 68,
+ 69, 70, 4, 1, 0, 0,
+ 1, 0, 0, 0, 100, 0,
+ 0, 0, 1, 0, 0, 0,
+ 60, 0, 0, 0, 0, 5,
+ 254, 255, 0, 1, 0, 0,
+ 220, 0, 0, 0, 82, 68,
+ 49, 49, 60, 0, 0, 0,
+ 24, 0, 0, 0, 32, 0,
+ 0, 0, 40, 0, 0, 0,
+ 36, 0, 0, 0, 12, 0,
+ 0, 0, 0, 0, 0, 0,
+ 92, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 1, 0,
+ 0, 0, 112, 97, 114, 97,
+ 109, 115, 0, 171, 92, 0,
+ 0, 0, 1, 0, 0, 0,
+ 124, 0, 0, 0, 64, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 164, 0,
+ 0, 0, 0, 0, 0, 0,
+ 64, 0, 0, 0, 2, 0,
+ 0, 0, 184, 0, 0, 0,
+ 0, 0, 0, 0, 255, 255,
+ 255, 255, 0, 0, 0, 0,
+ 255, 255, 255, 255, 0, 0,
+ 0, 0, 116, 114, 97, 110,
+ 115, 102, 111, 114, 109, 0,
+ 102, 108, 111, 97, 116, 52,
+ 120, 52, 0, 171, 3, 0,
+ 3, 0, 4, 0, 4, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 174, 0, 0, 0, 77, 105,
+ 99, 114, 111, 115, 111, 102,
+ 116, 32, 40, 82, 41, 32,
+ 72, 76, 83, 76, 32, 83,
+ 104, 97, 100, 101, 114, 32,
+ 67, 111, 109, 112, 105, 108,
+ 101, 114, 32, 49, 48, 46,
+ 49, 0, 73, 83, 71, 78,
+ 144, 0, 0, 0, 4, 0,
+ 0, 0, 8, 0, 0, 0,
+ 104, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 3, 0, 0, 0, 0, 0,
+ 0, 0, 3, 3, 0, 0,
+ 113, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 3, 0, 0, 0, 1, 0,
+ 0, 0, 3, 3, 0, 0,
+ 122, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 3, 0, 0, 0, 2, 0,
+ 0, 0, 15, 15, 0, 0,
+ 128, 0, 0, 0, 0, 0,
+ 0, 0, 8, 0, 0, 0,
+ 1, 0, 0, 0, 3, 0,
+ 0, 0, 1, 0, 0, 0,
+ 80, 79, 83, 73, 84, 73,
+ 79, 78, 0, 84, 69, 88,
+ 67, 79, 79, 82, 68, 0,
+ 67, 79, 76, 79, 82, 0,
+ 83, 86, 95, 73, 110, 115,
+ 116, 97, 110, 99, 101, 73,
+ 68, 0, 171, 171, 79, 83,
+ 71, 78, 108, 0, 0, 0,
+ 3, 0, 0, 0, 8, 0,
+ 0, 0, 80, 0, 0, 0,
+ 0, 0, 0, 0, 1, 0,
+ 0, 0, 3, 0, 0, 0,
+ 0, 0, 0, 0, 15, 0,
+ 0, 0, 92, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 3, 0, 0, 0,
+ 1, 0, 0, 0, 3, 12,
+ 0, 0, 101, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 3, 0, 0, 0,
+ 2, 0, 0, 0, 15, 0,
+ 0, 0, 83, 86, 95, 80,
+ 79, 83, 73, 84, 73, 79,
+ 78, 0, 84, 69, 88, 67,
+ 79, 79, 82, 68, 0, 67,
+ 79, 76, 79, 82, 0, 171,
+ 83, 72, 69, 88, 68, 1,
+ 0, 0, 80, 0, 1, 0,
+ 81, 0, 0, 0, 106, 8,
+ 0, 1, 89, 0, 0, 4,
+ 70, 142, 32, 0, 0, 0,
+ 0, 0, 4, 0, 0, 0,
+ 95, 0, 0, 3, 50, 16,
+ 16, 0, 0, 0, 0, 0,
+ 95, 0, 0, 3, 50, 16,
+ 16, 0, 1, 0, 0, 0,
+ 95, 0, 0, 3, 242, 16,
+ 16, 0, 2, 0, 0, 0,
+ 103, 0, 0, 4, 242, 32,
+ 16, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 101, 0,
+ 0, 3, 50, 32, 16, 0,
+ 1, 0, 0, 0, 101, 0,
+ 0, 3, 242, 32, 16, 0,
+ 2, 0, 0, 0, 104, 0,
+ 0, 2, 1, 0, 0, 0,
+ 54, 0, 0, 5, 50, 0,
+ 16, 0, 0, 0, 0, 0,
+ 70, 16, 16, 0, 0, 0,
+ 0, 0, 54, 0, 0, 5,
+ 66, 0, 16, 0, 0, 0,
+ 0, 0, 1, 64, 0, 0,
+ 0, 0, 128, 63, 16, 0,
+ 0, 8, 18, 32, 16, 0,
+ 0, 0, 0, 0, 70, 2,
+ 16, 0, 0, 0, 0, 0,
+ 70, 131, 32, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 16, 0, 0, 8, 34, 32,
+ 16, 0, 0, 0, 0, 0,
+ 70, 2, 16, 0, 0, 0,
+ 0, 0, 70, 131, 32, 0,
+ 0, 0, 0, 0, 1, 0,
+ 0, 0, 16, 0, 0, 8,
+ 66, 32, 16, 0, 0, 0,
+ 0, 0, 70, 2, 16, 0,
+ 0, 0, 0, 0, 70, 131,
+ 32, 0, 0, 0, 0, 0,
+ 2, 0, 0, 0, 16, 0,
+ 0, 8, 130, 32, 16, 0,
+ 0, 0, 0, 0, 70, 2,
+ 16, 0, 0, 0, 0, 0,
+ 70, 131, 32, 0, 0, 0,
+ 0, 0, 3, 0, 0, 0,
+ 54, 0, 0, 5, 50, 32,
+ 16, 0, 1, 0, 0, 0,
+ 70, 16, 16, 0, 1, 0,
+ 0, 0, 54, 0, 0, 5,
+ 242, 32, 16, 0, 2, 0,
+ 0, 0, 70, 30, 16, 0,
+ 2, 0, 0, 0, 62, 0,
+ 0, 1, 83, 84, 65, 84,
+ 148, 0, 0, 0, 9, 0,
+ 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 0, 6, 0,
+ 0, 0, 4, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 4, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0
+};
diff --git a/demo/DemoAppD3D12/meshD3D12.cpp b/demo/DemoAppD3D12/meshD3D12.cpp
new file mode 100644
index 0000000..3b04436
--- /dev/null
+++ b/demo/DemoAppD3D12/meshD3D12.cpp
@@ -0,0 +1,576 @@
+/*
+ * Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved.
+ *
+ * NVIDIA CORPORATION and its licensors retain all intellectual property
+ * and proprietary rights in and to this software, related documentation
+ * and any modifications thereto. Any use, reproduction, disclosure or
+ * distribution of this software and related documentation without an express
+ * license agreement from NVIDIA CORPORATION is strictly prohibited.
+ */
+
+//direct3d headers
+#include <d3d12.h>
+
+// include the Direct3D Library file
+#pragma comment (lib, "d3d12.lib")
+
+#include <math.h>
+
+#include <SDL.h>
+
+#include "meshD3D12.h"
+
+#include "meshVS.hlsl.h"
+#include "meshPS.hlsl.h"
+
+namespace
+{
+ template <class T>
+ void inline COMRelease(T& t)
+ {
+ if (t) t->Release();
+ t = nullptr;
+ }
+}
+
+struct MeshConstantHeap
+{
+ MeshConstantHeap* m_next = nullptr;
+ MeshContext* m_meshContext = nullptr;
+
+ ID3D12Resource* m_constantBuffer = nullptr;
+ UINT8* m_constantBufferData = nullptr;
+
+ int m_allocIdx = 0;
+ int m_size;
+
+ MeshConstantHeap(MeshContext* meshContext, int size);
+ ~MeshConstantHeap()
+ {
+ COMRelease(m_constantBuffer);
+ delete m_next;
+ }
+
+ void reset()
+ {
+ m_allocIdx = 0;
+ if (m_next)
+ {
+ m_next->reset();
+ }
+ }
+
+ UINT8* allocate(int size)
+ {
+ UINT8* ret = nullptr;
+ size = 256 * ((size + 255) / 256);
+ if (m_allocIdx + size <= m_size)
+ {
+ ret = m_constantBufferData + m_allocIdx;
+ m_allocIdx += size;
+ }
+ if (ret == nullptr)
+ {
+ if (m_next)
+ {
+ return m_next->allocate(size);
+ }
+ else
+ {
+ m_next = new MeshConstantHeap(m_meshContext, m_size);
+ return m_next->allocate(size);
+ }
+ }
+ return ret;
+ }
+
+ D3D12_GPU_VIRTUAL_ADDRESS getVirtualAddress(UINT8* cpuAddress)
+ {
+ size_t offset = cpuAddress - m_constantBufferData;
+ if (offset < m_size)
+ {
+ return m_constantBuffer->GetGPUVirtualAddress() + offset;
+ }
+ else
+ {
+ if (m_next)
+ {
+ return m_next->getVirtualAddress(cpuAddress);
+ }
+ else
+ {
+ return 0u;
+ }
+ }
+ }
+};
+
+struct MeshContext
+{
+ ID3D12Device* m_device = nullptr;
+ ID3D12GraphicsCommandList* m_commandList = nullptr;
+
+ ID3D12RootSignature* m_rootSignature = nullptr;
+ ID3D12PipelineState* m_pipelineStateLH = nullptr;
+ ID3D12PipelineState* m_pipelineStateRH = nullptr;
+
+ MeshConstantHeap* m_constantHeap = nullptr;
+
+ MeshContext() {}
+ ~MeshContext()
+ {
+ COMRelease(m_rootSignature);
+ COMRelease(m_pipelineStateLH);
+ COMRelease(m_pipelineStateRH);
+ if (m_constantHeap)
+ {
+ delete m_constantHeap;
+ m_constantHeap = nullptr;
+ }
+ }
+};
+
+struct MeshIndexBuffer
+{
+ ID3D12Resource* m_buffer = nullptr;
+ MeshUint m_numElements = 0u;
+ D3D12_INDEX_BUFFER_VIEW m_view = {};
+
+ ID3D12Resource* m_upload = nullptr;
+
+ MeshIndexBuffer() {}
+ ~MeshIndexBuffer()
+ {
+ COMRelease(m_buffer);
+ COMRelease(m_upload);
+ }
+};
+
+struct MeshVertexBuffer
+{
+ ID3D12Resource* m_buffer = nullptr;
+ MeshUint m_numElements = 0u;
+ D3D12_VERTEX_BUFFER_VIEW m_view = {};
+
+ ID3D12Resource* m_upload = nullptr;
+
+ MeshVertexBuffer() {}
+ ~MeshVertexBuffer()
+ {
+ COMRelease(m_buffer);
+ COMRelease(m_upload);
+ }
+};
+
+MeshConstantHeap::MeshConstantHeap(MeshContext* meshContext, int size) : m_meshContext(meshContext)
+{
+ // create a constant buffer
+ {
+ HRESULT hr = S_OK;
+
+ D3D12_HEAP_PROPERTIES heapProps = {};
+ heapProps.Type = D3D12_HEAP_TYPE_UPLOAD;
+ heapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
+ heapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
+ heapProps.CreationNodeMask = 0u;
+ heapProps.VisibleNodeMask = 0u;
+
+ m_size = 256 * ((size + 255) / 256);
+
+ D3D12_RESOURCE_DESC desc = {};
+ desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
+ desc.Alignment = 0u;
+ desc.Width = m_size;
+ desc.Height = 1u;
+ desc.DepthOrArraySize = 1u;
+ desc.MipLevels = 1;
+ desc.Format = DXGI_FORMAT_UNKNOWN;
+ desc.SampleDesc.Count = 1u;
+ desc.SampleDesc.Quality = 0u;
+ desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
+ desc.Flags = D3D12_RESOURCE_FLAG_NONE;
+
+ if (hr = meshContext->m_device->CreateCommittedResource(&heapProps, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_GENERIC_READ,
+ nullptr, IID_PPV_ARGS(&m_constantBuffer)))
+ {
+ }
+
+ UINT8* pdata;
+ D3D12_RANGE readRange = {};
+ if (hr = m_constantBuffer->Map(0, &readRange, (void**)&pdata))
+ {
+ }
+ else
+ {
+ m_constantBufferData = pdata;
+ //m_constantBuffer->Unmap(0, nullptr); // leave mapped
+ }
+ }
+}
+
+MeshContext* MeshContextCreate(const MeshContextDesc* desc)
+{
+ MeshContext* context = new MeshContext;
+
+ context->m_device = desc->device;
+ context->m_commandList = desc->commandList;
+
+ // create the root signature
+ {
+ D3D12_ROOT_PARAMETER params[1];
+ params[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
+ params[0].Descriptor.ShaderRegister = 0u;
+ params[0].Descriptor.RegisterSpace = 0u;
+ params[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
+
+ D3D12_ROOT_SIGNATURE_DESC desc;
+ desc.NumParameters = 1;
+ desc.pParameters = params;
+ desc.NumStaticSamplers = 0u;
+ desc.pStaticSamplers = nullptr;
+ desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT;
+
+ ID3DBlob* signature = nullptr;
+ ID3DBlob* error = nullptr;
+ HRESULT hr = S_OK;
+ if (hr = D3D12SerializeRootSignature(&desc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error))
+ {
+ delete context;
+ return nullptr;
+ }
+ if (hr = context->m_device->CreateRootSignature(0u, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&context->m_rootSignature)))
+ {
+ delete context;
+ return nullptr;
+ }
+ COMRelease(signature);
+ COMRelease(error);
+ }
+
+ // create the pipeline state object
+ {
+ D3D12_INPUT_ELEMENT_DESC inputElementDescs[] =
+ {
+ { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
+ { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }
+ };
+
+ const bool wireFrame = false;
+
+ D3D12_RASTERIZER_DESC rasterDesc;
+ if (wireFrame)
+ {
+ rasterDesc.FillMode = D3D12_FILL_MODE_WIREFRAME;
+ rasterDesc.CullMode = D3D12_CULL_MODE_NONE;
+ }
+ else
+ {
+ rasterDesc.FillMode = D3D12_FILL_MODE_SOLID;
+ rasterDesc.CullMode = D3D12_CULL_MODE_BACK;
+ }
+ rasterDesc.FrontCounterClockwise = FALSE;
+ rasterDesc.DepthBias = D3D12_DEFAULT_DEPTH_BIAS;
+ rasterDesc.DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP;
+ rasterDesc.SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS;
+ rasterDesc.DepthClipEnable = TRUE;
+ rasterDesc.MultisampleEnable = FALSE;
+ rasterDesc.AntialiasedLineEnable = FALSE;
+ rasterDesc.ForcedSampleCount = 0;
+ rasterDesc.ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF;
+
+ D3D12_BLEND_DESC blendDesc;
+ blendDesc.AlphaToCoverageEnable = FALSE;
+ blendDesc.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)
+ blendDesc.RenderTarget[i] = defaultRenderTargetBlendDesc;
+ }
+
+ D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {};
+ psoDesc.InputLayout.NumElements = 2;
+ psoDesc.InputLayout.pInputElementDescs = inputElementDescs;
+ psoDesc.pRootSignature = context->m_rootSignature;
+ psoDesc.VS.pShaderBytecode = g_meshVS;
+ psoDesc.VS.BytecodeLength = sizeof(g_meshVS);
+ psoDesc.PS.pShaderBytecode = g_meshPS;
+ psoDesc.PS.BytecodeLength = sizeof(g_meshPS);
+ psoDesc.RasterizerState = rasterDesc;
+ psoDesc.BlendState = blendDesc;
+ psoDesc.DepthStencilState.DepthEnable = TRUE;
+ psoDesc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL;
+ psoDesc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL;
+ psoDesc.DepthStencilState.StencilEnable = FALSE;
+ psoDesc.SampleMask = UINT_MAX;
+ psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
+ psoDesc.NumRenderTargets = 1;
+ psoDesc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM;
+ psoDesc.DSVFormat = DXGI_FORMAT_D32_FLOAT;
+ psoDesc.SampleDesc.Count = 1;
+ HRESULT hr = S_OK;
+
+ if (hr = context->m_device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&context->m_pipelineStateLH)))
+ {
+ delete context;
+ return nullptr;
+ }
+
+ psoDesc.RasterizerState.FrontCounterClockwise = TRUE;
+
+ if (hr = context->m_device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&context->m_pipelineStateRH)))
+ {
+ delete context;
+ return nullptr;
+ }
+ }
+
+ // create constant heap
+ {
+ context->m_constantHeap = new MeshConstantHeap(context, 4096u);
+ }
+
+ return context;
+}
+
+void MeshContextUpdate(MeshContext* context, const MeshContextDesc* desc)
+{
+ context->m_device = desc->device;
+ context->m_commandList = desc->commandList;
+
+ context->m_constantHeap->reset();
+}
+
+void MeshContextRelease(MeshContext* context)
+{
+ if (context == nullptr) return;
+
+ delete context;
+}
+
+MeshIndexBuffer* MeshIndexBufferCreate(MeshContext* context, MeshUint* indices, MeshUint numIndices)
+{
+ MeshIndexBuffer* buffer = new MeshIndexBuffer;
+
+ buffer->m_numElements = numIndices;
+ // create an index buffer
+ {
+ HRESULT hr = S_OK;
+
+ UINT bufferSize = (UINT)(numIndices) * sizeof(UINT);
+
+ D3D12_HEAP_PROPERTIES heapProps = {};
+ heapProps.Type = D3D12_HEAP_TYPE_UPLOAD;
+ heapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
+ heapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
+ heapProps.CreationNodeMask = 0u;
+ heapProps.VisibleNodeMask = 0u;
+
+ D3D12_RESOURCE_DESC desc = {};
+ desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
+ desc.Alignment = 0u;
+ desc.Width = bufferSize;
+ desc.Height = 1u;
+ desc.DepthOrArraySize = 1u;
+ desc.MipLevels = 1;
+ desc.Format = DXGI_FORMAT_UNKNOWN;
+ desc.SampleDesc.Count = 1u;
+ desc.SampleDesc.Quality = 0u;
+ desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
+ desc.Flags = D3D12_RESOURCE_FLAG_NONE;
+
+ if (hr = context->m_device->CreateCommittedResource(&heapProps, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_GENERIC_READ,
+ nullptr, IID_PPV_ARGS(&buffer->m_upload)))
+ {
+ delete buffer;
+ return nullptr;
+ }
+
+ UINT8* pdata;
+ D3D12_RANGE readRange = {};
+ if (hr = buffer->m_upload->Map(0, &readRange, (void**)&pdata))
+ {
+ delete buffer;
+ return nullptr;
+ }
+ else
+ {
+ memcpy(pdata, indices, numIndices * sizeof(UINT));
+
+ buffer->m_upload->Unmap(0, nullptr);
+ }
+
+ // create a GPU memory buffer
+ heapProps.Type = D3D12_HEAP_TYPE_DEFAULT;
+ if (hr = context->m_device->CreateCommittedResource(&heapProps, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_COPY_DEST,
+ nullptr, IID_PPV_ARGS(&buffer->m_buffer)))
+ {
+ delete buffer;
+ return nullptr;
+ }
+
+ // copy from upload to new buffer
+ context->m_commandList->CopyBufferRegion(buffer->m_buffer, 0, buffer->m_upload, 0, bufferSize);
+
+ D3D12_RESOURCE_BARRIER barrier[1];
+ barrier[0].Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
+ barrier[0].Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
+ barrier[0].Transition.pResource = buffer->m_buffer;
+ barrier[0].Transition.Subresource = 0u;
+ barrier[0].Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST;
+ barrier[0].Transition.StateAfter = D3D12_RESOURCE_STATE_INDEX_BUFFER;
+ context->m_commandList->ResourceBarrier(1, barrier);
+
+ bufferSize = (UINT)(numIndices) * sizeof(UINT);
+ buffer->m_view.BufferLocation = buffer->m_buffer->GetGPUVirtualAddress();
+ buffer->m_view.SizeInBytes = bufferSize;
+ buffer->m_view.Format = DXGI_FORMAT_R32_UINT;
+ }
+
+ return buffer;
+}
+
+void MeshIndexBufferRelease(MeshIndexBuffer* buffer)
+{
+ if (buffer == nullptr) return;
+
+ delete buffer;
+}
+
+MeshVertexBuffer* MeshVertexBufferCreate(MeshContext* context, MeshVertex* vertices, MeshUint numVertices)
+{
+ MeshVertexBuffer* buffer = new MeshVertexBuffer;
+
+ buffer->m_numElements = numVertices;
+ // create a vertex buffer
+ {
+ HRESULT hr = S_OK;
+
+ UINT bufferSize = (UINT)(numVertices * sizeof(MeshVertex));
+
+ D3D12_HEAP_PROPERTIES heapProps = {};
+ heapProps.Type = D3D12_HEAP_TYPE_UPLOAD;
+ heapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
+ heapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
+ heapProps.CreationNodeMask = 0u;
+ heapProps.VisibleNodeMask = 0u;
+
+ D3D12_RESOURCE_DESC desc = {};
+ desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
+ desc.Alignment = 0u;
+ desc.Width = bufferSize;
+ desc.Height = 1u;
+ desc.DepthOrArraySize = 1u;
+ desc.MipLevels = 1;
+ desc.Format = DXGI_FORMAT_UNKNOWN;
+ desc.SampleDesc.Count = 1u;
+ desc.SampleDesc.Quality = 0u;
+ desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
+ desc.Flags = D3D12_RESOURCE_FLAG_NONE;
+
+ if (hr = context->m_device->CreateCommittedResource(&heapProps, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_GENERIC_READ,
+ nullptr, IID_PPV_ARGS(&buffer->m_upload)))
+ {
+ delete buffer;
+ return nullptr;
+ }
+
+ UINT8* pdata;
+ D3D12_RANGE readRange = {};
+ if (hr = buffer->m_upload->Map(0, &readRange, (void**)&pdata))
+ {
+ delete buffer;
+ return nullptr;
+ }
+ else
+ {
+ memcpy(pdata, vertices, numVertices * sizeof(MeshVertex));
+
+ buffer->m_upload->Unmap(0, nullptr);
+ }
+
+ // create a GPU memory buffer
+ heapProps.Type = D3D12_HEAP_TYPE_DEFAULT;
+ if (hr = context->m_device->CreateCommittedResource(&heapProps, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_COPY_DEST,
+ nullptr, IID_PPV_ARGS(&buffer->m_buffer)))
+ {
+ delete buffer;
+ return nullptr;
+ }
+
+ // copy from upload to new buffer
+ context->m_commandList->CopyBufferRegion(buffer->m_buffer, 0, buffer->m_upload, 0, bufferSize);
+
+ D3D12_RESOURCE_BARRIER barrier[1];
+ barrier[0].Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
+ barrier[0].Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
+ barrier[0].Transition.pResource = buffer->m_buffer;
+ barrier[0].Transition.Subresource = 0u;
+ barrier[0].Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST;
+ barrier[0].Transition.StateAfter = D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER;
+ context->m_commandList->ResourceBarrier(1, barrier);
+
+ bufferSize = (UINT)(numVertices * sizeof(MeshVertex));
+ buffer->m_view.BufferLocation = buffer->m_buffer->GetGPUVirtualAddress();
+ buffer->m_view.StrideInBytes = 6 * sizeof(float);
+ buffer->m_view.SizeInBytes = bufferSize;
+ }
+
+ return buffer;
+}
+
+void MeshVertexBufferRelease(MeshVertexBuffer* buffer)
+{
+ if (buffer == nullptr) return;
+
+ delete buffer;
+}
+
+void MeshContextDraw(MeshContext* context, const MeshContextDrawParams* params)
+{
+ using namespace DirectX;
+
+ XMMATRIX matrix = XMMatrixTranspose(XMMatrixMultiply(XMMatrixMultiply(
+ params->params->model,
+ params->params->view),
+ params->params->projection
+ ));
+
+ UINT8* constantBufferData = context->m_constantHeap->allocate(256);
+
+ if (constantBufferData == nullptr)
+ {
+ return;
+ }
+
+ XMStoreFloat4x4((XMFLOAT4X4*)(constantBufferData), matrix);
+
+ ID3D12GraphicsCommandList* commandList = context->m_commandList;
+
+ commandList->SetGraphicsRootSignature(context->m_rootSignature);
+
+ float depthSign = DirectX::XMVectorGetW(params->params->projection.r[2]);
+ if (depthSign < 0.f)
+ {
+ commandList->SetPipelineState(context->m_pipelineStateRH);
+ }
+ else
+ {
+ commandList->SetPipelineState(context->m_pipelineStateLH);
+ }
+
+ D3D12_GPU_VIRTUAL_ADDRESS cbvHandle = context->m_constantHeap->getVirtualAddress(constantBufferData);
+ commandList->SetGraphicsRootConstantBufferView(0, cbvHandle);
+
+ commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
+ commandList->IASetVertexBuffers(0, 1, &params->vertexBuffer->m_view);
+ commandList->IASetIndexBuffer(&params->indexBuffer->m_view);
+
+ commandList->DrawIndexedInstanced((UINT)params->indexBuffer->m_numElements, 1, 0, 0, 0);
+} \ No newline at end of file
diff --git a/demo/DemoAppD3D12/meshD3D12.h b/demo/DemoAppD3D12/meshD3D12.h
new file mode 100644
index 0000000..4bd0fab
--- /dev/null
+++ b/demo/DemoAppD3D12/meshD3D12.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved.
+ *
+ * NVIDIA CORPORATION and its licensors retain all intellectual property
+ * and proprietary rights in and to this software, related documentation
+ * and any modifications thereto. Any use, reproduction, disclosure or
+ * distribution of this software and related documentation without an express
+ * license agreement from NVIDIA CORPORATION is strictly prohibited.
+ */
+
+#pragma once
+
+#include "../DemoApp/mesh.h"
+
+struct MeshContextDesc
+{
+ ID3D12Device* device;
+ ID3D12GraphicsCommandList* commandList;
+}; \ No newline at end of file
diff --git a/demo/DemoAppD3D12/meshInteropD3D12.cpp b/demo/DemoAppD3D12/meshInteropD3D12.cpp
new file mode 100644
index 0000000..19c034d
--- /dev/null
+++ b/demo/DemoAppD3D12/meshInteropD3D12.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved.
+ *
+ * NVIDIA CORPORATION and its licensors retain all intellectual property
+ * and proprietary rights in and to this software, related documentation
+ * and any modifications thereto. Any use, reproduction, disclosure or
+ * distribution of this software and related documentation without an express
+ * license agreement from NVIDIA CORPORATION is strictly prohibited.
+ */
+
+//direct3d headers
+#include <d3d12.h>
+
+// include the Direct3D Library file
+#pragma comment (lib, "d3d12.lib")
+
+#include "../DemoApp/meshInterop.h"
+
+#include "appD3D12Ctx.h"
+#include "meshD3D12.h"
+
+MeshContext* MeshInteropContextCreate(AppGraphCtx* appctx)
+{
+ MeshContextDesc desc = {};
+ desc.device = appctx->m_device;
+ desc.commandList = appctx->m_commandList;
+
+ return MeshContextCreate(&desc);
+}
+
+void MeshInteropContextUpdate(MeshContext* context, AppGraphCtx* appctx)
+{
+ MeshContextDesc desc = {};
+ desc.device = appctx->m_device;
+ desc.commandList = appctx->m_commandList;
+
+ return MeshContextUpdate(context, &desc);
+} \ No newline at end of file
diff --git a/demo/DemoAppD3D12/meshPS.hlsl.h b/demo/DemoAppD3D12/meshPS.hlsl.h
new file mode 100644
index 0000000..fcef532
--- /dev/null
+++ b/demo/DemoAppD3D12/meshPS.hlsl.h
@@ -0,0 +1,205 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// NORMAL 0 xyz 1 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_5_0
+dcl_globalFlags refactoringAllowed
+dcl_input_ps linear v1.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+dp3 r0.x, v1.xyzx, l(0.570000, 0.570000, 0.570000, 0.000000)
+max r0.x, r0.x, l(0.000000)
+mad r0.x, r0.x, l(0.400000), l(0.100000)
+dp3 r0.y, v1.xyzx, l(-0.570000, 0.570000, 0.570000, 0.000000)
+max r0.y, r0.y, l(0.000000)
+mad r0.x, r0.y, l(0.400000), r0.x
+dp3 r0.y, v1.xyzx, l(0.570000, 0.570000, -0.570000, 0.000000)
+max r0.y, r0.y, l(0.000000)
+mad r0.x, r0.y, l(0.400000), r0.x
+dp3 r0.y, v1.xzyx, l(-0.570000, -0.570000, 0.570000, 0.000000)
+max r0.y, r0.y, l(0.000000)
+mad o0.xyz, r0.yyyy, l(0.400000, 0.400000, 0.400000, 0.000000), r0.xxxx
+mov o0.w, l(1.000000)
+ret
+// Approximately 14 instruction slots used
+#endif
+
+const BYTE g_meshPS[] =
+{
+ 68, 88, 66, 67, 253, 169,
+ 122, 175, 25, 228, 25, 139,
+ 94, 18, 195, 68, 91, 159,
+ 92, 156, 1, 0, 0, 0,
+ 188, 3, 0, 0, 5, 0,
+ 0, 0, 52, 0, 0, 0,
+ 160, 0, 0, 0, 244, 0,
+ 0, 0, 40, 1, 0, 0,
+ 32, 3, 0, 0, 82, 68,
+ 69, 70, 100, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 60, 0, 0, 0, 0, 5,
+ 255, 255, 0, 1, 0, 0,
+ 60, 0, 0, 0, 82, 68,
+ 49, 49, 60, 0, 0, 0,
+ 24, 0, 0, 0, 32, 0,
+ 0, 0, 40, 0, 0, 0,
+ 36, 0, 0, 0, 12, 0,
+ 0, 0, 0, 0, 0, 0,
+ 77, 105, 99, 114, 111, 115,
+ 111, 102, 116, 32, 40, 82,
+ 41, 32, 72, 76, 83, 76,
+ 32, 83, 104, 97, 100, 101,
+ 114, 32, 67, 111, 109, 112,
+ 105, 108, 101, 114, 32, 49,
+ 48, 46, 49, 0, 73, 83,
+ 71, 78, 76, 0, 0, 0,
+ 2, 0, 0, 0, 8, 0,
+ 0, 0, 56, 0, 0, 0,
+ 0, 0, 0, 0, 1, 0,
+ 0, 0, 3, 0, 0, 0,
+ 0, 0, 0, 0, 15, 0,
+ 0, 0, 68, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 3, 0, 0, 0,
+ 1, 0, 0, 0, 7, 7,
+ 0, 0, 83, 86, 95, 80,
+ 79, 83, 73, 84, 73, 79,
+ 78, 0, 78, 79, 82, 77,
+ 65, 76, 0, 171, 79, 83,
+ 71, 78, 44, 0, 0, 0,
+ 1, 0, 0, 0, 8, 0,
+ 0, 0, 32, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 3, 0, 0, 0,
+ 0, 0, 0, 0, 15, 0,
+ 0, 0, 83, 86, 95, 84,
+ 65, 82, 71, 69, 84, 0,
+ 171, 171, 83, 72, 69, 88,
+ 240, 1, 0, 0, 80, 0,
+ 0, 0, 124, 0, 0, 0,
+ 106, 8, 0, 1, 98, 16,
+ 0, 3, 114, 16, 16, 0,
+ 1, 0, 0, 0, 101, 0,
+ 0, 3, 242, 32, 16, 0,
+ 0, 0, 0, 0, 104, 0,
+ 0, 2, 1, 0, 0, 0,
+ 16, 0, 0, 10, 18, 0,
+ 16, 0, 0, 0, 0, 0,
+ 70, 18, 16, 0, 1, 0,
+ 0, 0, 2, 64, 0, 0,
+ 133, 235, 17, 63, 133, 235,
+ 17, 63, 133, 235, 17, 63,
+ 0, 0, 0, 0, 52, 0,
+ 0, 7, 18, 0, 16, 0,
+ 0, 0, 0, 0, 10, 0,
+ 16, 0, 0, 0, 0, 0,
+ 1, 64, 0, 0, 0, 0,
+ 0, 0, 50, 0, 0, 9,
+ 18, 0, 16, 0, 0, 0,
+ 0, 0, 10, 0, 16, 0,
+ 0, 0, 0, 0, 1, 64,
+ 0, 0, 205, 204, 204, 62,
+ 1, 64, 0, 0, 205, 204,
+ 204, 61, 16, 0, 0, 10,
+ 34, 0, 16, 0, 0, 0,
+ 0, 0, 70, 18, 16, 0,
+ 1, 0, 0, 0, 2, 64,
+ 0, 0, 133, 235, 17, 191,
+ 133, 235, 17, 63, 133, 235,
+ 17, 63, 0, 0, 0, 0,
+ 52, 0, 0, 7, 34, 0,
+ 16, 0, 0, 0, 0, 0,
+ 26, 0, 16, 0, 0, 0,
+ 0, 0, 1, 64, 0, 0,
+ 0, 0, 0, 0, 50, 0,
+ 0, 9, 18, 0, 16, 0,
+ 0, 0, 0, 0, 26, 0,
+ 16, 0, 0, 0, 0, 0,
+ 1, 64, 0, 0, 205, 204,
+ 204, 62, 10, 0, 16, 0,
+ 0, 0, 0, 0, 16, 0,
+ 0, 10, 34, 0, 16, 0,
+ 0, 0, 0, 0, 70, 18,
+ 16, 0, 1, 0, 0, 0,
+ 2, 64, 0, 0, 133, 235,
+ 17, 63, 133, 235, 17, 63,
+ 133, 235, 17, 191, 0, 0,
+ 0, 0, 52, 0, 0, 7,
+ 34, 0, 16, 0, 0, 0,
+ 0, 0, 26, 0, 16, 0,
+ 0, 0, 0, 0, 1, 64,
+ 0, 0, 0, 0, 0, 0,
+ 50, 0, 0, 9, 18, 0,
+ 16, 0, 0, 0, 0, 0,
+ 26, 0, 16, 0, 0, 0,
+ 0, 0, 1, 64, 0, 0,
+ 205, 204, 204, 62, 10, 0,
+ 16, 0, 0, 0, 0, 0,
+ 16, 0, 0, 10, 34, 0,
+ 16, 0, 0, 0, 0, 0,
+ 134, 17, 16, 0, 1, 0,
+ 0, 0, 2, 64, 0, 0,
+ 133, 235, 17, 191, 133, 235,
+ 17, 191, 133, 235, 17, 63,
+ 0, 0, 0, 0, 52, 0,
+ 0, 7, 34, 0, 16, 0,
+ 0, 0, 0, 0, 26, 0,
+ 16, 0, 0, 0, 0, 0,
+ 1, 64, 0, 0, 0, 0,
+ 0, 0, 50, 0, 0, 12,
+ 114, 32, 16, 0, 0, 0,
+ 0, 0, 86, 5, 16, 0,
+ 0, 0, 0, 0, 2, 64,
+ 0, 0, 205, 204, 204, 62,
+ 205, 204, 204, 62, 205, 204,
+ 204, 62, 0, 0, 0, 0,
+ 6, 0, 16, 0, 0, 0,
+ 0, 0, 54, 0, 0, 5,
+ 130, 32, 16, 0, 0, 0,
+ 0, 0, 1, 64, 0, 0,
+ 0, 0, 128, 63, 62, 0,
+ 0, 1, 83, 84, 65, 84,
+ 148, 0, 0, 0, 14, 0,
+ 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 0, 2, 0,
+ 0, 0, 12, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0
+};
diff --git a/demo/DemoAppD3D12/meshVS.hlsl.h b/demo/DemoAppD3D12/meshVS.hlsl.h
new file mode 100644
index 0000000..e2c1466
--- /dev/null
+++ b/demo/DemoAppD3D12/meshVS.hlsl.h
@@ -0,0 +1,223 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Buffer Definitions:
+//
+// cbuffer params
+// {
+//
+// float4x4 projection; // Offset: 0 Size: 64
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// params cbuffer NA NA cb0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// POSITION 0 xyz 0 NONE float xyz
+// NORMAL 0 xyz 1 NONE float xyz
+// SV_InstanceID 0 x 2 INSTID uint
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float xyzw
+// NORMAL 0 xyz 1 NONE float xyz
+//
+vs_5_0
+dcl_globalFlags refactoringAllowed
+dcl_constantbuffer CB0[4], immediateIndexed
+dcl_input v0.xyz
+dcl_input v1.xyz
+dcl_output_siv o0.xyzw, position
+dcl_output o1.xyz
+dcl_temps 1
+mov r0.xyz, v0.xyzx
+mov r0.w, l(1.000000)
+dp4 o0.x, r0.xyzw, cb0[0].xyzw
+dp4 o0.y, r0.xyzw, cb0[1].xyzw
+dp4 o0.z, r0.xyzw, cb0[2].xyzw
+dp4 o0.w, r0.xyzw, cb0[3].xyzw
+mov o1.xyz, v1.xyzx
+ret
+// Approximately 8 instruction slots used
+#endif
+
+const BYTE g_meshVS[] =
+{
+ 68, 88, 66, 67, 146, 57,
+ 84, 204, 22, 172, 14, 230,
+ 119, 17, 66, 227, 109, 150,
+ 21, 41, 1, 0, 0, 0,
+ 200, 3, 0, 0, 5, 0,
+ 0, 0, 52, 0, 0, 0,
+ 64, 1, 0, 0, 184, 1,
+ 0, 0, 12, 2, 0, 0,
+ 44, 3, 0, 0, 82, 68,
+ 69, 70, 4, 1, 0, 0,
+ 1, 0, 0, 0, 100, 0,
+ 0, 0, 1, 0, 0, 0,
+ 60, 0, 0, 0, 0, 5,
+ 254, 255, 0, 1, 0, 0,
+ 220, 0, 0, 0, 82, 68,
+ 49, 49, 60, 0, 0, 0,
+ 24, 0, 0, 0, 32, 0,
+ 0, 0, 40, 0, 0, 0,
+ 36, 0, 0, 0, 12, 0,
+ 0, 0, 0, 0, 0, 0,
+ 92, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 1, 0,
+ 0, 0, 112, 97, 114, 97,
+ 109, 115, 0, 171, 92, 0,
+ 0, 0, 1, 0, 0, 0,
+ 124, 0, 0, 0, 64, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 164, 0,
+ 0, 0, 0, 0, 0, 0,
+ 64, 0, 0, 0, 2, 0,
+ 0, 0, 184, 0, 0, 0,
+ 0, 0, 0, 0, 255, 255,
+ 255, 255, 0, 0, 0, 0,
+ 255, 255, 255, 255, 0, 0,
+ 0, 0, 112, 114, 111, 106,
+ 101, 99, 116, 105, 111, 110,
+ 0, 102, 108, 111, 97, 116,
+ 52, 120, 52, 0, 3, 0,
+ 3, 0, 4, 0, 4, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 175, 0, 0, 0, 77, 105,
+ 99, 114, 111, 115, 111, 102,
+ 116, 32, 40, 82, 41, 32,
+ 72, 76, 83, 76, 32, 83,
+ 104, 97, 100, 101, 114, 32,
+ 67, 111, 109, 112, 105, 108,
+ 101, 114, 32, 49, 48, 46,
+ 49, 0, 73, 83, 71, 78,
+ 112, 0, 0, 0, 3, 0,
+ 0, 0, 8, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 3, 0, 0, 0, 0, 0,
+ 0, 0, 7, 7, 0, 0,
+ 89, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 3, 0, 0, 0, 1, 0,
+ 0, 0, 7, 7, 0, 0,
+ 96, 0, 0, 0, 0, 0,
+ 0, 0, 8, 0, 0, 0,
+ 1, 0, 0, 0, 2, 0,
+ 0, 0, 1, 0, 0, 0,
+ 80, 79, 83, 73, 84, 73,
+ 79, 78, 0, 78, 79, 82,
+ 77, 65, 76, 0, 83, 86,
+ 95, 73, 110, 115, 116, 97,
+ 110, 99, 101, 73, 68, 0,
+ 171, 171, 79, 83, 71, 78,
+ 76, 0, 0, 0, 2, 0,
+ 0, 0, 8, 0, 0, 0,
+ 56, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0,
+ 3, 0, 0, 0, 0, 0,
+ 0, 0, 15, 0, 0, 0,
+ 68, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 3, 0, 0, 0, 1, 0,
+ 0, 0, 7, 8, 0, 0,
+ 83, 86, 95, 80, 79, 83,
+ 73, 84, 73, 79, 78, 0,
+ 78, 79, 82, 77, 65, 76,
+ 0, 171, 83, 72, 69, 88,
+ 24, 1, 0, 0, 80, 0,
+ 1, 0, 70, 0, 0, 0,
+ 106, 8, 0, 1, 89, 0,
+ 0, 4, 70, 142, 32, 0,
+ 0, 0, 0, 0, 4, 0,
+ 0, 0, 95, 0, 0, 3,
+ 114, 16, 16, 0, 0, 0,
+ 0, 0, 95, 0, 0, 3,
+ 114, 16, 16, 0, 1, 0,
+ 0, 0, 103, 0, 0, 4,
+ 242, 32, 16, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0,
+ 101, 0, 0, 3, 114, 32,
+ 16, 0, 1, 0, 0, 0,
+ 104, 0, 0, 2, 1, 0,
+ 0, 0, 54, 0, 0, 5,
+ 114, 0, 16, 0, 0, 0,
+ 0, 0, 70, 18, 16, 0,
+ 0, 0, 0, 0, 54, 0,
+ 0, 5, 130, 0, 16, 0,
+ 0, 0, 0, 0, 1, 64,
+ 0, 0, 0, 0, 128, 63,
+ 17, 0, 0, 8, 18, 32,
+ 16, 0, 0, 0, 0, 0,
+ 70, 14, 16, 0, 0, 0,
+ 0, 0, 70, 142, 32, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 17, 0, 0, 8,
+ 34, 32, 16, 0, 0, 0,
+ 0, 0, 70, 14, 16, 0,
+ 0, 0, 0, 0, 70, 142,
+ 32, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 17, 0,
+ 0, 8, 66, 32, 16, 0,
+ 0, 0, 0, 0, 70, 14,
+ 16, 0, 0, 0, 0, 0,
+ 70, 142, 32, 0, 0, 0,
+ 0, 0, 2, 0, 0, 0,
+ 17, 0, 0, 8, 130, 32,
+ 16, 0, 0, 0, 0, 0,
+ 70, 14, 16, 0, 0, 0,
+ 0, 0, 70, 142, 32, 0,
+ 0, 0, 0, 0, 3, 0,
+ 0, 0, 54, 0, 0, 5,
+ 114, 32, 16, 0, 1, 0,
+ 0, 0, 70, 18, 16, 0,
+ 1, 0, 0, 0, 62, 0,
+ 0, 1, 83, 84, 65, 84,
+ 148, 0, 0, 0, 8, 0,
+ 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 0, 4, 0,
+ 0, 0, 4, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 3, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0
+};