Jelajahi Sumber

Material refactor WIP - Transpose matrices when updating from material to GPU params

BearishSun 9 tahun lalu
induk
melakukan
9675b3f6fd

+ 6 - 13
Source/BansheeCore/Include/BsGpuParams.h

@@ -45,12 +45,10 @@ namespace BansheeEngine
 		 *
 		 * @param[in]	paramDesc			Reference to parameter descriptions that will be used for finding needed 
 		 *									parameters.
-		 * @param[in]	transposeMatrices	If true the stored matrices will be transposed before submitted to the GPU 
-		 *									(some APIs require different matrix layout).
 		 *
 		 * @note	You normally do not want to call this manually. Instead use GpuProgram::createParameters.
 		 */
-		GpuParamsBase(const SPtr<GpuParamDesc>& paramDesc, bool transposeMatrices);
+		GpuParamsBase(const SPtr<GpuParamDesc>& paramDesc);
 		virtual ~GpuParamsBase();
 
 		// Note: Disallow copy/assign because it would require some care when copying (copy internal data shared_ptr and
@@ -93,9 +91,6 @@ namespace BansheeEngine
 		/**	Sets information that determines which texture surfaces to bind	as load/store parameters. */
 		void setLoadStoreSurface(UINT32 slot, const TextureSurface& surface) const;
 
-		/**	Checks whether matrices should be transformed before being written to the parameter buffer. */
-		bool getTransposeMatrices() const { return mTransposeMatrices; }
-
 		/** Marks the sim thread object as dirty, causing it to sync its contents with its core thread counterpart. */
 		virtual void _markCoreDirty() { }
 
@@ -115,8 +110,6 @@ namespace BansheeEngine
 		UINT32 mNumSamplerStates;
 
 		TextureSurface* mLoadStoreSurfaces;
-
-		bool mTransposeMatrices;
 	};
 
 	template<bool Core> struct TGpuParamsTypes { };
@@ -149,7 +142,7 @@ namespace BansheeEngine
 		typedef typename TGpuParamsTypes<Core>::SamplerType SamplerType;
 		typedef typename TGpuParamsTypes<Core>::ParamsBufferType ParamsBufferType;
 
-		TGpuParams(const SPtr<GpuParamDesc>& paramDesc, bool transposeMatrices);
+		TGpuParams(const SPtr<GpuParamDesc>& paramDesc);
 
 		virtual ~TGpuParams();
 
@@ -257,13 +250,13 @@ namespace BansheeEngine
 		~GpuParamsCore() { }
 
 		/** @copydoc GpuParamsBase::GpuParamsBase */
-		static SPtr<GpuParamsCore> create(const SPtr<GpuParamDesc>& paramDesc, bool transposeMatrices);
+		static SPtr<GpuParamsCore> create(const SPtr<GpuParamDesc>& paramDesc);
 
 	protected:
 		friend class GpuParams;
 
 		/** @copydoc GpuParamsBase::GpuParamsBase */
-		GpuParamsCore(const SPtr<GpuParamDesc>& paramDesc, bool transposeMatrices);
+		GpuParamsCore(const SPtr<GpuParamDesc>& paramDesc);
 
 		/** @copydoc CoreObject::getThisPtr */
 		SPtr<GpuParamsCore> _getThisPtr() const override;
@@ -293,7 +286,7 @@ namespace BansheeEngine
 		SPtr<GpuParamsCore> getCore() const;
 
 		/** @copydoc GpuParamsBase::GpuParamsBase */
-		static SPtr<GpuParams> create(const SPtr<GpuParamDesc>& paramDesc, bool transposeMatrices);
+		static SPtr<GpuParams> create(const SPtr<GpuParamDesc>& paramDesc);
 
 		/** Contains a lookup table for sizes of all data parameters. Sizes are in bytes. */
 		const static GpuDataParamInfos PARAM_SIZES;
@@ -311,7 +304,7 @@ namespace BansheeEngine
 		/** @} */
 	protected:
 		/** @copydoc GpuParamsBase::GpuParamsBase */
-		GpuParams(const SPtr<GpuParamDesc>& paramDesc, bool transposeMatrices);
+		GpuParams(const SPtr<GpuParamDesc>& paramDesc);
 
 		/** @copydoc CoreObject::getThisPtr */
 		SPtr<GpuParams> _getThisPtr() const override;

+ 0 - 1
Source/BansheeCore/Include/BsGpuParamsSet.h

@@ -57,7 +57,6 @@ namespace BansheeEngine
 			UINT32 paramIdx;
 			UINT32 blockIdx;
 			UINT32 offset;
-			UINT32 size;
 		};
 
 		/** Information about how an object parameter maps from a material parameter to a GPU stage slot. */

+ 1 - 1
Source/BansheeCore/Include/BsParamBlocks.h

@@ -34,7 +34,7 @@ namespace BansheeEngine
 			for (auto& param : params)																						\
 				paramsDesc->params[param.name] = param;																		\
 																															\
-			mParams = GpuParamsCore::create(paramsDesc, rapi.getAPIInfo().getGpuProgramHasColumnMajorMatrices());			\
+			mParams = GpuParamsCore::create(paramsDesc);																	\
 																															\
 			mBuffer = GpuParamBlockBufferCore::create(mBlockDesc.blockSize * sizeof(UINT32));								\
 			mParams->setParamBlockBuffer(#Name, mBuffer);																	\

+ 5 - 2
Source/BansheeCore/Source/BsGpuParam.cpp

@@ -4,6 +4,7 @@
 #include "BsGpuParams.h"
 #include "BsGpuParamBlockBuffer.h"
 #include "BsGpuParamDesc.h"
+#include "BsRenderAPI.h"
 #include "BsDebug.h"
 #include "BsException.h"
 #include "BsVectorNI.h"
@@ -42,7 +43,8 @@ namespace BansheeEngine
 		UINT32 elementSizeBytes = mParamDesc->elementSize * sizeof(UINT32);
 		UINT32 sizeBytes = std::min(elementSizeBytes, (UINT32)sizeof(T)); // Truncate if it doesn't fit within parameter size
 
-		if (TransposePolicy<T>::transposeEnabled(mParent->getTransposeMatrices()))
+		bool transposeMatrices = RenderAPICore::instance().getAPIInfo().getGpuProgramHasColumnMajorMatrices();
+		if (TransposePolicy<T>::transposeEnabled(transposeMatrices))
 		{
 			T transposed = TransposePolicy<T>::transpose(value);
 			paramBlock->write((mParamDesc->cpuMemOffset + arrayIdx * mParamDesc->arrayElementStride) * sizeof(UINT32), &transposed, sizeBytes);
@@ -84,7 +86,8 @@ namespace BansheeEngine
 		T value;
 		paramBlock->read((mParamDesc->cpuMemOffset + arrayIdx * mParamDesc->arrayElementStride) * sizeof(UINT32), &value, sizeBytes);
 
-		if (TransposePolicy<T>::transposeEnabled(mParent->getTransposeMatrices()))
+		bool transposeMatrices = RenderAPICore::instance().getAPIInfo().getGpuProgramHasColumnMajorMatrices();
+		if (TransposePolicy<T>::transposeEnabled(transposeMatrices))
 			return TransposePolicy<T>::transpose(value);
 		else
 			return value;

+ 13 - 13
Source/BansheeCore/Source/BsGpuParams.cpp

@@ -15,9 +15,9 @@
 
 namespace BansheeEngine
 {
-	GpuParamsBase::GpuParamsBase(const SPtr<GpuParamDesc>& paramDesc, bool transposeMatrices)
+	GpuParamsBase::GpuParamsBase(const SPtr<GpuParamDesc>& paramDesc)
 		: mParamDesc(paramDesc), mNumParamBlocks(0), mNumTextures(0), mNumLoadStoreTextures(0), mNumBuffers(0)
-		, mNumSamplerStates(0), mLoadStoreSurfaces(nullptr), mTransposeMatrices(transposeMatrices)
+		, mNumSamplerStates(0), mLoadStoreSurfaces(nullptr)
 	{
 		for (auto& paramBlock : mParamDesc->paramBlocks)
 		{
@@ -157,8 +157,8 @@ UINT32 GpuParamsBase::getDataParamSize(const String& name) const
 	}
 
 	template<bool Core>
-	TGpuParams<Core>::TGpuParams(const SPtr<GpuParamDesc>& paramDesc, bool transposeMatrices)
-		: GpuParamsBase(paramDesc, transposeMatrices), mParamBlockBuffers(nullptr), mTextures(nullptr)
+	TGpuParams<Core>::TGpuParams(const SPtr<GpuParamDesc>& paramDesc)
+		: GpuParamsBase(paramDesc), mParamBlockBuffers(nullptr), mTextures(nullptr)
 		, mLoadStoreTextures(nullptr), mBuffers(nullptr), mSamplerStates(nullptr)
 	{
 		if (mNumParamBlocks > 0)
@@ -472,8 +472,8 @@ UINT32 GpuParamsBase::getDataParamSize(const String& name) const
 	template BS_CORE_EXPORT void TGpuParams<true>::getParam<Matrix4x2>(const String&, TGpuDataParam<Matrix4x2, true>&) const;
 	template BS_CORE_EXPORT void TGpuParams<true>::getParam<Matrix4x3>(const String&, TGpuDataParam<Matrix4x3, true>&) const;
 
-	GpuParamsCore::GpuParamsCore(const SPtr<GpuParamDesc>& paramDesc, bool transposeMatrices)
-		: TGpuParams(paramDesc, transposeMatrices)
+	GpuParamsCore::GpuParamsCore(const SPtr<GpuParamDesc>& paramDesc)
+		: TGpuParams(paramDesc)
 	{
 
 	}
@@ -548,9 +548,9 @@ UINT32 GpuParamsBase::getDataParamSize(const String& name) const
 		}
 	}
 
-	SPtr<GpuParamsCore> GpuParamsCore::create(const SPtr<GpuParamDesc>& paramDesc, bool transposeMatrices)
+	SPtr<GpuParamsCore> GpuParamsCore::create(const SPtr<GpuParamDesc>& paramDesc)
 	{
-		GpuParamsCore* params = new (bs_alloc<GpuParamsCore>()) GpuParamsCore(paramDesc, transposeMatrices);
+		GpuParamsCore* params = new (bs_alloc<GpuParamsCore>()) GpuParamsCore(paramDesc);
 		SPtr<GpuParamsCore> paramsPtr = bs_shared_ptr<GpuParamsCore>(params);
 		paramsPtr->_setThisPtr(paramsPtr);
 
@@ -559,8 +559,8 @@ UINT32 GpuParamsBase::getDataParamSize(const String& name) const
 
 	const GpuDataParamInfos GpuParams::PARAM_SIZES;
 
-	GpuParams::GpuParams(const SPtr<GpuParamDesc>& paramDesc, bool transposeMatrices)
-		: TGpuParams(paramDesc, transposeMatrices)
+	GpuParams::GpuParams(const SPtr<GpuParamDesc>& paramDesc)
+		: TGpuParams(paramDesc)
 	{
 
 	}
@@ -577,7 +577,7 @@ UINT32 GpuParamsBase::getDataParamSize(const String& name) const
 
 	SPtr<CoreObjectCore> GpuParams::createCore() const
 	{
-		GpuParamsCore* obj = new (bs_alloc<GpuParamsCore>()) GpuParamsCore(mParamDesc, mTransposeMatrices);
+		GpuParamsCore* obj = new (bs_alloc<GpuParamsCore>()) GpuParamsCore(mParamDesc);
 
 		SPtr<CoreObjectCore> coreObj = bs_shared_ptr<GpuParamsCore>(obj);
 		coreObj->_setThisPtr(coreObj);
@@ -595,9 +595,9 @@ UINT32 GpuParamsBase::getDataParamSize(const String& name) const
 		markListenerResourcesDirty();
 	}
 
-	SPtr<GpuParams> GpuParams::create(const SPtr<GpuParamDesc>& paramDesc, bool transposeMatrices)
+	SPtr<GpuParams> GpuParams::create(const SPtr<GpuParamDesc>& paramDesc)
 	{
-		GpuParams* params = new (bs_alloc<GpuParams>()) GpuParams(paramDesc, transposeMatrices);
+		GpuParams* params = new (bs_alloc<GpuParams>()) GpuParams(paramDesc);
 		SPtr<GpuParams> paramsPtr = bs_core_ptr<GpuParams>(params);
 		paramsPtr->_setThisPtr(paramsPtr);
 		paramsPtr->initialize();

+ 86 - 7
Source/BansheeCore/Source/BsGpuParamsSet.cpp

@@ -7,6 +7,7 @@
 #include "BsGpuProgram.h"
 #include "BsMaterialParams.h"
 #include "BsGpuParamDesc.h"
+#include "BsRenderAPI.h"
 #include "BsGpuParamBlockBuffer.h"
 
 namespace BansheeEngine
@@ -549,11 +550,6 @@ namespace BansheeEngine
 							paramInfo.paramIdx = paramIdx;
 							paramInfo.blockIdx = globalBlockIdx;
 							paramInfo.offset = dataParam.second.cpuMemOffset;
-
-							const GpuParamDataTypeInfo& typeInfo = GpuParams::PARAM_SIZES.lookup[(int)dataParam.second.type];
-							UINT32 paramSize = typeInfo.numColumns * typeInfo.numRows * typeInfo.baseTypeSize;
-
-							paramInfo.size = paramSize * dataParam.second.arraySize;
 						}
 					}
 				}
@@ -780,9 +776,92 @@ namespace BansheeEngine
 			if ((materialParamInfo->dirtyFlags & dirtyFlagCheck) == 0 && !updateAll)
 				continue;
 
-			// TODO - Handle transposing matrices (POTENTIALLY add this to Material setters directly)
+			UINT32 arraySize = materialParamInfo->arraySize == 0 ? 1 : materialParamInfo->arraySize;
+			const GpuParamDataTypeInfo& typeInfo = GpuParams::PARAM_SIZES.lookup[(int)materialParamInfo->dataType];
+			UINT32 paramSize = typeInfo.numColumns * typeInfo.numRows * typeInfo.baseTypeSize;
+
 			UINT8* data = params->getData(materialParamInfo->index);
-			paramBlock->write(paramInfo.offset, data, paramInfo.size);
+
+			bool transposeMatrices = RenderAPICore::instance().getAPIInfo().getGpuProgramHasColumnMajorMatrices();
+			if (transposeMatrices)
+			{
+				auto writeTransposed = [&](auto& temp)
+				{
+					for (UINT32 i = 0; i < arraySize; i++)
+					{
+						UINT32 arrayOffset = i * paramSize;
+						memcpy(&temp, data + arrayOffset, paramSize);
+						temp.transpose();
+
+						paramBlock->write(paramInfo.offset + arrayOffset, &temp, paramSize);
+					}
+				};
+
+				switch (materialParamInfo->dataType)
+				{
+				case GPDT_MATRIX_2X2:
+				{
+					MatrixNxM<2, 2> matrix;
+					writeTransposed(matrix);
+				}
+					break;
+				case GPDT_MATRIX_2X3:
+				{
+					MatrixNxM<2, 3> matrix;
+					writeTransposed(matrix);
+				}
+					break;
+				case GPDT_MATRIX_2X4:
+				{
+					MatrixNxM<2, 4> matrix;
+					writeTransposed(matrix);
+				}
+					break;
+				case GPDT_MATRIX_3X2:
+				{
+					MatrixNxM<3, 2> matrix;
+					writeTransposed(matrix);
+				}
+					break;
+				case GPDT_MATRIX_3X3:
+				{
+					Matrix3 matrix;
+					writeTransposed(matrix);
+				}
+					break;
+				case GPDT_MATRIX_3X4:
+				{
+					MatrixNxM<3, 4> matrix;
+					writeTransposed(matrix);
+				}
+					break;
+				case GPDT_MATRIX_4X2:
+				{
+					MatrixNxM<4, 2> matrix;
+					writeTransposed(matrix);
+				}
+					break;
+				case GPDT_MATRIX_4X3:
+				{
+					MatrixNxM<4, 3> matrix;
+					writeTransposed(matrix);
+				}
+					break;
+				case GPDT_MATRIX_4X4:
+				{
+					Matrix4 matrix;
+					writeTransposed(matrix);
+				}
+					break;
+				default:
+				{
+					paramBlock->write(paramInfo.offset, data, paramSize * arraySize);
+					break;
+				}
+				}
+			}
+			else
+				paramBlock->write(paramInfo.offset, data, paramSize * arraySize);
 		}
 
 		// Update object params

+ 2 - 2
Source/BansheeCore/Source/BsGpuProgram.cpp

@@ -40,7 +40,7 @@ namespace BansheeEngine
 
 	SPtr<GpuParamsCore> GpuProgramCore::createParameters()
 	{
-		return GpuParamsCore::create(mParametersDesc, RenderAPICore::instance().getAPIInfo().getGpuProgramHasColumnMajorMatrices());
+		return GpuParamsCore::create(mParametersDesc);
 	}
 
 	SPtr<GpuProgramCore> GpuProgramCore::create(const String& source, const String& entryPoint, const String& language, GpuProgramType gptype,
@@ -69,7 +69,7 @@ namespace BansheeEngine
 
 	SPtr<GpuParams> GpuProgram::createParameters()
 	{
-		return GpuParams::create(getCore()->getParamDesc(), RenderAPICore::instance().getAPIInfo().getGpuProgramHasColumnMajorMatrices());
+		return GpuParams::create(getCore()->getParamDesc());
 	}
 
 	SPtr<GpuParamDesc> GpuProgram::getParamDesc() const