2
0
Эх сурвалжийг харах

Scene picking now preloads all uniform buffers before rendering

BearishSun 9 жил өмнө
parent
commit
d4208655f8

+ 2 - 2
Data/Raw/Editor/Includes/PickingAlphaCull.bslinc

@@ -1,7 +1,7 @@
 Parameters =
 Parameters =
 {
 {
 	mat4x4		gMatWorldViewProj;
 	mat4x4		gMatWorldViewProj;
-	float4		gColorIndex;
+	color		gColorIndex;
 	float		gAlphaCutoff;
 	float		gAlphaCutoff;
 	
 	
 	Sampler2D 	gMainTexSamp : alias("gMainTexture");
 	Sampler2D 	gMainTexSamp : alias("gMainTexture");
@@ -10,7 +10,7 @@ Parameters =
 
 
 Blocks =
 Blocks =
 {
 {
-	Block Uniforms : auto("GizmoUniforms");
+	Block Uniforms : auto("PickingUniforms");
 };
 };
 
 
 Technique : base("PickingAlphaCull") =
 Technique : base("PickingAlphaCull") =

+ 2 - 2
Data/Raw/Editor/Includes/PickingCull.bslinc

@@ -1,13 +1,13 @@
 Parameters =
 Parameters =
 {
 {
 	mat4x4		gMatWorldViewProj;
 	mat4x4		gMatWorldViewProj;
-	float4		gColorIndex;
+	color		gColorIndex;
 	float		gAlphaCutoff;
 	float		gAlphaCutoff;
 };
 };
 
 
 Blocks =
 Blocks =
 {
 {
-	Block Uniforms : auto("GizmoUniforms");
+	Block Uniforms : auto("PickingUniforms");
 };
 };
 
 
 Technique : base("PickingCull") =
 Technique : base("PickingCull") =

+ 18 - 13
Source/BansheeCore/Include/BsParamBlocks.h

@@ -28,22 +28,29 @@ namespace bs
 	{																														\
 	{																														\
 		Name()																												\
 		Name()																												\
 		{																													\
 		{																													\
-			Vector<GpuParamDataDesc> params = getEntries();																	\
-			RenderAPICore& rapi = RenderAPICore::instance();																\
+			static SPtr<GpuPipelineParamInfoCore> paramInfo = nullptr;														\
+			static GpuParamBlockDesc blockDesc;																				\
 																															\
 																															\
-			mBlockDesc = rapi.generateParamBlockDesc(#Name, params);														\
+			if (paramInfo == nullptr)																						\
+			{																												\
+				Vector<GpuParamDataDesc> params = getEntries();																\
+				RenderAPICore& rapi = RenderAPICore::instance();															\
 																															\
 																															\
-			SPtr<GpuParamDesc> paramsDesc = bs_shared_ptr_new<GpuParamDesc>();												\
-			paramsDesc->paramBlocks[#Name] = mBlockDesc;																	\
-			for (auto& param : params)																						\
-				paramsDesc->params[param.name] = param;																		\
+				blockDesc = rapi.generateParamBlockDesc(#Name, params);														\
+																															\
+				SPtr<GpuParamDesc> paramsDesc = bs_shared_ptr_new<GpuParamDesc>();											\
+				paramsDesc->paramBlocks[#Name] = blockDesc;																	\
+				for (auto& param : params)																					\
+					paramsDesc->params[param.name] = param;																	\
+																															\
+				GPU_PIPELINE_PARAMS_DESC pipelineParamDesc;																	\
+				pipelineParamDesc.vertexParams = paramsDesc;																\
+				paramInfo = GpuPipelineParamInfoCore::create(pipelineParamDesc);											\
+			}																												\
 																															\
 																															\
-			GPU_PIPELINE_PARAMS_DESC pipelineParamDesc;																		\
-			pipelineParamDesc.vertexParams = paramsDesc;																	\
-			SPtr<GpuPipelineParamInfoCore> paramInfo = GpuPipelineParamInfoCore::create(pipelineParamDesc);					\
 			mParams = GpuParamsCore::create(paramInfo);																		\
 			mParams = GpuParamsCore::create(paramInfo);																		\
 																															\
 																															\
-			mBuffer = GpuParamBlockBufferCore::create(mBlockDesc.blockSize * sizeof(UINT32));								\
+			mBuffer = GpuParamBlockBufferCore::create(blockDesc.blockSize * sizeof(UINT32));								\
 			mParams->setParamBlockBuffer(GPT_VERTEX_PROGRAM, #Name, mBuffer);												\
 			mParams->setParamBlockBuffer(GPT_VERTEX_PROGRAM, #Name, mBuffer);												\
 			initEntries();																									\
 			initEntries();																									\
 		}																													\
 		}																													\
@@ -54,7 +61,6 @@ namespace bs
 				mBuffer = buffer;																							\
 				mBuffer = buffer;																							\
 				mParams->setParamBlockBuffer(GPT_VERTEX_PROGRAM, #Name, mBuffer);											\
 				mParams->setParamBlockBuffer(GPT_VERTEX_PROGRAM, #Name, mBuffer);											\
 		}																													\
 		}																													\
-		const GpuParamBlockDesc& getDesc() const { return mBlockDesc; }														\
 		void flushToGPU(UINT32 queueIdx = 0) { mBuffer->flushToGPU(queueIdx); }												\
 		void flushToGPU(UINT32 queueIdx = 0) { mBuffer->flushToGPU(queueIdx); }												\
 																															\
 																															\
 	private:																												\
 	private:																												\
@@ -117,7 +123,6 @@ namespace bs
 																															\
 																															\
 		SPtr<GpuParamsCore> mParams;																						\
 		SPtr<GpuParamsCore> mParams;																						\
 		SPtr<GpuParamBlockBufferCore> mBuffer;																				\
 		SPtr<GpuParamBlockBufferCore> mBuffer;																				\
-		GpuParamBlockDesc mBlockDesc;																						\
 	};
 	};
 
 
 	/** @} */
 	/** @} */

+ 11 - 17
Source/BansheeEditor/Include/BsScenePicking.h

@@ -6,6 +6,7 @@
 #include "BsModule.h"
 #include "BsModule.h"
 #include "BsMatrix4.h"
 #include "BsMatrix4.h"
 #include "BsGpuParam.h"
 #include "BsGpuParam.h"
+#include "BsParamBlocks.h"
 
 
 namespace bs
 namespace bs
 {
 {
@@ -97,25 +98,15 @@ namespace bs
 	 *  @{
 	 *  @{
 	 */
 	 */
 
 
+	BS_PARAM_BLOCK_BEGIN(PickingParamBuffer)
+		BS_PARAM_BLOCK_ENTRY(Matrix4, gMatViewProj)
+		BS_PARAM_BLOCK_ENTRY(Color, gColorIndex)
+		BS_PARAM_BLOCK_ENTRY(float, gAlphaCutoff)
+	BS_PARAM_BLOCK_END
+
 	/** Core thread version of the ScenePicking manager. Handles actual rendering. */
 	/** Core thread version of the ScenePicking manager. Handles actual rendering. */
 	class ScenePickingCore
 	class ScenePickingCore
 	{
 	{
-		/** A list of materials and their parameters to be used for rendering of pickable objects. */
-		struct MaterialData
-		{
-			SPtr<MaterialCore> mMatPickingCore;
-			SPtr<MaterialCore> mMatPickingAlphaCore;
-
-			SPtr<GpuParamsSetCore> mPickingParams;
-			SPtr<GpuParamsSetCore> mPickingAlphaParams;
-
-			GpuParamMat4Core mParamPickingWVP;
-			GpuParamMat4Core mParamPickingAlphaWVP;
-			GpuParamColorCore mParamPickingColor;
-			GpuParamColorCore mParamPickingAlphaColor;
-			GpuParamTextureCore mParamPickingAlphaTexture;
-		};
-
 	public:
 	public:
 		/**	Initializes the manager. Must be called right after construction. */
 		/**	Initializes the manager. Must be called right after construction. */
 		void initialize();
 		void initialize();
@@ -157,8 +148,11 @@ namespace bs
 
 
 		static const float ALPHA_CUTOFF;
 		static const float ALPHA_CUTOFF;
 
 
-		MaterialData mMaterialData[3];
 		SPtr<RenderTextureCore> mPickingTexture;
 		SPtr<RenderTextureCore> mPickingTexture;
+
+		SPtr<MaterialCore> mMaterials[6];
+		Vector<SPtr<GpuParamsSetCore>> mParamSets[6];
+		Vector<PickingParamBuffer*> mParamBuffers;
 	};
 	};
 
 
 	/** @} */
 	/** @} */

+ 68 - 50
Source/BansheeEditor/Source/BsScenePicking.cpp

@@ -41,8 +41,8 @@ namespace bs
 			HMaterial matPicking = BuiltinEditorResources::instance().createPicking((CullingMode)i);
 			HMaterial matPicking = BuiltinEditorResources::instance().createPicking((CullingMode)i);
 			HMaterial matPickingAlpha = BuiltinEditorResources::instance().createPickingAlpha((CullingMode)i);
 			HMaterial matPickingAlpha = BuiltinEditorResources::instance().createPickingAlpha((CullingMode)i);
 
 
-			mCore->mMaterialData[i].mMatPickingCore = matPicking->getCore();
-			mCore->mMaterialData[i].mMatPickingAlphaCore = matPickingAlpha->getCore();
+			mCore->mMaterials[i] = matPicking->getCore();
+			mCore->mMaterials[3 + i] = matPickingAlpha->getCore();
 		}
 		}
 
 
 		gCoreThread().queueCommand(std::bind(&ScenePickingCore::initialize, mCore));
 		gCoreThread().queueCommand(std::bind(&ScenePickingCore::initialize, mCore));
@@ -247,35 +247,14 @@ namespace bs
 
 
 	void ScenePickingCore::initialize()
 	void ScenePickingCore::initialize()
 	{
 	{
-		for (UINT32 i = 0; i < 3; i++)
-		{
-			MaterialData& md = mMaterialData[i];
-
-			{
-				md.mPickingParams = md.mMatPickingCore->createParamsSet();
-
-				SPtr<GpuParamsCore> params = md.mPickingParams->getGpuParams();
-				params->getParam(GPT_VERTEX_PROGRAM, "matWorldViewProj", md.mParamPickingWVP);
-				params->getParam(GPT_FRAGMENT_PROGRAM, "colorIndex", md.mParamPickingColor);
-			}
-
-			{
-				md.mPickingAlphaParams = md.mMatPickingAlphaCore->createParamsSet();
-
-				SPtr<GpuParamsCore> params = md.mPickingAlphaParams->getGpuParams();
-				params->getParam(GPT_VERTEX_PROGRAM, "matWorldViewProj", md.mParamPickingAlphaWVP);
-				params->getParam(GPT_FRAGMENT_PROGRAM, "colorIndex", md.mParamPickingAlphaColor);
-				params->getTextureParam(GPT_FRAGMENT_PROGRAM, "mainTexture", md.mParamPickingAlphaTexture);
-
-				GpuParamFloatCore alphaCutoffParam;
-				params->getParam(GPT_FRAGMENT_PROGRAM, "alphaCutoff", alphaCutoffParam);
-				alphaCutoffParam.set(ALPHA_CUTOFF);
-			}
-		}
+		// Do nothing
 	}
 	}
 
 
 	void ScenePickingCore::destroy()
 	void ScenePickingCore::destroy()
 	{
 	{
+		for (auto& entry : mParamBuffers)
+			bs_delete(entry);
+
 		bs_delete(this);
 		bs_delete(this);
 	}
 	}
 
 
@@ -316,49 +295,88 @@ namespace bs
 		rs.clearRenderTarget(FBT_COLOR | FBT_DEPTH | FBT_STENCIL, Color::White);
 		rs.clearRenderTarget(FBT_COLOR | FBT_DEPTH | FBT_STENCIL, Color::White);
 		rs.setScissorRect(position.x, position.y, position.x + area.x, position.y + area.y);
 		rs.setScissorRect(position.x, position.y, position.x + area.x, position.y + area.y);
 
 
-		gRendererUtility().setPass(mMaterialData[0].mMatPickingCore, 0);
-		gRendererUtility().setPassParams(mMaterialData[0].mPickingParams, 0);
+		gRendererUtility().setPass(mMaterials[0]);
 
 
-		bool activeMaterialIsAlpha = false;
-		CullingMode activeMaterialCull = (CullingMode)0;
+		UINT32 numEntries = renderables.size();
+		UINT32* renderableIndices = bs_stack_alloc<UINT32>(numEntries);
 
 
+		UINT32 typeCounters[6];
+		bs_zero_out(typeCounters);
+
+		UINT32 idx = 0;
 		for (auto& renderable : renderables)
 		for (auto& renderable : renderables)
 		{
 		{
-			if (activeMaterialIsAlpha != renderable.alpha || activeMaterialCull != renderable.cullMode)
+			UINT32 typeIdx;
+			if (renderable.alpha)
+				typeIdx = 0;
+			else
+				typeIdx = 3;
+
+			typeIdx += (UINT32)renderable.cullMode;
+
+			UINT32 renderableIdx = typeCounters[typeIdx];
+			renderableIndices[idx] = renderableIdx;
+
+			SPtr<GpuParamsSetCore> paramsSet;
+			if (renderableIdx >= mParamSets[typeIdx].size())
 			{
 			{
-				activeMaterialIsAlpha = renderable.alpha;
-				activeMaterialCull = renderable.cullMode;
+				paramsSet = mMaterials[typeIdx]->createParamsSet();
+				mParamSets[typeIdx].push_back(paramsSet);
+			}
+			else
+				paramsSet = mParamSets[typeIdx][renderableIdx];
 
 
-				if (activeMaterialIsAlpha)
-					gRendererUtility().setPass(mMaterialData[(UINT32)activeMaterialCull].mMatPickingAlphaCore, 0);
-				else
-					gRendererUtility().setPass(mMaterialData[(UINT32)activeMaterialCull].mMatPickingCore, 0);
+			PickingParamBuffer* paramBuffer;
+			if (idx >= mParamBuffers.size())
+			{
+				paramBuffer = bs_new<PickingParamBuffer>();
+				mParamBuffers.push_back(paramBuffer);
 			}
 			}
+			else
+				paramBuffer = mParamBuffers[idx];
+
+			paramsSet->setParamBlockBuffer("Uniforms", paramBuffer->getBuffer(), true);
 
 
 			Color color = ScenePicking::encodeIndex(renderable.index);
 			Color color = ScenePicking::encodeIndex(renderable.index);
-			MaterialData& md = mMaterialData[(UINT32)activeMaterialCull];
 
 
-			if (activeMaterialIsAlpha)
-			{
-				md.mParamPickingAlphaWVP.set(renderable.wvpTransform);
-				md.mParamPickingAlphaColor.set(color);
-				md.mParamPickingAlphaTexture.set(renderable.mainTexture->getCore());
+			paramBuffer->gMatViewProj.set(renderable.wvpTransform);
+			paramBuffer->gAlphaCutoff.set(ALPHA_CUTOFF);
+			paramBuffer->gColorIndex.set(color);
 
 
-				gRendererUtility().setPassParams(md.mPickingAlphaParams);
-			}
+			typeCounters[typeIdx]++;
+			idx++;
+		}
+
+		UINT32 activeMaterialIdx = 0;
+		idx = 0;
+		for (auto& renderable : renderables)
+		{
+			UINT32 typeIdx;
+			if (renderable.alpha)
+				typeIdx = 0;
 			else
 			else
-			{
-				md.mParamPickingWVP.set(renderable.wvpTransform);
-				md.mParamPickingColor.set(color);
+				typeIdx = 3;
+
+			typeIdx += (UINT32)renderable.cullMode;
 
 
-				gRendererUtility().setPassParams(md.mPickingParams);
+			if (activeMaterialIdx != typeIdx)
+			{
+				gRendererUtility().setPass(mMaterials[typeIdx]);
+				activeMaterialIdx = typeIdx;
 			}
 			}
 
 
+			UINT32 renderableIdx = renderableIndices[idx];
+			gRendererUtility().setPassParams(mParamSets[typeIdx][renderableIdx]);
+
 			UINT32 numSubmeshes = renderable.mesh->getProperties().getNumSubMeshes();
 			UINT32 numSubmeshes = renderable.mesh->getProperties().getNumSubMeshes();
 
 
 			for (UINT32 i = 0; i < numSubmeshes; i++)
 			for (UINT32 i = 0; i < numSubmeshes; i++)
 				gRendererUtility().draw(renderable.mesh, renderable.mesh->getProperties().getSubMesh(i));
 				gRendererUtility().draw(renderable.mesh, renderable.mesh->getProperties().getSubMesh(i));
+
+			idx++;
 		}
 		}
+
+		bs_stack_free(renderableIndices);
 	}
 	}
 
 
 	void ScenePickingCore::corePickingEnd(const SPtr<RenderTargetCore>& target, const Rect2& viewportArea, const Vector2I& position,
 	void ScenePickingCore::corePickingEnd(const SPtr<RenderTargetCore>& target, const Rect2& viewportArea, const Vector2I& position,