Browse Source

Gpu param block is now tied to param block buffer

Marko Pintera 12 năm trước cách đây
mục cha
commit
9205a99b69

+ 2 - 2
CamelotClient/CamelotClient.cpp

@@ -35,8 +35,8 @@
 #include "CmRTTIType.h"
 #include "CmPlatform.h"
 
-//#define DX11
-#define DX9
+#define DX11
+//#define DX9
 //#define GL
 
 using namespace CamelotFramework;

+ 4 - 0
CamelotCore/Include/CmGpuParamBlockBuffer.h

@@ -35,9 +35,13 @@ namespace CamelotFramework
 
 		UINT32 getSize() const { return mSize; }
 
+		GpuParamBlock* getParamBlock() const { return mParamBlock; }
+
 	protected:
 		GpuParamBlockUsage mUsage;
 		UINT32 mSize;
+
+		GpuParamBlock* mParamBlock;
 	};
 
 	class CM_EXPORT GenericGpuParamBlockBuffer : public GpuParamBlockBuffer

+ 2 - 2
CamelotCore/Include/CmGpuParams.h

@@ -12,8 +12,8 @@ namespace CamelotFramework
 		GpuParams(GpuParamDesc& paramDesc, bool transposeMatrices);
 		~GpuParams();
 
-		void setParamBlockBuffer(UINT32 slot, GpuParamBlockBufferPtr paramBlockBuffer);
-		void setParamBlockBuffer(const String& name, GpuParamBlockBufferPtr paramBlockBuffer);
+		void setParamBlockBuffer(UINT32 slot, const GpuParamBlockBufferPtr& paramBlockBuffer);
+		void setParamBlockBuffer(const String& name, const GpuParamBlockBufferPtr& paramBlockBuffer);
 
 		const GpuParamDesc& getParamDesc() const { return mParamDesc; }
 		UINT32 getDataParamSize(const String& name) const;

+ 1 - 1
CamelotCore/Include/CmMaterial.h

@@ -84,7 +84,7 @@ namespace CamelotFramework
 		void setStructData(const String& name, void* value, UINT32 size, UINT32 arrayIdx = 0)	{ return getParamStruct(name).set(value, size, arrayIdx); }
 		void setRenderQueue(INT16 renderQueue) { mRenderQueue = renderQueue; }
 
-		//void setParamBlock(const String& name, GpuParamBlockPtr paramBlock);
+		void setParamBlockBuffer(const String& name, const GpuParamBlockBufferPtr& paramBlock);
 
 		HTexture getTexture(const String& name) const										{ return getParamTexture(name).get(); }
 		HSamplerState getSamplerState(const String& name) const								{ return getParamSamplerState(name).get(); }

+ 6 - 2
CamelotCore/Source/CmGpuParamBlockBuffer.cpp

@@ -1,16 +1,18 @@
 #include "CmGpuParamBlockBuffer.h"
+#include "CmGpuParamBlock.h"
 
 namespace CamelotFramework
 {
 	GpuParamBlockBuffer::GpuParamBlockBuffer()
-		:mSize(0), mUsage(GPBU_DYNAMIC)
+		:mSize(0), mUsage(GPBU_DYNAMIC), mParamBlock(nullptr)
 	{
 
 	}
 
 	GpuParamBlockBuffer::~GpuParamBlockBuffer()
 	{
-
+		if(mParamBlock != nullptr)
+			cm_delete(mParamBlock);
 	}
 
 	void GpuParamBlockBuffer::initialize(UINT32 size, GpuParamBlockUsage usage)
@@ -18,6 +20,8 @@ namespace CamelotFramework
 		mSize = size;
 		mUsage = usage;
 
+		mParamBlock = cm_new<GpuParamBlock, PoolAlloc>(size);
+
 		CoreObject::initialize();
 	}
 

+ 13 - 21
CamelotCore/Source/CmGpuParams.cpp

@@ -143,9 +143,6 @@ namespace CamelotFramework
 		// Ensure everything is destructed
 		for(UINT32 i = 0; i < mNumParamBlocks; i++)
 		{
-			if(mParamBlocks[i] != nullptr)
-				cm_delete<PoolAlloc>(mParamBlocks[i]);
-
 			mParamBlockBuffers[i].~shared_ptr();
 		}
 
@@ -158,7 +155,7 @@ namespace CamelotFramework
 		cm_free(mData);
 	}
 
-	void GpuParams::setParamBlockBuffer(UINT32 slot, GpuParamBlockBufferPtr paramBlockBuffer)
+	void GpuParams::setParamBlockBuffer(UINT32 slot, const GpuParamBlockBufferPtr& paramBlockBuffer)
 	{
 		if(slot < 0 || slot >= mNumParamBlocks)
 		{
@@ -166,14 +163,11 @@ namespace CamelotFramework
 				toString(mNumParamBlocks - 1) + ". Requested: " + toString(slot));
 		}
 
-		if(mParamBlocks[slot] != nullptr)
-			cm_delete<PoolAlloc>(mParamBlocks[slot]);
-
-		mParamBlocks[slot] = cm_new<GpuParamBlock, PoolAlloc>(paramBlockBuffer->getSize());
 		mParamBlockBuffers[slot] = paramBlockBuffer;
+		mParamBlocks[slot] = paramBlockBuffer->getParamBlock();
 	}
 
-	void GpuParams::setParamBlockBuffer(const String& name, GpuParamBlockBufferPtr paramBlockBuffer)
+	void GpuParams::setParamBlockBuffer(const String& name, const GpuParamBlockBufferPtr& paramBlockBuffer)
 	{
 		auto iterFind = mParamDesc.paramBlocks.find(name);
 
@@ -183,11 +177,8 @@ namespace CamelotFramework
 			return;
 		}
 
-		if(mParamBlocks[iterFind->second.slot] != nullptr)
-			cm_delete<PoolAlloc>(mParamBlocks[iterFind->second.slot]);
-
-		mParamBlocks[iterFind->second.slot] = cm_new<GpuParamBlock, PoolAlloc>(paramBlockBuffer->getSize());
 		mParamBlockBuffers[iterFind->second.slot] = paramBlockBuffer;
+		mParamBlocks[iterFind->second.slot] = paramBlockBuffer->getParamBlock();
 	}
 
 	UINT32 GpuParams::getDataParamSize(const String& name) const
@@ -273,7 +264,7 @@ namespace CamelotFramework
 	BindableGpuParams GpuParams::createBindableCopy(const GpuParamsPtr& params)
 	{
 		// Allocate everything in a single block of memory to get rid of extra memory allocations
-		UINT32 paramBlockBufferSize = params->mNumParamBlocks * sizeof(GpuParamBlock*);
+		UINT32 paramBlockBufferSize = params->mNumParamBlocks * sizeof(BindableGpuParamBlock*);
 		UINT32 paramBlockBuffersBufferSize = params->mNumParamBlocks * sizeof(GpuParamBlockBufferPtr);
 		UINT32 textureBufferSize = params->mNumTextures * sizeof(HTexture);
 		UINT32 samplerStateBufferSize = params->mNumSamplerStates * sizeof(HSamplerState);
@@ -281,8 +272,8 @@ namespace CamelotFramework
 		UINT32 bufferSize = paramBlockBufferSize + paramBlockBuffersBufferSize + textureBufferSize + samplerStateBufferSize;
 		for(UINT32 i = 0; i < params->mNumParamBlocks; i++)
 		{
-			if(params->mParamBlocks[i] != nullptr)
-				bufferSize += sizeof(BindableGpuParamBlock) + params->mParamBlocks[i]->getSize();
+			if(params->mParamBlockBuffers[i] != nullptr)
+				bufferSize += sizeof(BindableGpuParamBlock) + params->mParamBlockBuffers[i]->getSize();
 		}
 
 		// TODO - Alloc using stack
@@ -306,26 +297,27 @@ namespace CamelotFramework
 		dataIter += samplerStateBufferSize;
 
 		// Copy data
-		memcpy(bindableParams.mParamBlocks, params->mParamBlocks, paramBlockBufferSize);
 		memcpy(bindableParams.mParamBlockBuffers, params->mParamBlockBuffers, paramBlockBuffersBufferSize);
 		memcpy(bindableParams.mTextures, params->mTextures, textureBufferSize);
 		memcpy(bindableParams.mSamplerStates, params->mSamplerStates, samplerStateBufferSize);
 
 		for(UINT32 i = 0; i < params->mNumParamBlocks; i++)
 		{
-			if(params->mParamBlocks[i] != nullptr)
+			if(params->mParamBlockBuffers[i] != nullptr)
 			{
-				UINT32 bufferSize = params->mParamBlocks[i]->getSize();
+				GpuParamBlock* paramBlock = params->mParamBlockBuffers[i]->getParamBlock();
+
+				UINT32 bufferSize = paramBlock->getSize();
 				bindableParams.mParamBlocks[i] = (BindableGpuParamBlock*)dataIter;
 
 				dataIter += sizeof(BindableGpuParamBlock);
 				bindableParams.mParamBlocks[i]->mData = dataIter;
 
 				dataIter += bufferSize;
-				memcpy(bindableParams.mParamBlocks[i]->mData, params->mParamBlocks[i]->getData(), bufferSize);
+				memcpy(bindableParams.mParamBlocks[i]->mData, paramBlock->getData(), bufferSize);
 
 				bindableParams.mParamBlocks[i]->mSize = bufferSize;
-				bindableParams.mParamBlocks[i]->mDirty = params->mParamBlocks[i]->isDirty();
+				bindableParams.mParamBlocks[i]->mDirty = paramBlock->isDirty();
 			}
 		}
 

+ 24 - 24
CamelotCore/Source/CmMaterial.cpp

@@ -469,30 +469,30 @@ namespace CamelotFramework
 		return getParamVec4(name).set(Vector4(value.r, value.g, value.b, value.a), arrayIdx); 
 	}
 
-	//void Material::setParamBlock(const String& name, GpuParamBlockPtr paramBlock)
-	//{
-	//	auto iterFind = mValidShareableParamBlocks.find(name);
-	//	if(iterFind == mValidShareableParamBlocks.end())
-	//	{
-	//		LOGWRN("Material doesn't have a parameter block named " + name);
-	//		return;
-	//	}
-
-	//	for(auto iter = mParametersPerPass.begin(); iter != mParametersPerPass.end(); ++iter)
-	//	{
-	//		PassParametersPtr params = *iter;
-
-	//		for(UINT32 i = 0; i < params->getNumParams(); i++)
-	//		{
-	//			GpuParamsPtr& paramPtr = params->getParamByIdx(i);
-	//			if(paramPtr)
-	//			{
-	//				if(paramPtr->hasParamBlock(name))
-	//					paramPtr->setParam(name, paramBlock);
-	//			}
-	//		}
-	//	}
-	//}
+	void Material::setParamBlockBuffer(const String& name, const GpuParamBlockBufferPtr& paramBlockBuffer)
+	{
+		auto iterFind = mValidShareableParamBlocks.find(name);
+		if(iterFind == mValidShareableParamBlocks.end())
+		{
+			LOGWRN("Material doesn't have a parameter block named " + name);
+			return;
+		}
+
+		for(auto iter = mParametersPerPass.begin(); iter != mParametersPerPass.end(); ++iter)
+		{
+			PassParametersPtr params = *iter;
+
+			for(UINT32 i = 0; i < params->getNumParams(); i++)
+			{
+				GpuParamsPtr& paramPtr = params->getParamByIdx(i);
+				if(paramPtr)
+				{
+					if(paramPtr->hasParamBlock(name))
+						paramPtr->setParamBlockBuffer(name, paramBlockBuffer);
+				}
+			}
+		}
+	}
 
 	UINT32 Material::getNumPasses() const
 	{

+ 3 - 8
Opts.txt

@@ -28,15 +28,10 @@ TransientMesh
  - Accepts starting buffer sizes, and will enlarge them as needed
   - When buffer is enlarged send a warning so user knows to use a bigger buffer next time
  - Keeps track of parts of the buffer used by GPU using GPU queries
+   - Need to implement a proper GPU query interface
+ - Keeps track of fragmentation and has an option to defragment, manually or auto after certain %
 
 ----------
 
 BIG TODO FINALLY: Reorganize GUI so it all uses one big vertex buffer (probably in the form of a TransientMesh). This means I need better support for drawing individual objects
-from a transient mesh by drawing only parts of its buffer. But only do this after I have optimized and tested the normal mesh (on all render systems)
-
----------
-
- Problem with Texture::allocateSubresourceBuffer
-  - Fix DX9 & DX11
-   - Implement properly TextureManager::getNativeFormat for DX9 and DX11
-   - After that is done remove the synchronize() point from FreeImgImporter::import, FontImporter and two texture updates in GUIManager
+from a transient mesh by drawing only parts of its buffer. But only do this after I have optimized and tested the normal mesh (on all render systems)

+ 0 - 3
TODO.txt

@@ -126,9 +126,6 @@ Low priority TODO
   - Resources::unload will deadlock if the resource isn't being loaded!
     - Maybe re-think how I handle ResourceHandle.isCreated?
   - Check D3D9/D3D11/GL resource usages. DX11 reports many unreleased objects. I'm guessing DX9 will as well. Not sure how to check OpenGL.
- - Shared GPU buffers
-   - wouldn't work atm due to the way I update the buffers (and the way I mark them dirty)
-   - Material::setParamBlock is commented out
  - onMovedOrResized is still used by Viewport while that same callback is offered by RenderWindowManager. There is no need to have them in both places.
  - Texture "ScaleToFit" will cause the texture to repeat instead of clipping the image. e.g. a 50x20 texture placed on an 50x100 area will repeat 5x
  - When writing to mesh vertex buffer in Mesh::writeSubresource that requires a color flip I need to create a temporary copy of the