Browse Source

Fixed OpenGL queries as they were being incorrectly created
Fixed MeshHeap memory corruption
Fixed an issue with OpenGL and zero sized buffers
Fixed some invalid range checks
Ensured QueueManager is updated every frame

Marko Pintera 12 years ago
parent
commit
4a861a2399

+ 2 - 2
CamelotClient/CamelotClient.cpp

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

+ 3 - 0
CamelotCore/Include/CmMeshBase.h

@@ -46,6 +46,9 @@ namespace CamelotFramework
 		 */
 		 */
 		UINT32 getNumSubMeshes() const;
 		UINT32 getNumSubMeshes() const;
 
 
+		UINT32 getNumVertices() const { return mNumVertices; }
+		UINT32 getNumIndices() const { return mNumIndices; }
+
 		/**
 		/**
 		 * @brief	Get vertex data used for rendering.
 		 * @brief	Get vertex data used for rendering.
 		 *  
 		 *  

+ 4 - 1
CamelotCore/Source/CmApplication.cpp

@@ -30,6 +30,7 @@
 #include "CmCoreThread.h"
 #include "CmCoreThread.h"
 #include "CmStringTable.h"
 #include "CmStringTable.h"
 #include "CmProfiler.h"
 #include "CmProfiler.h"
+#include "CmQueryManager.h"
 
 
 #include "CmMaterial.h"
 #include "CmMaterial.h"
 #include "CmShader.h"
 #include "CmShader.h"
@@ -105,10 +106,12 @@ namespace CamelotFramework
 
 
 			PROFILE_CALL(gSceneManager().update(), "SceneManager");
 			PROFILE_CALL(gSceneManager().update(), "SceneManager");
 
 
+			gCoreThread().queueCommand(boost::bind(&Application::beginCoreProfiling, this));
+			gCoreThread().queueCommand(boost::bind(&QueryManager::update, QueryManager::instancePtr()));
+
 			if(!mainLoopCallback.empty())
 			if(!mainLoopCallback.empty())
 				mainLoopCallback();
 				mainLoopCallback();
 
 
-			gCoreThread().queueCommand(boost::bind(&Application::beginCoreProfiling, this));
 			PROFILE_CALL(RendererManager::instance().getActive()->renderAll(), "Render");
 			PROFILE_CALL(RendererManager::instance().getActive()->renderAll(), "Render");
 
 
 			// Core and sim thread run in lockstep. This will result in a larger input latency than if I was 
 			// Core and sim thread run in lockstep. This will result in a larger input latency than if I was 

+ 2 - 2
CamelotCore/Source/CmMeshBase.cpp

@@ -30,7 +30,7 @@ namespace CamelotFramework
 
 
 	void MeshBase::addSubMesh(UINT32 indexOffset, UINT32 indexCount, DrawOperationType drawOp)
 	void MeshBase::addSubMesh(UINT32 indexOffset, UINT32 indexCount, DrawOperationType drawOp)
 	{
 	{
-		if((indexOffset + indexCount) >= mNumIndices)
+		if((indexOffset + indexCount) > mNumIndices)
 		{
 		{
 			LOGWRN("Provided sub-mesh references indexes out of range. Sub-mesh range: " 
 			LOGWRN("Provided sub-mesh references indexes out of range. Sub-mesh range: " 
 				+ toString(indexOffset) + " .. " + toString(indexOffset + indexCount) + "." \
 				+ toString(indexOffset) + " .. " + toString(indexOffset + indexCount) + "." \
@@ -48,7 +48,7 @@ namespace CamelotFramework
 
 
 		for(auto& subMesh : subMeshes)
 		for(auto& subMesh : subMeshes)
 		{
 		{
-			if((subMesh.indexOffset + subMesh.indexCount) >= mNumIndices)
+			if((subMesh.indexOffset + subMesh.indexCount) > mNumIndices)
 			{
 			{
 				LOGWRN("Provided sub-mesh references indexes out of range. Sub-mesh range: " 
 				LOGWRN("Provided sub-mesh references indexes out of range. Sub-mesh range: " 
 					+ toString(subMesh.indexOffset) + " .. " + toString(subMesh.indexOffset + subMesh.indexCount) + "." \
 					+ toString(subMesh.indexOffset) + " .. " + toString(subMesh.indexOffset + subMesh.indexCount) + "." \

+ 20 - 15
CamelotCore/Source/CmMeshHeap.cpp

@@ -178,9 +178,15 @@ namespace CamelotFramework
 		ChunkData& vertChunk = mVertChunks[freeVertChunkIdx];
 		ChunkData& vertChunk = mVertChunks[freeVertChunkIdx];
 		ChunkData& idxChunk = mIdxChunks[freeIdxChunkIdx];
 		ChunkData& idxChunk = mIdxChunks[freeIdxChunkIdx];
 
 
+		UINT32 vertChunkStart = vertChunk.start;
+		UINT32 idxChunkStart = idxChunk.start;
+
 		UINT32 remainingNumVerts = vertChunk.size - meshData->getNumVertices();
 		UINT32 remainingNumVerts = vertChunk.size - meshData->getNumVertices();
 		UINT32 remainingNumIdx = idxChunk.size - meshData->getNumIndices();
 		UINT32 remainingNumIdx = idxChunk.size - meshData->getNumIndices();
 
 
+		vertChunk.size = meshData->getNumVertices();
+		idxChunk.size = meshData->getNumIndices();
+
 		if(remainingNumVerts > 0)
 		if(remainingNumVerts > 0)
 		{
 		{
 			if(!mEmptyVertChunks.empty())
 			if(!mEmptyVertChunks.empty())
@@ -189,14 +195,14 @@ namespace CamelotFramework
 				ChunkData& emptyChunk = mVertChunks[emptyChunkIdx];
 				ChunkData& emptyChunk = mVertChunks[emptyChunkIdx];
 				mEmptyVertChunks.pop();
 				mEmptyVertChunks.pop();
 
 
-				emptyChunk.start = vertChunk.start + meshData->getNumVertices();
+				emptyChunk.start = vertChunkStart + meshData->getNumVertices();
 				emptyChunk.size = remainingNumVerts;
 				emptyChunk.size = remainingNumVerts;
 			}
 			}
 			else
 			else
 			{
 			{
 				ChunkData newChunk;
 				ChunkData newChunk;
 				newChunk.size = remainingNumVerts;
 				newChunk.size = remainingNumVerts;
-				newChunk.start = vertChunk.start + meshData->getNumVertices();
+				newChunk.start = vertChunkStart + meshData->getNumVertices();
 
 
 				mVertChunks.push_back(newChunk);
 				mVertChunks.push_back(newChunk);
 				mFreeVertChunks.push_back((UINT32)(mVertChunks.size() - 1));
 				mFreeVertChunks.push_back((UINT32)(mVertChunks.size() - 1));
@@ -211,23 +217,20 @@ namespace CamelotFramework
 				ChunkData& emptyChunk = mIdxChunks[emptyChunkIdx];
 				ChunkData& emptyChunk = mIdxChunks[emptyChunkIdx];
 				mEmptyIdxChunks.pop();
 				mEmptyIdxChunks.pop();
 
 
-				emptyChunk.start = idxChunk.start + meshData->getNumIndices();
+				emptyChunk.start = idxChunkStart + meshData->getNumIndices();
 				emptyChunk.size = remainingNumIdx;
 				emptyChunk.size = remainingNumIdx;
 			}
 			}
 			else
 			else
 			{
 			{
 				ChunkData newChunk;
 				ChunkData newChunk;
 				newChunk.size = remainingNumIdx;
 				newChunk.size = remainingNumIdx;
-				newChunk.start = idxChunk.start + meshData->getNumIndices();
+				newChunk.start = idxChunkStart + meshData->getNumIndices();
 
 
 				mIdxChunks.push_back(newChunk);
 				mIdxChunks.push_back(newChunk);
 				mFreeIdxChunks.push_back((UINT32)(mIdxChunks.size() - 1));
 				mFreeIdxChunks.push_back((UINT32)(mIdxChunks.size() - 1));
 			}
 			}
 		}
 		}
 
 
-		vertChunk.size = meshData->getNumVertices();
-		idxChunk.size = meshData->getNumIndices();
-
 		AllocatedData newAllocData;
 		AllocatedData newAllocData;
 		newAllocData.vertChunkIdx = freeVertChunkIdx;
 		newAllocData.vertChunkIdx = freeVertChunkIdx;
 		newAllocData.idxChunkIdx = freeIdxChunkIdx;
 		newAllocData.idxChunkIdx = freeIdxChunkIdx;
@@ -245,8 +248,8 @@ namespace CamelotFramework
 			UINT32 vertSize = mVertexData->vertexDeclaration->getVertexSize(i);
 			UINT32 vertSize = mVertexData->vertexDeclaration->getVertexSize(i);
 			VertexBufferPtr vertexBuffer = mVertexData->getBuffer(i);
 			VertexBufferPtr vertexBuffer = mVertexData->getBuffer(i);
 
 
-			UINT8* vertDest = mCPUVertexData[i] + vertChunk.start * vertSize;
-			memcpy(vertDest, meshData->getStreamData(i), vertChunk.start * vertSize);
+			UINT8* vertDest = mCPUVertexData[i] + vertChunkStart * vertSize;
+			memcpy(vertDest, meshData->getStreamData(i), vertChunkStart * vertSize);
 
 
 			if(vertexBuffer->vertexColorReqRGBFlip())
 			if(vertexBuffer->vertexColorReqRGBFlip())
 			{
 			{
@@ -268,15 +271,15 @@ namespace CamelotFramework
 				}
 				}
 			}
 			}
 
 
-			vertexBuffer->writeData(vertChunk.start * vertSize, vertChunk.size * vertSize, vertDest, BufferWriteType::NoOverwrite);
+			vertexBuffer->writeData(vertChunkStart * vertSize, meshData->getNumVertices() * vertSize, vertDest, BufferWriteType::NoOverwrite);
 		}
 		}
 
 
 		IndexBufferPtr indexBuffer = mIndexData->indexBuffer;
 		IndexBufferPtr indexBuffer = mIndexData->indexBuffer;
 		UINT32 idxSize = indexBuffer->getIndexSize();
 		UINT32 idxSize = indexBuffer->getIndexSize();
 
 
-		UINT8* idxDest = mCPUIndexData + idxChunk.start * idxSize;
-		memcpy(idxDest, meshData->getIndexData(), idxChunk.start * idxSize);
-		indexBuffer->writeData(idxChunk.start * idxSize, idxChunk.size * idxSize, idxDest, BufferWriteType::NoOverwrite);
+		UINT8* idxDest = mCPUIndexData + idxChunkStart * idxSize;
+		memcpy(idxDest, meshData->getIndexData(), idxChunkStart * idxSize);
+		indexBuffer->writeData(idxChunkStart * idxSize, meshData->getNumIndices() * idxSize, idxDest, BufferWriteType::NoOverwrite);
 	}
 	}
 
 
 	void MeshHeap::deallocInternal(UINT32 meshId)
 	void MeshHeap::deallocInternal(UINT32 meshId)
@@ -341,7 +344,8 @@ namespace CamelotFramework
 				cm_free(oldBuffer);
 				cm_free(oldBuffer);
 			}
 			}
 
 
-			vertexBuffer->writeData(0, destOffset * vertSize, buffer, BufferWriteType::NoOverwrite);
+			if(destOffset > 0)
+				vertexBuffer->writeData(0, destOffset * vertSize, buffer, BufferWriteType::NoOverwrite);
 
 
 			mCPUVertexData[i] = buffer;
 			mCPUVertexData[i] = buffer;
 		}
 		}
@@ -414,7 +418,8 @@ namespace CamelotFramework
 			cm_free(oldBuffer);
 			cm_free(oldBuffer);
 		}
 		}
 
 
-		mIndexData->indexBuffer->writeData(0, destOffset * idxSize, buffer, BufferWriteType::NoOverwrite);
+		if(destOffset > 0)
+			mIndexData->indexBuffer->writeData(0, destOffset * idxSize, buffer, BufferWriteType::NoOverwrite);
 
 
 		mCPUIndexData = buffer;
 		mCPUIndexData = buffer;
 
 

+ 2 - 8
CamelotGLRenderer/Source/CmGLEventQuery.cpp

@@ -5,18 +5,12 @@ namespace CamelotFramework
 	GLEventQuery::GLEventQuery()
 	GLEventQuery::GLEventQuery()
 		:mQueryObj(0)
 		:mQueryObj(0)
 	{
 	{
-		GLuint queries[1];
-		queries[0] = mQueryObj;
-
-		glGenQueries(1, queries);
+		glGenQueries(1, &mQueryObj);
 	}
 	}
 
 
 	GLEventQuery::~GLEventQuery()
 	GLEventQuery::~GLEventQuery()
 	{
 	{
-		GLuint queries[1];
-		queries[0] = mQueryObj;
-
-		glDeleteQueries(1, queries);
+		glDeleteQueries(1, &mQueryObj);
 	}
 	}
 
 
 	void GLEventQuery::begin()
 	void GLEventQuery::begin()

+ 3 - 3
CamelotGLRenderer/Source/CmGLTimerQuery.cpp

@@ -8,10 +8,10 @@ namespace CamelotFramework
 		mTimeDelta(0.0f), mFinalized(false)
 		mTimeDelta(0.0f), mFinalized(false)
 	{
 	{
 		GLuint queries[2];
 		GLuint queries[2];
-		queries[0] = mQueryStartObj;
-		queries[1] = mQueryEndObj;
-
 		glGenQueries(2, queries);
 		glGenQueries(2, queries);
+
+		mQueryStartObj = queries[0];
+		mQueryEndObj = queries[1];
 	}
 	}
 
 
 	GLTimerQuery::~GLTimerQuery()
 	GLTimerQuery::~GLTimerQuery()

+ 0 - 2
CamelotUtility/Source/CmTime.cpp

@@ -32,8 +32,6 @@ namespace CamelotFramework
 
 
 	UINT64 Time::getTimePrecise() const
 	UINT64 Time::getTimePrecise() const
 	{
 	{
-		// TODO Low priority - Timer internally calls high performance OS specific methods. We can go a step further and use CPU specific instructions, which would
-		// (likely) give even more precise measurements in cycles. (RDTSC instruction - although that might not be valid with todays variable CPU clocks)
 		return mTimer->getMicroseconds();
 		return mTimer->getMicroseconds();
 	}
 	}