Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions MiniEngine/Core/Core_VS14.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@
<Manifest>
<EnableDPIAwareness>true</EnableDPIAwareness>
</Manifest>
<ClCompile>
<AssemblerOutput Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AssemblyAndMachineCode</AssemblerOutput>
</ClCompile>
<ClCompile>
<AssemblerOutput Condition="'$(Configuration)|$(Platform)'=='Profile|x64'">AssemblyAndMachineCode</AssemblerOutput>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="BufferManager.h" />
Expand Down
1 change: 1 addition & 0 deletions Templates/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ Release/
x64/
*.ipch
*.sdf
*.opendb
*.opensdf
*.user
13 changes: 10 additions & 3 deletions Templates/DirectX12App/App.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ using namespace Windows::System;
using namespace Windows::Foundation;
using namespace Windows::Graphics::Display;

using Microsoft::WRL::ComPtr;

// The DirectX 12 Application template is documented at http://go.microsoft.com/fwlink/?LinkID=613670&clcid=0x409

// The main function is only used to initialize our IFrameworkView class.
Expand Down Expand Up @@ -142,9 +144,7 @@ void App::OnSuspending(Platform::Object^ sender, SuspendingEventArgs^ args)

create_task([this, deferral]()
{
// TODO: Insert your code here.
m_main->OnSuspending();

deferral->Complete();
});
}
Expand All @@ -155,7 +155,6 @@ void App::OnResuming(Platform::Object^ sender, Platform::Object^ args)
// and state are persisted when resuming from suspend. Note that this event
// does not occur if the app was previously terminated.

// TODO: Insert your code here.
m_main->OnResuming();
}

Expand Down Expand Up @@ -209,6 +208,14 @@ std::shared_ptr<DX::DeviceResources> App::GetDeviceResources()

m_deviceResources = nullptr;
m_main->OnDeviceRemoved();

#if defined(_DEBUG)
ComPtr<IDXGIDebug1> dxgiDebug;
if (SUCCEEDED(DXGIGetDebugInterface1(0, IID_PPV_ARGS(&dxgiDebug))))
{
dxgiDebug->ReportLiveObjects(DXGI_DEBUG_ALL, DXGI_DEBUG_RLO_FLAGS(DXGI_DEBUG_RLO_SUMMARY | DXGI_DEBUG_RLO_IGNORE_INTERNAL));
}
#endif
}

if (m_deviceResources == nullptr)
Expand Down
130 changes: 58 additions & 72 deletions Templates/DirectX12App/Common/DeviceResources.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,14 @@ namespace ScreenRotation
};

// Constructor for DeviceResources.
DX::DeviceResources::DeviceResources() :
DX::DeviceResources::DeviceResources(DXGI_FORMAT backBufferFormat, DXGI_FORMAT depthBufferFormat) :
m_currentFrame(0),
m_screenViewport(),
m_rtvDescriptorSize(0),
m_fenceEvent(0),
m_backBufferFormat(backBufferFormat),
m_depthBufferFormat(depthBufferFormat),
m_fenceValues{},
m_d3dRenderTargetSize(),
m_outputSize(),
m_logicalSize(),
Expand All @@ -78,7 +81,6 @@ DX::DeviceResources::DeviceResources() :
m_effectiveDpi(-1.0f),
m_deviceRemoved(false)
{
ZeroMemory(m_fenceValues, sizeof(m_fenceValues));
CreateDeviceIndependentResources();
CreateDeviceResources();
}
Expand All @@ -105,7 +107,7 @@ void DX::DeviceResources::CreateDeviceResources()
DX::ThrowIfFailed(CreateDXGIFactory1(IID_PPV_ARGS(&m_dxgiFactory)));

ComPtr<IDXGIAdapter1> adapter;
GetHardwareAdapter(m_dxgiFactory.Get(), &adapter);
GetHardwareAdapter(&adapter);

// Create the Direct3D 12 API device object
HRESULT hr = D3D12CreateDevice(
Expand All @@ -114,23 +116,21 @@ void DX::DeviceResources::CreateDeviceResources()
IID_PPV_ARGS(&m_d3dDevice) // Returns the Direct3D device created.
);

#if defined(_DEBUG)
if (FAILED(hr))
{
// If the initialization fails, fall back to the WARP device.
// For more information on WARP, see:
// http://go.microsoft.com/fwlink/?LinkId=286690

ComPtr<IDXGIAdapter> warpAdapter;
m_dxgiFactory->EnumWarpAdapter(IID_PPV_ARGS(&warpAdapter));
DX::ThrowIfFailed(m_dxgiFactory->EnumWarpAdapter(IID_PPV_ARGS(&warpAdapter)));

DX::ThrowIfFailed(
D3D12CreateDevice(
warpAdapter.Get(),
D3D_FEATURE_LEVEL_11_0,
IID_PPV_ARGS(&m_d3dDevice)
)
);
hr = D3D12CreateDevice(warpAdapter.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&m_d3dDevice));
}
#endif

DX::ThrowIfFailed(hr);

// Create the command queue.
D3D12_COMMAND_QUEUE_DESC queueDesc = {};
Expand All @@ -139,6 +139,23 @@ void DX::DeviceResources::CreateDeviceResources()

DX::ThrowIfFailed(m_d3dDevice->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&m_commandQueue)));

// Create descriptor heaps for render target views and depth stencil views.
D3D12_DESCRIPTOR_HEAP_DESC rtvHeapDesc = {};
rtvHeapDesc.NumDescriptors = c_frameCount;
rtvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
rtvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
DX::ThrowIfFailed(m_d3dDevice->CreateDescriptorHeap(&rtvHeapDesc, IID_PPV_ARGS(&m_rtvHeap)));
DX::SetName(m_rtvHeap.Get(), L"Render Target View Descriptor Heap");

m_rtvDescriptorSize = m_d3dDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);

D3D12_DESCRIPTOR_HEAP_DESC dsvHeapDesc = {};
dsvHeapDesc.NumDescriptors = 1;
dsvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV;
dsvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
ThrowIfFailed(m_d3dDevice->CreateDescriptorHeap(&dsvHeapDesc, IID_PPV_ARGS(&m_dsvHeap)));
DX::SetName(m_dsvHeap.Get(), L"Depth Stencil View Descriptor Heap");

for (UINT n = 0; n < c_frameCount; n++)
{
DX::ThrowIfFailed(
Expand All @@ -159,12 +176,12 @@ void DX::DeviceResources::CreateWindowSizeDependentResources()
// Wait until all previous GPU work is complete.
WaitForGpu();

// Clear the previous window size specific content.
// Clear the previous window size specific content and update the tracked fence values.
for (UINT n = 0; n < c_frameCount; n++)
{
m_renderTargets[n] = nullptr;
m_fenceValues[n] = m_fenceValues[m_currentFrame];
}
m_rtvHeap = nullptr;

UpdateRenderTargetSize();

Expand All @@ -177,16 +194,13 @@ void DX::DeviceResources::CreateWindowSizeDependentResources()
m_d3dRenderTargetSize.Width = swapDimensions ? m_outputSize.Height : m_outputSize.Width;
m_d3dRenderTargetSize.Height = swapDimensions ? m_outputSize.Width : m_outputSize.Height;

UINT backBufferWidth = lround(m_d3dRenderTargetSize.Width);
UINT backBufferHeight = lround(m_d3dRenderTargetSize.Height);

if (m_swapChain != nullptr)
{
// If the swap chain already exists, resize it.
HRESULT hr = m_swapChain->ResizeBuffers(
c_frameCount,
lround(m_d3dRenderTargetSize.Width),
lround(m_d3dRenderTargetSize.Height),
DXGI_FORMAT_B8G8R8A8_UNORM,
0
);
HRESULT hr = m_swapChain->ResizeBuffers(c_frameCount, backBufferWidth, backBufferHeight, m_backBufferFormat, 0);

if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET)
{
Expand All @@ -207,15 +221,15 @@ void DX::DeviceResources::CreateWindowSizeDependentResources()
DXGI_SCALING scaling = DisplayMetrics::SupportHighResolutions ? DXGI_SCALING_NONE : DXGI_SCALING_STRETCH;
DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {};

swapChainDesc.Width = lround(m_d3dRenderTargetSize.Width); // Match the size of the window.
swapChainDesc.Height = lround(m_d3dRenderTargetSize.Height);
swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; // This is the most common swap chain format.
swapChainDesc.Width = backBufferWidth; // Match the size of the window.
swapChainDesc.Height = backBufferHeight;
swapChainDesc.Format = m_backBufferFormat;
swapChainDesc.Stereo = false;
swapChainDesc.SampleDesc.Count = 1; // Don't use multi-sampling.
swapChainDesc.SampleDesc.Quality = 0;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.BufferCount = c_frameCount; // Use triple-buffering to minimize latency.
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; // All Windows Universal apps must use _FLIP_ SwapEffects
swapChainDesc.BufferCount = c_frameCount; // Use triple-buffering to minimize latency.
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; // All Windows Universal apps must use _FLIP_ SwapEffects.
swapChainDesc.Flags = 0;
swapChainDesc.Scaling = scaling;
swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_IGNORE;
Expand Down Expand Up @@ -266,51 +280,30 @@ void DX::DeviceResources::CreateWindowSizeDependentResources()

// Create render target views of the swap chain back buffer.
{
D3D12_DESCRIPTOR_HEAP_DESC rtvHeapDesc = {};
rtvHeapDesc.NumDescriptors = c_frameCount;
rtvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
rtvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
DX::ThrowIfFailed(m_d3dDevice->CreateDescriptorHeap(&rtvHeapDesc, IID_PPV_ARGS(&m_rtvHeap)));
m_rtvHeap->SetName(L"Render Target View Descriptor Heap");

m_currentFrame = 0;
m_currentFrame = m_swapChain->GetCurrentBackBufferIndex();
CD3DX12_CPU_DESCRIPTOR_HANDLE rtvDescriptor(m_rtvHeap->GetCPUDescriptorHandleForHeapStart());
m_rtvDescriptorSize = m_d3dDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
for (UINT n = 0; n < c_frameCount; n++)
{
DX::ThrowIfFailed(m_swapChain->GetBuffer(n, IID_PPV_ARGS(&m_renderTargets[n])));
m_d3dDevice->CreateRenderTargetView(m_renderTargets[n].Get(), nullptr, rtvDescriptor);
rtvDescriptor.Offset(m_rtvDescriptorSize);

WCHAR name[25];
swprintf_s(name, L"Render Target %d", n);
m_renderTargets[n]->SetName(name);
if (swprintf_s(name, L"Render Target %u", n) > 0)
{
DX::SetName(m_renderTargets[n].Get(), name);
}
}
}

// Create a depth stencil view.
// Create a depth stencil and view.
{
D3D12_DESCRIPTOR_HEAP_DESC dsvHeapDesc = {};
dsvHeapDesc.NumDescriptors = 1;
dsvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV;
dsvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
ThrowIfFailed(m_d3dDevice->CreateDescriptorHeap(&dsvHeapDesc, IID_PPV_ARGS(&m_dsvHeap)));

D3D12_HEAP_PROPERTIES depthHeapProperties = CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT);
D3D12_RESOURCE_DESC depthResourceDesc = CD3DX12_RESOURCE_DESC::Tex2D(
DXGI_FORMAT_D32_FLOAT,
static_cast<UINT>(m_d3dRenderTargetSize.Width),
static_cast<UINT>(m_d3dRenderTargetSize.Height),
1,
0,
1,
0,
D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL);

D3D12_CLEAR_VALUE depthOptimizedClearValue = {};
depthOptimizedClearValue.Format = DXGI_FORMAT_D32_FLOAT;
depthOptimizedClearValue.DepthStencil.Depth = 1.0f;
depthOptimizedClearValue.DepthStencil.Stencil = 0;

D3D12_RESOURCE_DESC depthResourceDesc = CD3DX12_RESOURCE_DESC::Tex2D(m_depthBufferFormat, backBufferWidth, backBufferHeight);
depthResourceDesc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;

CD3DX12_CLEAR_VALUE depthOptimizedClearValue(m_depthBufferFormat, 1.0f, 0);

ThrowIfFailed(m_d3dDevice->CreateCommittedResource(
&depthHeapProperties,
Expand All @@ -321,25 +314,21 @@ void DX::DeviceResources::CreateWindowSizeDependentResources()
IID_PPV_ARGS(&m_depthStencil)
));

DX::SetName(m_depthStencil.Get(), L"Depth Buffer");

D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc = {};
dsvDesc.Format = DXGI_FORMAT_D32_FLOAT;
dsvDesc.Format = m_depthBufferFormat;
dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
dsvDesc.Flags = D3D12_DSV_FLAG_NONE;

m_d3dDevice->CreateDepthStencilView(m_depthStencil.Get(), &dsvDesc, m_dsvHeap->GetCPUDescriptorHandleForHeapStart());
}

// All pending GPU work was already finished. Update the tracked fence values
// to the last value signaled.
for (UINT n = 0; n < c_frameCount; n++)
{
m_fenceValues[n] = m_fenceValues[m_currentFrame];
}

// Set the 3D rendering viewport to target the entire window.
m_screenViewport = { 0.0f, 0.0f, m_d3dRenderTargetSize.Width, m_d3dRenderTargetSize.Height, 0.0f, 1.0f };
}

// Determine the dimensions of the render target and whether it will be scaled down.
void DX::DeviceResources::UpdateRenderTargetSize()
{
m_effectiveDpi = m_dpi;
Expand Down Expand Up @@ -427,11 +416,8 @@ void DX::DeviceResources::ValidateDevice()

// Next, get the information for the current default adapter.

ComPtr<IDXGIFactory2> currentFactory;
DX::ThrowIfFailed(CreateDXGIFactory1(IID_PPV_ARGS(&currentFactory)));

ComPtr<IDXGIAdapter1> currentDefaultAdapter;
DX::ThrowIfFailed(currentFactory->EnumAdapters1(0, &currentDefaultAdapter));
GetHardwareAdapter(&currentDefaultAdapter);

DXGI_ADAPTER_DESC currentDesc;
DX::ThrowIfFailed(currentDefaultAdapter->GetDesc(&currentDesc));
Expand Down Expand Up @@ -491,7 +477,7 @@ void DX::DeviceResources::MoveToNextFrame()
DX::ThrowIfFailed(m_commandQueue->Signal(m_fence.Get(), currentFenceValue));

// Advance the frame index.
m_currentFrame = (m_currentFrame + 1) % c_frameCount;
m_currentFrame = m_swapChain->GetCurrentBackBufferIndex();

// Check to see if the next frame is ready to start.
if (m_fence->GetCompletedValue() < m_fenceValues[m_currentFrame])
Expand Down Expand Up @@ -561,12 +547,12 @@ DXGI_MODE_ROTATION DX::DeviceResources::ComputeDisplayRotation()

// This method acquires the first available hardware adapter that supports Direct3D 12.
// If no such adapter can be found, *ppAdapter will be set to nullptr.
void DX::DeviceResources::GetHardwareAdapter(IDXGIFactory4* pFactory, IDXGIAdapter1** ppAdapter)
void DX::DeviceResources::GetHardwareAdapter(IDXGIAdapter1** ppAdapter)
{
ComPtr<IDXGIAdapter1> adapter;
*ppAdapter = nullptr;

for (UINT adapterIndex = 0; DXGI_ERROR_NOT_FOUND != pFactory->EnumAdapters1(adapterIndex, &adapter); ++adapterIndex)
for (UINT adapterIndex = 0; DXGI_ERROR_NOT_FOUND != m_dxgiFactory->EnumAdapters1(adapterIndex, &adapter); adapterIndex++)
{
DXGI_ADAPTER_DESC1 desc;
adapter->GetDesc1(&desc);
Expand Down
10 changes: 7 additions & 3 deletions Templates/DirectX12App/Common/DeviceResources.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace DX
class DeviceResources
{
public:
DeviceResources();
DeviceResources(DXGI_FORMAT backBufferFormat = DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT depthBufferFormat = DXGI_FORMAT_D32_FLOAT);
void SetWindow(Windows::UI::Core::CoreWindow^ window);
void SetLogicalSize(Windows::Foundation::Size logicalSize);
void SetCurrentOrientation(Windows::Graphics::Display::DisplayOrientations currentOrientation);
Expand All @@ -33,6 +33,8 @@ namespace DX
ID3D12Resource* GetDepthStencil() const { return m_depthStencil.Get(); }
ID3D12CommandQueue* GetCommandQueue() const { return m_commandQueue.Get(); }
ID3D12CommandAllocator* GetCommandAllocator() const { return m_commandAllocators[m_currentFrame].Get(); }
DXGI_FORMAT GetBackBufferFormat() const { return m_backBufferFormat; }
DXGI_FORMAT GetDepthBufferFormat() const { return m_depthBufferFormat; }
D3D12_VIEWPORT GetScreenViewport() const { return m_screenViewport; }
DirectX::XMFLOAT4X4 GetOrientationTransform3D() const { return m_orientationTransform3D; }
UINT GetCurrentFrameIndex() const { return m_currentFrame; }
Expand All @@ -53,7 +55,7 @@ namespace DX
void UpdateRenderTargetSize();
void MoveToNextFrame();
DXGI_MODE_ROTATION ComputeDisplayRotation();
void GetHardwareAdapter(IDXGIFactory4* pFactory, IDXGIAdapter1** ppAdapter);
void GetHardwareAdapter(IDXGIAdapter1** ppAdapter);

UINT m_currentFrame;

Expand All @@ -65,10 +67,12 @@ namespace DX
Microsoft::WRL::ComPtr<ID3D12Resource> m_depthStencil;
Microsoft::WRL::ComPtr<ID3D12DescriptorHeap> m_rtvHeap;
Microsoft::WRL::ComPtr<ID3D12DescriptorHeap> m_dsvHeap;
UINT m_rtvDescriptorSize;
Microsoft::WRL::ComPtr<ID3D12CommandQueue> m_commandQueue;
Microsoft::WRL::ComPtr<ID3D12CommandAllocator> m_commandAllocators[c_frameCount];
DXGI_FORMAT m_backBufferFormat;
DXGI_FORMAT m_depthBufferFormat;
D3D12_VIEWPORT m_screenViewport;
UINT m_rtvDescriptorSize;
bool m_deviceRemoved;

// CPU/GPU Synchronization.
Expand Down
12 changes: 12 additions & 0 deletions Templates/DirectX12App/Common/DirectXHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,16 @@ namespace DX
static const float dipsPerInch = 96.0f;
return floorf(dips * dpi / dipsPerInch + 0.5f); // Round to nearest integer.
}

// Assign a name to the object to aid with debugging.
#if defined(_DEBUG)
inline void SetName(ID3D12Object* pObject, LPCWSTR name)
{
pObject->SetName(name);
}
#else
inline void SetName(ID3D12Object*, LPCWSTR)
{
}
#endif
}
Loading