@@ -64,11 +64,14 @@ namespace ScreenRotation
6464};
6565
6666// Constructor for DeviceResources.
67- DX::DeviceResources::DeviceResources () :
67+ DX::DeviceResources::DeviceResources (DXGI_FORMAT backBufferFormat, DXGI_FORMAT depthBufferFormat ) :
6868 m_currentFrame(0 ),
6969 m_screenViewport(),
7070 m_rtvDescriptorSize(0 ),
7171 m_fenceEvent(0 ),
72+ m_backBufferFormat(backBufferFormat),
73+ m_depthBufferFormat(depthBufferFormat),
74+ m_fenceValues{},
7275 m_d3dRenderTargetSize (),
7376 m_outputSize(),
7477 m_logicalSize(),
@@ -78,7 +81,6 @@ DX::DeviceResources::DeviceResources() :
7881 m_effectiveDpi(-1 .0f ),
7982 m_deviceRemoved(false )
8083{
81- ZeroMemory (m_fenceValues, sizeof (m_fenceValues));
8284 CreateDeviceIndependentResources ();
8385 CreateDeviceResources ();
8486}
@@ -105,7 +107,7 @@ void DX::DeviceResources::CreateDeviceResources()
105107 DX::ThrowIfFailed (CreateDXGIFactory1 (IID_PPV_ARGS (&m_dxgiFactory)));
106108
107109 ComPtr<IDXGIAdapter1> adapter;
108- GetHardwareAdapter (m_dxgiFactory. Get (), &adapter);
110+ GetHardwareAdapter (&adapter);
109111
110112 // Create the Direct3D 12 API device object
111113 HRESULT hr = D3D12CreateDevice (
@@ -114,23 +116,21 @@ void DX::DeviceResources::CreateDeviceResources()
114116 IID_PPV_ARGS (&m_d3dDevice) // Returns the Direct3D device created.
115117 );
116118
119+ #if defined(_DEBUG)
117120 if (FAILED (hr))
118121 {
119122 // If the initialization fails, fall back to the WARP device.
120123 // For more information on WARP, see:
121124 // http://go.microsoft.com/fwlink/?LinkId=286690
122125
123126 ComPtr<IDXGIAdapter> warpAdapter;
124- m_dxgiFactory->EnumWarpAdapter (IID_PPV_ARGS (&warpAdapter));
127+ DX::ThrowIfFailed ( m_dxgiFactory->EnumWarpAdapter (IID_PPV_ARGS (&warpAdapter)));
125128
126- DX::ThrowIfFailed (
127- D3D12CreateDevice (
128- warpAdapter.Get (),
129- D3D_FEATURE_LEVEL_11_0,
130- IID_PPV_ARGS (&m_d3dDevice)
131- )
132- );
129+ hr = D3D12CreateDevice (warpAdapter.Get (), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS (&m_d3dDevice));
133130 }
131+ #endif
132+
133+ DX::ThrowIfFailed (hr);
134134
135135 // Create the command queue.
136136 D3D12_COMMAND_QUEUE_DESC queueDesc = {};
@@ -139,6 +139,23 @@ void DX::DeviceResources::CreateDeviceResources()
139139
140140 DX::ThrowIfFailed (m_d3dDevice->CreateCommandQueue (&queueDesc, IID_PPV_ARGS (&m_commandQueue)));
141141
142+ // Create descriptor heaps for render target views and depth stencil views.
143+ D3D12_DESCRIPTOR_HEAP_DESC rtvHeapDesc = {};
144+ rtvHeapDesc.NumDescriptors = c_frameCount;
145+ rtvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
146+ rtvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
147+ DX::ThrowIfFailed (m_d3dDevice->CreateDescriptorHeap (&rtvHeapDesc, IID_PPV_ARGS (&m_rtvHeap)));
148+ DX::SetName (m_rtvHeap.Get (), L" Render Target View Descriptor Heap" );
149+
150+ m_rtvDescriptorSize = m_d3dDevice->GetDescriptorHandleIncrementSize (D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
151+
152+ D3D12_DESCRIPTOR_HEAP_DESC dsvHeapDesc = {};
153+ dsvHeapDesc.NumDescriptors = 1 ;
154+ dsvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV;
155+ dsvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
156+ ThrowIfFailed (m_d3dDevice->CreateDescriptorHeap (&dsvHeapDesc, IID_PPV_ARGS (&m_dsvHeap)));
157+ DX::SetName (m_dsvHeap.Get (), L" Depth Stencil View Descriptor Heap" );
158+
142159 for (UINT n = 0 ; n < c_frameCount; n++)
143160 {
144161 DX::ThrowIfFailed (
@@ -159,12 +176,12 @@ void DX::DeviceResources::CreateWindowSizeDependentResources()
159176 // Wait until all previous GPU work is complete.
160177 WaitForGpu ();
161178
162- // Clear the previous window size specific content.
179+ // Clear the previous window size specific content and update the tracked fence values .
163180 for (UINT n = 0 ; n < c_frameCount; n++)
164181 {
165182 m_renderTargets[n] = nullptr ;
183+ m_fenceValues[n] = m_fenceValues[m_currentFrame];
166184 }
167- m_rtvHeap = nullptr ;
168185
169186 UpdateRenderTargetSize ();
170187
@@ -177,16 +194,13 @@ void DX::DeviceResources::CreateWindowSizeDependentResources()
177194 m_d3dRenderTargetSize.Width = swapDimensions ? m_outputSize.Height : m_outputSize.Width ;
178195 m_d3dRenderTargetSize.Height = swapDimensions ? m_outputSize.Width : m_outputSize.Height ;
179196
197+ UINT backBufferWidth = lround (m_d3dRenderTargetSize.Width );
198+ UINT backBufferHeight = lround (m_d3dRenderTargetSize.Height );
199+
180200 if (m_swapChain != nullptr )
181201 {
182202 // If the swap chain already exists, resize it.
183- HRESULT hr = m_swapChain->ResizeBuffers (
184- c_frameCount,
185- lround (m_d3dRenderTargetSize.Width ),
186- lround (m_d3dRenderTargetSize.Height ),
187- DXGI_FORMAT_B8G8R8A8_UNORM,
188- 0
189- );
203+ HRESULT hr = m_swapChain->ResizeBuffers (c_frameCount, backBufferWidth, backBufferHeight, m_backBufferFormat, 0 );
190204
191205 if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET)
192206 {
@@ -207,15 +221,15 @@ void DX::DeviceResources::CreateWindowSizeDependentResources()
207221 DXGI_SCALING scaling = DisplayMetrics::SupportHighResolutions ? DXGI_SCALING_NONE : DXGI_SCALING_STRETCH;
208222 DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {};
209223
210- swapChainDesc.Width = lround (m_d3dRenderTargetSize. Width ); // Match the size of the window.
211- swapChainDesc.Height = lround (m_d3dRenderTargetSize. Height ) ;
212- swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; // This is the most common swap chain format.
224+ swapChainDesc.Width = backBufferWidth; // Match the size of the window.
225+ swapChainDesc.Height = backBufferHeight ;
226+ swapChainDesc.Format = m_backBufferFormat;
213227 swapChainDesc.Stereo = false ;
214228 swapChainDesc.SampleDesc .Count = 1 ; // Don't use multi-sampling.
215229 swapChainDesc.SampleDesc .Quality = 0 ;
216230 swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
217- swapChainDesc.BufferCount = c_frameCount; // Use triple-buffering to minimize latency.
218- swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; // All Windows Universal apps must use _FLIP_ SwapEffects
231+ swapChainDesc.BufferCount = c_frameCount; // Use triple-buffering to minimize latency.
232+ swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; // All Windows Universal apps must use _FLIP_ SwapEffects.
219233 swapChainDesc.Flags = 0 ;
220234 swapChainDesc.Scaling = scaling;
221235 swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_IGNORE;
@@ -266,51 +280,30 @@ void DX::DeviceResources::CreateWindowSizeDependentResources()
266280
267281 // Create render target views of the swap chain back buffer.
268282 {
269- D3D12_DESCRIPTOR_HEAP_DESC rtvHeapDesc = {};
270- rtvHeapDesc.NumDescriptors = c_frameCount;
271- rtvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
272- rtvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
273- DX::ThrowIfFailed (m_d3dDevice->CreateDescriptorHeap (&rtvHeapDesc, IID_PPV_ARGS (&m_rtvHeap)));
274- m_rtvHeap->SetName (L" Render Target View Descriptor Heap" );
275-
276- m_currentFrame = 0 ;
283+ m_currentFrame = m_swapChain->GetCurrentBackBufferIndex ();
277284 CD3DX12_CPU_DESCRIPTOR_HANDLE rtvDescriptor (m_rtvHeap->GetCPUDescriptorHandleForHeapStart ());
278- m_rtvDescriptorSize = m_d3dDevice->GetDescriptorHandleIncrementSize (D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
279285 for (UINT n = 0 ; n < c_frameCount; n++)
280286 {
281287 DX::ThrowIfFailed (m_swapChain->GetBuffer (n, IID_PPV_ARGS (&m_renderTargets[n])));
282288 m_d3dDevice->CreateRenderTargetView (m_renderTargets[n].Get (), nullptr , rtvDescriptor);
283289 rtvDescriptor.Offset (m_rtvDescriptorSize);
284290
285291 WCHAR name[25 ];
286- swprintf_s (name, L" Render Target %d" , n);
287- m_renderTargets[n]->SetName (name);
292+ if (swprintf_s (name, L" Render Target %u" , n) > 0 )
293+ {
294+ DX::SetName (m_renderTargets[n].Get (), name);
295+ }
288296 }
289297 }
290298
291- // Create a depth stencil view.
299+ // Create a depth stencil and view.
292300 {
293- D3D12_DESCRIPTOR_HEAP_DESC dsvHeapDesc = {};
294- dsvHeapDesc.NumDescriptors = 1 ;
295- dsvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV;
296- dsvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
297- ThrowIfFailed (m_d3dDevice->CreateDescriptorHeap (&dsvHeapDesc, IID_PPV_ARGS (&m_dsvHeap)));
298-
299301 D3D12_HEAP_PROPERTIES depthHeapProperties = CD3DX12_HEAP_PROPERTIES (D3D12_HEAP_TYPE_DEFAULT);
300- D3D12_RESOURCE_DESC depthResourceDesc = CD3DX12_RESOURCE_DESC::Tex2D (
301- DXGI_FORMAT_D32_FLOAT,
302- static_cast <UINT>(m_d3dRenderTargetSize.Width ),
303- static_cast <UINT>(m_d3dRenderTargetSize.Height ),
304- 1 ,
305- 0 ,
306- 1 ,
307- 0 ,
308- D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL);
309-
310- D3D12_CLEAR_VALUE depthOptimizedClearValue = {};
311- depthOptimizedClearValue.Format = DXGI_FORMAT_D32_FLOAT;
312- depthOptimizedClearValue.DepthStencil .Depth = 1 .0f ;
313- depthOptimizedClearValue.DepthStencil .Stencil = 0 ;
302+
303+ D3D12_RESOURCE_DESC depthResourceDesc = CD3DX12_RESOURCE_DESC::Tex2D (m_depthBufferFormat, backBufferWidth, backBufferHeight);
304+ depthResourceDesc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;
305+
306+ CD3DX12_CLEAR_VALUE depthOptimizedClearValue (m_depthBufferFormat, 1 .0f , 0 );
314307
315308 ThrowIfFailed (m_d3dDevice->CreateCommittedResource (
316309 &depthHeapProperties,
@@ -321,25 +314,21 @@ void DX::DeviceResources::CreateWindowSizeDependentResources()
321314 IID_PPV_ARGS (&m_depthStencil)
322315 ));
323316
317+ DX::SetName (m_depthStencil.Get (), L" Depth Buffer" );
318+
324319 D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc = {};
325- dsvDesc.Format = DXGI_FORMAT_D32_FLOAT ;
320+ dsvDesc.Format = m_depthBufferFormat ;
326321 dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
327322 dsvDesc.Flags = D3D12_DSV_FLAG_NONE;
328323
329324 m_d3dDevice->CreateDepthStencilView (m_depthStencil.Get (), &dsvDesc, m_dsvHeap->GetCPUDescriptorHandleForHeapStart ());
330325 }
331326
332- // All pending GPU work was already finished. Update the tracked fence values
333- // to the last value signaled.
334- for (UINT n = 0 ; n < c_frameCount; n++)
335- {
336- m_fenceValues[n] = m_fenceValues[m_currentFrame];
337- }
338-
339327 // Set the 3D rendering viewport to target the entire window.
340328 m_screenViewport = { 0 .0f , 0 .0f , m_d3dRenderTargetSize.Width , m_d3dRenderTargetSize.Height , 0 .0f , 1 .0f };
341329}
342330
331+ // Determine the dimensions of the render target and whether it will be scaled down.
343332void DX::DeviceResources::UpdateRenderTargetSize ()
344333{
345334 m_effectiveDpi = m_dpi;
@@ -427,11 +416,8 @@ void DX::DeviceResources::ValidateDevice()
427416
428417 // Next, get the information for the current default adapter.
429418
430- ComPtr<IDXGIFactory2> currentFactory;
431- DX::ThrowIfFailed (CreateDXGIFactory1 (IID_PPV_ARGS (¤tFactory)));
432-
433419 ComPtr<IDXGIAdapter1> currentDefaultAdapter;
434- DX::ThrowIfFailed (currentFactory-> EnumAdapters1 ( 0 , ¤tDefaultAdapter) );
420+ GetHardwareAdapter ( ¤tDefaultAdapter);
435421
436422 DXGI_ADAPTER_DESC currentDesc;
437423 DX::ThrowIfFailed (currentDefaultAdapter->GetDesc (¤tDesc));
@@ -491,7 +477,7 @@ void DX::DeviceResources::MoveToNextFrame()
491477 DX::ThrowIfFailed (m_commandQueue->Signal (m_fence.Get (), currentFenceValue));
492478
493479 // Advance the frame index.
494- m_currentFrame = (m_currentFrame + 1 ) % c_frameCount ;
480+ m_currentFrame = m_swapChain-> GetCurrentBackBufferIndex () ;
495481
496482 // Check to see if the next frame is ready to start.
497483 if (m_fence->GetCompletedValue () < m_fenceValues[m_currentFrame])
@@ -561,12 +547,12 @@ DXGI_MODE_ROTATION DX::DeviceResources::ComputeDisplayRotation()
561547
562548// This method acquires the first available hardware adapter that supports Direct3D 12.
563549// If no such adapter can be found, *ppAdapter will be set to nullptr.
564- void DX::DeviceResources::GetHardwareAdapter (IDXGIFactory4* pFactory, IDXGIAdapter1** ppAdapter)
550+ void DX::DeviceResources::GetHardwareAdapter (IDXGIAdapter1** ppAdapter)
565551{
566552 ComPtr<IDXGIAdapter1> adapter;
567553 *ppAdapter = nullptr ;
568554
569- for (UINT adapterIndex = 0 ; DXGI_ERROR_NOT_FOUND != pFactory ->EnumAdapters1 (adapterIndex, &adapter); ++adapterIndex )
555+ for (UINT adapterIndex = 0 ; DXGI_ERROR_NOT_FOUND != m_dxgiFactory ->EnumAdapters1 (adapterIndex, &adapter); adapterIndex++ )
570556 {
571557 DXGI_ADAPTER_DESC1 desc;
572558 adapter->GetDesc1 (&desc);
0 commit comments