Procházet zdrojové kódy

D3D11/12: Allow headless device creation.

Branimir Karadžić před 7 roky
rodič
revize
1fb2ec7f2b
4 změnil soubory, kde provedl 187 přidání a 161 odebrání
  1. 2 3
      src/bgfx.cpp
  2. 1 1
      src/dxgi.cpp
  3. 41 38
      src/renderer_d3d11.cpp
  4. 143 119
      src/renderer_d3d12.cpp

+ 2 - 3
src/bgfx.cpp

@@ -2879,8 +2879,7 @@ namespace bgfx
 		&&  NULL == g_platformData.backBufferDS
 		   )
 		{
-			BX_TRACE("bgfx platform data like window handle or backbuffer must be set.");
-			goto error;
+			BX_TRACE("bgfx platform data like window handle or backbuffer is not set, creating headless device.");
 		}
 
 		bx::memSet(&g_caps, 0, sizeof(g_caps) );
@@ -2921,7 +2920,7 @@ namespace bgfx
 			return true;
 		}
 
-error:
+//error:
 		BX_TRACE("Init failed.");
 
 		switch (errorState)

+ 1 - 1
src/dxgi.cpp

@@ -240,7 +240,7 @@ namespace bgfx
 
 				IDXGIOutput* output;
 				for (uint32_t jj = 0
-					; DXGI_ERROR_NOT_FOUND != adapter->EnumOutputs(jj, &output)
+					; SUCCEEDED(adapter->EnumOutputs(jj, &output) )
 					; ++jj
 					)
 				{

+ 41 - 38
src/renderer_d3d11.cpp

@@ -992,50 +992,53 @@ namespace bgfx { namespace d3d11
 					m_scd.ndt         = g_platformData.ndt;
 					m_scd.windowed    = true;
 
-					hr = m_dxgi.createSwapChain(m_device
-						, m_scd
-						, &m_swapChain
-						);
-
 					m_msaaRt = NULL;
 
-					if (FAILED(hr) )
+					if (NULL != m_scd.nwh)
 					{
-						// DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL is not available on win7
-						// Try again with DXGI_SWAP_EFFECT_DISCARD
-						m_swapEffect      = DXGI_SWAP_EFFECT_DISCARD;
-						m_swapBufferCount = 1;
-
-						m_scd.bufferCount = m_swapBufferCount;
-						m_scd.swapEffect  = m_swapEffect;
 						hr = m_dxgi.createSwapChain(m_device
 							, m_scd
 							, &m_swapChain
 							);
-					}
-					else
-					{
-						m_resolution       = _init.resolution;
-						m_resolution.reset = _init.resolution.reset & (~BGFX_RESET_INTERNAL_FORCE);
 
-						m_textVideoMem.resize(false, _init.resolution.width, _init.resolution.height);
-						m_textVideoMem.clear();
-					}
+						if (FAILED(hr) )
+						{
+							// DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL is not available on win7
+							// Try again with DXGI_SWAP_EFFECT_DISCARD
+							m_swapEffect      = DXGI_SWAP_EFFECT_DISCARD;
+							m_swapBufferCount = 1;
+
+							m_scd.bufferCount = m_swapBufferCount;
+							m_scd.swapEffect  = m_swapEffect;
+							hr = m_dxgi.createSwapChain(m_device
+								, m_scd
+								, &m_swapChain
+								);
+						}
+						else
+						{
+							m_resolution       = _init.resolution;
+							m_resolution.reset = _init.resolution.reset & (~BGFX_RESET_INTERNAL_FORCE);
 
-					if (1 < m_scd.sampleDesc.Count)
-					{
-						D3D11_TEXTURE2D_DESC desc;
-						desc.Width      = m_scd.width;
-						desc.Height     = m_scd.height;
-						desc.MipLevels  = 1;
-						desc.ArraySize  = 1;
-						desc.Format     = m_scd.format;
-						desc.SampleDesc = m_scd.sampleDesc;
-						desc.Usage      = D3D11_USAGE_DEFAULT;
-						desc.BindFlags  = D3D11_BIND_RENDER_TARGET;
-						desc.CPUAccessFlags = 0;
-						desc.MiscFlags      = 0;
-						DX_CHECK(m_device->CreateTexture2D(&desc, NULL, &m_msaaRt) );
+							m_textVideoMem.resize(false, _init.resolution.width, _init.resolution.height);
+							m_textVideoMem.clear();
+						}
+
+						if (1 < m_scd.sampleDesc.Count)
+						{
+							D3D11_TEXTURE2D_DESC desc;
+							desc.Width      = m_scd.width;
+							desc.Height     = m_scd.height;
+							desc.MipLevels  = 1;
+							desc.ArraySize  = 1;
+							desc.Format     = m_scd.format;
+							desc.SampleDesc = m_scd.sampleDesc;
+							desc.Usage      = D3D11_USAGE_DEFAULT;
+							desc.BindFlags  = D3D11_BIND_RENDER_TARGET;
+							desc.CPUAccessFlags = 0;
+							desc.MiscFlags      = 0;
+							DX_CHECK(m_device->CreateTexture2D(&desc, NULL, &m_msaaRt) );
+						}
 					}
 
 #if BX_PLATFORM_WINDOWS
@@ -2167,8 +2170,7 @@ namespace bgfx { namespace d3d11
 
 		void flip() override
 		{
-			if (NULL != m_swapChain
-			&&  !m_lost)
+			if (!m_lost)
 			{
 				HRESULT hr = S_OK;
 				uint32_t syncInterval = BX_ENABLED(!BX_PLATFORM_WINDOWS)
@@ -2183,7 +2185,8 @@ namespace bgfx { namespace d3d11
 
 				if (SUCCEEDED(hr) )
 				{
-					if (m_needPresent)
+					if (NULL != m_swapChain
+					&&  m_needPresent)
 					{
 						hr = m_swapChain->Present(syncInterval, 0);
 

+ 143 - 119
src/renderer_d3d12.cpp

@@ -615,6 +615,7 @@ namespace bgfx { namespace d3d12
 			, m_renderdocdll(NULL)
 			, m_winPixEvent(NULL)
 			, m_featureLevel(D3D_FEATURE_LEVEL(0) )
+			, m_swapChain(NULL)
 			, m_wireframe(false)
 			, m_lost(false)
 			, m_maxAnisotropy(1)
@@ -890,51 +891,55 @@ namespace bgfx { namespace d3d12
 
 				m_backBufferColorIdx = m_scd.bufferCount-1;
 
-				hr = m_dxgi.createSwapChain(
-					  getDeviceForSwapChain()
-					, m_scd
-					, &m_swapChain
-					);
-
 				m_msaaRt = NULL;
 
-				if (FAILED(hr) )
-				{
-					BX_TRACE("Init error: Unable to create Direct3D12 swap chain.");
-					goto error;
-				}
-				else
+				if (NULL != m_scd.nwh)
 				{
-					m_resolution       = _init.resolution;
-					m_resolution.reset = _init.resolution.reset & (~BGFX_RESET_INTERNAL_FORCE);
+					hr = m_dxgi.createSwapChain(
+						  getDeviceForSwapChain()
+						, m_scd
+						, &m_swapChain
+						);
 
-					m_textVideoMem.resize(false, _init.resolution.width, _init.resolution.height);
-					m_textVideoMem.clear();
-				}
 
-				if (1 < m_scd.sampleDesc.Count)
-				{
-					D3D12_RESOURCE_DESC resourceDesc;
-					resourceDesc.Dimension  = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
-					resourceDesc.Alignment  = D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT;
-					resourceDesc.Width      = m_scd.width;
-					resourceDesc.Height     = m_scd.height;
-					resourceDesc.MipLevels  = 1;
-					resourceDesc.Format     = m_scd.format;
-					resourceDesc.SampleDesc = m_scd.sampleDesc;
-					resourceDesc.Layout     = D3D12_TEXTURE_LAYOUT_UNKNOWN;
-					resourceDesc.Flags      = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
-					resourceDesc.DepthOrArraySize = 1;
-
-					D3D12_CLEAR_VALUE clearValue;
-					clearValue.Format   = resourceDesc.Format;
-					clearValue.Color[0] = 0.0f;
-					clearValue.Color[1] = 0.0f;
-					clearValue.Color[2] = 0.0f;
-					clearValue.Color[3] = 0.0f;
-
-					m_msaaRt = createCommittedResource(m_device, HeapProperty::Texture, &resourceDesc, &clearValue, true);
-					setDebugObjectName(m_msaaRt, "MSAA Backbuffer");
+					if (FAILED(hr) )
+					{
+						BX_TRACE("Init error: Unable to create Direct3D12 swap chain.");
+						goto error;
+					}
+					else
+					{
+						m_resolution       = _init.resolution;
+						m_resolution.reset = _init.resolution.reset & (~BGFX_RESET_INTERNAL_FORCE);
+
+						m_textVideoMem.resize(false, _init.resolution.width, _init.resolution.height);
+						m_textVideoMem.clear();
+					}
+
+					if (1 < m_scd.sampleDesc.Count)
+					{
+						D3D12_RESOURCE_DESC resourceDesc;
+						resourceDesc.Dimension  = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
+						resourceDesc.Alignment  = D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT;
+						resourceDesc.Width      = m_scd.width;
+						resourceDesc.Height     = m_scd.height;
+						resourceDesc.MipLevels  = 1;
+						resourceDesc.Format     = m_scd.format;
+						resourceDesc.SampleDesc = m_scd.sampleDesc;
+						resourceDesc.Layout     = D3D12_TEXTURE_LAYOUT_UNKNOWN;
+						resourceDesc.Flags      = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
+						resourceDesc.DepthOrArraySize = 1;
+
+						D3D12_CLEAR_VALUE clearValue;
+						clearValue.Format   = resourceDesc.Format;
+						clearValue.Color[0] = 0.0f;
+						clearValue.Color[1] = 0.0f;
+						clearValue.Color[2] = 0.0f;
+						clearValue.Color[3] = 0.0f;
+
+						m_msaaRt = createCommittedResource(m_device, HeapProperty::Texture, &resourceDesc, &clearValue, true);
+						setDebugObjectName(m_msaaRt, "MSAA Backbuffer");
+					}
 				}
 			}
 
@@ -1406,8 +1411,7 @@ namespace bgfx { namespace d3d12
 
 		void flip() override
 		{
-			if (NULL != m_swapChain
-			&&  !m_lost)
+			if (!m_lost)
 			{
 				int64_t start = bx::getHPCounter();
 
@@ -1422,7 +1426,8 @@ namespace bgfx { namespace d3d12
 					hr = frameBuffer.present(syncInterval, flags);
 				}
 
-				if (SUCCEEDED(hr) )
+				if (SUCCEEDED(hr)
+				&&  NULL != m_swapChain)
 				{
 					hr = m_swapChain->Present(syncInterval, flags);
 				}
@@ -1896,7 +1901,7 @@ namespace bgfx { namespace d3d12
 			m_commandList->SetGraphicsRootConstantBufferView(Rdt::CBV, gpuAddress);
 
 			TextureD3D12& texture = m_textures[_blitter.m_texture.idx];
-			uint32_t samplerFlags[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS] = { texture.m_flags & BGFX_SAMPLER_BITS_MASK };
+			uint32_t samplerFlags[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS] = { uint32_t(texture.m_flags & BGFX_SAMPLER_BITS_MASK) };
 			uint16_t samplerStateIdx = getSamplerState(samplerFlags, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, NULL);
 			m_commandList->SetGraphicsRootDescriptorTable(Rdt::Sampler, m_samplerAllocator.get(samplerStateIdx) );
 			D3D12_GPU_DESCRIPTOR_HANDLE srvHandle;
@@ -1942,15 +1947,18 @@ namespace bgfx { namespace d3d12
 		{
 			finishAll();
 
-			for (uint32_t ii = 0, num = m_scd.bufferCount; ii < num; ++ii)
+			if (NULL != m_swapChain)
 			{
+				for (uint32_t ii = 0, num = m_scd.bufferCount; ii < num; ++ii)
+				{
 #if BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT
-				DX_RELEASE(m_backBufferColor[ii], num-1-ii);
+					DX_RELEASE(m_backBufferColor[ii], num-1-ii);
 #else
-				DX_RELEASE(m_backBufferColor[ii], 1);
+					DX_RELEASE(m_backBufferColor[ii], 1);
 #endif // BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT
+				}
+				DX_RELEASE(m_backBufferDepthStencil, 0);
 			}
-			DX_RELEASE(m_backBufferDepthStencil, 0);
 
 			for (uint32_t ii = 0; ii < BX_COUNTOF(m_frameBuffers); ++ii)
 			{
@@ -1968,33 +1976,36 @@ namespace bgfx { namespace d3d12
 
 			uint32_t rtvDescriptorSize = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
 
-			for (uint32_t ii = 0, num = m_scd.bufferCount; ii < num; ++ii)
+			if (NULL != m_swapChain)
 			{
-				D3D12_CPU_DESCRIPTOR_HANDLE handle = getCPUHandleHeapStart(m_rtvDescriptorHeap);
-				handle.ptr += ii * rtvDescriptorSize;
-				DX_CHECK(m_swapChain->GetBuffer(ii
-					, IID_ID3D12Resource
-					, (void**)&m_backBufferColor[ii]
-					) );
-				m_device->CreateRenderTargetView(
-					  NULL == m_msaaRt
-					? m_backBufferColor[ii]
-					: m_msaaRt
-					, NULL
-					, handle
-					);
-
-				if (BX_ENABLED(BX_PLATFORM_XBOXONE) )
+				for (uint32_t ii = 0, num = m_scd.bufferCount; ii < num; ++ii)
 				{
-					ID3D12Resource* resource = m_backBufferColor[ii];
+					D3D12_CPU_DESCRIPTOR_HANDLE handle = getCPUHandleHeapStart(m_rtvDescriptorHeap);
+					handle.ptr += ii * rtvDescriptorSize;
+					DX_CHECK(m_swapChain->GetBuffer(ii
+						, IID_ID3D12Resource
+						, (void**)&m_backBufferColor[ii]
+						) );
+					m_device->CreateRenderTargetView(
+						  NULL == m_msaaRt
+						? m_backBufferColor[ii]
+						: m_msaaRt
+						, NULL
+						, handle
+						);
 
-					BX_CHECK(DXGI_FORMAT_R8G8B8A8_UNORM == m_scd.format, "");
-					const uint32_t size = m_scd.width*m_scd.height*4;
+					if (BX_ENABLED(BX_PLATFORM_XBOXONE) )
+					{
+						ID3D12Resource* resource = m_backBufferColor[ii];
+
+						BX_CHECK(DXGI_FORMAT_R8G8B8A8_UNORM == m_scd.format, "");
+						const uint32_t size = m_scd.width*m_scd.height*4;
 
-					void* ptr;
-					DX_CHECK(resource->Map(0, NULL, &ptr) );
-					bx::memSet(ptr, 0, size);
-					resource->Unmap(0, NULL);
+						void* ptr;
+						DX_CHECK(resource->Map(0, NULL, &ptr) );
+						bx::memSet(ptr, 0, size);
+						resource->Unmap(0, NULL);
+					}
 				}
 			}
 
@@ -2138,58 +2149,64 @@ namespace bgfx { namespace d3d12
 
 				DX_RELEASE(m_msaaRt, 0);
 
-				if (resize)
+				if (NULL == m_swapChain)
 				{
-#if BX_PLATFORM_WINDOWS
-					uint32_t nodeMask[] = { 1, 1, 1, 1 };
-					BX_STATIC_ASSERT(BX_COUNTOF(m_backBufferColor) == BX_COUNTOF(nodeMask) );
-					IUnknown* presentQueue[] ={ m_cmd.m_commandQueue, m_cmd.m_commandQueue, m_cmd.m_commandQueue, m_cmd.m_commandQueue };
-					BX_STATIC_ASSERT(BX_COUNTOF(m_backBufferColor) == BX_COUNTOF(presentQueue) );
-					DX_CHECK(m_dxgi.resizeBuffers(m_swapChain, m_scd, nodeMask, presentQueue) );
-#elif BX_PLATFORM_WINRT
-					DX_CHECK(m_dxgi.resizeBuffers(m_swapChain, m_scd);
-					m_backBufferColorIdx = m_scd.bufferCount-1;
-#endif // BX_PLATFORM_WINDOWS
 				}
 				else
 				{
-					updateMsaa(m_scd.format);
-					m_scd.sampleDesc = s_msaa[(m_resolution.reset&BGFX_RESET_MSAA_MASK)>>BGFX_RESET_MSAA_SHIFT];
+					if (resize)
+					{
+#if BX_PLATFORM_WINDOWS
+						uint32_t nodeMask[] = { 1, 1, 1, 1 };
+						BX_STATIC_ASSERT(BX_COUNTOF(m_backBufferColor) == BX_COUNTOF(nodeMask) );
+						IUnknown* presentQueue[] ={ m_cmd.m_commandQueue, m_cmd.m_commandQueue, m_cmd.m_commandQueue, m_cmd.m_commandQueue };
+						BX_STATIC_ASSERT(BX_COUNTOF(m_backBufferColor) == BX_COUNTOF(presentQueue) );
+						DX_CHECK(m_dxgi.resizeBuffers(m_swapChain, m_scd, nodeMask, presentQueue) );
+#elif BX_PLATFORM_WINRT
+						DX_CHECK(m_dxgi.resizeBuffers(m_swapChain, m_scd);
+						m_backBufferColorIdx = m_scd.bufferCount-1;
+#endif // BX_PLATFORM_WINDOWS
+					}
+					else
+					{
+						updateMsaa(m_scd.format);
+						m_scd.sampleDesc = s_msaa[(m_resolution.reset&BGFX_RESET_MSAA_MASK)>>BGFX_RESET_MSAA_SHIFT];
 
-					DX_RELEASE(m_swapChain, 0);
+						DX_RELEASE(m_swapChain, 0);
 
-					HRESULT hr;
-					hr = m_dxgi.createSwapChain(
-						  getDeviceForSwapChain()
-						, m_scd
-						, &m_swapChain
-						);
-					BGFX_FATAL(SUCCEEDED(hr), bgfx::Fatal::UnableToInitialize, "Failed to create swap chain.");
-				}
+						HRESULT hr;
+						hr = m_dxgi.createSwapChain(
+							  getDeviceForSwapChain()
+							, m_scd
+							, &m_swapChain
+							);
+						BGFX_FATAL(SUCCEEDED(hr), bgfx::Fatal::UnableToInitialize, "Failed to create swap chain.");
+					}
 
-				if (1 < m_scd.sampleDesc.Count)
-				{
-					D3D12_RESOURCE_DESC resourceDesc;
-					resourceDesc.Dimension  = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
-					resourceDesc.Alignment  = D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT;
-					resourceDesc.Width      = m_scd.width;
-					resourceDesc.Height     = m_scd.height;
-					resourceDesc.MipLevels  = 1;
-					resourceDesc.Format     = m_scd.format;
-					resourceDesc.SampleDesc = m_scd.sampleDesc;
-					resourceDesc.Layout     = D3D12_TEXTURE_LAYOUT_UNKNOWN;
-					resourceDesc.Flags      = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
-					resourceDesc.DepthOrArraySize = 1;
-
-					D3D12_CLEAR_VALUE clearValue;
-					clearValue.Format   = resourceDesc.Format;
-					clearValue.Color[0] = 0.0f;
-					clearValue.Color[1] = 0.0f;
-					clearValue.Color[2] = 0.0f;
-					clearValue.Color[3] = 0.0f;
-
-					m_msaaRt = createCommittedResource(m_device, HeapProperty::Texture, &resourceDesc, &clearValue, true);
-					setDebugObjectName(m_msaaRt, "MSAA Backbuffer");
+					if (1 < m_scd.sampleDesc.Count)
+					{
+						D3D12_RESOURCE_DESC resourceDesc;
+						resourceDesc.Dimension  = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
+						resourceDesc.Alignment  = D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT;
+						resourceDesc.Width      = m_scd.width;
+						resourceDesc.Height     = m_scd.height;
+						resourceDesc.MipLevels  = 1;
+						resourceDesc.Format     = m_scd.format;
+						resourceDesc.SampleDesc = m_scd.sampleDesc;
+						resourceDesc.Layout     = D3D12_TEXTURE_LAYOUT_UNKNOWN;
+						resourceDesc.Flags      = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
+						resourceDesc.DepthOrArraySize = 1;
+
+						D3D12_CLEAR_VALUE clearValue;
+						clearValue.Format   = resourceDesc.Format;
+						clearValue.Color[0] = 0.0f;
+						clearValue.Color[1] = 0.0f;
+						clearValue.Color[2] = 0.0f;
+						clearValue.Color[3] = 0.0f;
+
+						m_msaaRt = createCommittedResource(m_device, HeapProperty::Texture, &resourceDesc, &clearValue, true);
+						setDebugObjectName(m_msaaRt, "MSAA Backbuffer");
+					}
 				}
 
 				postReset();
@@ -5599,7 +5616,14 @@ namespace bgfx { namespace d3d12
 			);
 
 #if BX_PLATFORM_WINDOWS
-		m_backBufferColorIdx = m_swapChain->GetCurrentBackBufferIndex();
+		if (NULL != m_swapChain)
+		{
+			m_backBufferColorIdx = m_swapChain->GetCurrentBackBufferIndex();
+		}
+		else
+		{
+			m_backBufferColorIdx = (m_backBufferColorIdx+1) % BX_COUNTOF(m_scratchBuffer);
+		}
 #else
 		m_backBufferColorIdx = (m_backBufferColorIdx+1) % m_scd.bufferCount;
 #endif // BX_PLATFORM_WINDOWS
@@ -5631,7 +5655,7 @@ namespace bgfx { namespace d3d12
 				, D3D12_RESOURCE_STATE_RESOLVE_DEST
 				);
 		}
-		else
+		else if (NULL != m_swapChain)
 		{
 			setResourceBarrier(m_commandList
 				, m_backBufferColor[m_backBufferColorIdx]
@@ -6579,7 +6603,7 @@ namespace bgfx { namespace d3d12
 				, D3D12_RESOURCE_STATE_PRESENT
 				);
 		}
-		else
+		else if (NULL != m_swapChain)
 		{
 			setResourceBarrier(m_commandList
 				, m_backBufferColor[m_backBufferColorIdx]