소스 검색

Added CPUReadable flag to meshes and textures since this is no longer assumed by default (due to Vulkan usage flags)

BearishSun 9 년 전
부모
커밋
b019758427
34개의 변경된 파일215개의 추가작업 그리고 64개의 파일을 삭제
  1. 3 1
      Source/BansheeCore/Include/BsMeshBase.h
  2. 9 2
      Source/BansheeCore/Include/BsMeshImportOptions.h
  3. 2 1
      Source/BansheeCore/Include/BsMeshImportOptionsRTTI.h
  4. 15 2
      Source/BansheeCore/Include/BsMeshRTTI.h
  5. 3 1
      Source/BansheeCore/Include/BsTexture.h
  6. 8 1
      Source/BansheeCore/Include/BsTextureImportOptions.h
  7. 5 1
      Source/BansheeCore/Include/BsTextureImportOptionsRTTI.h
  8. 21 4
      Source/BansheeCore/Include/BsTextureRTTI.h
  9. 12 2
      Source/BansheeCore/Source/BsMesh.cpp
  10. 2 2
      Source/BansheeCore/Source/BsMeshImportOptions.cpp
  11. 2 2
      Source/BansheeCore/Source/BsRenderTexture.cpp
  12. 7 9
      Source/BansheeCore/Source/BsTexture.cpp
  13. 1 2
      Source/BansheeCore/Source/BsTextureImportOptions.cpp
  14. 2 2
      Source/BansheeD3D11RenderAPI/Source/BsD3D11Texture.cpp
  15. 1 2
      Source/BansheeEditor/Source/BsScenePicking.cpp
  16. 1 1
      Source/BansheeEngine/Source/BsBuiltinResources.cpp
  17. 8 2
      Source/BansheeFBXImporter/Source/BsFBXImporter.cpp
  18. 4 1
      Source/BansheeFreeImgImporter/Source/BsFreeImgImporter.cpp
  19. 4 0
      Source/BansheeUtility/Include/BsFrameworkConfig.h
  20. 0 2
      Source/BansheeUtility/Include/BsPlatformDefines.h
  21. 2 6
      Source/BansheeUtility/Include/BsPrerequisitesUtil.h
  22. 0 3
      Source/CMake/BsEngineConfig.h.in
  23. 4 0
      Source/CMake/BsFrameworkConfig.h.in
  24. 8 1
      Source/CMakeLists.txt
  25. 5 0
      Source/MBansheeEditor/Inspectors/MeshInspector.cs
  26. 4 0
      Source/MBansheeEditor/Inspectors/Texture2DInspector.cs
  27. 30 0
      Source/MBansheeEditor/Windows/Library/ImportOptions.cs
  28. 5 2
      Source/MBansheeEditor/Windows/Scene/SceneWindow.cs
  29. 7 2
      Source/MBansheeEngine/Rendering/Mesh.cs
  30. 7 2
      Source/MBansheeEngine/Rendering/Texture.cs
  31. 4 0
      Source/SBansheeEditor/Include/BsScriptImportOptions.h
  32. 24 0
      Source/SBansheeEditor/Source/BsScriptImportOptions.cpp
  33. 1 1
      Source/SBansheeEngine/Include/BsScriptRenderTexture2D.h
  34. 4 7
      Source/SBansheeEngine/Source/BsScriptRenderTexture2D.cpp

+ 3 - 1
Source/BansheeCore/Include/BsMeshBase.h

@@ -21,7 +21,9 @@ namespace BansheeEngine
 	{
 		MU_STATIC, /**< Specify for a mesh that is not often updated from the CPU. */
 		MU_DYNAMIC, /**< Specify for a mesh that is often updated from the CPU. */
-		MU_CPUCACHED = 0x1000 /**< All mesh data will also be cached in CPU memory, making it readable with GPU reads. */
+		/** All mesh data will also be cached in CPU memory, making it available for fast read access from the CPU. */
+		MU_CPUCACHED = 0x1000, 
+		MU_CPUREADABLE = 0x2000 /**< Allows the CPU to directly read the mesh data buffers from the GPU. */
 	};
 
 	/** Properties of a Mesh. Shared between sim and core thread versions of a Mesh. */

+ 9 - 2
Source/BansheeCore/Include/BsMeshImportOptions.h

@@ -65,9 +65,15 @@ namespace BansheeEngine
 		MeshImportOptions();
 
 		/**	Sets whether the texture data is also stored in CPU memory. */
-		void setCPUReadable(bool readable) { mCPUReadable = readable; }
+		void setCPUCached(bool cached) { mCPUCached = cached; }
 		
 		/**	Retrieves whether the texture data is also stored in CPU memory. */
+		bool getCPUCached() const { return mCPUCached; }
+
+		/**	Sets whether the texture data can be read directly from the GPU. */
+		void setCPUReadable(bool readable) { mCPUReadable = readable; }
+
+		/**	Retrieves whether the texture data can be read directly from the GPU. */
 		bool getCPUReadable() const { return mCPUReadable; }
 
 		/**	Sets a value that controls should mesh normals be imported if available. */
@@ -163,7 +169,7 @@ namespace BansheeEngine
 		bool getImportRootMotion() const { return mImportRootMotion; }
 
 	private:
-		bool mCPUReadable;
+		bool mCPUCached;
 		bool mImportNormals;
 		bool mImportTangents;
 		bool mImportBlendShapes;
@@ -172,6 +178,7 @@ namespace BansheeEngine
 		bool mReduceKeyFrames;
 		bool mImportRootMotion;
 		float mImportScale;
+		bool mCPUReadable;
 		CollisionMeshType mCollisionMeshType;
 		Vector<AnimationSplitInfo> mAnimationSplits;
 		Vector<ImportedAnimationEvents> mAnimationEvents;

+ 2 - 1
Source/BansheeCore/Include/BsMeshImportOptionsRTTI.h

@@ -18,7 +18,7 @@ namespace BansheeEngine
 	{
 	private:
 		BS_BEGIN_RTTI_MEMBERS
-			BS_RTTI_MEMBER_PLAIN(mCPUReadable, 0)
+			BS_RTTI_MEMBER_PLAIN(mCPUCached, 0)
 			BS_RTTI_MEMBER_PLAIN(mImportNormals, 1)
 			BS_RTTI_MEMBER_PLAIN(mImportTangents, 2)
 			BS_RTTI_MEMBER_PLAIN(mImportBlendShapes, 3)
@@ -30,6 +30,7 @@ namespace BansheeEngine
 			BS_RTTI_MEMBER_PLAIN(mReduceKeyFrames, 9)
 			BS_RTTI_MEMBER_REFL_ARRAY(mAnimationEvents, 10)
 			BS_RTTI_MEMBER_PLAIN(mImportRootMotion, 11)
+			BS_RTTI_MEMBER_PLAIN(mCPUReadable, 12)
 		BS_END_RTTI_MEMBERS
 	public:
 		MeshImportOptionsRTTI()

+ 15 - 2
Source/BansheeCore/Include/BsMeshRTTI.h

@@ -30,10 +30,23 @@ namespace BansheeEngine
 		SPtr<MeshData> getMeshData(Mesh* obj) 
 		{ 
 			SPtr<MeshData> meshData = obj->allocateSubresourceBuffer(0);
+			int usage = obj->mUsage;
 
-			obj->readSubresource(gCoreAccessor(), 0, meshData);
-			gCoreAccessor().submitToCoreThread(true);
+			if((usage & MU_CPUREADABLE) || BS_EDITOR_BUILD)
+			{
+				obj->readSubresource(gCoreAccessor(), 0, meshData);
+				gCoreAccessor().submitToCoreThread(true);
 
+				return meshData;
+			}
+
+			if(usage & MU_CPUCACHED)
+			{
+				obj->readData(*meshData);
+				return meshData;
+			}
+
+			LOGERR("Attempting to save a mesh that isn't flagged with either MU_CPUCACHED OR MU_GPUREADABLE flags.");
 			return meshData;
 		}
 

+ 3 - 1
Source/BansheeCore/Include/BsTexture.h

@@ -22,7 +22,9 @@ namespace BansheeEngine
 		TU_RENDERTARGET = 0x200, /**< Texture that can be rendered to by the GPU. */
 		TU_DEPTHSTENCIL = 0x400, /**< Texture used as a depth/stencil buffer by the GPU. */
 		TU_LOADSTORE = 0x800, /**< Texture that allows load/store operations from the GPU program. */
-		TU_CPUCACHED = 0x1000, /**< Ensures all texture data will also be cached in system memory. */
+		/** All mesh data will also be cached in CPU memory, making it available for fast read access from the CPU. */
+		TU_CPUCACHED = 0x1000, 
+		TU_CPUREADABLE = 0x2000, /**< Allows the CPU to directly read the texture data buffers from the GPU. */
 		TU_DEFAULT = TU_STATIC
     };
 

+ 8 - 1
Source/BansheeCore/Include/BsTextureImportOptions.h

@@ -31,6 +31,9 @@ namespace BansheeEngine
 		void setMaxMip(UINT32 maxMip) { mMaxMip = maxMip; }
 
 		/** Sets whether the texture data is also stored in main memory, available for fast CPU access. */
+		void setCPUCached(bool cached) { mCPUCached = cached; }
+
+		/** Sets whether the texture data can be read directly from the GPU. */
 		void setCPUReadable(bool readable) { mCPUReadable = readable; }
 
 		/** 
@@ -52,6 +55,9 @@ namespace BansheeEngine
 		UINT32 getMaxMip() const { return mMaxMip; }
 
 		/** Retrieves whether the texture data is also stored in main memory, available for fast CPU access. */
+		bool getCPUCached() const { return mCPUCached; }
+
+		/** Retrieves whether the texture data can be read directly from the GPU. */
 		bool getCPUReadable() const { return mCPUReadable; }
 
 		/**
@@ -66,13 +72,14 @@ namespace BansheeEngine
 	public:
 		friend class TextureImportOptionsRTTI;
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const override;
+		RTTITypeBase* getRTTI() const override;
 
 	private:
 		PixelFormat mFormat;
 		bool mGenerateMips;
 		UINT32 mMaxMip;
 		bool mCPUReadable;
+		bool mCPUCached;
 		bool mSRGB;
 	};
 

+ 5 - 1
Source/BansheeCore/Include/BsTextureImportOptionsRTTI.h

@@ -25,6 +25,9 @@ namespace BansheeEngine
 		UINT32& getMaxMip(TextureImportOptions* obj) { return obj->mMaxMip; }
 		void setMaxMip(TextureImportOptions* obj, UINT32& value) { obj->mMaxMip = value; }
 
+		bool& getCPUCached(TextureImportOptions* obj) { return obj->mCPUCached; }
+		void setCPUCached(TextureImportOptions* obj, bool& value) { obj->mCPUCached = value; }
+
 		bool& getCPUReadable(TextureImportOptions* obj) { return obj->mCPUReadable; }
 		void setCPUReadable(TextureImportOptions* obj, bool& value) { obj->mCPUReadable = value; }
 
@@ -37,8 +40,9 @@ namespace BansheeEngine
 			addPlainField("mPixelFormat", 0, &TextureImportOptionsRTTI::getPixelFormat, &TextureImportOptionsRTTI::setPixelFormat);
 			addPlainField("mGenerateMips", 1, &TextureImportOptionsRTTI::getGenerateMips, &TextureImportOptionsRTTI::setGenerateMips);
 			addPlainField("mMaxMip", 2, &TextureImportOptionsRTTI::getMaxMip, &TextureImportOptionsRTTI::setMaxMip);
-			addPlainField("mCPUReadable", 3, &TextureImportOptionsRTTI::getCPUReadable, &TextureImportOptionsRTTI::setCPUReadable);
+			addPlainField("mCPUCached", 3, &TextureImportOptionsRTTI::getCPUCached, &TextureImportOptionsRTTI::setCPUCached);
 			addPlainField("mSRGB", 4, &TextureImportOptionsRTTI::getSRGB, &TextureImportOptionsRTTI::setSRGB);
+			addPlainField("mCPUReadable", 5, &TextureImportOptionsRTTI::getCPUReadable, &TextureImportOptionsRTTI::setCPUReadable);
 		}
 
 		const String& getRTTIName() override

+ 21 - 4
Source/BansheeCore/Include/BsTextureRTTI.h

@@ -38,8 +38,11 @@ namespace BansheeEngine
 		{ 
 			// Render target and depth stencil texture formats are for in-memory use only
 			// and don't make sense when serialized
-			if (val == TU_DEPTHSTENCIL || val == TU_RENDERTARGET)
-				obj->mProperties.mDesc.usage = TU_STATIC;
+			if ((val & (TU_DEPTHSTENCIL | TU_RENDERTARGET)) != 0)
+			{
+				obj->mProperties.mDesc.usage &= ~(TU_DEPTHSTENCIL | TU_RENDERTARGET);
+				obj->mProperties.mDesc.usage |= TU_STATIC;
+			}
 			else
 				obj->mProperties.mDesc.usage = val;
 		}
@@ -55,9 +58,23 @@ namespace BansheeEngine
 			UINT32 subresourceIdx = obj->mProperties.mapToSubresourceIdx(face, mipmap);
 			SPtr<PixelData> pixelData = obj->mProperties.allocateSubresourceBuffer(subresourceIdx);
 
-			obj->readSubresource(gCoreAccessor(), subresourceIdx, pixelData);
-			gCoreAccessor().submitToCoreThread(true);
+			int usage = obj->getProperties().getUsage();
+
+			if (usage & TU_CPUREADABLE || BS_EDITOR_BUILD)
+			{
+				obj->readSubresource(gCoreAccessor(), subresourceIdx, pixelData);
+				gCoreAccessor().submitToCoreThread(true);
+
+				return pixelData;
+			}
+
+			if(usage & TU_CPUCACHED)
+			{
+				obj->readData(*pixelData, mipmap, face);
+				return pixelData;
+			}
 
+			LOGERR("Attempting to save a texture that isn't flagged with either TU_CPUCACHED OR TU_GPUREADABLE flags.");
 			return pixelData;
 		}
 

+ 12 - 2
Source/BansheeCore/Source/BsMesh.cpp

@@ -38,11 +38,15 @@ namespace BansheeEngine
 		THROW_IF_NOT_CORE_THREAD;
 
 		bool isDynamic = (mUsage & MU_DYNAMIC) != 0;
+		bool isGpuReadable = (mUsage & MU_CPUREADABLE) != 0 || BS_EDITOR_BUILD;
+
+		int usage = isDynamic ? GBU_DYNAMIC : GBU_STATIC;
+		usage |= isGpuReadable ? GBU_READABLE : 0;
 
 		INDEX_BUFFER_DESC ibDesc;
 		ibDesc.indexType = mIndexType;
 		ibDesc.numIndices = mProperties.mNumIndices;
-		ibDesc.usage = isDynamic ? GBU_DYNAMIC : GBU_STATIC;
+		ibDesc.usage = (GpuBufferUsage)usage;
 
 		mIndexBuffer = IndexBufferCore::create(ibDesc, mDeviceMask);
 
@@ -59,7 +63,7 @@ namespace BansheeEngine
 			VERTEX_BUFFER_DESC vbDesc;
 			vbDesc.vertexSize = mVertexData->vertexDeclaration->getProperties().getVertexSize(i);
 			vbDesc.numVerts = mVertexData->vertexCount;
-			vbDesc.usage = isDynamic ? GBU_DYNAMIC : GBU_STATIC;
+			vbDesc.usage = (GpuBufferUsage)usage;
 
 			SPtr<VertexBufferCore> vertexBuffer = VertexBufferCore::create(vbDesc, mDeviceMask);
 			mVertexData->setBuffer(i, vertexBuffer);
@@ -211,6 +215,12 @@ namespace BansheeEngine
 	{
 		THROW_IF_NOT_CORE_THREAD;
 
+		if ((mUsage & MU_CPUREADABLE) == 0 && !BS_EDITOR_BUILD)
+		{
+			LOGERR("Attempting to read GPU data from a mesh that is created without a CPU readable flag.");
+			return;
+		}
+
 		IndexType indexType = IT_32BIT;
 		if (mIndexBuffer)
 			indexType = mIndexBuffer->getProperties().getType();

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

@@ -26,8 +26,8 @@ namespace BansheeEngine
 	}
 
 	MeshImportOptions::MeshImportOptions()
-		: mCPUReadable(false), mImportNormals(true), mImportTangents(true), mImportBlendShapes(false), mImportSkin(false)
-		, mImportAnimation(false), mReduceKeyFrames(true), mImportRootMotion(false), mImportScale(1.0f)
+		: mCPUCached(false), mImportNormals(true), mImportTangents(true), mImportBlendShapes(false), mImportSkin(false)
+		, mImportAnimation(false), mReduceKeyFrames(true), mImportRootMotion(false), mImportScale(1.0f), mCPUReadable(false)
 		, mCollisionMeshType(CollisionMeshType::None)
 	{ }
 

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

@@ -84,7 +84,7 @@ namespace BansheeEngine
 			{
 				SPtr<TextureCore> texture = mDesc.colorSurfaces[i].texture;
 
-				if (texture->getProperties().getUsage() != TU_RENDERTARGET)
+				if ((texture->getProperties().getUsage() & TU_RENDERTARGET) == 0)
 					BS_EXCEPT(InvalidParametersException, "Provided texture is not created with render target usage.");
 
 				mColorSurfaces[i] = TextureCore::requestView(texture, mDesc.colorSurfaces[i].mipLevel, 1,
@@ -96,7 +96,7 @@ namespace BansheeEngine
 		{
 			SPtr<TextureCore> texture = mDesc.depthStencilSurface.texture;
 
-			if (texture->getProperties().getUsage() != TU_DEPTHSTENCIL)
+			if ((texture->getProperties().getUsage() & TU_DEPTHSTENCIL) == 0)
 				BS_EXCEPT(InvalidParametersException, "Provided texture is not created with depth stencil usage.");
 
 			mDepthStencilSurface = TextureCore::requestView(texture, mDesc.depthStencilSurface.mipLevel, 1,

+ 7 - 9
Source/BansheeCore/Source/BsTexture.cpp

@@ -98,20 +98,12 @@ namespace BansheeEngine
 
 		if(discardEntireBuffer)
 		{
-			if(mProperties.getUsage() != TU_DYNAMIC)
+			if((mProperties.getUsage() & TU_DYNAMIC) == 0)
 			{
 				// Buffer discard is enabled but buffer was not created as dynamic. Disabling discard.
 				discardEntireBuffer = false;
 			}
 		}
-		else
-		{
-			if (mProperties.getUsage() == TU_DYNAMIC)
-			{
-				LOGWRN("Buffer discard is not enabled but buffer was not created as dynamic. Enabling discard.");
-				discardEntireBuffer = true;
-			}
-		}
 
 		UINT32 face = 0;
 		UINT32 mip = 0;
@@ -124,6 +116,12 @@ namespace BansheeEngine
 	{
 		THROW_IF_NOT_CORE_THREAD;
 
+		if ((mProperties.getUsage() & TU_CPUREADABLE) == 0 && !BS_EDITOR_BUILD)
+		{
+			LOGERR("Attempting to read GPU data from a texture that is created without a CPU readable flag.");
+			return;
+		}
+
 		UINT32 face = 0;
 		UINT32 mip = 0;
 		mProperties.mapFromSubresourceIdx(subresourceIdx, face, mip);

+ 1 - 2
Source/BansheeCore/Source/BsTextureImportOptions.cpp

@@ -6,8 +6,7 @@
 namespace BansheeEngine
 {
 	TextureImportOptions::TextureImportOptions()
-		:mFormat(PF_R8G8B8A8), mGenerateMips(false), mMaxMip(0), 
-		mCPUReadable(false), mSRGB(false)
+		: mFormat(PF_R8G8B8A8), mGenerateMips(false), mMaxMip(0), mCPUReadable(false), mCPUCached(false), mSRGB(false)
 	{ }
 
 	/************************************************************************/

+ 2 - 2
Source/BansheeD3D11RenderAPI/Source/BsD3D11Texture.cpp

@@ -124,7 +124,7 @@ namespace BansheeEngine
 		}
 		else
 		{
-			if (mProperties.getUsage() == TU_DYNAMIC)
+			if ((mProperties.getUsage() & TU_DYNAMIC) != 0)
 			{
 				UINT8* data = (UINT8*)map(mTex, flags, face, mipLevel, rowPitch, slicePitch);
 				lockedArea.setExternalBuffer(data);
@@ -146,7 +146,7 @@ namespace BansheeEngine
 			unmapstagingbuffer();
 		else
 		{
-			if (mProperties.getUsage() == TU_DYNAMIC)
+			if ((mProperties.getUsage() & TU_DYNAMIC) != 0)
 				unmap(mTex);
 			else
 				unmapstaticbuffer();

+ 1 - 2
Source/BansheeEditor/Source/BsScenePicking.cpp

@@ -294,7 +294,7 @@ namespace BansheeEngine
 		normalTexDesc.width = outputTextureProperties.getWidth();
 		normalTexDesc.height = outputTextureProperties.getHeight();
 		normalTexDesc.format = PF_R8G8B8A8;
-		normalTexDesc.usage = TU_RENDERTARGET;
+		normalTexDesc.usage = TU_RENDERTARGET | TU_CPUREADABLE;
 
 		SPtr<TextureCore> normalsTexture = TextureCore::create(normalTexDesc);
 		SPtr<TextureCore> depthTexture = rtt->getDepthStencilTexture();
@@ -372,7 +372,6 @@ namespace BansheeEngine
 
 		if (rtProps.isWindow())
 		{
-			// TODO: When I do implement this then I will likely want a method in RenderTarget that unifies both render window and render texture readback
 			BS_EXCEPT(NotImplementedException, "Picking is not supported on render windows as framebuffer readback methods aren't implemented");
 		}
 

+ 1 - 1
Source/BansheeEngine/Source/BsBuiltinResources.cpp

@@ -376,7 +376,7 @@ namespace BansheeEngine
 			Path outputPath = mBuiltinDataFolder + (WString(SplashScreenName) + L".asset");
 
 			auto textureIO = gImporter().createImportOptions<TextureImportOptions>(inputPath);
-			textureIO->setCPUReadable(true);
+			textureIO->setCPUCached(true);
 			textureIO->setGenerateMipmaps(false);
 			HTexture splashTexture = gImporter().import<Texture>(inputPath, textureIO);
 

+ 8 - 2
Source/BansheeFBXImporter/Source/BsFBXImporter.cpp

@@ -127,9 +127,12 @@ namespace BansheeEngine
 		const MeshImportOptions* meshImportOptions = static_cast<const MeshImportOptions*>(importOptions.get());
 
 		desc.usage = MU_STATIC;
-		if (meshImportOptions->getCPUReadable())
+		if (meshImportOptions->getCPUCached())
 			desc.usage |= MU_CPUCACHED;
 
+		if (meshImportOptions->getCPUReadable())
+			desc.usage |= MU_CPUREADABLE;
+
 		SPtr<Mesh> mesh = Mesh::_createPtr(rendererMeshData->getData(), desc);
 
 		WString fileName = filePath.getWFilename(false);
@@ -149,9 +152,12 @@ namespace BansheeEngine
 		const MeshImportOptions* meshImportOptions = static_cast<const MeshImportOptions*>(importOptions.get());
 
 		desc.usage = MU_STATIC;
-		if (meshImportOptions->getCPUReadable())
+		if (meshImportOptions->getCPUCached())
 			desc.usage |= MU_CPUCACHED;
 
+		if (meshImportOptions->getCPUReadable())
+			desc.usage |= MU_CPUREADABLE;
+
 		SPtr<Mesh> mesh = Mesh::_createPtr(rendererMeshData->getData(), desc);
 
 		WString fileName = filePath.getWFilename(false);

+ 4 - 1
Source/BansheeFreeImgImporter/Source/BsFreeImgImporter.cpp

@@ -151,9 +151,12 @@ namespace BansheeEngine
 		}
 
 		int usage = TU_DEFAULT;
-		if (textureImportOptions->getCPUReadable())
+		if (textureImportOptions->getCPUCached())
 			usage |= TU_CPUCACHED;
 
+		if (textureImportOptions->getCPUReadable())
+			usage |= TU_CPUREADABLE;
+
 		bool sRGB = textureImportOptions->getSRGB();
 
 		TEXTURE_DESC texDesc;

+ 4 - 0
Source/BansheeUtility/Include/BsFrameworkConfig.h

@@ -0,0 +1,4 @@
+#define BS_VERSION_MAJOR 0
+#define BS_VERSION_MINOR 4
+
+#define BS_EDITOR_BUILD 1

+ 0 - 2
Source/BansheeUtility/Include/BsPlatformDefines.h

@@ -21,8 +21,6 @@
 #define BS_ENDIAN_BIG 2
 #define BS_ENDIAN BS_ENDIAN_LITTLE
 
-#define BS_EDITOR_BUILD 1
-
 // Finds the compiler type and version.
 #if defined(__clang__)
 #   define BS_COMPILER BS_COMPILER_CLANG

+ 2 - 6
Source/BansheeUtility/Include/BsPrerequisitesUtil.h

@@ -139,12 +139,8 @@
 
 #define BS_PROFILING_ENABLED 1
 
-// Versions
-
-#define BS_VER_DEV 1
-#define BS_VER_PREVIEW 2
-
-#define BS_VER BS_VER_DEV
+// Config from the build system
+#include "BsFrameworkConfig.h"
 
 // Platform-specific stuff
 #include "BsPlatformDefines.h"

+ 0 - 3
Source/CMake/BsEngineConfig.h.in

@@ -1,6 +1,3 @@
-#define BS_VERSION_MAJOR @BS_VERSION_MAJOR@
-#define BS_VERSION_MINOR @BS_VERSION_MINOR@
-
 #define BS_RENDERER_MODULE "@RENDERER_MODULE_LIB@"
 #define BS_RENDER_API_MODULE "@RENDER_API_MODULE_LIB@"
 #define BS_AUDIO_MODULE "@AUDIO_MODULE_LIB@"

+ 4 - 0
Source/CMake/BsFrameworkConfig.h.in

@@ -0,0 +1,4 @@
+#define BS_VERSION_MAJOR @BS_VERSION_MAJOR@
+#define BS_VERSION_MINOR @BS_VERSION_MINOR@
+
+#define BS_EDITOR_BUILD @BS_EDITOR_BUILD@

+ 8 - 1
Source/CMakeLists.txt

@@ -292,5 +292,12 @@ set(RENDERER_MODULE_LIB RenderBeast)
 set(INPUT_MODULE_LIB BansheeOISInput)
 set(PHYSICS_MODULE_LIB BansheePhysX)
 
-## Generate config file
+if(BUILD_EDITOR)
+	set(BS_EDITOR_BUILD 1)
+else()
+	set(BS_EDITOR_BUILD 0)
+endif()
+
+## Generate config files
 configure_file("${PROJECT_SOURCE_DIR}/CMake/BsEngineConfig.h.in" "${PROJECT_SOURCE_DIR}/BansheeEngine/Include/BsEngineConfig.h")
+configure_file("${PROJECT_SOURCE_DIR}/CMake/BsFrameworkConfig.h.in" "${PROJECT_SOURCE_DIR}/BansheeUtility/Include/BsFrameworkConfig.h")

+ 5 - 0
Source/MBansheeEditor/Inspectors/MeshInspector.cs

@@ -21,6 +21,7 @@ namespace BansheeEditor
         private GUIToggleField blendShapesField;
         private GUIToggleField animationField;
         private GUIFloatField scaleField;
+        private GUIToggleField cpuCachedField;
         private GUIToggleField cpuReadableField;
         private GUIEnumField collisionMeshTypeField;
         private GUIToggleField keyFrameReductionField;
@@ -54,6 +55,7 @@ namespace BansheeEditor
             blendShapesField.Value = newImportOptions.ImportBlendShapes;
             animationField.Value = newImportOptions.ImportAnimation;
             scaleField.Value = newImportOptions.Scale;
+            cpuCachedField.Value = newImportOptions.CPUCached;
             cpuReadableField.Value = newImportOptions.CPUReadable;
             collisionMeshTypeField.Value = (ulong)newImportOptions.CollisionMeshType;
             keyFrameReductionField.Value = newImportOptions.KeyframeReduction;
@@ -77,6 +79,7 @@ namespace BansheeEditor
             blendShapesField = new GUIToggleField(new LocEdString("Import Blend Shapes"));
             animationField = new GUIToggleField(new LocEdString("Import Animation"));
             scaleField = new GUIFloatField(new LocEdString("Scale"));
+            cpuCachedField = new GUIToggleField(new LocEdString("CPU cached"));
             cpuReadableField = new GUIToggleField(new LocEdString("CPU readable"));
             collisionMeshTypeField = new GUIEnumField(typeof(CollisionMeshType), new LocEdString("Collision mesh"));
             keyFrameReductionField = new GUIToggleField(new LocEdString("Keyframe Reduction"));
@@ -89,6 +92,7 @@ namespace BansheeEditor
             blendShapesField.OnChanged += x => importOptions.ImportBlendShapes = x;
             animationField.OnChanged += x => importOptions.ImportAnimation = x;
             scaleField.OnChanged += x => importOptions.Scale = x;
+            cpuCachedField.OnChanged += x => importOptions.CPUCached = x;
             cpuReadableField.OnChanged += x => importOptions.CPUReadable = x;
             collisionMeshTypeField.OnSelectionChanged += x => importOptions.CollisionMeshType = (CollisionMeshType)x;
             keyFrameReductionField.OnChanged += x => importOptions.KeyframeReduction = x;
@@ -102,6 +106,7 @@ namespace BansheeEditor
             Layout.AddElement(blendShapesField);
             Layout.AddElement(animationField);
             Layout.AddElement(scaleField);
+            Layout.AddElement(cpuCachedField);
             Layout.AddElement(cpuReadableField);
             Layout.AddElement(collisionMeshTypeField);
             Layout.AddElement(keyFrameReductionField);

+ 4 - 0
Source/MBansheeEditor/Inspectors/Texture2DInspector.cs

@@ -19,6 +19,7 @@ namespace BansheeEditor
         private GUIToggleField generateMipsField = new GUIToggleField(new LocEdString("Generate mipmaps"));
         private GUIIntField maximumMipsField = new GUIIntField(new LocEdString("Maximum mipmap level"));
         private GUIToggleField srgbField = new GUIToggleField(new LocEdString("Gamma space"));
+        private GUIToggleField cpuCachedField = new GUIToggleField(new LocEdString("CPU cached"));
         private GUIToggleField cpuReadableField = new GUIToggleField(new LocEdString("CPU readable"));
         private GUIButton reimportButton = new GUIButton(new LocEdString("Reimport"));
 
@@ -35,6 +36,7 @@ namespace BansheeEditor
                 generateMipsField.OnChanged += x => importOptions.GenerateMipmaps = x;
                 maximumMipsField.OnChanged += x => importOptions.MaxMipmapLevel = x;
                 srgbField.OnChanged += x => importOptions.IsSRGB = x;
+                cpuCachedField.OnChanged += x => importOptions.CPUCached = x;
                 cpuReadableField.OnChanged += x => importOptions.CPUReadable = x;
 
                 reimportButton.OnClick += TriggerReimport;
@@ -43,6 +45,7 @@ namespace BansheeEditor
                 Layout.AddElement(generateMipsField);
                 Layout.AddElement(maximumMipsField);
                 Layout.AddElement(srgbField);
+                Layout.AddElement(cpuCachedField);
                 Layout.AddElement(cpuReadableField);
                 Layout.AddSpace(10);
 
@@ -61,6 +64,7 @@ namespace BansheeEditor
             generateMipsField.Value = newImportOptions.GenerateMipmaps;
             maximumMipsField.Value = newImportOptions.MaxMipmapLevel;
             srgbField.Value = newImportOptions.IsSRGB;
+            cpuCachedField.Value = newImportOptions.CPUCached;
             cpuReadableField.Value = newImportOptions.CPUReadable;
 
             importOptions = newImportOptions;

+ 30 - 0
Source/MBansheeEditor/Windows/Library/ImportOptions.cs

@@ -61,6 +61,15 @@ namespace BansheeEditor
         /// <summary>
         /// Determines whether the texture data is also stored in main memory, available for fast CPU access.
         /// </summary>
+        public bool CPUCached
+        {
+            get { return Internal_GetCPUCached(mCachedPtr); }
+            set { Internal_SetCPUCached(mCachedPtr, value); }
+        }
+
+        /// <summary>
+        /// Determines whether the texture data can be read directly from the GPU.
+        /// </summary>
         public bool CPUReadable
         {
             get { return Internal_GetCPUReadable(mCachedPtr); }
@@ -98,6 +107,12 @@ namespace BansheeEditor
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_SetMaxMipmapLevel(IntPtr thisPtr, int value);
 
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern bool Internal_GetCPUCached(IntPtr thisPtr);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetCPUCached(IntPtr thisPtr, bool value);
+
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern bool Internal_GetCPUReadable(IntPtr thisPtr);
 
@@ -157,6 +172,15 @@ namespace BansheeEditor
         /// <summary>
         /// Determines whether the mesh data is also stored in main memory, available for fast CPU access. 
         /// </summary>
+        public bool CPUCached
+        {
+            get { return Internal_GetCPUCached(mCachedPtr); }
+            set { Internal_SetCPUCached(mCachedPtr, value); }
+        }
+
+        /// <summary>
+        /// Determines whether the mesh data can be read directly from the GPU.
+        /// </summary>
         public bool CPUReadable
         {
             get { return Internal_GetCPUReadable(mCachedPtr); }
@@ -271,6 +295,12 @@ namespace BansheeEditor
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_CreateInstance(MeshImportOptions instance);
 
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern bool Internal_GetCPUCached(IntPtr thisPtr);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetCPUCached(IntPtr thisPtr, bool value);
+
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern bool Internal_GetCPUReadable(IntPtr thisPtr);
 

+ 5 - 2
Source/MBansheeEditor/Windows/Scene/SceneWindow.cs

@@ -853,8 +853,11 @@ namespace BansheeEditor
             width = MathEx.Max(20, width);
             height = MathEx.Max(20, height);
 
-            // Note: Depth buffer is required because ScenePicking uses it
-            renderTexture = new RenderTexture2D(PixelFormat.R8G8B8A8, width, height, 1, false, true);
+            // Note: Depth buffer and readable flags are required because ScenePicking uses it
+            Texture2D colorTex = new Texture2D(width, height, PixelFormat.R8G8B8A8, TextureUsage.Render | TextureUsage.CPUReadable);
+            Texture2D depthTex = new Texture2D(width, height, PixelFormat.D24S8, TextureUsage.DepthStencil | TextureUsage.CPUReadable);
+
+            renderTexture = new RenderTexture2D(colorTex, depthTex);
             renderTexture.Priority = 1;
 
 		    if (camera == null)

+ 7 - 2
Source/MBansheeEngine/Rendering/Mesh.cs

@@ -245,9 +245,14 @@ namespace BansheeEngine
         Dynamic = 0x2,
 
         /// <summary>
-        /// All mesh data will also be cached in CPU memory allowing the mesh data to be read.
+        /// All mesh data will also be cached in CPU memory, making it available for fast read access from the CPU.
         /// </summary>
-        CPUCached = 0x1000
+        CPUCached = 0x1000,
+
+        /// <summary>
+        /// Allows the CPU to directly read the mesh data buffers from the GPU.
+        /// </summary>
+        CPUReadable = 0x2000 
     }
 
     /** @} */

+ 7 - 2
Source/MBansheeEngine/Rendering/Texture.cs

@@ -161,9 +161,14 @@ namespace BansheeEngine
         LoadStore = 0x800,
 
         /// <summary>
-        /// Ensures all texture data will also be cached in system memory so it can be read by the CPU.
+        /// All mesh data will also be cached in CPU memory, making it available for fast read access from the CPU.
         /// </summary>
-        CPUCached = 0x1000
+        CPUCached = 0x1000,
+
+        /// <summary>
+        /// Allows the CPU to directly read the texture data buffers from the GPU.
+        /// </summary>
+        CPUReadable = 0x2000,
     }
 
     /** @} */

+ 4 - 0
Source/SBansheeEditor/Include/BsScriptImportOptions.h

@@ -74,6 +74,8 @@ namespace BansheeEngine
 		static void internal_SetMaxMipmapLevel(ScriptTextureImportOptions* thisPtr, UINT32 value);
 		static bool internal_GetCPUReadable(ScriptTextureImportOptions* thisPtr);
 		static void internal_SetCPUReadable(ScriptTextureImportOptions* thisPtr, bool value);
+		static bool internal_GetCPUCached(ScriptTextureImportOptions* thisPtr);
+		static void internal_SetCPUCached(ScriptTextureImportOptions* thisPtr, bool value);
 		static bool internal_GetIsSRGB(ScriptTextureImportOptions* thisPtr);
 		static void internal_SetIsSRGB(ScriptTextureImportOptions* thisPtr, bool value);
 	};
@@ -102,6 +104,8 @@ namespace BansheeEngine
 		static void internal_CreateInstance(MonoObject* instance);
 		static bool internal_GetCPUReadable(ScriptMeshImportOptions* thisPtr);
 		static void internal_SetCPUReadable(ScriptMeshImportOptions* thisPtr, bool value);
+		static bool internal_GetCPUCached(ScriptMeshImportOptions* thisPtr);
+		static void internal_SetCPUCached(ScriptMeshImportOptions* thisPtr, bool value);
 		static bool internal_GetImportNormals(ScriptMeshImportOptions* thisPtr);
 		static void internal_SetImportNormals(ScriptMeshImportOptions* thisPtr, bool value);
 		static bool internal_GetImportTangents(ScriptMeshImportOptions* thisPtr);

+ 24 - 0
Source/SBansheeEditor/Source/BsScriptImportOptions.cpp

@@ -79,6 +79,8 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_SetMaxMipmapLevel", &ScriptTextureImportOptions::internal_SetMaxMipmapLevel);
 		metaData.scriptClass->addInternalCall("Internal_GetCPUReadable", &ScriptTextureImportOptions::internal_GetCPUReadable);
 		metaData.scriptClass->addInternalCall("Internal_SetCPUReadable", &ScriptTextureImportOptions::internal_SetCPUReadable);
+		metaData.scriptClass->addInternalCall("Internal_GetCPUCached", &ScriptTextureImportOptions::internal_GetCPUCached);
+		metaData.scriptClass->addInternalCall("Internal_SetCPUCached", &ScriptTextureImportOptions::internal_SetCPUCached);
 		metaData.scriptClass->addInternalCall("Internal_GetIsSRGB", &ScriptTextureImportOptions::internal_GetIsSRGB);
 		metaData.scriptClass->addInternalCall("Internal_SetIsSRGB", &ScriptTextureImportOptions::internal_SetIsSRGB);
 	}
@@ -147,6 +149,16 @@ namespace BansheeEngine
 		thisPtr->getTexImportOptions()->setCPUReadable(value);
 	}
 
+	bool ScriptTextureImportOptions::internal_GetCPUCached(ScriptTextureImportOptions* thisPtr)
+	{
+		return thisPtr->getTexImportOptions()->getCPUCached();
+	}
+
+	void ScriptTextureImportOptions::internal_SetCPUCached(ScriptTextureImportOptions* thisPtr, bool value)
+	{
+		thisPtr->getTexImportOptions()->setCPUCached(value);
+	}
+
 	bool ScriptTextureImportOptions::internal_GetIsSRGB(ScriptTextureImportOptions* thisPtr)
 	{
 		return thisPtr->getTexImportOptions()->getSRGB();
@@ -168,6 +180,8 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_CreateInstance", &ScriptMeshImportOptions::internal_CreateInstance);
 		metaData.scriptClass->addInternalCall("Internal_GetCPUReadable", &ScriptMeshImportOptions::internal_GetCPUReadable);
 		metaData.scriptClass->addInternalCall("Internal_SetCPUReadable", &ScriptMeshImportOptions::internal_SetCPUReadable);
+		metaData.scriptClass->addInternalCall("Internal_GetCPUCached", &ScriptMeshImportOptions::internal_GetCPUCached);
+		metaData.scriptClass->addInternalCall("Internal_SetCPUCached", &ScriptMeshImportOptions::internal_SetCPUCached);
 		metaData.scriptClass->addInternalCall("Internal_GetImportNormals", &ScriptMeshImportOptions::internal_GetImportNormals);
 		metaData.scriptClass->addInternalCall("Internal_SetImportNormals", &ScriptMeshImportOptions::internal_SetImportNormals);
 		metaData.scriptClass->addInternalCall("Internal_GetImportTangents", &ScriptMeshImportOptions::internal_GetImportTangents);
@@ -226,6 +240,16 @@ namespace BansheeEngine
 		thisPtr->getMeshImportOptions()->setCPUReadable(value);
 	}
 
+	bool ScriptMeshImportOptions::internal_GetCPUCached(ScriptMeshImportOptions* thisPtr)
+	{
+		return thisPtr->getMeshImportOptions()->getCPUCached();
+	}
+
+	void ScriptMeshImportOptions::internal_SetCPUCached(ScriptMeshImportOptions* thisPtr, bool value)
+	{
+		thisPtr->getMeshImportOptions()->setCPUCached(value);
+	}
+
 	bool ScriptMeshImportOptions::internal_GetImportNormals(ScriptMeshImportOptions* thisPtr)
 	{
 		return thisPtr->getMeshImportOptions()->getImportNormals();

+ 1 - 1
Source/SBansheeEngine/Include/BsScriptRenderTexture2D.h

@@ -34,7 +34,7 @@ namespace BansheeEngine
 		/************************************************************************/
 		static void internal_createDetailed(MonoObject* instance, PixelFormat format, UINT32 width, UINT32 height,
 			UINT32 numSamples, bool gammaCorrection, bool createDepth, PixelFormat depthStencilFormat);
-		static void internal_create(MonoObject* instance, MonoArray* colorSurfaces, MonoObject* depthStencilSurface);
+		static void internal_create(MonoObject* instance, MonoArray* colorSurfaces, ScriptTexture2D* depthStencilSurface);
 
 		static void internal_getColorSurfaces(ScriptRenderTexture2D* thisPtr, MonoArray** value);
 		static void internal_getDepthStencilSurface(ScriptRenderTexture2D* thisPtr, MonoObject** value);

+ 4 - 7
Source/SBansheeEngine/Source/BsScriptRenderTexture2D.cpp

@@ -46,19 +46,18 @@ namespace BansheeEngine
 		new (bs_alloc<ScriptRenderTexture2D>()) ScriptRenderTexture2D(tex, instance);
 	}
 
-	void ScriptRenderTexture2D::internal_create(MonoObject* instance, MonoArray* colorSurfaces, MonoObject* depthStencilSurface)
+	void ScriptRenderTexture2D::internal_create(MonoObject* instance, MonoArray* colorSurfaces, ScriptTexture2D* depthStencilSurface)
 	{
 		ScriptArray colorSurfacesList(colorSurfaces);
 
 		RENDER_SURFACE_DESC depthStencilSurfaceDesc;
-		ScriptTexture2D* scriptDepthStencilSurface = ScriptTexture2D::toNative(depthStencilSurface);
-		if (scriptDepthStencilSurface != nullptr)
+		if (depthStencilSurface != nullptr)
 		{
 			depthStencilSurfaceDesc.face = 0;
 			depthStencilSurfaceDesc.mipLevel = 0;
 			depthStencilSurfaceDesc.numFaces = 1;
 
-			HTexture textureHandle = scriptDepthStencilSurface->getHandle();
+			HTexture textureHandle = depthStencilSurface->getHandle();
 			if (!textureHandle.isLoaded())
 			{
 				LOGERR("Render texture must be created using a fully loaded texture.");
@@ -77,9 +76,7 @@ namespace BansheeEngine
 			surfaceDesc.mipLevel = 0;
 			surfaceDesc.numFaces = 1;
 
-			MonoObject* surfaceObj = colorSurfacesList.get<MonoObject*>(i);
-			ScriptTexture2D* scriptSurface = ScriptTexture2D::toNative(surfaceObj);
-
+			ScriptTexture2D* scriptSurface = colorSurfacesList.get<ScriptTexture2D*>(i);
 			if (scriptSurface != nullptr)
 			{
 				HTexture textureHandle = scriptSurface->getHandle();