diff options
Diffstat (limited to 'demo/DemoAppD3D12')
| -rw-r--r-- | demo/DemoAppD3D12/DemoAppD3D12.vcxproj | 269 | ||||
| -rw-r--r-- | demo/DemoAppD3D12/DemoAppD3D12.vcxproj.filters | 71 | ||||
| -rw-r--r-- | demo/DemoAppD3D12/NvFlowInteropD3D12.cpp | 105 | ||||
| -rw-r--r-- | demo/DemoAppD3D12/appD3D12Ctx.cpp | 1097 | ||||
| -rw-r--r-- | demo/DemoAppD3D12/appD3D12Ctx.h | 113 | ||||
| -rw-r--r-- | demo/DemoAppD3D12/computeContextD3D12.cpp | 759 | ||||
| -rw-r--r-- | demo/DemoAppD3D12/computeContextD3D12.h | 52 | ||||
| -rw-r--r-- | demo/DemoAppD3D12/imguiGraphD3D12.cpp | 662 | ||||
| -rw-r--r-- | demo/DemoAppD3D12/imguiGraphD3D12.h | 48 | ||||
| -rw-r--r-- | demo/DemoAppD3D12/imguiInteropD3D12.cpp | 60 | ||||
| -rw-r--r-- | demo/DemoAppD3D12/imguiPS.hlsl.h | 195 | ||||
| -rw-r--r-- | demo/DemoAppD3D12/imguiVS.hlsl.h | 246 | ||||
| -rw-r--r-- | demo/DemoAppD3D12/meshD3D12.cpp | 576 | ||||
| -rw-r--r-- | demo/DemoAppD3D12/meshD3D12.h | 19 | ||||
| -rw-r--r-- | demo/DemoAppD3D12/meshInteropD3D12.cpp | 38 | ||||
| -rw-r--r-- | demo/DemoAppD3D12/meshPS.hlsl.h | 205 | ||||
| -rw-r--r-- | demo/DemoAppD3D12/meshVS.hlsl.h | 223 |
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, ¶ms, 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), ¶ms, 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, ¶ms->vertexBuffer->m_view); + commandList->IASetIndexBuffer(¶ms->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 +}; |