Explorar o código

DX11 clearing render target sub-area works

Marko Pintera %!s(int64=12) %!d(string=hai) anos
pai
achega
f49f30f089

+ 1 - 0
BansheeForwardRenderer/Source/BsForwardRenderer.cpp

@@ -77,6 +77,7 @@ namespace BansheeEngine
 			RenderTargetPtr target = camerasPerTarget.target;
 			const Vector<HCamera>::type& cameras = camerasPerTarget.cameras;
 
+			coreAccessor.setRenderTarget(target);
 			coreAccessor.beginFrame();
 
 			for(auto& camera : cameras)

+ 4 - 3
CamelotClient/CamelotClient.cpp

@@ -36,8 +36,8 @@
 #include "CmRTTIType.h"
 #include "CmCursor.h"
 
-//#define DX11
-#define DX9
+#define DX11
+//#define DX9
 //#define GL
 
 using namespace CamelotFramework;
@@ -274,7 +274,7 @@ int CALLBACK WinMain(
 	/* 								EDITOR INIT                      		*/
 	/************************************************************************/
 
-	MainEditorWindow mainWindow(gApplication().getPrimaryWindow());
+	MainEditorWindow* mainWindow = cm_new<MainEditorWindow>(gApplication().getPrimaryWindow());
 	EditorWindowManager::startUp(cm_new<EditorWindowManager>());
 
 	/************************************************************************/
@@ -291,6 +291,7 @@ int CALLBACK WinMain(
 	/************************************************************************/
 
 	EditorWindowManager::shutDown();
+	cm_delete(mainWindow);
 
 	/************************************************************************/
 	/* 							EDITOR SHUTDOWN END                    		*/

+ 8 - 7
CamelotD3D11RenderSystem/Include/CmD3D11RenderUtility.h

@@ -11,7 +11,7 @@ namespace CamelotFramework
 		D3D11RenderUtility(D3D11Device* device);
 		~D3D11RenderUtility();
 
-		void drawClearQuad(float clipLeft, float clipWidth, float clipTop, float clipHeight, UINT32 clearBuffers, const Color& color, float depth, UINT16 stencil);
+		void drawClearQuad(const Rect& screenArea, UINT32 clearBuffers, const Color& color, float depth, UINT16 stencil);
 
 	protected:
 		D3D11Device* mDevice;
@@ -24,11 +24,12 @@ namespace CamelotFramework
 		ID3D11VertexShader* mClearQuadVS;
 		ID3D11PixelShader* mClearQuadPS;
 
-		BlendStatePtr mClearQuadBlendState;
-		RasterizerStatePtr mClearQuadRasterizerState;
-		DepthStencilStatePtr mClearQuadDSState_NoD_NoS;
-		DepthStencilStatePtr mClearQuadDSState_YesD_NoS;
-		DepthStencilStatePtr mClearQuadDSState_YesD_YesS;
-		DepthStencilStatePtr mClearQuadDSState_NoD_YesS;
+		HBlendState mClearQuadBlendStateYesC;
+		HBlendState mClearQuadBlendStateNoC;
+		HRasterizerState mClearQuadRasterizerState;
+		HDepthStencilState mClearQuadDSStateNoD_NoS;
+		HDepthStencilState mClearQuadDSStateYesD_NoS;
+		HDepthStencilState mClearQuadDSStateYesD_YesS;
+		HDepthStencilState mClearQuadDSStateNoD_YesS;
 	};
 }

+ 11 - 9
CamelotD3D11RenderSystem/Source/CmD3D11Device.cpp

@@ -26,6 +26,8 @@ namespace CamelotFramework
 
 			if (FAILED(hr))
 				CM_EXCEPT(RenderingAPIException, "Unable to query D3D11InfoQueue");
+
+			setExceptionsErrorLevel(D3D11ERR_ERROR);
 #endif
 
 			// If feature level is 11, create class linkage
@@ -128,23 +130,23 @@ namespace CamelotFramework
 
 		switch(exceptionsErrorLevel)
 		{
-		case D3D11ERR_NO_EXCEPTION:
-			severityList.push_back(D3D11_MESSAGE_SEVERITY_CORRUPTION);
-		case D3D11ERR_CORRUPTION:
-			severityList.push_back(D3D11_MESSAGE_SEVERITY_ERROR);
-		case D3D11ERR_ERROR:
-			severityList.push_back(D3D11_MESSAGE_SEVERITY_WARNING);
-		case D3D11ERR_WARNING:
 		case D3D11ERR_INFO:
 			severityList.push_back(D3D11_MESSAGE_SEVERITY_INFO);
+		case D3D11ERR_WARNING:
+			severityList.push_back(D3D11_MESSAGE_SEVERITY_WARNING);
+		case D3D11ERR_ERROR:
+			severityList.push_back(D3D11_MESSAGE_SEVERITY_ERROR);
+		case D3D11ERR_CORRUPTION:
+			severityList.push_back(D3D11_MESSAGE_SEVERITY_CORRUPTION);
+		case D3D11ERR_NO_EXCEPTION:
 		default: 
 			break;
 		}
 
 		if (severityList.size() > 0)
 		{
-			filter.DenyList.NumSeverities = (UINT)severityList.size();
-			filter.DenyList.pSeverityList = &severityList[0];
+			filter.AllowList.NumSeverities = (UINT)severityList.size();
+			filter.AllowList.pSeverityList = &severityList[0];
 		}
 
 		mInfoQueue->AddStorageFilterEntries(&filter);

+ 6 - 12
CamelotD3D11RenderSystem/Source/CmD3D11RenderSystem.cpp

@@ -580,24 +580,18 @@ namespace CamelotFramework
 	{
 		THROW_IF_NOT_CORE_THREAD;
 
-		if(clearArea.width > 0 && clearArea.height > 0)
+		bool clearEntireTarget = clearArea.width == 0 || clearArea.height == 0;
+		clearEntireTarget |= (clearArea.x == 0 && clearArea.y == 0 && clearArea.width == target->getWidth() && clearArea.height == target->getHeight());
+
+		if(!clearEntireTarget)
 		{
 			RenderTargetPtr oldRenderTarget = mActiveRenderTarget;
 			if(target != mActiveRenderTarget)
 				setRenderTarget(target);
 
-			float invViewportWidth = 1.0f / (target->getWidth() * 0.5f);
-			float invViewportHeight = 1.0f / (target->getHeight() * 0.5f);
-
-			float clipLeft = -1.0f + (clearArea.x * invViewportWidth);
-			float clipRight = -1.0f + ((clearArea.x + clearArea.width) * invViewportWidth);
-
-			float clipTop = 1.0f - (clearArea.y * invViewportHeight);
-			float clipBottom = 1.0f - ((clearArea.y + clearArea.height) * invViewportHeight);
-
-			D3D11RenderUtility::instance().drawClearQuad(clipLeft, clipRight - clipLeft, clipTop, clipBottom - clipTop, buffers, color, depth, stencil);
+			D3D11RenderUtility::instance().drawClearQuad(clearArea, buffers, color, depth, stencil);
 
-			if(oldRenderTarget != mActiveRenderTarget)
+			if(oldRenderTarget != mActiveRenderTarget && oldRenderTarget != nullptr)
 				setRenderTarget(oldRenderTarget);
 		}
 		else

+ 122 - 21
CamelotD3D11RenderSystem/Source/CmD3D11RenderUtility.cpp

@@ -3,6 +3,9 @@
 #include "CmVector3.h"
 #include "CmColor.h"
 #include "CmRect.h"
+#include "CmD3D11BlendState.h"
+#include "CmD3D11RasterizerState.h"
+#include "CmD3D11DepthStencilState.h"
 
 namespace CamelotFramework
 {
@@ -16,7 +19,7 @@ namespace CamelotFramework
 		:mDevice(device), mClearQuadIB(nullptr), mClearQuadVB(nullptr), 
 		mClearQuadIL(nullptr), mClearQuadVS(nullptr), mClearQuadPS(nullptr)
 	{
-
+		initClearQuadResources();
 	}
 
 	D3D11RenderUtility::~D3D11RenderUtility()
@@ -26,29 +29,83 @@ namespace CamelotFramework
 		SAFE_RELEASE(mClearQuadIL);
 		SAFE_RELEASE(mClearQuadIB);
 		SAFE_RELEASE(mClearQuadVB);
-
-		// TODO - Clear up all resources
 	}
 
-	void D3D11RenderUtility::drawClearQuad(float clipLeft, float clipWidth, float clipTop, float clipHeight, 
+	void D3D11RenderUtility::drawClearQuad(const Rect& screenArea, 
 		UINT32 clearBuffers, const Color& color, float depth, UINT16 stencil)
 	{
-		// TODO - Set up states
-		// TODO - Make sure to apply proper states depending on "clearBuffers" flags. Don't forget about stencil
+		// Set viewport
+		UINT32 oldNumViewports = 0;
+		mDevice->getImmediateContext()->RSGetViewports(&oldNumViewports, nullptr);
+
+		D3D11_VIEWPORT* oldViewports = cm_newN<D3D11_VIEWPORT>(oldNumViewports);
+		mDevice->getImmediateContext()->RSGetViewports(&oldNumViewports, oldViewports);
+
+		D3D11_VIEWPORT newViewport;
+		newViewport.TopLeftX = (float)screenArea.x;
+		newViewport.TopLeftY = (float)screenArea.y;
+		newViewport.Width = (float)screenArea.width;
+		newViewport.Height = (float)screenArea.height;
+		newViewport.MinDepth = 0.0f;
+		newViewport.MaxDepth = 1.0f;
+
+		mDevice->getImmediateContext()->RSSetViewports(1, &newViewport);
+
+		// Set states
+		if((clearBuffers & FBT_COLOR) != 0)
+		{
+			D3D11BlendState* d3d11BlendState = static_cast<D3D11BlendState*>(const_cast<BlendState*>(mClearQuadBlendStateYesC.get()));
+			mDevice->getImmediateContext()->OMSetBlendState(d3d11BlendState->getInternal(), nullptr, 0xFFFFFFFF);
+		}
+		else
+		{
+			D3D11BlendState* d3d11BlendState = static_cast<D3D11BlendState*>(const_cast<BlendState*>(mClearQuadBlendStateNoC.get()));
+			mDevice->getImmediateContext()->OMSetBlendState(d3d11BlendState->getInternal(), nullptr, 0xFFFFFFFF);
+		}
+
+		D3D11RasterizerState* d3d11RasterizerState = static_cast<D3D11RasterizerState*>(const_cast<RasterizerState*>(mClearQuadRasterizerState.get()));
+		mDevice->getImmediateContext()->RSSetState(d3d11RasterizerState->getInternal());
+
+		if((clearBuffers & FBT_DEPTH) != 0)
+		{
+			if((clearBuffers & FBT_STENCIL) != 0)
+			{
+				D3D11DepthStencilState* d3d11RasterizerState = static_cast<D3D11DepthStencilState*>(const_cast<DepthStencilState*>(mClearQuadDSStateYesD_YesS.get()));
+				mDevice->getImmediateContext()->OMSetDepthStencilState(d3d11RasterizerState->getInternal(), stencil);
+			}
+			else
+			{
+				D3D11DepthStencilState* d3d11RasterizerState = static_cast<D3D11DepthStencilState*>(const_cast<DepthStencilState*>(mClearQuadDSStateYesD_NoS.get()));
+				mDevice->getImmediateContext()->OMSetDepthStencilState(d3d11RasterizerState->getInternal(), stencil);
+			}
+		}
+		else
+		{
+			if((clearBuffers & FBT_STENCIL) != 0)
+			{
+				D3D11DepthStencilState* d3d11RasterizerState = static_cast<D3D11DepthStencilState*>(const_cast<DepthStencilState*>(mClearQuadDSStateNoD_YesS.get()));
+				mDevice->getImmediateContext()->OMSetDepthStencilState(d3d11RasterizerState->getInternal(), stencil);
+			}
+			else
+			{
+				D3D11DepthStencilState* d3d11RasterizerState = static_cast<D3D11DepthStencilState*>(const_cast<DepthStencilState*>(mClearQuadDSStateNoD_NoS.get()));
+				mDevice->getImmediateContext()->OMSetDepthStencilState(d3d11RasterizerState->getInternal(), stencil);
+			}
+		}
 
 		// TODO - How smart it is to update buffer right before drawing it!? (cache the clip area)
 		ClearVertex vertexData[4];
-		vertexData[0].pos = Vector3(clipLeft, clipTop, depth);
-		vertexData[1].pos = Vector3(clipLeft + clipWidth, clipTop, depth);
-		vertexData[2].pos = Vector3(clipLeft, clipTop + clipHeight, depth);
-		vertexData[3].pos = Vector3(clipLeft + clipWidth, clipTop + clipHeight, depth);
+		vertexData[0].pos = Vector3(-1.0f, 1.0f, depth);
+		vertexData[1].pos = Vector3(1.0f, 1.0f, depth);
+		vertexData[2].pos = Vector3(-1.0f, -1.0f, depth);
+		vertexData[3].pos = Vector3(1.0f, -1.0f, depth);
 
-		vertexData[0].col = color.getAsBGRA();
-		vertexData[1].col = color.getAsBGRA();
-		vertexData[2].col = color.getAsBGRA();
-		vertexData[3].col = color.getAsBGRA();
+		vertexData[0].col = color.getAsRGBA();
+		vertexData[1].col = color.getAsRGBA();
+		vertexData[2].col = color.getAsRGBA();
+		vertexData[3].col = color.getAsRGBA();
 
-		mDevice->getImmediateContext()->UpdateSubresource(mClearQuadVB, 0, nullptr, vertexData, 0, sizeof(vertexData));
+		mDevice->getImmediateContext()->UpdateSubresource(mClearQuadVB, 0, nullptr, vertexData, 0, sizeof(ClearVertex) * 4);
 
 		mDevice->getImmediateContext()->VSSetShader(mClearQuadVS, nullptr, 0);
 		mDevice->getImmediateContext()->PSSetShader(mClearQuadPS, nullptr, 0);
@@ -64,12 +121,56 @@ namespace CamelotFramework
 		mDevice->getImmediateContext()->IASetVertexBuffers(0, 1, buffers, strides, offsets);
 		mDevice->getImmediateContext()->IASetInputLayout(mClearQuadIL);
 
-		mDevice->getImmediateContext()->DrawIndexed(4, 0, 0);
+		mDevice->getImmediateContext()->DrawIndexed(6, 0, 0);
 
+		// Restore viewports
+		mDevice->getImmediateContext()->RSSetViewports(oldNumViewports, oldViewports);
+		cm_deleteN(oldViewports, oldNumViewports);
 	}
 
 	void D3D11RenderUtility::initClearQuadResources()
 	{
+		BLEND_STATE_DESC blendStateDescYesC;
+		mClearQuadBlendStateYesC = BlendState::create(blendStateDescYesC);
+
+		BLEND_STATE_DESC blendStateDescNoC;
+		for(int i = 0; i < CM_MAX_MULTIPLE_RENDER_TARGETS; i++)
+			blendStateDescNoC.renderTargetDesc[i].renderTargetWriteMask = 0;
+
+		mClearQuadBlendStateNoC = BlendState::create(blendStateDescNoC);
+
+		DEPTH_STENCIL_STATE_DESC depthStateDescNoD_NoS;
+		depthStateDescNoD_NoS.depthReadEnable = false;
+		depthStateDescNoD_NoS.depthWriteEnable = false;
+		depthStateDescNoD_NoS.depthComparisonFunc = CMPF_ALWAYS_PASS;
+		mClearQuadDSStateNoD_NoS = DepthStencilState::create(depthStateDescNoD_NoS);
+
+		DEPTH_STENCIL_STATE_DESC depthStateDescYesD_NoS;
+		depthStateDescYesD_NoS.depthReadEnable = false;
+		depthStateDescYesD_NoS.depthWriteEnable = false; // TODO - Set to true
+		//depthStateDescYesD_NoS.depthComparisonFunc = CMPF_ALWAYS_PASS;
+		mClearQuadDSStateYesD_NoS = DepthStencilState::create(depthStateDescYesD_NoS);
+
+		DEPTH_STENCIL_STATE_DESC depthStateDescYesD_YesS;
+		depthStateDescYesD_YesS.depthReadEnable = false;
+		depthStateDescYesD_YesS.depthWriteEnable = true;
+		depthStateDescYesD_YesS.depthComparisonFunc = CMPF_ALWAYS_PASS;
+		depthStateDescYesD_YesS.stencilEnable = true;
+		depthStateDescYesD_YesS.frontStencilComparisonFunc = CMPF_ALWAYS_PASS;
+		depthStateDescYesD_YesS.frontStencilPassOp = SOP_REPLACE;
+		mClearQuadDSStateYesD_YesS = DepthStencilState::create(depthStateDescYesD_YesS);
+
+		DEPTH_STENCIL_STATE_DESC depthStateDescNoD_YesS;
+		depthStateDescNoD_YesS.depthReadEnable = false;
+		depthStateDescNoD_YesS.depthWriteEnable = false;
+		depthStateDescNoD_YesS.depthComparisonFunc = CMPF_ALWAYS_PASS;
+		depthStateDescNoD_YesS.stencilEnable = true;
+		depthStateDescNoD_YesS.frontStencilComparisonFunc = CMPF_ALWAYS_PASS;
+		mClearQuadDSStateNoD_YesS = DepthStencilState::create(depthStateDescNoD_YesS);
+
+		RASTERIZER_STATE_DESC rasterizerStateDesc;
+		mClearQuadRasterizerState = RasterizerState::create(rasterizerStateDesc);
+
 		String vsShaderCode = "										\
 						void main(									\
 						in float3 inPos : POSITION,					\
@@ -82,7 +183,7 @@ namespace CamelotFramework
 						}											\
 						";
 
-		String psShaderCode = "float4 ps_main(in float4 inPos : SV_Position, float4 color : COLOR) : SV_Target	\
+		String psShaderCode = "float4 main(in float4 inPos : SV_Position, float4 color : COLOR0) : SV_Target	\
 								{ return color; }";
 
 		HRESULT hr;
@@ -170,12 +271,12 @@ namespace CamelotFramework
 		// Create vertex buffer
 		D3D11_BUFFER_DESC mVBDesc;
 
-		mVBDesc.ByteWidth = sizeof(float) * 3 + sizeof(UINT32);
+		mVBDesc.ByteWidth = sizeof(ClearVertex) * 4;
 		mVBDesc.MiscFlags = 0;
 		mVBDesc.StructureByteStride = 0;
 
 		mVBDesc.Usage = D3D11_USAGE_DEFAULT;
-		mVBDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; 
+		mVBDesc.CPUAccessFlags = 0; 
 		mVBDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
 
 		ClearVertex vertexData[4];
@@ -202,12 +303,12 @@ namespace CamelotFramework
 		// Create index buffer
 		D3D11_BUFFER_DESC mIBDesc;
 
-		mIBDesc.ByteWidth = sizeof(UINT16) * 4;
+		mIBDesc.ByteWidth = sizeof(UINT16) * 6;
 		mIBDesc.MiscFlags = 0;
 		mIBDesc.StructureByteStride = 0;
 
 		mIBDesc.Usage = D3D11_USAGE_DEFAULT;
-		mIBDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; 
+		mIBDesc.CPUAccessFlags = 0; 
 		mIBDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
 
 		UINT16 indexData[6];