BlueBear

D3D.cpp

Oct 25th, 2018
146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #pragma once
  2.  
  3. #ifndef WIN32_LEAN_AND_MEAN
  4. #define WIN32_LEAN_AND_MEAN    // Exclude rarely-used stuff from Windows headers.
  5. #endif
  6.  
  7. #pragma comment(lib, "d3d12.lib")
  8. #pragma comment(lib, "dxgi.lib")
  9. #pragma comment(lib, "d3dcompiler.lib")
  10.  
  11. #include <Vector.hpp>
  12. #include "Types.hpp"
  13.  
  14. #include "Allocator.hpp"
  15. #include "Memory.hpp"
  16. #include "Thread.hpp"
  17.  
  18. #include <d3d12.h>
  19. #include <dxgi1_4.h>
  20. #include <D3Dcompiler.h>
  21. #include <DirectXMath.h>
  22. #include "d3dx12.h"
  23. #include <string>
  24. #include <wrl.h>
  25.  
  26. #include <windows.h>
  27.  
  28. using namespace DirectX;
  29. using namespace Microsoft::WRL;
  30.  
  31. #define SAFE_RELEASE(p) { if ( (p) ) { (p)->Release(); (p) = 0; } }
  32.  
  33. struct ConstantBufferPerObject
  34. {
  35.     XMFLOAT4X4 wvpMat;
  36. };
  37.  
  38. struct Vertex
  39. {
  40.     Vertex(float x, float y, float z, float r, float g, float b, float a) : pos(x, y, z), color(r, g, b, a) {}
  41.     XMFLOAT3 pos;
  42.     XMFLOAT4 color;
  43. };
  44.  
  45. HWND hwnd = NULL;
  46. int32 Width = 800;
  47. int32 Height = 600;
  48. bool FullScreen = false;
  49. bool Running = true;
  50. bool InitializeWindow(HINSTANCE hInstance, int32 ShowWnd, bool fullscreen);
  51. bool InitD3D();
  52. void Update();
  53. void UpdatePipeline();
  54. void Render();
  55. void Cleanup();
  56. void WaitForPreviousFrame();
  57. LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
  58.  
  59. const int32 frameBufferCount = 3;
  60. ComPtr<ID3D12Device> device;
  61. IDXGISwapChain3* swapChain;
  62. ID3D12CommandQueue* commandQueue;
  63. ID3D12DescriptorHeap* rtvDescriptorHeap;
  64. ID3D12Resource* renderTargets[frameBufferCount];
  65. ID3D12CommandAllocator* commandAllocator[frameBufferCount];
  66. ID3D12GraphicsCommandList* commandList;
  67. ID3D12Fence* fence[frameBufferCount];
  68. HANDLE fenceEvent;
  69. uint64 fenceValue[frameBufferCount];
  70. SIZE_T frameIndex;
  71. int32 rtvDescriptorSize;
  72. ID3D12PipelineState* pipelineStateObject;
  73. ID3D12RootSignature* rootSignature;
  74. D3D12_VIEWPORT viewport;
  75. D3D12_RECT scissorRect;
  76. ID3D12Resource* vertexBuffer;
  77. ID3D12Resource* indexBuffer;
  78. D3D12_VERTEX_BUFFER_VIEW vertexBufferView;
  79. D3D12_INDEX_BUFFER_VIEW indexBufferView;
  80. ID3D12Resource* depthStencilBuffer;
  81. ID3D12DescriptorHeap* dsDescriptorHeap;
  82. int32 ConstantBufferPerObjectAlignedSize = (sizeof(ConstantBufferPerObject) + 255) & ~255;
  83. ConstantBufferPerObject cbPerObject;
  84. ID3D12Resource* constantBufferUploadHeaps[frameBufferCount];
  85. uint8* cbvGPUAddress[frameBufferCount];
  86.  
  87. XMFLOAT4X4 cameraProjMat;
  88. XMFLOAT4X4 cameraViewMat;
  89. XMFLOAT4 cameraPosition;
  90. XMFLOAT4 cameraTarget;
  91. XMFLOAT4 cameraUp;
  92. XMFLOAT4X4 cube1WorldMat;
  93. XMFLOAT4X4 cube1RotMat;
  94. XMFLOAT4 cube1Position;
  95. XMFLOAT4X4 cube2WorldMat;
  96. XMFLOAT4X4 cube2RotMat;
  97. XMFLOAT4 cube2PositionOffset;
  98. int32 numCubeIndices;
  99.  
  100. struct SThreadTest
  101. {
  102.     uint8 DoWork()
  103.     {
  104.         for (SIZE_T i = 0; i < 100; ++i)
  105.         {
  106.             OutputDebugStringA("thread stuff\n");
  107.         }
  108.         return 0;
  109.     }
  110. };
  111.  
  112. struct SThreadTest2
  113. {
  114.     uint8 DoWork()
  115.     {
  116.         for (SIZE_T i = 0; i < 100; ++i)
  117.         {
  118.             OutputDebugStringA("thread stuff2\n");
  119.         }
  120.         return 0;
  121.     }
  122. };
  123.  
  124. int32 WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int32 nShowCmd)
  125. {
  126.     using namespace Aberration::Memory;
  127.     using namespace Aberration::OS;
  128.     //default memory allocator, basically aligned malloc and aligned free
  129.     IAllocator* allocator = GlobalAllocator;
  130.  
  131.     //allocate single int
  132.     auto mem = TMemory<int>::Allocate(allocator);
  133.     //do something with memory mem
  134.     //free single int
  135.     TMemory<int>::Free(allocator, mem);
  136.  
  137.     //allocate an array of 10 ints, non initialized
  138.     auto array = TMemory<int[]>::Allocate(allocator, 10);
  139.     //do something with memory array
  140.     //free array of ints
  141.     TMemory<int[]>::Free(allocator, array, 10);
  142.  
  143.     //allocate an array of 10 ints, initialized
  144.     auto defaultinitedarray = TMemory<int[]>::Allocate(allocator, 10, 7);
  145.     //do something with memory defaultinitedarray
  146.     //free array of ints
  147.     TMemory<int[]>::Free(allocator, defaultinitedarray, 10);
  148.  
  149.  
  150.     Aberration::OS::FThread::FMainFunctionType ThreadMain;
  151.  
  152.     SThreadTest ThreadTest;
  153.     ThreadMain.Bind<SThreadTest, &SThreadTest::DoWork>(&ThreadTest);
  154.  
  155.     Aberration::OS::FThread::FMainFunctionType ThreadMain2;
  156.     SThreadTest2 ThreadTest2;
  157.     ThreadMain2.Bind<SThreadTest2, &SThreadTest2::DoWork>(&ThreadTest2);
  158.  
  159.     //FThread TestThread;
  160.     //auto err = TestThread.Create(ThreadMain, "test", 0);
  161.     //FThread TestThread2;
  162.     //err = TestThread2.Create(ThreadMain2, "test2", 0);
  163.  
  164.     /*for (SIZE_T i = 0; i < 100; ++i)
  165.     {
  166.         OutputDebugStringA("main thread\n");
  167.     }
  168.     */
  169.     if (!InitializeWindow(hInstance, nShowCmd, FullScreen))
  170.     {
  171.         MessageBox(0, L"Window Initialization - Failed", L"Error", MB_OK);
  172.         return 1;
  173.     }
  174.  
  175.     if (!InitD3D())
  176.     {
  177.         MessageBox(0, L"Failed to initialize direct3d 12", L"Error", MB_OK);
  178.         Cleanup();
  179.         return 1;
  180.     }
  181.  
  182.     MSG msg = MSG();
  183.     while (Running)
  184.     {
  185.         if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  186.         {
  187.             if (msg.message == WM_QUIT)
  188.                 break;
  189.  
  190.             TranslateMessage(&msg);
  191.             DispatchMessage(&msg);
  192.         }
  193.         else
  194.         {
  195.             Update();
  196.             Render();
  197.         }
  198.     }
  199.  
  200.     WaitForPreviousFrame();
  201.     CloseHandle(fenceEvent);
  202.     Cleanup();
  203.     return 0;
  204. }
  205.  
  206. bool InitializeWindow(HINSTANCE hInstance, int32 ShowWnd, bool fullscreen)
  207. {
  208.     if (fullscreen)
  209.     {
  210.         HMONITOR hmon = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
  211.         MONITORINFO mi = { sizeof(mi) };
  212.         GetMonitorInfo(hmon, &mi);
  213.         Width = mi.rcMonitor.right - mi.rcMonitor.left;
  214.         Height = mi.rcMonitor.bottom - mi.rcMonitor.top;
  215.     }
  216.  
  217.     WNDCLASSEX wc;
  218.     wc.cbSize = sizeof(WNDCLASSEX);
  219.     wc.style = CS_HREDRAW | CS_VREDRAW;
  220.     wc.lpfnWndProc = WndProc;
  221.     wc.cbClsExtra = NULL;
  222.     wc.cbWndExtra = NULL;
  223.     wc.hInstance = hInstance;
  224.     wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  225.     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  226.     wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 2);
  227.     wc.lpszMenuName = NULL;
  228.     wc.lpszClassName = L"AberrationEngineWindowName";
  229.     wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
  230.     if (!RegisterClassEx(&wc))
  231.     {
  232.         MessageBox(NULL, L"Error registering class", L"Error", MB_OK | MB_ICONERROR);
  233.         return false;
  234.     }
  235.     hwnd = CreateWindowEx(NULL, L"AberrationEngineWindowName", L"Aberration Engine", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, Width, Height, NULL, NULL, hInstance, NULL);
  236.     if (!hwnd)
  237.     {
  238.         MessageBox(NULL, L"Error creating window", L"Error", MB_OK | MB_ICONERROR);
  239.         return false;
  240.     }
  241.     if (fullscreen)
  242.     {
  243.         SetWindowLong(hwnd, GWL_STYLE, 0);
  244.     }
  245.     ShowWindow(hwnd, ShowWnd);
  246.     UpdateWindow(hwnd);
  247.     return true;
  248. }
  249.  
  250. LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  251. {
  252.     switch (msg)
  253.     {
  254.     case WM_KEYDOWN:
  255.         if (wParam == VK_ESCAPE)
  256.         {
  257.             if (MessageBox(0, L"Are you sure you want to exit?", L"Really?", MB_YESNO | MB_ICONQUESTION) == IDYES)
  258.             {
  259.                 Running = false;
  260.                 DestroyWindow(hwnd);
  261.             }
  262.         }
  263.         return 0;
  264.  
  265.     case WM_DESTROY:
  266.         Running = false;
  267.         PostQuitMessage(0);
  268.         return 0;
  269.     }
  270.     return DefWindowProc(hwnd, msg, wParam, lParam);
  271. }
  272.  
  273. bool InitD3D()
  274. {
  275.     IDXGIFactory4* dxgiFactory;
  276.     auto hr = CreateDXGIFactory1(IID_PPV_ARGS(&dxgiFactory));
  277.     if (FAILED(hr))
  278.     {
  279.         return false;
  280.     }
  281.  
  282.     IDXGIAdapter1* adapter;
  283.     int32 adapterIndex = 0;
  284.     bool adapterFound = false;
  285.     while (dxgiFactory->EnumAdapters1(adapterIndex, &adapter) != DXGI_ERROR_NOT_FOUND)
  286.     {
  287.         DXGI_ADAPTER_DESC1 desc;
  288.         adapter->GetDesc1(&desc);
  289.  
  290.         if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE)
  291.         {
  292.             adapterIndex++;
  293.             continue;
  294.         }
  295.         auto hresult = D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr);
  296.         if (SUCCEEDED(hresult))
  297.         {
  298.             adapterFound = true;
  299.             break;
  300.         }
  301.         adapterIndex++;
  302.     }
  303.  
  304.  
  305.     if (!adapterFound)
  306.     {
  307.         return false;
  308.     }
  309.     {
  310.         // Create the device
  311.         auto res = D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&device));
  312.         if (FAILED(res))
  313.         {
  314.             return false;
  315.         }
  316.     }
  317.  
  318.     D3D12_COMMAND_QUEUE_DESC cqDesc = {};
  319.     cqDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
  320.     cqDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
  321.     if (FAILED(device->CreateCommandQueue(&cqDesc, IID_PPV_ARGS(&commandQueue))))
  322.     {
  323.         return false;
  324.     }
  325.  
  326.     DXGI_MODE_DESC backBufferDesc = {};
  327.     backBufferDesc.Width = Width;
  328.     backBufferDesc.Height = Height;
  329.     backBufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
  330.    
  331.     DXGI_SWAP_CHAIN_DESC swapChainDesc = {};
  332.     swapChainDesc.BufferCount = frameBufferCount;
  333.     swapChainDesc.BufferDesc = backBufferDesc;
  334.     swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
  335.     swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
  336.     swapChainDesc.OutputWindow = hwnd;
  337.     swapChainDesc.SampleDesc.Count = 1;
  338.     swapChainDesc.Windowed = !FullScreen;
  339.  
  340.     IDXGISwapChain* tempSwapChain;
  341.     dxgiFactory->CreateSwapChain(commandQueue, &swapChainDesc, &tempSwapChain);
  342.     swapChain = static_cast<IDXGISwapChain3*>(tempSwapChain);
  343.     frameIndex = swapChain->GetCurrentBackBufferIndex();
  344.  
  345.     D3D12_DESCRIPTOR_HEAP_DESC rtvHeapDesc = D3D12_DESCRIPTOR_HEAP_DESC();
  346.     rtvHeapDesc.NumDescriptors = frameBufferCount;
  347.     rtvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
  348.     rtvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
  349.     hr = device->CreateDescriptorHeap(&rtvHeapDesc, IID_PPV_ARGS(&rtvDescriptorHeap));
  350.     if (FAILED(hr))
  351.     {
  352.         return false;
  353.     }
  354.  
  355.     rtvDescriptorSize = device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
  356.     D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle(rtvDescriptorHeap->GetCPUDescriptorHandleForHeapStart());
  357.  
  358.     for (SIZE_T i = 0; i < frameBufferCount; i++)
  359.     {
  360.         hr = swapChain->GetBuffer((UINT)i, IID_PPV_ARGS(&renderTargets[i]));
  361.         if (FAILED(hr))
  362.         {
  363.             return false;
  364.         }
  365.         device->CreateRenderTargetView(renderTargets[i], nullptr, rtvHandle);
  366.         rtvHandle.ptr += 1 * rtvDescriptorSize;
  367.     }
  368.  
  369.     for (SIZE_T i = 0; i < frameBufferCount; i++)
  370.     {
  371.         if (FAILED(device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&commandAllocator[i]))))
  372.         {
  373.             return false;
  374.         }
  375.     }
  376.  
  377.     if (FAILED(device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, commandAllocator[frameIndex], NULL, IID_PPV_ARGS(&commandList))))
  378.     {
  379.         return false;
  380.     }
  381.  
  382.     for (SIZE_T i = 0; i < frameBufferCount; i++)
  383.     {
  384.         hr = device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fence[i]));
  385.         if (FAILED(hr))
  386.         {
  387.             return false;
  388.         }
  389.         fenceValue[i] = 0;
  390.     }
  391.  
  392.     fenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
  393.     if (fenceEvent == nullptr)
  394.     {
  395.         return false;
  396.     }
  397.  
  398.     D3D12_ROOT_DESCRIPTOR rootCBVDescriptor;
  399.     rootCBVDescriptor.RegisterSpace = 0;
  400.     rootCBVDescriptor.ShaderRegister = 0;
  401.  
  402.     D3D12_ROOT_PARAMETER rootParameters[1];
  403.     rootParameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
  404.     rootParameters[0].Descriptor = rootCBVDescriptor;
  405.     rootParameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
  406.  
  407.     D3D12_ROOT_SIGNATURE_DESC rootSignatureDesc = D3D12_ROOT_SIGNATURE_DESC();
  408.     rootSignatureDesc.NumParameters = _countof(rootParameters);
  409.     rootSignatureDesc.pParameters = rootParameters;
  410.     rootSignatureDesc.NumStaticSamplers = 0;
  411.     rootSignatureDesc.pStaticSamplers = nullptr;
  412.     rootSignatureDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |
  413.         D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS |
  414.         D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS |
  415.         D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS |
  416.         D3D12_ROOT_SIGNATURE_FLAG_DENY_PIXEL_SHADER_ROOT_ACCESS;
  417.  
  418.     ID3DBlob* signature;
  419.     if (FAILED(D3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, nullptr))) { return false; }
  420.     if (FAILED(device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&rootSignature)))) { return false; }
  421.  
  422.     ID3DBlob* vertexShader;
  423.     ID3DBlob* errorBuff;
  424.     hr = D3DCompileFromFile(L"BaseShader.vs.hlsl", nullptr, nullptr, "main", "vs_5_0", D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION, 0, &vertexShader, &errorBuff);
  425.     if (FAILED(hr))
  426.     {
  427.         OutputDebugStringA((LPCSTR)errorBuff->GetBufferPointer());
  428.         return false;
  429.     }
  430.  
  431.     D3D12_SHADER_BYTECODE vertexShaderBytecode = {};
  432.     vertexShaderBytecode.BytecodeLength = vertexShader->GetBufferSize();
  433.     vertexShaderBytecode.pShaderBytecode = vertexShader->GetBufferPointer();
  434.  
  435.     // compile pixel shader
  436.     ID3DBlob* pixelShader;
  437.     hr = D3DCompileFromFile(L"BaseShader.ps.hlsl", nullptr, nullptr, "main", "ps_5_0", D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION, 0, &pixelShader, &errorBuff);
  438.     if (FAILED(hr))
  439.     {
  440.         OutputDebugStringA((LPCSTR)errorBuff->GetBufferPointer());
  441.         return false;
  442.     }
  443.  
  444.     D3D12_SHADER_BYTECODE pixelShaderBytecode = {};
  445.     pixelShaderBytecode.BytecodeLength = pixelShader->GetBufferSize();
  446.     pixelShaderBytecode.pShaderBytecode = pixelShader->GetBufferPointer();
  447.  
  448.     const D3D12_INPUT_ELEMENT_DESC inputLayout[] =
  449.     {
  450.         { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
  451.         { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }
  452.     };
  453.  
  454.     D3D12_INPUT_LAYOUT_DESC inputLayoutDesc = {};
  455.     inputLayoutDesc.NumElements = sizeof(inputLayout) / sizeof(D3D12_INPUT_ELEMENT_DESC);
  456.     inputLayoutDesc.pInputElementDescs = inputLayout;
  457.  
  458.     D3D12_RASTERIZER_DESC rasterDesc = D3D12_RASTERIZER_DESC();
  459.     rasterDesc.FillMode = D3D12_FILL_MODE_SOLID;
  460.     rasterDesc.CullMode = D3D12_CULL_MODE_BACK;
  461.     rasterDesc.FrontCounterClockwise = FALSE;
  462.     rasterDesc.DepthBias = D3D12_DEFAULT_DEPTH_BIAS;
  463.     rasterDesc.DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP;
  464.     rasterDesc.SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS;
  465.     rasterDesc.DepthClipEnable = TRUE;
  466.     rasterDesc.MultisampleEnable = FALSE;
  467.     rasterDesc.AntialiasedLineEnable = FALSE;
  468.     rasterDesc.ForcedSampleCount = 0;
  469.     rasterDesc.ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF;
  470.  
  471.     D3D12_BLEND_DESC blendDesc = D3D12_BLEND_DESC();
  472.     blendDesc.IndependentBlendEnable = FALSE;
  473.     const D3D12_RENDER_TARGET_BLEND_DESC defaultRenderTargetBlendDesc =
  474.     {
  475.         FALSE,FALSE,
  476.         D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD,
  477.         D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD,
  478.         D3D12_LOGIC_OP_NOOP,
  479.         D3D12_COLOR_WRITE_ENABLE_ALL,
  480.     };
  481.     for (UINT i = 0; i < D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i)
  482.     {
  483.         blendDesc.RenderTarget[i] = defaultRenderTargetBlendDesc;
  484.     }
  485.  
  486.     D3D12_DEPTH_STENCIL_DESC dsDesc = D3D12_DEPTH_STENCIL_DESC();
  487.     dsDesc.DepthEnable = TRUE;
  488.     dsDesc.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL;
  489.     dsDesc.DepthFunc = D3D12_COMPARISON_FUNC_LESS;
  490.     dsDesc.StencilEnable = FALSE;
  491.     dsDesc.StencilReadMask = D3D12_DEFAULT_STENCIL_READ_MASK;
  492.     dsDesc.StencilWriteMask = D3D12_DEFAULT_STENCIL_WRITE_MASK;
  493.     const D3D12_DEPTH_STENCILOP_DESC defaultStencilOp =
  494.     { D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_COMPARISON_FUNC_ALWAYS };
  495.     dsDesc.FrontFace = defaultStencilOp;
  496.     dsDesc.BackFace = defaultStencilOp;
  497.  
  498.     D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {};
  499.     psoDesc.InputLayout = inputLayoutDesc;
  500.     psoDesc.pRootSignature = rootSignature;
  501.     psoDesc.VS = vertexShaderBytecode;
  502.     psoDesc.PS = pixelShaderBytecode;
  503.     psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
  504.     psoDesc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
  505.     psoDesc.SampleDesc.Count = 1;
  506.     psoDesc.SampleMask = 0xffffffff;
  507.     psoDesc.RasterizerState = rasterDesc;
  508.     psoDesc.BlendState = blendDesc;
  509.     psoDesc.NumRenderTargets = 1;
  510.     psoDesc.DepthStencilState = dsDesc;
  511.  
  512.     // create the pso
  513.     if (FAILED(device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&pipelineStateObject))))
  514.     {
  515.         return false;
  516.     }
  517.  
  518.     Vertex vList[] = {
  519.         // front face
  520.         { -0.5f,  0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f },
  521.         { 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 1.0f, 1.0f },
  522.         { -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 1.0f },
  523.         { 0.5f,  0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f },
  524.  
  525.         // right side face
  526.         { 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f },
  527.         { 0.5f,  0.5f,  0.5f, 1.0f, 0.0f, 1.0f, 1.0f },
  528.         { 0.5f, -0.5f,  0.5f, 0.0f, 0.0f, 1.0f, 1.0f },
  529.         { 0.5f,  0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f },
  530.  
  531.         // left side face
  532.         { -0.5f,  0.5f,  0.5f, 1.0f, 0.0f, 0.0f, 1.0f },
  533.         { -0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 1.0f, 1.0f },
  534.         { -0.5f, -0.5f,  0.5f, 0.0f, 0.0f, 1.0f, 1.0f },
  535.         { -0.5f,  0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f },
  536.  
  537.         // back face
  538.         { 0.5f,  0.5f,  0.5f, 1.0f, 0.0f, 0.0f, 1.0f },
  539.         { -0.5f, -0.5f,  0.5f, 1.0f, 0.0f, 1.0f, 1.0f },
  540.         { 0.5f, -0.5f,  0.5f, 0.0f, 0.0f, 1.0f, 1.0f },
  541.         { -0.5f,  0.5f,  0.5f, 0.0f, 1.0f, 0.0f, 1.0f },
  542.  
  543.         // top face
  544.         { -0.5f,  0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f },
  545.         { 0.5f,  0.5f,  0.5f, 1.0f, 0.0f, 1.0f, 1.0f },
  546.         { 0.5f,  0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 1.0f },
  547.         { -0.5f,  0.5f,  0.5f, 0.0f, 1.0f, 0.0f, 1.0f },
  548.  
  549.         // bottom face
  550.         { 0.5f, -0.5f,  0.5f, 1.0f, 0.0f, 0.0f, 1.0f },
  551.         { -0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 1.0f, 1.0f },
  552.         { 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 1.0f },
  553.         { -0.5f, -0.5f,  0.5f, 0.0f, 1.0f, 0.0f, 1.0f },
  554.     };
  555.  
  556.     int32 vBufferSize = sizeof(vList);
  557.  
  558.     D3D12_HEAP_PROPERTIES heapProps = D3D12_HEAP_PROPERTIES();
  559.     heapProps.Type = D3D12_HEAP_TYPE_DEFAULT;
  560.     heapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
  561.     heapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
  562.     heapProps.CreationNodeMask = 1;
  563.     heapProps.VisibleNodeMask = 1;
  564.  
  565.     D3D12_RESOURCE_DESC bufferResourceDesc = D3D12_RESOURCE_DESC();
  566.     bufferResourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
  567.     bufferResourceDesc.Alignment = 0;
  568.     bufferResourceDesc.Width = vBufferSize;
  569.     bufferResourceDesc.Height = 1;
  570.     bufferResourceDesc.DepthOrArraySize = 1;
  571.     bufferResourceDesc.MipLevels = 1;
  572.     bufferResourceDesc.Format = DXGI_FORMAT_UNKNOWN;
  573.     bufferResourceDesc.SampleDesc.Count = 1;
  574.     bufferResourceDesc.SampleDesc.Quality = 0;
  575.     bufferResourceDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
  576.     bufferResourceDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
  577.  
  578.     device->CreateCommittedResource(&heapProps, D3D12_HEAP_FLAG_NONE, &bufferResourceDesc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&vertexBuffer));
  579.     vertexBuffer->SetName(L"Vertex Buffer Resource Heap");
  580.  
  581.     ID3D12Resource* vBufferUploadHeap;
  582.     heapProps.Type = D3D12_HEAP_TYPE_UPLOAD;
  583.     device->CreateCommittedResource(&heapProps, D3D12_HEAP_FLAG_NONE, &bufferResourceDesc, D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&vBufferUploadHeap));
  584.     vBufferUploadHeap->SetName(L"Vertex Buffer Upload Resource Heap");
  585.  
  586.     D3D12_SUBRESOURCE_DATA vertexData = {};
  587.     vertexData.pData = reinterpret_cast<BYTE*>(vList);
  588.     vertexData.RowPitch = vBufferSize;
  589.     vertexData.SlicePitch = vBufferSize;
  590.  
  591.     UpdateSubresources(commandList, vertexBuffer, vBufferUploadHeap, 0, 0, 1, &vertexData);
  592.  
  593.     D3D12_RESOURCE_BARRIER barrier = D3D12_RESOURCE_BARRIER();
  594.     barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
  595.     barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
  596.     barrier.Transition.pResource = vertexBuffer;
  597.     barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST;
  598.     barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER;
  599.     barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
  600.     commandList->ResourceBarrier(1, &barrier);
  601.    
  602.     DWORD iList[] =
  603.     {
  604.         // ffront face
  605.         0, 1, 2, // first triangle
  606.         0, 3, 1, // second triangle
  607.  
  608.         // left face
  609.         4, 5, 6, // first triangle
  610.         4, 7, 5, // second triangle
  611.  
  612.         // right face
  613.         8, 9, 10, // first triangle
  614.         8, 11, 9, // second triangle
  615.  
  616.         // back face
  617.         12, 13, 14, // first triangle
  618.         12, 15, 13, // second triangle
  619.  
  620.         // top face
  621.         16, 17, 18, // first triangle
  622.         16, 19, 17, // second triangle
  623.  
  624.         // bottom face
  625.         20, 21, 22, // first triangle
  626.         20, 23, 21, // second triangle
  627.     };
  628.  
  629.  
  630.     int32 iBufferSize = sizeof(iList);
  631.     numCubeIndices = sizeof(iList) / sizeof(DWORD);
  632.    
  633.  
  634.     D3D12_RESOURCE_DESC indexBufferResourceDesc = D3D12_RESOURCE_DESC();
  635.     indexBufferResourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
  636.     indexBufferResourceDesc.Alignment = 0;
  637.     indexBufferResourceDesc.Width = iBufferSize;
  638.     indexBufferResourceDesc.Height = 1;
  639.     indexBufferResourceDesc.DepthOrArraySize = 1;
  640.     indexBufferResourceDesc.MipLevels = 1;
  641.     indexBufferResourceDesc.Format = DXGI_FORMAT_UNKNOWN;
  642.     indexBufferResourceDesc.SampleDesc.Count = 1;
  643.     indexBufferResourceDesc.SampleDesc.Quality = 0;
  644.     indexBufferResourceDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
  645.     indexBufferResourceDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
  646.  
  647.     heapProps.Type = D3D12_HEAP_TYPE_DEFAULT;
  648.     device->CreateCommittedResource(&heapProps, D3D12_HEAP_FLAG_NONE, &indexBufferResourceDesc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&indexBuffer));
  649.     vertexBuffer->SetName(L"Index Buffer Resource Heap");
  650.  
  651.     ID3D12Resource* iBufferUploadHeap;
  652.     heapProps.Type = D3D12_HEAP_TYPE_UPLOAD;
  653.     device->CreateCommittedResource(&heapProps, D3D12_HEAP_FLAG_NONE, &bufferResourceDesc, D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&iBufferUploadHeap));
  654.     vBufferUploadHeap->SetName(L"Index Buffer Upload Resource Heap");
  655.  
  656.     D3D12_SUBRESOURCE_DATA indexData = {};
  657.     indexData.pData = reinterpret_cast<BYTE*>(iList);
  658.     indexData.RowPitch = iBufferSize;
  659.     indexData.SlicePitch = iBufferSize;
  660.  
  661.     UpdateSubresources(commandList, indexBuffer, iBufferUploadHeap, 0, 0, 1, &indexData);
  662.  
  663.     D3D12_RESOURCE_BARRIER indexBufferBarrier = D3D12_RESOURCE_BARRIER();
  664.     indexBufferBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
  665.     indexBufferBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
  666.     indexBufferBarrier.Transition.pResource = indexBuffer;
  667.     indexBufferBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST;
  668.     indexBufferBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER;
  669.     indexBufferBarrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
  670.     commandList->ResourceBarrier(1, &indexBufferBarrier);
  671.  
  672.     D3D12_DESCRIPTOR_HEAP_DESC dsvHeapDesc = {};
  673.     dsvHeapDesc.NumDescriptors = 1;
  674.     dsvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV;
  675.     dsvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
  676.     if (FAILED(device->CreateDescriptorHeap(&dsvHeapDesc, IID_PPV_ARGS(&dsDescriptorHeap))))
  677.     {
  678.         Running = false;
  679.     }
  680.  
  681.     D3D12_DEPTH_STENCIL_VIEW_DESC depthStencilDesc = {};
  682.     depthStencilDesc.Format = DXGI_FORMAT_D32_FLOAT;
  683.     depthStencilDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
  684.     depthStencilDesc.Flags = D3D12_DSV_FLAG_NONE;
  685.  
  686.     D3D12_CLEAR_VALUE depthOptimizedClearValue = {};
  687.     depthOptimizedClearValue.Format = DXGI_FORMAT_D32_FLOAT;
  688.     depthOptimizedClearValue.DepthStencil.Depth = 1.0f;
  689.     depthOptimizedClearValue.DepthStencil.Stencil = 0;
  690.  
  691.     D3D12_RESOURCE_DESC depthstencilResourceDesc = D3D12_RESOURCE_DESC();
  692.     depthstencilResourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
  693.     depthstencilResourceDesc.Alignment = 0;
  694.     depthstencilResourceDesc.Width = Width;
  695.     depthstencilResourceDesc.Height = Height;
  696.     depthstencilResourceDesc.DepthOrArraySize = 1;
  697.     depthstencilResourceDesc.MipLevels = 0;
  698.     depthstencilResourceDesc.Format = DXGI_FORMAT_D32_FLOAT;
  699.     depthstencilResourceDesc.SampleDesc.Count = 1;
  700.     depthstencilResourceDesc.SampleDesc.Quality = 0;
  701.     depthstencilResourceDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
  702.     depthstencilResourceDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
  703.  
  704.     heapProps.Type = D3D12_HEAP_TYPE_DEFAULT;
  705.     device->CreateCommittedResource(&heapProps, D3D12_HEAP_FLAG_NONE, &depthstencilResourceDesc, D3D12_RESOURCE_STATE_DEPTH_WRITE, &depthOptimizedClearValue, IID_PPV_ARGS(&depthStencilBuffer));
  706.     dsDescriptorHeap->SetName(L"Depth/Stencil Resource Heap");
  707.  
  708.     device->CreateDepthStencilView(depthStencilBuffer, &depthStencilDesc, dsDescriptorHeap->GetCPUDescriptorHandleForHeapStart());
  709.  
  710.     for (int32 i = 0; i < frameBufferCount; ++i)
  711.     {
  712.         D3D12_RESOURCE_DESC constantBufferResourceDesc = D3D12_RESOURCE_DESC();
  713.         constantBufferResourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
  714.         constantBufferResourceDesc.Alignment = 0;
  715.         constantBufferResourceDesc.Width = 1024 * 64;
  716.         constantBufferResourceDesc.Height = 1;
  717.         constantBufferResourceDesc.DepthOrArraySize = 1;
  718.         constantBufferResourceDesc.MipLevels = 1;
  719.         constantBufferResourceDesc.Format = DXGI_FORMAT_UNKNOWN;
  720.         constantBufferResourceDesc.SampleDesc.Count = 1;
  721.         constantBufferResourceDesc.SampleDesc.Quality = 0;
  722.         constantBufferResourceDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
  723.         constantBufferResourceDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
  724.  
  725.         heapProps.Type = D3D12_HEAP_TYPE_UPLOAD;
  726.         hr = device->CreateCommittedResource(&heapProps, D3D12_HEAP_FLAG_NONE, &constantBufferResourceDesc, D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&constantBufferUploadHeaps[i]));
  727.         constantBufferUploadHeaps[i]->SetName(L"Constant Buffer Upload Resource Heap");
  728.  
  729.         ZeroMemory(&cbPerObject, sizeof(cbPerObject));
  730.  
  731.         D3D12_RANGE readRange = D3D12_RANGE();
  732.         readRange.Begin = 0;
  733.         readRange.End = 0;
  734.         hr = constantBufferUploadHeaps[i]->Map(0, &readRange, reinterpret_cast<void**>(&cbvGPUAddress[i]));
  735.         memcpy(cbvGPUAddress[i], &cbPerObject, sizeof(cbPerObject));
  736.         memcpy(cbvGPUAddress[i] + ConstantBufferPerObjectAlignedSize, &cbPerObject, sizeof(cbPerObject));
  737.     }
  738.  
  739.     commandList->Close();
  740.     ID3D12CommandList* ppCommandLists[] = { commandList };
  741.     commandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists);
  742.  
  743.     fenceValue[frameIndex]++;
  744.     hr = commandQueue->Signal(fence[frameIndex], fenceValue[frameIndex]);
  745.     if (FAILED(hr))
  746.     {
  747.         Running = false;
  748.     }
  749.  
  750.     vertexBufferView.BufferLocation = vertexBuffer->GetGPUVirtualAddress();
  751.     vertexBufferView.StrideInBytes = sizeof(Vertex);
  752.     vertexBufferView.SizeInBytes = vBufferSize;
  753.  
  754.     indexBufferView.BufferLocation = indexBuffer->GetGPUVirtualAddress();
  755.     indexBufferView.Format = DXGI_FORMAT_R32_UINT;
  756.     indexBufferView.SizeInBytes = iBufferSize;
  757.  
  758.     viewport.TopLeftX = 0;
  759.     viewport.TopLeftY = 0;
  760.     viewport.Width = (FLOAT)Width;
  761.     viewport.Height = (FLOAT)Height;
  762.     viewport.MinDepth = 0.0f;
  763.     viewport.MaxDepth = 1.0f;
  764.  
  765.     scissorRect.left = 0;
  766.     scissorRect.top = 0;
  767.     scissorRect.right = (LONG)Width;
  768.     scissorRect.bottom = (LONG)Height;
  769.  
  770.     XMMATRIX tmpMat = XMMatrixPerspectiveFovLH(45.0f*(3.14f / 180.0f), (float)Width / (float)Height, 0.1f, 1000.0f);
  771.     XMStoreFloat4x4(&cameraProjMat, tmpMat);
  772.     cameraPosition = XMFLOAT4(0.0f, 2.0f, -4.0f, 0.0f);
  773.     cameraTarget = XMFLOAT4(0.0f, 0.0f, 0.0f, 0.0f);
  774.     cameraUp = XMFLOAT4(0.0f, 1.0f, 0.0f, 0.0f);
  775.  
  776.     XMVECTOR cPos = XMLoadFloat4(&cameraPosition);
  777.     XMVECTOR cTarg = XMLoadFloat4(&cameraTarget);
  778.     XMVECTOR cUp = XMLoadFloat4(&cameraUp);
  779.     tmpMat = XMMatrixLookAtLH(cPos, cTarg, cUp);
  780.     XMStoreFloat4x4(&cameraViewMat, tmpMat);
  781.  
  782.     // first cube
  783.     cube1Position = XMFLOAT4(0.0f, 0.0f, 0.0f, 0.0f);
  784.     XMVECTOR posVec = XMLoadFloat4(&cube1Position);
  785.     tmpMat = XMMatrixTranslationFromVector(posVec);
  786.     XMStoreFloat4x4(&cube1RotMat, XMMatrixIdentity());
  787.     XMStoreFloat4x4(&cube1WorldMat, tmpMat);
  788.  
  789.     // second cube
  790.     cube2PositionOffset = XMFLOAT4(1.5f, 0.0f, 0.0f, 0.0f);
  791.     posVec = XMLoadFloat4(&cube2PositionOffset) + XMLoadFloat4(&cube1Position);
  792.     tmpMat = XMMatrixTranslationFromVector(posVec);
  793.     XMStoreFloat4x4(&cube2RotMat, XMMatrixIdentity());
  794.     XMStoreFloat4x4(&cube2WorldMat, tmpMat);
  795.  
  796.     return true;
  797. }
  798.  
  799. void Update()
  800. {
  801.     XMMATRIX rotXMat = XMMatrixRotationX(0.0001f);
  802.     XMMATRIX rotYMat = XMMatrixRotationY(0.0002f);
  803.     XMMATRIX rotZMat = XMMatrixRotationZ(0.0003f);
  804.     XMMATRIX rotMat = XMLoadFloat4x4(&cube1RotMat) * rotXMat * rotYMat * rotZMat;
  805.     XMStoreFloat4x4(&cube1RotMat, rotMat);
  806.     XMMATRIX translationMat = XMMatrixTranslationFromVector(XMLoadFloat4(&cube1Position));
  807.     XMMATRIX worldMat = rotMat * translationMat;
  808.     XMStoreFloat4x4(&cube1WorldMat, worldMat);
  809.     XMMATRIX viewMat = XMLoadFloat4x4(&cameraViewMat);
  810.     XMMATRIX projMat = XMLoadFloat4x4(&cameraProjMat);
  811.     XMMATRIX wvpMat = XMLoadFloat4x4(&cube1WorldMat) * viewMat * projMat;
  812.     XMMATRIX transposed = XMMatrixTranspose(wvpMat);
  813.     XMStoreFloat4x4(&cbPerObject.wvpMat, transposed);
  814.     memcpy(cbvGPUAddress[frameIndex], &cbPerObject, sizeof(cbPerObject));
  815.     rotXMat = XMMatrixRotationX(0.0003f);
  816.     rotYMat = XMMatrixRotationY(0.0002f);
  817.     rotZMat = XMMatrixRotationZ(0.0001f);
  818.     rotMat = rotZMat * (XMLoadFloat4x4(&cube2RotMat) * (rotXMat * rotYMat));
  819.     XMStoreFloat4x4(&cube2RotMat, rotMat);
  820.  
  821.     XMMATRIX translationOffsetMat = XMMatrixTranslationFromVector(XMLoadFloat4(&cube2PositionOffset));
  822.     XMMATRIX scaleMat = XMMatrixScaling(0.5f, 0.5f, 0.5f);
  823.     worldMat = scaleMat * translationOffsetMat * rotMat * translationMat;
  824.     wvpMat = XMLoadFloat4x4(&cube2WorldMat) * viewMat * projMat;
  825.     transposed = XMMatrixTranspose(wvpMat);
  826.     XMStoreFloat4x4(&cbPerObject.wvpMat, transposed);
  827.     memcpy(cbvGPUAddress[frameIndex] + ConstantBufferPerObjectAlignedSize, &cbPerObject, sizeof(cbPerObject));
  828.     XMStoreFloat4x4(&cube2WorldMat, worldMat);
  829. }
  830.  
  831. void UpdatePipeline()
  832. {
  833.     HRESULT hr;
  834.     WaitForPreviousFrame();
  835.     if (FAILED(commandAllocator[frameIndex]->Reset()))
  836.     {
  837.         Running = false;
  838.     }
  839.  
  840.     hr = commandList->Reset(commandAllocator[frameIndex], pipelineStateObject);
  841.     if (FAILED(hr))
  842.     {
  843.         Running = false;
  844.     }
  845.  
  846.     D3D12_RESOURCE_BARRIER renderTargetsBarrier = D3D12_RESOURCE_BARRIER();
  847.     renderTargetsBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
  848.     renderTargetsBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
  849.     renderTargetsBarrier.Transition.pResource = renderTargets[frameIndex];
  850.     renderTargetsBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT;
  851.     renderTargetsBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET;
  852.     renderTargetsBarrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
  853.     commandList->ResourceBarrier(1, &renderTargetsBarrier);
  854.  
  855.  
  856.     D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle(rtvDescriptorHeap->GetCPUDescriptorHandleForHeapStart());
  857.     rtvHandle.ptr += (int32)frameIndex * rtvDescriptorSize;
  858.  
  859.     D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle(dsDescriptorHeap->GetCPUDescriptorHandleForHeapStart());
  860.     commandList->OMSetRenderTargets(1, &rtvHandle, FALSE, &dsvHandle);
  861.  
  862.     const float clearColor[] = { 0.0f, 0.2f, 0.4f, 1.0f };
  863.     commandList->ClearRenderTargetView(rtvHandle, clearColor, 0, nullptr);
  864.     commandList->ClearDepthStencilView(dsDescriptorHeap->GetCPUDescriptorHandleForHeapStart(), D3D12_CLEAR_FLAG_DEPTH, 1.0f, 0, 0, nullptr);
  865.     commandList->SetGraphicsRootSignature(rootSignature);
  866.     commandList->RSSetViewports(1, &viewport);
  867.     commandList->RSSetScissorRects(1, &scissorRect);
  868.     commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
  869.     commandList->IASetVertexBuffers(0, 1, &vertexBufferView);
  870.     commandList->IASetIndexBuffer(&indexBufferView);
  871.     //first cube
  872.     commandList->SetGraphicsRootConstantBufferView(0, constantBufferUploadHeaps[frameIndex]->GetGPUVirtualAddress());
  873.     commandList->DrawIndexedInstanced(numCubeIndices, 1, 0, 0, 0);
  874.     //second cube
  875.     commandList->SetGraphicsRootConstantBufferView(0, constantBufferUploadHeaps[frameIndex]->GetGPUVirtualAddress() + ConstantBufferPerObjectAlignedSize);
  876.     commandList->DrawIndexedInstanced(numCubeIndices, 1, 0, 0, 0);
  877.  
  878.     D3D12_RESOURCE_BARRIER presentBarrier = D3D12_RESOURCE_BARRIER();
  879.     presentBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
  880.     presentBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
  881.     presentBarrier.Transition.pResource = renderTargets[frameIndex];
  882.     presentBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET;
  883.     presentBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT;
  884.     presentBarrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
  885.     commandList->ResourceBarrier(1, &presentBarrier);
  886.  
  887.     hr = commandList->Close();
  888.     if (FAILED(hr))
  889.     {
  890.         Running = false;
  891.     }
  892. }
  893.  
  894. void Render()
  895. {
  896.     UpdatePipeline();
  897.     ID3D12CommandList* ppCommandLists[] = { commandList };
  898.     commandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists);
  899.     auto hr = commandQueue->Signal(fence[frameIndex], fenceValue[frameIndex]);
  900.     if (FAILED(hr))
  901.     {
  902.         Running = false;
  903.     }
  904.  
  905.     hr = swapChain->Present(0, 0);
  906.     if (FAILED(hr))
  907.     {
  908.         Running = false;
  909.     }
  910. }
  911.  
  912. void Cleanup()
  913. {
  914.     for (SIZE_T i = 0; i < frameBufferCount; ++i)
  915.     {
  916.         frameIndex = i;
  917.         WaitForPreviousFrame();
  918.     }
  919.  
  920.     BOOL fs = false;
  921.     if (swapChain->GetFullscreenState(&fs, NULL))
  922.     {
  923.         swapChain->SetFullscreenState(false, NULL);
  924.     }
  925.    
  926.     SAFE_RELEASE(swapChain);
  927.     SAFE_RELEASE(commandQueue);
  928.     SAFE_RELEASE(rtvDescriptorHeap);
  929.     SAFE_RELEASE(commandList);
  930.  
  931.     for (SIZE_T i = 0; i < frameBufferCount; ++i)
  932.     {
  933.         SAFE_RELEASE(renderTargets[i]);
  934.         SAFE_RELEASE(commandAllocator[i]);
  935.         SAFE_RELEASE(fence[i]);
  936.     };
  937.  
  938.     SAFE_RELEASE(pipelineStateObject);
  939.     SAFE_RELEASE(rootSignature);
  940.     SAFE_RELEASE(vertexBuffer);
  941.     SAFE_RELEASE(indexBuffer);
  942.  
  943.     SAFE_RELEASE(depthStencilBuffer);
  944.     SAFE_RELEASE(dsDescriptorHeap);
  945.  
  946.     for (SIZE_T i = 0; i < frameBufferCount; ++i)
  947.     {
  948.         SAFE_RELEASE(constantBufferUploadHeaps[i]);
  949.     };
  950. }
  951.  
  952. void WaitForPreviousFrame()
  953. {
  954.     frameIndex = swapChain->GetCurrentBackBufferIndex();
  955.     if (fence[frameIndex]->GetCompletedValue() < fenceValue[frameIndex])
  956.     {
  957.         auto hr = fence[frameIndex]->SetEventOnCompletion(fenceValue[frameIndex], fenceEvent);
  958.         if (FAILED(hr))
  959.         {
  960.             Running = false;
  961.         }
  962.         WaitForSingleObject(fenceEvent, INFINITE);
  963.     }
  964.     fenceValue[frameIndex]++;
  965. }
Add Comment
Please, Sign In to add comment