Pārlūkot izejas kodu

D3D12: MSAA WIP.

Branimir Karadžić 7 gadi atpakaļ
vecāks
revīzija
2ce838061b
3 mainītis faili ar 135 papildinājumiem un 36 dzēšanām
  1. 14 0
      src/dxgi.cpp
  2. 13 0
      src/renderer_d3d.h
  3. 108 36
      src/renderer_d3d12.cpp

+ 14 - 0
src/dxgi.cpp

@@ -395,6 +395,8 @@ namespace bgfx
 		}
 	}
 
+	static const GUID IID_ID3D12CommandQueue = { 0x0ec870a6, 0x5d7e, 0x4c22, { 0x8c, 0xfc, 0x5b, 0xaa, 0xe0, 0x76, 0x16, 0xed } };
+
 	HRESULT Dxgi::createSwapChain(IUnknown* _device, const SwapChainDesc& _scd, SwapChainI** _swapChain)
 	{
 		HRESULT hr = S_OK;
@@ -429,6 +431,12 @@ namespace bgfx
 			| (allowTearing ? DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING : 0)
 			;
 
+		if (isType(_device, IID_ID3D12CommandQueue) )
+		{
+			scd.SampleDesc.Count   = 1;
+			scd.SampleDesc.Quality = 0;
+		}
+
 		hr = m_factory->CreateSwapChain(
 				  _device
 				, &scd
@@ -448,6 +456,12 @@ namespace bgfx
 		scd.AlphaMode   = _scd.alphaMode;
 		scd.Flags       = _scd.flags;
 
+		if (isType(_device, IID_ID3D12CommandQueue) )
+		{
+			scd.SampleDesc.Count   = 1;
+			scd.SampleDesc.Quality = 0;
+		}
+
 		if (NULL == _scd.ndt)
 		{
 			hr = m_factory->CreateSwapChainForCoreWindow(

+ 13 - 0
src/renderer_d3d.h

@@ -111,6 +111,19 @@ namespace bgfx
 #define D3DCOLOR_COMPUTE toRgba8(0xa7, 0xdb, 0xd8, 0xff)
 #define D3DCOLOR_MARKER  toRgba8(0xff, 0x00, 0x00, 0xff)
 
+	inline bool isType(IUnknown* _interface, const GUID& _id)
+	{
+		IUnknown* out;
+		HRESULT hr = _interface->QueryInterface(_id, (void**)&out);
+		if (FAILED(hr) )
+		{
+			return false;
+		}
+
+		out->Release();
+		return true;
+	}
+
 	inline int getRefCount(IUnknown* _interface)
 	{
 		_interface->AddRef();

+ 108 - 36
src/renderer_d3d12.cpp

@@ -847,13 +847,14 @@ namespace bgfx { namespace d3d12
 
 			if (NULL == g_platformData.backBuffer)
 			{
+				updateMsaa();
+
 				bx::memSet(&m_scd, 0, sizeof(m_scd) );
 				m_scd.width  = _init.resolution.width;
 				m_scd.height = _init.resolution.height;
 				m_scd.format = DXGI_FORMAT_R8G8B8A8_UNORM;
 				m_scd.stereo  = false;
-				m_scd.sampleDesc.Count   = 1;
-				m_scd.sampleDesc.Quality = 0;
+				m_scd.sampleDesc  = s_msaa[(_init.resolution.reset&BGFX_RESET_MSAA_MASK)>>BGFX_RESET_MSAA_SHIFT];
 				m_scd.bufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
 				m_scd.bufferCount = bx::uint32_min(BX_COUNTOF(m_backBufferColor), 4);
 				m_scd.scaling = 0 == g_platformData.ndt
@@ -870,15 +871,13 @@ namespace bgfx { namespace d3d12
 				m_backBufferColorIdx = m_scd.bufferCount-1;
 
 				hr = m_dxgi.createSwapChain(
-#if BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT
-					  m_cmd.m_commandQueue
-#else
-					  m_device
-#endif // BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT
+					  getDeviceForSwapChain()
 					, m_scd
 					, &m_swapChain
 					);
 
+				m_msaaRt = NULL;
+
 				if (FAILED(hr) )
 				{
 					BX_TRACE("Init error: Unable to create Direct3D12 swap chain.");
@@ -1323,6 +1322,7 @@ namespace bgfx { namespace d3d12
 			}
 
 			DX_RELEASE(m_rootSignature, 0);
+			DX_RELEASE(m_msaaRt, 0);
 			DX_RELEASE(m_swapChain, 0);
 
 			m_cmd.shutdown();
@@ -1899,27 +1899,39 @@ 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_msaaRt)
 			{
-				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(m_backBufferColor[ii], 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(m_backBufferColor[ii], 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);
+					}
+				}
+			}
+			else
+			{
+				for (uint32_t ii = 0, num = m_scd.bufferCount; ii < num; ++ii)
+				{
+					D3D12_CPU_DESCRIPTOR_HANDLE handle = getCPUHandleHeapStart(m_rtvDescriptorHeap);
+					handle.ptr += ii * rtvDescriptorSize;
+					m_device->CreateRenderTargetView(m_msaaRt, NULL, handle);
 				}
 			}
 
@@ -1964,6 +1976,15 @@ namespace bgfx { namespace d3d12
 				m_frameBuffers[ii].postReset();
 			}
 
+			if (NULL != m_msaaRt)
+			{
+				setResourceBarrier(m_commandList
+					, m_msaaRt
+					, D3D12_RESOURCE_STATE_COMMON
+					, D3D12_RESOURCE_STATE_RENDER_TARGET
+					);
+			}
+
 //			capturePostReset();
 		}
 
@@ -1988,13 +2009,11 @@ namespace bgfx { namespace d3d12
 				data.Flags = D3D12_MULTISAMPLE_QUALITY_LEVELS_FLAG_NONE;
 				HRESULT hr = m_device->CheckFeatureSupport(D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS, &data, sizeof(data) );
 
-data.NumQualityLevels = 0;
-
 				if (SUCCEEDED(hr)
 				&&  0 < data.NumQualityLevels)
 				{
 					s_msaa[ii].Count   = data.SampleCount;
-					s_msaa[ii].Quality = data.NumQualityLevels - 1;
+					s_msaa[ii].Quality = DXGI_STANDARD_MULTISAMPLE_QUALITY_PATTERN;
 					last = ii;
 				}
 				else
@@ -2004,6 +2023,15 @@ data.NumQualityLevels = 0;
 			}
 		}
 
+		IUnknown* getDeviceForSwapChain() const
+		{
+#	if BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT
+			return m_cmd.m_commandQueue;
+#	else
+			return m_device;
+#	endif // BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT
+		}
+
 		bool updateResolution(const Resolution& _resolution)
 		{
 			if (!!(_resolution.reset & BGFX_RESET_MAXANISOTROPY) )
@@ -2052,6 +2080,8 @@ data.NumQualityLevels = 0;
 
 				preReset();
 
+				DX_RELEASE(m_msaaRt, 0);
+
 				BX_UNUSED(resize);
 				if (resize)
 				{
@@ -2090,17 +2120,38 @@ data.NumQualityLevels = 0;
 
 					HRESULT hr;
 					hr = m_dxgi.createSwapChain(
-#	if BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT
-							  m_cmd.m_commandQueue
-#	else
-							  m_device
-#	endif // BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT
-							, m_scd
-							, &m_swapChain
-							);
+						  getDeviceForSwapChain()
+						, m_scd
+						, &m_swapChain
+						);
 					BGFX_FATAL(SUCCEEDED(hr), bgfx::Fatal::UnableToInitialize, "Failed to create swap chain.");
 				}
 
+				if (BX_ENABLED(false)
+				&&  1 < m_scd.sampleDesc.Count)
+				{
+					D3D12_RESOURCE_DESC resourceDesc;
+					resourceDesc.Dimension  = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
+					resourceDesc.Alignment  = 0;
+					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);
+				}
+
 				postReset();
 			}
 
@@ -3051,6 +3102,7 @@ data.NumQualityLevels = 0;
 		D3D12_FEATURE_DATA_D3D12_OPTIONS m_options;
 
 		Dxgi::SwapChainI* m_swapChain;
+		ID3D12Resource*   m_msaaRt;
 
 #if BX_PLATFORM_WINDOWS
 		ID3D12InfoQueue* m_infoQueue;
@@ -4813,7 +4865,7 @@ data.NumQualityLevels = 0;
 
 		HRESULT hr;
 		hr = s_renderD3D12->m_dxgi.createSwapChain(
-				  s_renderD3D12->m_cmd.m_commandQueue
+				  s_renderD3D12->getDeviceForSwapChain()
 				, scd
 				, &m_swapChain
 				);
@@ -5525,6 +5577,15 @@ data.NumQualityLevels = 0;
 			, D3D12_RESOURCE_STATE_RENDER_TARGET
 			);
 
+		if (NULL != m_msaaRt)
+		{
+			setResourceBarrier(m_commandList
+				, m_msaaRt
+				, D3D12_RESOURCE_STATE_RESOLVE_SOURCE
+				, D3D12_RESOURCE_STATE_RENDER_TARGET
+				);
+		}
+
 		if (0 == (_render->m_debug&BGFX_DEBUG_IFH) )
 		{
 			setFrameBuffer(BGFX_INVALID_HANDLE, true);
@@ -6448,6 +6509,17 @@ data.NumQualityLevels = 0;
 
 		m_commandList->OMSetRenderTargets(0, NULL, false, NULL);
 
+		if (NULL != m_msaaRt)
+		{
+			setResourceBarrier(m_commandList
+				, m_msaaRt
+				, D3D12_RESOURCE_STATE_RENDER_TARGET
+				, D3D12_RESOURCE_STATE_RESOLVE_SOURCE
+				);
+
+			m_commandList->ResolveSubresource(m_backBufferColor[m_backBufferColorIdx], 0, m_msaaRt, 0, m_scd.format);
+		}
+
 		setResourceBarrier(m_commandList
 			, m_backBufferColor[m_backBufferColorIdx]
 			, D3D12_RESOURCE_STATE_RENDER_TARGET