Browse Source

Texture refactor to comply with new CoreObject design

Marko Pintera 11 năm trước cách đây
mục cha
commit
f256dad7d6
70 tập tin đã thay đổi với 1271 bổ sung1289 xóa
  1. 0 3
      BansheeCore/BansheeCore.vcxproj
  2. 0 9
      BansheeCore/BansheeCore.vcxproj.filters
  3. 1 3
      BansheeCore/Include/BsCorePrerequisites.h
  4. 0 24
      BansheeCore/Include/BsCoreThreadAccessor.h
  5. 0 50
      BansheeCore/Include/BsGpuResource.h
  6. 0 33
      BansheeCore/Include/BsGpuResourceRTTI.h
  7. 1 1
      BansheeCore/Include/BsMeshBase.h
  8. 1 1
      BansheeCore/Include/BsMeshBaseRTTI.h
  9. 2 18
      BansheeCore/Include/BsRenderSystem.h
  10. 220 167
      BansheeCore/Include/BsTexture.h
  11. 18 21
      BansheeCore/Include/BsTextureManager.h
  12. 52 45
      BansheeCore/Include/BsTextureRTTI.h
  13. 4 4
      BansheeCore/Include/BsTextureView.h
  14. 2 19
      BansheeCore/Source/BsCoreThreadAccessor.cpp
  15. 0 15
      BansheeCore/Source/BsGpuResource.cpp
  16. 0 2
      BansheeCore/Source/BsMesh.cpp
  17. 51 43
      BansheeCore/Source/BsMultiRenderTexture.cpp
  18. 2 33
      BansheeCore/Source/BsRenderSystem.cpp
  19. 30 25
      BansheeCore/Source/BsRenderTexture.cpp
  20. 272 206
      BansheeCore/Source/BsTexture.cpp
  21. 15 23
      BansheeCore/Source/BsTextureManager.cpp
  22. 1 1
      BansheeCore/Source/BsTextureView.cpp
  23. 3 3
      BansheeD3D11RenderSystem/Include/BsD3D11RenderSystem.h
  24. 1 1
      BansheeD3D11RenderSystem/Include/BsD3D11RenderWindow.h
  25. 10 9
      BansheeD3D11RenderSystem/Include/BsD3D11Texture.h
  26. 8 6
      BansheeD3D11RenderSystem/Include/BsD3D11TextureManager.h
  27. 5 5
      BansheeD3D11RenderSystem/Include/BsD3D11TextureView.h
  28. 8 8
      BansheeD3D11RenderSystem/Source/BsD3D11RenderSystem.cpp
  29. 5 5
      BansheeD3D11RenderSystem/Source/BsD3D11RenderWindow.cpp
  30. 137 117
      BansheeD3D11RenderSystem/Source/BsD3D11Texture.cpp
  31. 9 7
      BansheeD3D11RenderSystem/Source/BsD3D11TextureManager.cpp
  32. 15 12
      BansheeD3D11RenderSystem/Source/BsD3D11TextureView.cpp
  33. 2 2
      BansheeD3D9RenderSystem/Include/BsD3D9PixelBuffer.h
  34. 1 2
      BansheeD3D9RenderSystem/Include/BsD3D9Prerequisites.h
  35. 2 2
      BansheeD3D9RenderSystem/Include/BsD3D9RenderSystem.h
  36. 16 15
      BansheeD3D9RenderSystem/Include/BsD3D9Texture.h
  37. 7 5
      BansheeD3D9RenderSystem/Include/BsD3D9TextureManager.h
  38. 4 4
      BansheeD3D9RenderSystem/Source/BsD3D9MultiRenderTexture.cpp
  39. 1 1
      BansheeD3D9RenderSystem/Source/BsD3D9PixelBuffer.cpp
  40. 5 5
      BansheeD3D9RenderSystem/Source/BsD3D9RenderSystem.cpp
  41. 2 2
      BansheeD3D9RenderSystem/Source/BsD3D9RenderTexture.cpp
  42. 162 141
      BansheeD3D9RenderSystem/Source/BsD3D9Texture.cpp
  43. 9 7
      BansheeD3D9RenderSystem/Source/BsD3D9TextureManager.cpp
  44. 3 4
      BansheeEditor/Source/BsScenePicking.cpp
  45. 1 1
      BansheeEditorExec/BsEditorExec.cpp
  46. 10 10
      BansheeEngine/Source/BsBuiltinResources.cpp
  47. 4 4
      BansheeEngine/Source/BsGUIButtonBase.cpp
  48. 2 2
      BansheeEngine/Source/BsGUIHelper.cpp
  49. 2 2
      BansheeEngine/Source/BsGUIInputBox.cpp
  50. 4 5
      BansheeEngine/Source/BsGUIManager.cpp
  51. 1 1
      BansheeEngine/Source/BsGUIScrollBarHandle.cpp
  52. 4 4
      BansheeEngine/Source/BsGUITexture.cpp
  53. 2 2
      BansheeEngine/Source/BsImageSprite.cpp
  54. 2 2
      BansheeEngine/Source/BsSpriteTexture.cpp
  55. 4 8
      BansheeFontImporter/Source/BsFontImporter.cpp
  56. 2 3
      BansheeFreeImgImporter/Source/BsFreeImgImporter.cpp
  57. 1 1
      BansheeGLRenderSystem/Include/BsGLPrerequisites.h
  58. 2 2
      BansheeGLRenderSystem/Include/BsGLRenderSystem.h
  59. 15 16
      BansheeGLRenderSystem/Include/BsGLTexture.h
  60. 7 5
      BansheeGLRenderSystem/Include/BsGLTextureManager.h
  61. 4 4
      BansheeGLRenderSystem/Source/BsGLMultiRenderTexture.cpp
  62. 6 6
      BansheeGLRenderSystem/Source/BsGLRenderSystem.cpp
  63. 4 4
      BansheeGLRenderSystem/Source/BsGLRenderTexture.cpp
  64. 70 61
      BansheeGLRenderSystem/Source/BsGLTexture.cpp
  65. 10 8
      BansheeGLRenderSystem/Source/BsGLTextureManager.cpp
  66. 7 7
      SBansheeEngine/Source/BsScriptTexture.cpp
  67. 6 6
      SBansheeEngine/Source/BsScriptTexture2D.cpp
  68. 6 6
      SBansheeEngine/Source/BsScriptTexture3D.cpp
  69. 6 7
      SBansheeEngine/Source/BsScriptTextureCube.cpp
  70. 2 3
      TODO.txt

+ 0 - 3
BansheeCore/BansheeCore.vcxproj

@@ -292,9 +292,7 @@
     <ClInclude Include="Include\BsProfilerGPU.h" />
     <ClInclude Include="Include\BsProfilerGPU.h" />
     <ClInclude Include="Include\BsGpuResourceData.h" />
     <ClInclude Include="Include\BsGpuResourceData.h" />
     <ClInclude Include="Include\BsGpuParamBlockBuffer.h" />
     <ClInclude Include="Include\BsGpuParamBlockBuffer.h" />
-    <ClInclude Include="Include\BsGpuResource.h" />
     <ClInclude Include="Include\BsGpuResourceDataRTTI.h" />
     <ClInclude Include="Include\BsGpuResourceDataRTTI.h" />
-    <ClInclude Include="Include\BsGpuResourceRTTI.h" />
     <ClInclude Include="Include\BsGpuParam.h" />
     <ClInclude Include="Include\BsGpuParam.h" />
     <ClInclude Include="Include\BsInputFwd.h" />
     <ClInclude Include="Include\BsInputFwd.h" />
     <ClInclude Include="Include\BsMeshBase.h" />
     <ClInclude Include="Include\BsMeshBase.h" />
@@ -455,7 +453,6 @@
     <ClCompile Include="Source\BsGpuProgram.cpp" />
     <ClCompile Include="Source\BsGpuProgram.cpp" />
     <ClCompile Include="Source\BsGpuProgramImporter.cpp" />
     <ClCompile Include="Source\BsGpuProgramImporter.cpp" />
     <ClCompile Include="Source\BsGpuProgramImportOptions.cpp" />
     <ClCompile Include="Source\BsGpuProgramImportOptions.cpp" />
-    <ClCompile Include="Source\BsGpuResource.cpp" />
     <ClCompile Include="Source\BsGpuResourceData.cpp" />
     <ClCompile Include="Source\BsGpuResourceData.cpp" />
     <ClCompile Include="Source\BsHardwareBufferManager.cpp" />
     <ClCompile Include="Source\BsHardwareBufferManager.cpp" />
     <ClCompile Include="Source\BsGpuParam.cpp" />
     <ClCompile Include="Source\BsGpuParam.cpp" />

+ 0 - 9
BansheeCore/BansheeCore.vcxproj.filters

@@ -183,9 +183,6 @@
     <ClInclude Include="Include\BsGpuResourceDataRTTI.h">
     <ClInclude Include="Include\BsGpuResourceDataRTTI.h">
       <Filter>Header Files\RTTI</Filter>
       <Filter>Header Files\RTTI</Filter>
     </ClInclude>
     </ClInclude>
-    <ClInclude Include="Include\BsGpuResourceRTTI.h">
-      <Filter>Header Files\RTTI</Filter>
-    </ClInclude>
     <ClInclude Include="Include\BsImportOptionsRTTI.h">
     <ClInclude Include="Include\BsImportOptionsRTTI.h">
       <Filter>Header Files\RTTI</Filter>
       <Filter>Header Files\RTTI</Filter>
     </ClInclude>
     </ClInclude>
@@ -282,9 +279,6 @@
     <ClInclude Include="Include\BsGpuResourceData.h">
     <ClInclude Include="Include\BsGpuResourceData.h">
       <Filter>Header Files\Resources</Filter>
       <Filter>Header Files\Resources</Filter>
     </ClInclude>
     </ClInclude>
-    <ClInclude Include="Include\BsGpuResource.h">
-      <Filter>Header Files\Resources</Filter>
-    </ClInclude>
     <ClInclude Include="Include\BsGpuProgInclude.h">
     <ClInclude Include="Include\BsGpuProgInclude.h">
       <Filter>Header Files\Resources</Filter>
       <Filter>Header Files\Resources</Filter>
     </ClInclude>
     </ClInclude>
@@ -599,9 +593,6 @@
     <ClCompile Include="Source\BsGpuProgInclude.cpp">
     <ClCompile Include="Source\BsGpuProgInclude.cpp">
       <Filter>Source Files\Resources</Filter>
       <Filter>Source Files\Resources</Filter>
     </ClCompile>
     </ClCompile>
-    <ClCompile Include="Source\BsGpuResource.cpp">
-      <Filter>Source Files\Resources</Filter>
-    </ClCompile>
     <ClCompile Include="Source\BsGpuResourceData.cpp">
     <ClCompile Include="Source\BsGpuResourceData.cpp">
       <Filter>Source Files\Resources</Filter>
       <Filter>Source Files\Resources</Filter>
     </ClCompile>
     </ClCompile>

+ 1 - 3
BansheeCore/Include/BsCorePrerequisites.h

@@ -122,7 +122,6 @@ namespace BansheeEngine
 	class ImportOptions;
 	class ImportOptions;
 	struct FontData;
 	struct FontData;
 	class GameObject;
 	class GameObject;
-	class GpuResource;
 	class GpuResourceData;
 	class GpuResourceData;
 	struct RenderOperation;
 	struct RenderOperation;
 	class RenderQueue;
 	class RenderQueue;
@@ -147,6 +146,7 @@ namespace BansheeEngine
 	class DrawList;
 	class DrawList;
 	struct SubMesh;
 	struct SubMesh;
 	class TransientMeshCore;
 	class TransientMeshCore;
+	class TextureCore;
 	// Asset import
 	// Asset import
 	class SpecificImporter;
 	class SpecificImporter;
 	class Importer;
 	class Importer;
@@ -230,7 +230,6 @@ namespace BansheeEngine
 	typedef std::shared_ptr<ImportOptions> ImportOptionsPtr;
 	typedef std::shared_ptr<ImportOptions> ImportOptionsPtr;
 	typedef std::shared_ptr<const ImportOptions> ConstImportOptionsPtr;
 	typedef std::shared_ptr<const ImportOptions> ConstImportOptionsPtr;
 	typedef std::shared_ptr<Font> FontPtr;
 	typedef std::shared_ptr<Font> FontPtr;
-	typedef std::shared_ptr<GpuResource> GpuResourcePtr;
 	typedef std::shared_ptr<VertexDataDesc> VertexDataDescPtr;
 	typedef std::shared_ptr<VertexDataDesc> VertexDataDescPtr;
 	typedef CoreThreadAccessor<CommandQueueNoSync> CoreAccessor;
 	typedef CoreThreadAccessor<CommandQueueNoSync> CoreAccessor;
 	typedef CoreThreadAccessor<CommandQueueSync> SyncedCoreAccessor;
 	typedef CoreThreadAccessor<CommandQueueSync> SyncedCoreAccessor;
@@ -302,7 +301,6 @@ namespace BansheeEngine
 		TID_FontData = 1057,
 		TID_FontData = 1057,
 		TID_SceneObject = 1059,
 		TID_SceneObject = 1059,
 		TID_GameObject = 1060,
 		TID_GameObject = 1060,
-		TID_GpuResource = 1061,
 		TID_PixelData = 1062,
 		TID_PixelData = 1062,
 		TID_GpuResourceData = 1063,
 		TID_GpuResourceData = 1063,
 		TID_VertexDataDesc = 1064,
 		TID_VertexDataDesc = 1064,

+ 0 - 24
BansheeCore/Include/BsCoreThreadAccessor.h

@@ -102,30 +102,6 @@ namespace BansheeEngine
 		/** @copydoc RenderSystem::drawIndexed() */
 		/** @copydoc RenderSystem::drawIndexed() */
 		void drawIndexed(UINT32 startIndex, UINT32 indexCount, UINT32 vertexOffset, UINT32 vertexCount);
 		void drawIndexed(UINT32 startIndex, UINT32 indexCount, UINT32 vertexOffset, UINT32 vertexCount);
 
 
-		/**
-		 * @copydoc RenderSystem::writeSubresource()
-		 *
-		 * @param discardEntireBuffer When true the existing contents of the resource you are updating will be discarded. This can make the
-		 * 							  operation faster. Resources with certain buffer types might require this flag to be in a specific state
-		 * 							  otherwise the operation will fail. 
-		 *
-		 * @note Resource is updated with data from "data" parameter when the async operation completes. 
-		 * 		 Until the async operation completes "data" is owned by the core thread and you won't
-		 * 		 be able to access it. 
-		 * 		 
-		 *		Normally dynamic buffers will require you to enable "discardEntireBuffer" flag, while static buffers require it disabled.
-		 */
-		AsyncOp writeSubresource(GpuResourcePtr resource, UINT32 subresourceIdx, const GpuResourceDataPtr& data, bool discardEntireBuffer = false);
-
-		/**
-		 * @copydoc RenderSystem::readSubresource()
-		 *
-		 * @note "data" parameter is populated with subresource data when the async operation completes. 
-		 * 		 Until the async operation completes "data" is owned by the core thread and you won't
-		 * 		 be able to access it.
-		 */
-		AsyncOp readSubresource(GpuResourcePtr resource, UINT32 subresourceIdx, const GpuResourceDataPtr& data);
-
 		/**
 		/**
 		* @brief	Queues a new generic command that will be added to the command queue.
 		* @brief	Queues a new generic command that will be added to the command queue.
 		*/
 		*/

+ 0 - 50
BansheeCore/Include/BsGpuResource.h

@@ -1,50 +0,0 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsResource.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Represents a resource that in some way deals directly with the rendering
-	 *			API and the GPU.
-	 *
-	 * @note	e.g. texture, mesh, buffer, etc.
-	 */
-	class BS_CORE_EXPORT GpuResource : public Resource
-	{
-	public:
-		/**
-		 * @brief	Called just before writeSubresource is queued. Called from sim thread.
-		 *
-		 * @note	Sim thread only.
-		 */
-		virtual void _writeSubresourceSim(UINT32 subresourceIdx, const GpuResourceData& data, bool discardEntireBuffer) { }
-
-		/**
-		 * @brief	Updates a part of the current resource with the provided data. Specific resource
-		 * 			implementations provide a way to retrieve a subresource index.
-		 * 			
-		 * @note	Core thread only.
-		 */
-		virtual void writeSubresource(UINT32 subresourceIdx, const GpuResourceData& data, bool discardEntireBuffer) = 0;
-
-		/**
-		 * @brief	Reads a part of the current resource into the provided "data" parameter.
-		 * 			Data buffer needs to be pre-allocated. Specific resource implementations 
-		 * 			provide a way to retrieve a subresource index and a way to allocate
-		 * 			the GpuResourceData buffer.
-		 * 			
-		 * @note	Core thread only.
-		 */
-		virtual void readSubresource(UINT32 subresourceIdx, GpuResourceData& data) = 0;
-
-		/************************************************************************/
-		/* 								SERIALIZATION                      		*/
-		/************************************************************************/
-	public:
-		friend class GpuResourceRTTI;
-		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;
-	};
-}

+ 0 - 33
BansheeCore/Include/BsGpuResourceRTTI.h

@@ -1,33 +0,0 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsRTTIType.h"
-#include "BsGpuResource.h"
-
-namespace BansheeEngine
-{
-	class BS_CORE_EXPORT GpuResourceRTTI : public RTTIType<GpuResource, Resource, GpuResourceRTTI>
-	{
-	public:
-		GpuResourceRTTI()
-		{
-
-		}
-
-		virtual const String& getRTTIName()
-		{
-			static String name = "GpuResource";
-			return name;
-		}
-
-		virtual UINT32 getRTTIId()
-		{
-			return TID_GpuResource;
-		}
-
-		virtual std::shared_ptr<IReflectable> newRTTIObject()
-		{
-			BS_EXCEPT(InternalErrorException, "Cannot instantiate an abstract class.");
-		}
-	};
-}

+ 1 - 1
BansheeCore/Include/BsMeshBase.h

@@ -1,7 +1,7 @@
 #pragma once
 #pragma once
 
 
 #include "BsCorePrerequisites.h"
 #include "BsCorePrerequisites.h"
-#include "BsGpuResource.h"
+#include "BsResource.h"
 #include "BsBounds.h"
 #include "BsBounds.h"
 #include "BsDrawOps.h"
 #include "BsDrawOps.h"
 #include "BsSubMesh.h"
 #include "BsSubMesh.h"

+ 1 - 1
BansheeCore/Include/BsMeshBaseRTTI.h

@@ -10,7 +10,7 @@ namespace BansheeEngine
 {
 {
 	BS_ALLOW_MEMCPY_SERIALIZATION(SubMesh);
 	BS_ALLOW_MEMCPY_SERIALIZATION(SubMesh);
 
 
-	class MeshBaseRTTI : public RTTIType<MeshBase, GpuResource, MeshBaseRTTI>
+	class MeshBaseRTTI : public RTTIType<MeshBase, Resource, MeshBaseRTTI>
 	{
 	{
 		SubMesh& getSubMesh(MeshBase* obj, UINT32 arrayIdx) { return obj->mProperties.mSubMeshes[arrayIdx]; }
 		SubMesh& getSubMesh(MeshBase* obj, UINT32 arrayIdx) { return obj->mProperties.mSubMeshes[arrayIdx]; }
 		void setSubMesh(MeshBase* obj, UINT32 arrayIdx, SubMesh& value) { obj->mProperties.mSubMeshes[arrayIdx] = value; }
 		void setSubMesh(MeshBase* obj, UINT32 arrayIdx, SubMesh& value) { obj->mProperties.mSubMeshes[arrayIdx] = value; }

+ 2 - 18
BansheeCore/Include/BsRenderSystem.h

@@ -79,7 +79,7 @@ namespace BansheeEngine
 		 *			If the slot matches the one configured in the GPU program the program will be able to access
 		 *			If the slot matches the one configured in the GPU program the program will be able to access
 		 *			this texture on the GPU.
 		 *			this texture on the GPU.
 		 */
 		 */
-		virtual void setTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const TexturePtr& texPtr) = 0;
+		virtual void setTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const SPtr<TextureCore>& texPtr) = 0;
 
 
 		/**
 		/**
 		* @brief	Turns off a texture unit.
 		* @brief	Turns off a texture unit.
@@ -90,7 +90,7 @@ namespace BansheeEngine
 		 * @brief	Binds a texture that can be used for random load/store operations from a GPU program.
 		 * @brief	Binds a texture that can be used for random load/store operations from a GPU program.
 		 */
 		 */
 		virtual void setLoadStoreTexture(GpuProgramType gptype, UINT16 unit, bool enabled, 
 		virtual void setLoadStoreTexture(GpuProgramType gptype, UINT16 unit, bool enabled, 
-			const TexturePtr& texPtr, const TextureSurface& surface) = 0;
+			const SPtr<TextureCore>& texPtr, const TextureSurface& surface) = 0;
 
 
 		/**
 		/**
 		 * @brief	Signals that rendering for a specific viewport has started. Any draw calls
 		 * @brief	Signals that rendering for a specific viewport has started. Any draw calls
@@ -239,22 +239,6 @@ namespace BansheeEngine
 		 */
 		 */
         virtual void setRenderTarget(const SPtr<RenderTargetCore>& target) = 0;
         virtual void setRenderTarget(const SPtr<RenderTargetCore>& target) = 0;
 
 
-		/**
-		 * @brief	Updates the resource with the specified data.
-		 *
-		 * @note	It is assumed GpuResourceData has been locked before being passed here. Data will be unlocked
-		 *			when this method finishes.
-		 */
-		void writeSubresource(GpuResourcePtr resource, UINT32 subresourceIdx, const GpuResourceDataPtr& data, bool discardEntireBuffer, AsyncOp& asyncOp);
-
-		/**
-		 * @brief	Reads data from a resource into a pre-allocated GpuResourceData instance.
-		 *
-		 * @note	It is assumed GpuResourceData has been locked before being passed here. Data will be unlocked
-		 *			when this method finishes.
-		 */
-		void readSubresource(GpuResourcePtr resource, UINT32 subresourceIdx, GpuResourceDataPtr& data, AsyncOp& asyncOp);
-
 		/**
 		/**
 		 * @brief	Returns information about available output devices and their video modes.
 		 * @brief	Returns information about available output devices and their video modes.
 		 *
 		 *

+ 220 - 167
BansheeCore/Include/BsTexture.h

@@ -1,7 +1,7 @@
 #pragma once
 #pragma once
 
 
 #include "BsCorePrerequisites.h"
 #include "BsCorePrerequisites.h"
-#include "BsGpuResource.h"
+#include "BsResource.h"
 #include "BsHardwareBuffer.h"
 #include "BsHardwareBuffer.h"
 #include "BsPixelUtil.h"
 #include "BsPixelUtil.h"
 #include "BsTextureView.h"
 #include "BsTextureView.h"
@@ -42,119 +42,72 @@ namespace BansheeEngine
 	};
 	};
 
 
 	/**
 	/**
-	 * @brief	Abstract class representing a texture. Specific render systems have their
-	 *			own Texture implementations. Internally represented as one or more surfaces
-	 *			with pixels in a certain number of dimensions, backed by a hardware buffer.
-	 *
-	 * @note	Core thread unless specified otherwise.
+	 * @brief	Contains various information about a texture
 	 */
 	 */
-    class BS_CORE_EXPORT Texture : public GpuResource
-    {
-    public:
-        /**
+	class BS_CORE_EXPORT TextureProperties
+	{
+	public:
+		TextureProperties();
+		TextureProperties(TextureType textureType, UINT32 width, UINT32 height, UINT32 depth, UINT32 numMipmaps,
+			PixelFormat format, int usage, bool hwGamma, UINT32 multisampleCount);
+
+		/**
          * @brief	Gets the type of texture.
          * @brief	Gets the type of texture.
-         * 			
-		 * @note	Thread safe.
          */
          */
-        virtual TextureType getTextureType() const { return mTextureType; }
+        TextureType getTextureType() const { return mTextureType; }
 
 
         /**
         /**
 		 * @brief	Gets the number of mipmaps to be used for this texture. This number excludes the top level  
 		 * @brief	Gets the number of mipmaps to be used for this texture. This number excludes the top level  
 		 *			map (which is always assumed to be present).
 		 *			map (which is always assumed to be present).
-         *
-         * @note	Thread safe.
          */
          */
-        virtual UINT32 getNumMipmaps() const {return mNumMipmaps;}
+        UINT32 getNumMipmaps() const {return mNumMipmaps;}
 
 
 		/**
 		/**
 		 * @brief	Gets whether this texture will be set up so that on sampling it,
 		 * @brief	Gets whether this texture will be set up so that on sampling it,
 		 *			hardware gamma correction is applied.
 		 *			hardware gamma correction is applied.
-		 *
-		 * @note	Thread safe.
 		 */
 		 */
-		virtual bool isHardwareGammaEnabled() const { return mHwGamma; }
+		bool isHardwareGammaEnabled() const { return mHwGamma; }
 
 
 		/**
 		/**
 		 * @brief	Gets the number of samples used for multisampling.
 		 * @brief	Gets the number of samples used for multisampling.
 		 *			(0 if multisampling is not used).
 		 *			(0 if multisampling is not used).
-		 *
-		 * @note	Thread safe.
 		 */
 		 */
-		virtual UINT32 getMultisampleCount() const { return mMultisampleCount; }
+		UINT32 getMultisampleCount() const { return mMultisampleCount; }
 
 
         /**
         /**
          * @brief	Returns the height of the texture.
          * @brief	Returns the height of the texture.
-         *
-         * @note	Thread safe.
          */
          */
-        virtual UINT32 getHeight() const { return mHeight; }
+        UINT32 getHeight() const { return mHeight; }
 
 
         /**
         /**
          * @brief	Returns the width of the texture.
          * @brief	Returns the width of the texture.
-         *
-         * @note	Thread safe.
          */
          */
-        virtual UINT32 getWidth() const { return mWidth; }
+        UINT32 getWidth() const { return mWidth; }
 
 
         /**
         /**
          * @brief	Returns the depth of the texture (only applicable for 3D textures).
          * @brief	Returns the depth of the texture (only applicable for 3D textures).
-         *
-         * @note	Thread safe.
          */
          */
-        virtual UINT32 getDepth() const { return mDepth; }
+        UINT32 getDepth() const { return mDepth; }
 
 
         /**
         /**
          * @brief	Returns texture usage (TextureUsage) of this texture.
          * @brief	Returns texture usage (TextureUsage) of this texture.
-         *
-         * @note	Thread safe.
          */
          */
-        virtual int getUsage() const { return mUsage; }
+        int getUsage() const { return mUsage; }
 
 
 		/**
 		/**
 		 * @brief	Returns the pixel format for the texture surface.
 		 * @brief	Returns the pixel format for the texture surface.
-		 *
-		 * @note	Thread safe.
 		 */
 		 */
-		virtual PixelFormat getFormat() const { return mFormat; }
+		PixelFormat getFormat() const { return mFormat; }
 
 
         /**
         /**
          * @brief	Returns true if the texture has an alpha layer.
          * @brief	Returns true if the texture has an alpha layer.
-         *
-         * @note	Thread safe.
          */
          */
-        virtual bool hasAlpha() const;
+        bool hasAlpha() const;
 
 
         /**
         /**
          * @brief	Return the number of faces this texture has.
          * @brief	Return the number of faces this texture has.
-         *
-         * @note	Thread safe.
          */
          */
-        virtual UINT32 getNumFaces() const;
-
-		/**
-		 * @copydoc GpuResource::_writeSubresourceSim
-		 */
-		virtual void _writeSubresourceSim(UINT32 subresourceIdx, const GpuResourceData& data, bool discardEntireBuffer);
-
-		/**
-		 * @copydoc GpuResource::writeSubresource
-		 */
-		virtual void writeSubresource(UINT32 subresourceIdx, const GpuResourceData& data, bool discardEntireBuffer);
-
-		/**
-		 * @copydoc GpuResource::readSubresource
-		 */
-		virtual void readSubresource(UINT32 subresourceIdx, GpuResourceData& data);
-
-		/**
-		 * @brief	Allocates a buffer you may use for storage when reading or writing a sub-resource. You
-		 * 			need to allocate such a buffer if you are calling "readSubresource".
-		 *
-		 *			You can retrieve a sub-resource index by calling "mapToSubresourceIdx".
-		 * 			
-		 * @note	Thread safe.
-		 */
-		PixelDataPtr allocateSubresourceBuffer(UINT32 subresourceIdx) const;
+        UINT32 getNumFaces() const;
 
 
 		/**
 		/**
 		 * @brief	Maps a sub-resource index to an exact face and mip level. Sub-resource indexes
 		 * @brief	Maps a sub-resource index to an exact face and mip level. Sub-resource indexes
@@ -163,8 +116,6 @@ namespace BansheeEngine
 		 * @note	Sub-resource index is only valid for the instance it was created on. You cannot use a sub-resource
 		 * @note	Sub-resource index is only valid for the instance it was created on. You cannot use a sub-resource
 		 * 			index from a different texture and expect to get valid result. Modifying the resource so the number
 		 * 			index from a different texture and expect to get valid result. Modifying the resource so the number
 		 * 			of sub-resources changes invalidates all sub-resource indexes.
 		 * 			of sub-resources changes invalidates all sub-resource indexes.
-		 * 			
-		 *			Thread safe.
 		 */
 		 */
 		void mapFromSubresourceIdx(UINT32 subresourceIdx, UINT32& face, UINT32& mip) const;
 		void mapFromSubresourceIdx(UINT32 subresourceIdx, UINT32& face, UINT32& mip) const;
 
 
@@ -174,11 +125,60 @@ namespace BansheeEngine
 		 * 			
 		 * 			
 		 * @note	Generated sub-resource index is only valid for the instance it was created on. Modifying the resource so the number
 		 * @note	Generated sub-resource index is only valid for the instance it was created on. Modifying the resource so the number
 		 * 			of sub-resources changes, invalidates all sub-resource indexes.
 		 * 			of sub-resources changes, invalidates all sub-resource indexes.
-		 * 			
-		 *			Thread safe.
 		 */
 		 */
 		UINT32 mapToSubresourceIdx(UINT32 face, UINT32 mip) const;
 		UINT32 mapToSubresourceIdx(UINT32 face, UINT32 mip) const;
 
 
+	protected:
+		friend class TextureRTTI;
+
+		UINT32 mHeight;
+		UINT32 mWidth;
+		UINT32 mDepth;
+
+		UINT32 mNumMipmaps;
+		bool mHwGamma;
+		UINT32 mMultisampleCount;
+
+		TextureType mTextureType;
+		PixelFormat mFormat;
+		int mUsage;
+	};
+
+	/**
+	 * @brief	Core thread version of a Texture.
+	 *
+	 * @see		Texture
+	 *
+	 * @note	Core thread.
+	 */
+	class BS_CORE_EXPORT TextureCore : public CoreObjectCore
+	{
+	public:
+		TextureCore(TextureType textureType, UINT32 width, UINT32 height, UINT32 depth, UINT32 numMipmaps,
+			PixelFormat format, int usage, bool hwGamma, UINT32 multisampleCount);
+		virtual ~TextureCore() {}
+
+		/**
+		 * @brief	Updates a part of the texture with the provided data.
+		 *
+		 * @param	subresourceIdx		Index of the subresource to update, if the texture has more than one.
+		 * @param	data				Data to update the texture with.
+		 * @param	discardEntireBuffer When true the existing contents of the resource you are updating will be discarded. This can make the
+		 * 								operation faster. Resources with certain buffer types might require this flag to be in a specific state
+		 * 								otherwise the operation will fail.
+		 */
+		virtual void writeSubresource(UINT32 subresourceIdx, const PixelData& data, bool discardEntireBuffer);
+
+		/**
+		 * @brief	Reads a part of the current resource into the provided "data" parameter.
+		 * 			Data buffer needs to be pre-allocated.
+		 *
+		 * @param	subresourceIdx		Index of the subresource to update, if the texture has more than one.
+		 * @param	data				Buffer that will receive the data. Should be allocated with "allocateSubresourceBuffer"
+		 *								to ensure it is of valid type and size.
+		 */
+		virtual void readSubresource(UINT32 subresourceIdx, PixelData& data);
+
 		/**
 		/**
 		 * @brief	Locks the buffer for reading or writing.
 		 * @brief	Locks the buffer for reading or writing.
 		 *
 		 *
@@ -190,16 +190,12 @@ namespace BansheeEngine
 		 * 			
 		 * 			
 		 * @note	If you are just reading or writing one block of data use
 		 * @note	If you are just reading or writing one block of data use
 		 * 			readData/writeData methods as they can be much faster in certain situations.
 		 * 			readData/writeData methods as they can be much faster in certain situations.
-		 * 			
-		 *			Core thread only.
 		 */
 		 */
 		PixelData lock(GpuLockOptions options, UINT32 mipLevel = 0, UINT32 face = 0);
 		PixelData lock(GpuLockOptions options, UINT32 mipLevel = 0, UINT32 face = 0);
 
 
 		/**
 		/**
 		 * @brief	Unlocks a previously locked buffer. After the buffer is unlocked,
 		 * @brief	Unlocks a previously locked buffer. After the buffer is unlocked,
 		 * 			any data returned by lock becomes invalid.
 		 * 			any data returned by lock becomes invalid.
-		 * 			
-		 * @note	Core thread only.
 		 */
 		 */
 		void unlock();
 		void unlock();
 
 
@@ -213,28 +209,8 @@ namespace BansheeEngine
 		 * @param	srcSubresourceIdx	Index of the subresource to copy from.
 		 * @param	srcSubresourceIdx	Index of the subresource to copy from.
 		 * @param	destSubresourceIdx	Index of the subresource to copy to.
 		 * @param	destSubresourceIdx	Index of the subresource to copy to.
 		 * @param	target				Texture that contains the destination subresource.
 		 * @param	target				Texture that contains the destination subresource.
-		 * 			
-		 * @note	Core thread only.
 		 */
 		 */
-		void copy(UINT32 srcSubresourceIdx, UINT32 destSubresourceIdx, TexturePtr& target);
-
-		/**
-		 * @brief	Reads data from the cached system memory texture buffer into the provided buffer. 
-		 * 		  
-		 * @param	dest		Previously allocated buffer to read data into.
-		 * @param	mipLevel	(optional) Mipmap level to read from.
-		 * @param	face		(optional) Texture face to read from.
-		 *
-		 * @note	Sim thread only.
-		 *
-		 *			The data read is the cached texture data. Any data written to the texture from the GPU 
-		 *			or core thread will not be reflected in this data. Use "readData" if you require
-		 *			those changes.
-		 *
-		 *			The texture must have been created with TU_CPUCACHED usage otherwise this method
-		 *			will not return any data.
-		 */
-		virtual void readDataSim(PixelData& dest, UINT32 mipLevel = 0, UINT32 face = 0);
+		void copy(UINT32 srcSubresourceIdx, UINT32 destSubresourceIdx, const SPtr<TextureCore>& target);
 
 
 		/**
 		/**
 		 * @brief	Reads data from the texture buffer into the provided buffer.
 		 * @brief	Reads data from the texture buffer into the provided buffer.
@@ -242,8 +218,6 @@ namespace BansheeEngine
 		 * @param	dest	Previously allocated buffer to read data into.
 		 * @param	dest	Previously allocated buffer to read data into.
 		 * @param	mipLevel	(optional) Mipmap level to read from.
 		 * @param	mipLevel	(optional) Mipmap level to read from.
 		 * @param	face		(optional) Texture face to read from.
 		 * @param	face		(optional) Texture face to read from.
-		 *
-		 * @note	Core thread only.
 		 */
 		 */
 		virtual void readData(PixelData& dest, UINT32 mipLevel = 0, UINT32 face = 0) = 0;
 		virtual void readData(PixelData& dest, UINT32 mipLevel = 0, UINT32 face = 0) = 0;
 
 
@@ -255,18 +229,9 @@ namespace BansheeEngine
 		 * @param	face		(optional) Texture face to write into.
 		 * @param	face		(optional) Texture face to write into.
 		 * @param	discardWholeBuffer (optional) If true any existing texture data will be discard. This can
 		 * @param	discardWholeBuffer (optional) If true any existing texture data will be discard. This can
 		 *							    improve performance of the write operation.
 		 *							    improve performance of the write operation.
-		 *
-		 * @note	Core thread only.
 		 */
 		 */
 		virtual void writeData(const PixelData& src, UINT32 mipLevel = 0, UINT32 face = 0, bool discardWholeBuffer = false) = 0;
 		virtual void writeData(const PixelData& src, UINT32 mipLevel = 0, UINT32 face = 0, bool discardWholeBuffer = false) = 0;
 
 
-		/**
-		 * @brief	Returns a dummy 2x2 texture. Don't modify the returned texture.
-		 * 			
-		 * @note	Thread safe.
-		 */
-		static const HTexture& dummy();
-
 		/**
 		/**
 		 * @brief	Returns true if the texture can be bound to a shader.
 		 * @brief	Returns true if the texture can be bound to a shader.
 		 *
 		 *
@@ -275,6 +240,11 @@ namespace BansheeEngine
 		 */
 		 */
 		virtual bool isBindableAsShaderResource() const { return true; }
 		virtual bool isBindableAsShaderResource() const { return true; }
 
 
+		/**
+		 * @brief	Returns properties that contain information about the texture.
+		 */
+		const TextureProperties& getProperties() const { return mProperties; }
+
 		/************************************************************************/
 		/************************************************************************/
 		/* 								TEXTURE VIEW                      		*/
 		/* 								TEXTURE VIEW                      		*/
 		/************************************************************************/
 		/************************************************************************/
@@ -286,14 +256,141 @@ namespace BansheeEngine
 		 *
 		 *
 		 * @note	Core thread only.
 		 * @note	Core thread only.
 		 */
 		 */
-		static TextureViewPtr requestView(TexturePtr texture, UINT32 mostDetailMip, UINT32 numMips, UINT32 firstArraySlice, UINT32 numArraySlices, GpuViewUsage usage);
+		static TextureViewPtr requestView(const SPtr<TextureCore>& texture, UINT32 mostDetailMip, UINT32 numMips, 
+			UINT32 firstArraySlice, UINT32 numArraySlices, GpuViewUsage usage);
 
 
 		/**
 		/**
 		 * @brief	Releases the view. View won't actually get destroyed until all references to it are released.
 		 * @brief	Releases the view. View won't actually get destroyed until all references to it are released.
 		 *
 		 *
 		 * @note	Core thread only.
 		 * @note	Core thread only.
 		 */
 		 */
-		static void releaseView(TextureViewPtr view);
+		static void releaseView(const TextureViewPtr& view);
+
+	protected:
+		/**
+		 * @copydoc	lock
+		 */
+		virtual PixelData lockImpl(GpuLockOptions options, UINT32 mipLevel = 0, UINT32 face = 0) = 0;
+
+		/**
+		 * @copydoc	unlock
+		 */
+		virtual void unlockImpl() = 0;
+
+		/**
+		 * @copydoc	copy
+		 */
+		virtual void copyImpl(UINT32 srcFace, UINT32 srcMipLevel, UINT32 destFace, UINT32 destMipLevel, const SPtr<TextureCore>& target) = 0;
+
+		/************************************************************************/
+		/* 								TEXTURE VIEW                      		*/
+		/************************************************************************/
+
+		/**
+		 * @brief	Creates a new empty/undefined texture view.
+		 */
+		virtual TextureViewPtr createView();
+
+		/**
+		 * @brief	Releases all internal texture view references. Views won't get destroyed if there are external references still held.
+		 */
+		void clearBufferViews();
+
+		/**
+		 * @brief	Holds a single texture view with a usage reference count.
+		 */
+		struct TextureViewReference
+		{
+			TextureViewReference(TextureViewPtr _view)
+				:view(_view), refCount(0)
+			{ }
+
+			TextureViewPtr view;
+			UINT32 refCount;
+		};
+
+		UnorderedMap<TEXTURE_VIEW_DESC, TextureViewReference*, TextureView::HashFunction, TextureView::EqualFunction> mTextureViews;
+		TextureProperties mProperties;
+	};
+
+	/**
+	 * @brief	Abstract class representing a texture. Specific render systems have their
+	 *			own Texture implementations. Internally represented as one or more surfaces
+	 *			with pixels in a certain number of dimensions, backed by a hardware buffer.
+	 *
+	 * @note	Sim thread.
+	 */
+    class BS_CORE_EXPORT Texture : public Resource
+    {
+    public:
+		/**
+		 * @brief	Updates the texture with new data. The actual write will be queued for later execution on the core thread.
+		 *			Provided data buffer will be locked until the operation completes.
+		 *
+		 * @param	accessor			Accessor to queue the operation on.
+		 * 
+		 * @return	Async operation object you can use to track operation completion.
+		 *
+		 * @see		TextureCore::writeSubresource
+		 */
+		AsyncOp writeSubresource(CoreAccessor& accessor, UINT32 subresourceIdx, const PixelDataPtr& data, bool discardEntireBuffer);
+
+		/**
+		 * @brief	Reads internal texture data to the provided previously allocated buffer. The read is queued for execution
+		 *			on the core thread and not executed immediately. Provided data buffer will be locked until the
+		 *			operation completes.
+		 *
+		 * @param	accessor			Accessor to queue the operation on.
+		 *
+		 * @return	Async operation object you can use to track operation completion.
+		 *
+		 * @see		TextureCore::readSubresource
+		 */
+		AsyncOp readSubresource(CoreAccessor& accessor, UINT32 subresourceIdx, const PixelDataPtr& data);
+
+		/**
+		 * @brief	Allocates a buffer you may use for storage when reading or writing a sub-resource. You
+		 * 			need to allocate such a buffer if you are calling "readSubresource".
+		 *
+		 *			You can retrieve a sub-resource index by calling "mapToSubresourceIdx".
+		 * 			
+		 * @note	Thread safe.
+		 */
+		PixelDataPtr allocateSubresourceBuffer(UINT32 subresourceIdx) const;
+
+		/**
+		 * @brief	Reads data from the cached system memory texture buffer into the provided buffer. 
+		 * 		  
+		 * @param	dest		Previously allocated buffer to read data into.
+		 * @param	mipLevel	(optional) Mipmap level to read from.
+		 * @param	face		(optional) Texture face to read from.
+		 *
+		 * @note	The data read is the cached texture data. Any data written to the texture from the GPU 
+		 *			or core thread will not be reflected in this data. Use "readSubresource" if you require
+		 *			those changes.
+		 *
+		 *			The texture must have been created with TU_CPUCACHED usage otherwise this method
+		 *			will not return any data.
+		 */
+		void readData(PixelData& dest, UINT32 mipLevel = 0, UINT32 face = 0);
+
+		/**
+		 * @brief	Returns properties that contain information about the texture.
+		 */
+		const TextureProperties& getProperties() const { return mProperties; }
+
+		/**
+		 * @brief	Retrieves a core implementation of a texture usable only from the
+		 *			core thread.
+		 */
+		SPtr<TextureCore> getCore() const;
+
+		/**
+		 * @brief	Returns a dummy 2x2 texture. Don't modify the returned texture.
+		 * 			
+		 * @note	Thread safe.
+		 */
+		static const HTexture& dummy();
 
 
 		/************************************************************************/
 		/************************************************************************/
 		/* 								STATICS		                     		*/
 		/* 								STATICS		                     		*/
@@ -352,61 +449,21 @@ namespace BansheeEngine
 		static TexturePtr _createPtr(TextureType texType, UINT32 width, UINT32 height, int num_mips,
 		static TexturePtr _createPtr(TextureType texType, UINT32 width, UINT32 height, int num_mips,
 			PixelFormat format, int usage = TU_DEFAULT, bool hwGammaCorrection = false, UINT32 multisampleCount = 0);
 			PixelFormat format, int usage = TU_DEFAULT, bool hwGammaCorrection = false, UINT32 multisampleCount = 0);
 
 
-	protected:
-		/************************************************************************/
-		/* 								TEXTURE VIEW                      		*/
-		/************************************************************************/
-
-		/**
-		 * @brief	Creates a new empty/undefined texture view.
-		 */
-		virtual TextureViewPtr createView();
-
-		/**
-		 * @brief	Releases all internal texture view references. Views won't get destroyed if there are external references still held.
-		 */
-		void clearBufferViews();
-
-		/**
-		 * @brief	Holds a single texture view with a usage reference count.
-		 */
-		struct TextureViewReference
-		{
-			TextureViewReference(TextureViewPtr _view)
-				:view(_view), refCount(0)
-			{ }
-
-			TextureViewPtr view;
-			UINT32 refCount;
-		};
-
-		UnorderedMap<TEXTURE_VIEW_DESC, TextureViewReference*, TextureView::HashFunction, TextureView::EqualFunction> mTextureViews;
-
     protected:
     protected:
 		friend class TextureManager;
 		friend class TextureManager;
 
 
-		Texture();
-
-		/**
-		 * @copydoc	GpuResource::initialize
-		 */
-		void initialize(TextureType textureType, UINT32 width, UINT32 height, UINT32 depth, UINT32 numMipmaps, 
+		Texture(TextureType textureType, UINT32 width, UINT32 height, UINT32 depth, UINT32 numMipmaps,
 			PixelFormat format, int usage, bool hwGamma, UINT32 multisampleCount);
 			PixelFormat format, int usage, bool hwGamma, UINT32 multisampleCount);
 
 
 		/**
 		/**
-		 * @copydoc	lock
-		 */
-		virtual PixelData lockImpl(GpuLockOptions options, UINT32 mipLevel = 0, UINT32 face = 0) = 0;
-
-		/**
-		 * @copydoc	unlock
+		 * @copydoc	Resource::initialize
 		 */
 		 */
-		virtual void unlockImpl() = 0;
+		void initialize();
 
 
 		/**
 		/**
-		 * @copydoc	copy
+		 * @copydoc	CoreObject::createCore
 		 */
 		 */
-		virtual void copyImpl(UINT32 srcFace, UINT32 srcMipLevel, UINT32 destFace, UINT32 destMipLevel, TexturePtr& target) = 0;
+		SPtr<CoreObjectCore> createCore() const;
 
 
 		/**
 		/**
 		 * @copydoc	Resource::calculateSize
 		 * @copydoc	Resource::calculateSize
@@ -420,25 +477,21 @@ namespace BansheeEngine
 		 */
 		 */
 		void createCPUBuffers();
 		void createCPUBuffers();
 
 
-	protected:
-		UINT32 mHeight; // Immutable
-		UINT32 mWidth; // Immutable
-		UINT32 mDepth; // Immutable
-
-		UINT32 mNumMipmaps; // Immutable
-		bool mHwGamma; // Immutable
-		UINT32 mMultisampleCount; // Immutable
-
-		TextureType mTextureType; // Immutable
-		PixelFormat mFormat; // Immutable
-		int mUsage; // Immutable
+		/**
+		 * @brief	Updates the cached CPU buffers with new data.
+		 */
+		void updateCPUBuffers(UINT32 subresourceIdx, const PixelData& data);
 
 
+	protected:
 		Vector<PixelDataPtr> mCPUSubresourceData;
 		Vector<PixelDataPtr> mCPUSubresourceData;
+		TextureProperties mProperties;
 
 
 		/************************************************************************/
 		/************************************************************************/
 		/* 								SERIALIZATION                      		*/
 		/* 								SERIALIZATION                      		*/
 		/************************************************************************/
 		/************************************************************************/
 	public:
 	public:
+		Texture(); // Serialization only
+
 		friend class TextureRTTI;
 		friend class TextureRTTI;
 		static RTTITypeBase* getRTTIStatic();
 		static RTTITypeBase* getRTTIStatic();
 		virtual RTTITypeBase* getRTTI() const;
 		virtual RTTITypeBase* getRTTI() const;

+ 18 - 21
BansheeCore/Include/BsTextureManager.h

@@ -20,14 +20,14 @@ namespace BansheeEngine
 		virtual ~TextureManager() { }
 		virtual ~TextureManager() { }
 
 
 		/**
 		/**
-		 * @copydoc	Texture::create(TextureType, UINT32, UINT32, UINT32, int, PixelFormat, int, bool, UINT32, const String&)
+		 * @copydoc	Texture::create(TextureType, UINT32, UINT32, UINT32, int, PixelFormat, int, bool, UINT32)
 		 */
 		 */
         TexturePtr createTexture(TextureType texType, UINT32 width, UINT32 height, UINT32 depth, 
         TexturePtr createTexture(TextureType texType, UINT32 width, UINT32 height, UINT32 depth, 
 			int numMips, PixelFormat format, int usage = TU_DEFAULT, bool hwGammaCorrection = false, 
 			int numMips, PixelFormat format, int usage = TU_DEFAULT, bool hwGammaCorrection = false, 
 			UINT32 multisampleCount = 0);
 			UINT32 multisampleCount = 0);
 			
 			
 		/**
 		/**
-		 * @copydoc	Texture::create(TextureType, UINT32, UINT32, int, PixelFormat, int, bool, UINT32, const String&)
+		 * @copydoc	Texture::create(TextureType, UINT32, UINT32, int, PixelFormat, int, bool, UINT32)
 		 */
 		 */
 		TexturePtr createTexture(TextureType texType, UINT32 width, UINT32 height, int numMips,
 		TexturePtr createTexture(TextureType texType, UINT32 width, UINT32 height, int numMips,
 			PixelFormat format, int usage = TU_DEFAULT, bool hwGammaCorrection = false, UINT32 multisampleCount = 0)
 			PixelFormat format, int usage = TU_DEFAULT, bool hwGammaCorrection = false, UINT32 multisampleCount = 0)
@@ -84,12 +84,6 @@ namespace BansheeEngine
 		virtual PixelFormat getNativeFormat(TextureType ttype, PixelFormat format, int usage, bool hwGamma) = 0;
 		virtual PixelFormat getNativeFormat(TextureType ttype, PixelFormat format, int usage, bool hwGamma) = 0;
 
 
 	protected:
 	protected:
-		/**
-		 * @brief	Creates an empty and uninitialized texture of a specific type. This is to be implemented
-		 *			by render systems with their own implementations.
-		 */
-		virtual TexturePtr createTextureImpl() = 0;
-
 		/**
 		/**
 		 * @brief	Creates an empty and uninitialized render texture of a specific type. This 
 		 * @brief	Creates an empty and uninitialized render texture of a specific type. This 
 		 *			is to be implemented by render systems with their own implementations.
 		 *			is to be implemented by render systems with their own implementations.
@@ -114,6 +108,13 @@ namespace BansheeEngine
     public:
     public:
 		virtual ~TextureCoreManager() { }
 		virtual ~TextureCoreManager() { }
 
 
+		/**
+		 * @copydoc	TextureManager::createTexture(TextureType, UINT32, UINT32, UINT32, int, PixelFormat, int, bool, UINT32)
+		 */
+		SPtr<TextureCore> createTexture(TextureType texType, UINT32 width, UINT32 height, UINT32 depth,
+			int numMips, PixelFormat format, int usage = TU_DEFAULT, bool hwGammaCorrection = false, 
+			UINT32 multisampleCount = 0);
+
 		/**
 		/**
 		 * @copydoc	TextureManager::createRenderTexture(const RENDER_TEXTURE_DESC&)
 		 * @copydoc	TextureManager::createRenderTexture(const RENDER_TEXTURE_DESC&)
 		 */
 		 */
@@ -124,15 +125,19 @@ namespace BansheeEngine
 		 */
 		 */
 		SPtr<MultiRenderTextureCore> createMultiRenderTexture(const MULTI_RENDER_TEXTURE_DESC& desc);
 		SPtr<MultiRenderTextureCore> createMultiRenderTexture(const MULTI_RENDER_TEXTURE_DESC& desc);
 
 
-		/**
-		 * @brief	Returns tiny dummy texture for use when no other is available.
-		 */
-		const HTexture& getDummyTexture() const { return mDummyTexture; }
-
 	protected:
 	protected:
+		friend class Texture;
 		friend class RenderTexture;
 		friend class RenderTexture;
 		friend class MultiRenderTexture;
 		friend class MultiRenderTexture;
 
 
+		/**
+		 * @brief	Creates an empty and uninitialized texture of a specific type. This is to be implemented
+		 *			by render systems with their own implementations.
+		 */
+		virtual SPtr<TextureCore> createTextureInternal(TextureType texType, UINT32 width, UINT32 height, UINT32 depth,
+			int numMips, PixelFormat format, int usage = TU_DEFAULT, bool hwGammaCorrection = false,
+			UINT32 multisampleCount = 0) = 0;
+
 		/**
 		/**
 		 * @copydoc	TextureManager::createRenderTextureImpl
 		 * @copydoc	TextureManager::createRenderTextureImpl
 		 */
 		 */
@@ -142,13 +147,5 @@ namespace BansheeEngine
 		 * @copydoc	TextureManager::createMultiRenderTextureImpl
 		 * @copydoc	TextureManager::createMultiRenderTextureImpl
 		 */
 		 */
 		virtual SPtr<MultiRenderTextureCore> createMultiRenderTextureInternal(const MULTI_RENDER_TEXTURE_DESC& desc) = 0;
 		virtual SPtr<MultiRenderTextureCore> createMultiRenderTextureInternal(const MULTI_RENDER_TEXTURE_DESC& desc) = 0;
-
-		/**
-		 * @copydoc	Module::onStartUp
-		 */
-		virtual void onStartUp();
-
-	protected:
-		HTexture mDummyTexture;
     };
     };
 }
 }

+ 52 - 45
BansheeCore/Include/BsTextureRTTI.h

@@ -16,25 +16,42 @@ namespace BansheeEngine
 	class BS_CORE_EXPORT TextureRTTI : public RTTIType<Texture, Resource, TextureRTTI>
 	class BS_CORE_EXPORT TextureRTTI : public RTTIType<Texture, Resource, TextureRTTI>
 	{
 	{
 	private:
 	private:
-		BS_SETGET_MEMBER(mSize, UINT32, Texture)
-		BS_SETGET_MEMBER(mHeight, UINT32, Texture)
-		BS_SETGET_MEMBER(mWidth, UINT32, Texture)
-		BS_SETGET_MEMBER(mDepth, UINT32, Texture)
-		BS_SETGET_MEMBER(mNumMipmaps, UINT32, Texture)
-		BS_SETGET_MEMBER(mHwGamma, bool, Texture)
-		BS_SETGET_MEMBER(mMultisampleCount, UINT32, Texture)
-		BS_SETGET_MEMBER(mTextureType, TextureType, Texture)
-		BS_SETGET_MEMBER(mFormat, PixelFormat, Texture)
-
-		INT32& getUsage(Texture* obj) { return obj->mUsage; }
+		UINT32& getSize(Texture* obj) { return obj->mSize; }
+		void setSize(Texture* obj, UINT32& val) { obj->mSize = val; }
+
+		UINT32& getWidth(Texture* obj) { return obj->mProperties.mWidth; }
+		void setWidth(Texture* obj, UINT32& val) { obj->mProperties.mWidth = val; }
+
+		UINT32& getHeight(Texture* obj) { return obj->mProperties.mHeight; }
+		void setHeight(Texture* obj, UINT32& val) { obj->mProperties.mHeight = val; }
+
+		UINT32& getDepth(Texture* obj) { return obj->mProperties.mDepth; }
+		void setDepth(Texture* obj, UINT32& val) { obj->mProperties.mDepth = val; }
+
+		UINT32& getNumMipmaps(Texture* obj) { return obj->mProperties.mNumMipmaps; }
+		void setNumMipmaps(Texture* obj, UINT32& val) { obj->mProperties.mNumMipmaps = val; }
+
+		bool& getHwGamma(Texture* obj) { return obj->mProperties.mHwGamma; }
+		void setHwGamma(Texture* obj, bool& val) { obj->mProperties.mHwGamma = val; }
+
+		UINT32& getMultisampleCount(Texture* obj) { return obj->mProperties.mMultisampleCount; }
+		void setMultisampleCount(Texture* obj, UINT32& val) { obj->mProperties.mMultisampleCount = val; }
+
+		TextureType& getTextureType(Texture* obj) { return obj->mProperties.mTextureType; }
+		void setTextureType(Texture* obj, TextureType& val) { obj->mProperties.mTextureType = val; }
+
+		PixelFormat& getFormat(Texture* obj) { return obj->mProperties.mFormat; }
+		void setFormat(Texture* obj, PixelFormat& val) { obj->mProperties.mFormat = val; }
+
+		INT32& getUsage(Texture* obj) { return obj->mProperties.mUsage; }
 		void setUsage(Texture* obj, INT32& val) 
 		void setUsage(Texture* obj, INT32& val) 
 		{ 
 		{ 
 			// Render target and depth stencil texture formats are for in-memory use only
 			// Render target and depth stencil texture formats are for in-memory use only
 			// and don't make sense when serialized
 			// and don't make sense when serialized
 			if (val == TU_DEPTHSTENCIL || val == TU_RENDERTARGET)
 			if (val == TU_DEPTHSTENCIL || val == TU_RENDERTARGET)
-				obj->mUsage = TU_STATIC;
+				obj->mProperties.mUsage = TU_STATIC;
 			else
 			else
-				obj->mUsage = val; 
+				obj->mProperties.mUsage = val;
 		}
 		}
 
 
 #define BS_ADD_PLAINFIELD(name, id, parentType) \
 #define BS_ADD_PLAINFIELD(name, id, parentType) \
@@ -42,19 +59,14 @@ namespace BansheeEngine
 
 
 		PixelDataPtr getPixelData(Texture* obj, UINT32 idx)
 		PixelDataPtr getPixelData(Texture* obj, UINT32 idx)
 		{
 		{
-			UINT32 face = (size_t)Math::floor(idx / (float)(obj->getNumMipmaps() + 1));
-			UINT32 mipmap = idx % (obj->getNumMipmaps() + 1);
+			UINT32 face = (size_t)Math::floor(idx / (float)(obj->mProperties.getNumMipmaps() + 1));
+			UINT32 mipmap = idx % (obj->mProperties.getNumMipmaps() + 1);
 
 
-			UINT32 subresourceIdx = obj->mapToSubresourceIdx(face, mipmap);
+			UINT32 subresourceIdx = obj->mProperties.mapToSubresourceIdx(face, mipmap);
 			PixelDataPtr pixelData = obj->allocateSubresourceBuffer(subresourceIdx);
 			PixelDataPtr pixelData = obj->allocateSubresourceBuffer(subresourceIdx);
 
 
-			GpuResourcePtr sharedTexPtr = std::static_pointer_cast<GpuResource>(obj->getThisPtr());
-
-			// We want the data right away so queue directly to main core thread queue and block until we get it
-			pixelData->_lock();
-			gCoreThread().queueReturnCommand(
-				std::bind(&RenderSystem::readSubresource, RenderSystem::instancePtr(), sharedTexPtr, subresourceIdx, 
-				std::static_pointer_cast<GpuResourceData>(pixelData), std::placeholders::_1), true);
+			obj->readSubresource(gCoreAccessor(), subresourceIdx, pixelData);
+			gCoreAccessor().submitToCoreThread(true);
 
 
 			return pixelData;
 			return pixelData;
 		}
 		}
@@ -68,7 +80,7 @@ namespace BansheeEngine
 
 
 		UINT32 getPixelDataArraySize(Texture* obj)
 		UINT32 getPixelDataArraySize(Texture* obj)
 		{
 		{
-			return obj->getNumFaces() * (obj->getNumMipmaps() + 1);
+			return obj->mProperties.getNumFaces() * (obj->mProperties.getNumMipmaps() + 1);
 		}
 		}
 
 
 		void setPixelDataArraySize(Texture* obj, UINT32 size)
 		void setPixelDataArraySize(Texture* obj, UINT32 size)
@@ -81,16 +93,15 @@ namespace BansheeEngine
 	public:
 	public:
 		TextureRTTI()
 		TextureRTTI()
 		{
 		{
-			BS_ADD_PLAINFIELD(mSize, 0, TextureRTTI)
-			BS_ADD_PLAINFIELD(mHeight, 2, TextureRTTI)
-			BS_ADD_PLAINFIELD(mWidth, 3, TextureRTTI)
-			BS_ADD_PLAINFIELD(mDepth, 4, TextureRTTI)
-			BS_ADD_PLAINFIELD(mNumMipmaps, 5, TextureRTTI)
-			BS_ADD_PLAINFIELD(mHwGamma, 6, TextureRTTI)
-			BS_ADD_PLAINFIELD(mMultisampleCount, 7, TextureRTTI)
-			BS_ADD_PLAINFIELD(mTextureType, 9, TextureRTTI)
-			BS_ADD_PLAINFIELD(mFormat, 10, TextureRTTI)
-
+			addPlainField("mSize", 0, &TextureRTTI::getSize, &TextureRTTI::setSize);
+			addPlainField("mHeight", 2, &TextureRTTI::getHeight, &TextureRTTI::setHeight);
+			addPlainField("mWidth", 3, &TextureRTTI::getWidth, &TextureRTTI::setWidth);
+			addPlainField("mDepth", 4, &TextureRTTI::getDepth, &TextureRTTI::setDepth);
+			addPlainField("mNumMipmaps", 5, &TextureRTTI::getNumMipmaps, &TextureRTTI::setNumMipmaps);
+			addPlainField("mHwGamma", 6, &TextureRTTI::getHwGamma, &TextureRTTI::setHwGamma);
+			addPlainField("mMultisampleCount", 7, &TextureRTTI::getMultisampleCount, &TextureRTTI::setMultisampleCount);
+			addPlainField("mTextureType", 9, &TextureRTTI::getTextureType, &TextureRTTI::setTextureType);
+			addPlainField("mFormat", 10, &TextureRTTI::getFormat, &TextureRTTI::setFormat);
 			addPlainField("mUsage", 11, &TextureRTTI::getUsage, &TextureRTTI::setUsage);
 			addPlainField("mUsage", 11, &TextureRTTI::getUsage, &TextureRTTI::setUsage);
 
 
 			addReflectablePtrArrayField("mPixelData", 12, &TextureRTTI::getPixelData, &TextureRTTI::getPixelDataArraySize, 
 			addReflectablePtrArrayField("mPixelData", 12, &TextureRTTI::getPixelData, &TextureRTTI::getPixelDataArraySize, 
@@ -111,25 +122,21 @@ namespace BansheeEngine
 			if(texture->mRTTIData.empty())
 			if(texture->mRTTIData.empty())
 				return;
 				return;
 
 
+			const TextureProperties texProps = texture->getProperties();
+
 			// A bit clumsy initializing with already set values, but I feel its better than complicating things and storing the values
 			// A bit clumsy initializing with already set values, but I feel its better than complicating things and storing the values
 			// in mRTTIData.
 			// in mRTTIData.
-			texture->initialize(texture->getTextureType(), texture->getWidth(), texture->getHeight(), texture->getDepth(), 
-				texture->getNumMipmaps(), texture->getFormat(), texture->getUsage(), texture->isHardwareGammaEnabled(), 
-				texture->getMultisampleCount());
+			texture->initialize();
 
 
 			Vector<PixelDataPtr>* pixelData = any_cast<Vector<PixelDataPtr>*>(texture->mRTTIData);
 			Vector<PixelDataPtr>* pixelData = any_cast<Vector<PixelDataPtr>*>(texture->mRTTIData);
 			for(size_t i = 0; i < pixelData->size(); i++)
 			for(size_t i = 0; i < pixelData->size(); i++)
 			{
 			{
-				UINT32 face = (size_t)Math::floor(i / (float)(texture->getNumMipmaps() + 1));
-				UINT32 mipmap = i % (texture->getNumMipmaps() + 1);
-
-				UINT32 subresourceIdx = texture->mapToSubresourceIdx(face, mipmap);
+				UINT32 face = (size_t)Math::floor(i / (float)(texProps.getNumMipmaps() + 1));
+				UINT32 mipmap = i % (texProps.getNumMipmaps() + 1);
 
 
-				GpuResourcePtr sharedTexPtr = std::static_pointer_cast<GpuResource>(texture->getThisPtr());
+				UINT32 subresourceIdx = texProps.mapToSubresourceIdx(face, mipmap);
 
 
-				pixelData->at(i)->_lock();
-				gCoreThread().queueReturnCommand(std::bind(&RenderSystem::writeSubresource, RenderSystem::instancePtr(), 
-					sharedTexPtr, subresourceIdx, pixelData->at(i), false, std::placeholders::_1));
+				texture->writeSubresource(gCoreAccessor(), subresourceIdx, pixelData->at(i), false);
 			}
 			}
 
 
 			bs_delete<PoolAlloc>(pixelData);
 			bs_delete<PoolAlloc>(pixelData);

+ 4 - 4
BansheeCore/Include/BsTextureView.h

@@ -104,19 +104,19 @@ namespace BansheeEngine
 		/**
 		/**
 		 * @brief	Gets the owner texture the view is referencing.
 		 * @brief	Gets the owner texture the view is referencing.
 		 */
 		 */
-		TexturePtr getTexture() const { return mOwnerTexture; }
+		SPtr<TextureCore> getTexture() const { return mOwnerTexture; }
 
 
 	protected:
 	protected:
 		/**
 		/**
 		 * @brief	Initializes the texture view. This must be called right after construction.
 		 * @brief	Initializes the texture view. This must be called right after construction.
 		 */
 		 */
-		virtual void initialize(TexturePtr texture, TEXTURE_VIEW_DESC& _desc);
+		virtual void initialize(const SPtr<TextureCore>& texture, TEXTURE_VIEW_DESC& _desc);
 
 
 	protected:
 	protected:
-		friend class Texture;
+		friend class TextureCore;
 
 
 		TEXTURE_VIEW_DESC mDesc;
 		TEXTURE_VIEW_DESC mDesc;
-		TexturePtr mOwnerTexture;
+		SPtr<TextureCore> mOwnerTexture;
 
 
 		TextureView();
 		TextureView();
 	};
 	};

+ 2 - 19
BansheeCore/Source/BsCoreThreadAccessor.cpp

@@ -33,13 +33,13 @@ namespace BansheeEngine
 
 
 	void CoreThreadAccessorBase::setTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const TexturePtr &texPtr)
 	void CoreThreadAccessorBase::setTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const TexturePtr &texPtr)
 	{
 	{
-		mCommandQueue->queue(std::bind(&RenderSystem::setTexture, RenderSystem::instancePtr(), gptype, unit, enabled, texPtr));
+		mCommandQueue->queue(std::bind(&RenderSystem::setTexture, RenderSystem::instancePtr(), gptype, unit, enabled, texPtr->getCore()));
 	}
 	}
 
 
 	void CoreThreadAccessorBase::setLoadStoreTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const TexturePtr& texPtr,
 	void CoreThreadAccessorBase::setLoadStoreTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const TexturePtr& texPtr,
 		const TextureSurface& surface)
 		const TextureSurface& surface)
 	{
 	{
-		mCommandQueue->queue(std::bind(&RenderSystem::setLoadStoreTexture, RenderSystem::instancePtr(), gptype, unit, enabled, texPtr, 
+		mCommandQueue->queue(std::bind(&RenderSystem::setLoadStoreTexture, RenderSystem::instancePtr(), gptype, unit, enabled, texPtr->getCore(), 
 			surface));
 			surface));
 	}
 	}
 
 
@@ -173,23 +173,6 @@ namespace BansheeEngine
 		mCommandQueue->queue(std::bind(&RenderSystem::drawIndexed, RenderSystem::instancePtr(), startIndex, indexCount, vertexOffset, vertexCount));
 		mCommandQueue->queue(std::bind(&RenderSystem::drawIndexed, RenderSystem::instancePtr(), startIndex, indexCount, vertexOffset, vertexCount));
 	}
 	}
 
 
-	AsyncOp CoreThreadAccessorBase::writeSubresource(GpuResourcePtr resource, UINT32 subresourceIdx, const GpuResourceDataPtr& data, bool discardEntireBuffer)
-	{
-		data->_lock();
-
-		resource->_writeSubresourceSim(subresourceIdx, *data, discardEntireBuffer);
-		return mCommandQueue->queueReturn(std::bind(&RenderSystem::writeSubresource, RenderSystem::instancePtr(), resource, 
-			subresourceIdx, data, discardEntireBuffer, std::placeholders::_1));
-	}
-
-	AsyncOp CoreThreadAccessorBase::readSubresource(GpuResourcePtr resource, UINT32 subresourceIdx, const GpuResourceDataPtr& data)
-	{
-		data->_lock();
-
-		return mCommandQueue->queueReturn(std::bind(&RenderSystem::readSubresource, RenderSystem::instancePtr(), 
-			resource, subresourceIdx, data, std::placeholders::_1));
-	}
-
 	AsyncOp CoreThreadAccessorBase::queueReturnCommand(std::function<void(AsyncOp&)> commandCallback)
 	AsyncOp CoreThreadAccessorBase::queueReturnCommand(std::function<void(AsyncOp&)> commandCallback)
 	{
 	{
 		return mCommandQueue->queueReturn(commandCallback);
 		return mCommandQueue->queueReturn(commandCallback);

+ 0 - 15
BansheeCore/Source/BsGpuResource.cpp

@@ -1,15 +0,0 @@
-#include "BsGpuResource.h"
-#include "BsGpuResourceRTTI.h"
-
-namespace BansheeEngine
-{
-	RTTITypeBase* GpuResource::getRTTIStatic()
-	{
-		return GpuResourceRTTI::instance();
-	}
-
-	RTTITypeBase* GpuResource::getRTTI() const
-	{
-		return GpuResource::getRTTIStatic();
-	}
-}

+ 0 - 2
BansheeCore/Source/BsMesh.cpp

@@ -345,8 +345,6 @@ namespace BansheeEngine
 
 
 	AsyncOp Mesh::readSubresource(CoreAccessor& accessor, UINT32 subresourceIdx, const MeshDataPtr& data)
 	AsyncOp Mesh::readSubresource(CoreAccessor& accessor, UINT32 subresourceIdx, const MeshDataPtr& data)
 	{
 	{
-		updateBounds(*data);
-
 		data->_lock();
 		data->_lock();
 
 
 		std::function<void(const SPtr<MeshCore>&, UINT32, const MeshDataPtr&, AsyncOp&)> func =
 		std::function<void(const SPtr<MeshCore>&, UINT32, const MeshDataPtr&, AsyncOp&)> func =

+ 51 - 43
BansheeCore/Source/BsMultiRenderTexture.cpp

@@ -16,12 +16,14 @@ namespace BansheeEngine
 
 
 			if (texture != nullptr)
 			if (texture != nullptr)
 			{
 			{
-				mWidth = texture->getWidth();
-				mHeight = texture->getWidth();
-				mColorDepth = BansheeEngine::PixelUtil::getNumElemBits(texture->getFormat());
+				const TextureProperties& texProps = texture->getProperties();
+
+				mWidth = texProps.getWidth();
+				mHeight = texProps.getWidth();
+				mColorDepth = BansheeEngine::PixelUtil::getNumElemBits(texProps.getFormat());
 				mActive = true;
 				mActive = true;
-				mHwGamma = texture->isHardwareGammaEnabled();
-				mMultisampleCount = texture->getMultisampleCount();
+				mHwGamma = texProps.isHardwareGammaEnabled();
+				mMultisampleCount = texProps.getMultisampleCount();
 				mIsWindow = false;
 				mIsWindow = false;
 				mRequiresTextureFlipping = requiresTextureFlipping();
 				mRequiresTextureFlipping = requiresTextureFlipping();
 
 
@@ -55,24 +57,24 @@ namespace BansheeEngine
 					continue;
 					continue;
 				}
 				}
 
 
-				TexturePtr texture = mDesc.colorSurfaces[i].texture;
+				SPtr<TextureCore> texture = mDesc.colorSurfaces[i].texture->getCore();
 
 
-				if (texture->getUsage() != TU_RENDERTARGET)
+				if (texture->getProperties().getUsage() != TU_RENDERTARGET)
 					BS_EXCEPT(InvalidParametersException, "Provided texture is not created with render target usage.");
 					BS_EXCEPT(InvalidParametersException, "Provided texture is not created with render target usage.");
 
 
-				mColorSurfaces[i] = Texture::requestView(texture, mDesc.colorSurfaces[i].mipLevel, 1,
+				mColorSurfaces[i] = TextureCore::requestView(texture, mDesc.colorSurfaces[i].mipLevel, 1,
 					mDesc.colorSurfaces[i].face, 1, GVU_RENDERTARGET);
 					mDesc.colorSurfaces[i].face, 1, GVU_RENDERTARGET);
 			}
 			}
 		}
 		}
 
 
 		if (mDesc.depthStencilSurface.texture != nullptr)
 		if (mDesc.depthStencilSurface.texture != nullptr)
 		{
 		{
-			TexturePtr texture = mDesc.depthStencilSurface.texture;
+			SPtr<TextureCore> texture = mDesc.depthStencilSurface.texture->getCore();
 
 
-			if (texture->getUsage() != TU_DEPTHSTENCIL)
+			if (texture->getProperties().getUsage() != TU_DEPTHSTENCIL)
 				BS_EXCEPT(InvalidParametersException, "Provided texture is not created with depth stencil usage.");
 				BS_EXCEPT(InvalidParametersException, "Provided texture is not created with depth stencil usage.");
 
 
-			mDepthStencilSurface = Texture::requestView(texture, mDesc.depthStencilSurface.mipLevel, 1,
+			mDepthStencilSurface = TextureCore::requestView(texture, mDesc.depthStencilSurface.mipLevel, 1,
 				mDesc.depthStencilSurface.face, 1, GVU_DEPTHSTENCIL);
 				mDesc.depthStencilSurface.face, 1, GVU_DEPTHSTENCIL);
 		}
 		}
 
 
@@ -84,11 +86,11 @@ namespace BansheeEngine
 		for (auto iter = mColorSurfaces.begin(); iter != mColorSurfaces.end(); ++iter)
 		for (auto iter = mColorSurfaces.begin(); iter != mColorSurfaces.end(); ++iter)
 		{
 		{
 			if (*iter != nullptr)
 			if (*iter != nullptr)
-				Texture::releaseView(*iter);
+				TextureCore::releaseView(*iter);
 		}
 		}
 
 
 		if (mDepthStencilSurface != nullptr)
 		if (mDepthStencilSurface != nullptr)
-			Texture::releaseView(mDepthStencilSurface);
+			TextureCore::releaseView(mDepthStencilSurface);
 
 
 		RenderTargetCore::destroy();
 		RenderTargetCore::destroy();
 	}
 	}
@@ -129,48 +131,54 @@ namespace BansheeEngine
 				continue;
 				continue;
 			}
 			}
 
 
-			if(mColorSurfaces[i]->getTexture()->getWidth() != firstSurfaceDesc->getTexture()->getWidth() ||
-				mColorSurfaces[i]->getTexture()->getHeight() != firstSurfaceDesc->getTexture()->getHeight() ||
-				mColorSurfaces[i]->getTexture()->getMultisampleCount() != firstSurfaceDesc->getTexture()->getMultisampleCount())
+			const TextureProperties& curTexProps = mColorSurfaces[i]->getTexture()->getProperties();
+			const TextureProperties& firstTexProps = firstSurfaceDesc->getTexture()->getProperties();
+
+			if (curTexProps.getWidth() != firstTexProps.getWidth() ||
+				curTexProps.getHeight() != firstTexProps.getHeight() ||
+				curTexProps.getMultisampleCount() != firstTexProps.getMultisampleCount())
 			{
 			{
-				String errorInfo = "\nWidth: " + toString(mColorSurfaces[i]->getTexture()->getWidth()) + "/" + toString(firstSurfaceDesc->getTexture()->getWidth());
-				errorInfo += "\nHeight: " + toString(mColorSurfaces[i]->getTexture()->getHeight()) + "/" + toString(firstSurfaceDesc->getTexture()->getHeight());
-				errorInfo += "\nMultisample Count: " + toString(mColorSurfaces[i]->getTexture()->getMultisampleCount()) + "/" + toString(firstSurfaceDesc->getTexture()->getMultisampleCount());
+				String errorInfo = "\nWidth: " + toString(curTexProps.getWidth()) + "/" + toString(firstTexProps.getWidth());
+				errorInfo += "\nHeight: " + toString(curTexProps.getHeight()) + "/" + toString(firstTexProps.getHeight());
+				errorInfo += "\nMultisample Count: " + toString(curTexProps.getMultisampleCount()) + "/" + toString(firstTexProps.getMultisampleCount());
 
 
 				BS_EXCEPT(InvalidParametersException, "Provided texture and depth stencil buffer don't match!" + errorInfo);
 				BS_EXCEPT(InvalidParametersException, "Provided texture and depth stencil buffer don't match!" + errorInfo);
 			}
 			}
 		}
 		}
 
 
-		if(firstSurfaceDesc == nullptr)
-			return;
+		if (firstSurfaceDesc != nullptr)
+		{
+			const TextureProperties& firstTexProps = firstSurfaceDesc->getTexture()->getProperties();
 
 
-		if(firstSurfaceDesc->getTexture()->getTextureType() != TEX_TYPE_2D)
-			BS_EXCEPT(NotImplementedException, "Render textures are currently only implemented for 2D surfaces.");
+			if (firstTexProps.getTextureType() != TEX_TYPE_2D)
+				BS_EXCEPT(NotImplementedException, "Render textures are currently only implemented for 2D surfaces.");
 
 
-		if((firstSurfaceDesc->getFirstArraySlice() + firstSurfaceDesc->getNumArraySlices()) >= firstSurfaceDesc->getTexture()->getNumFaces())
-		{
-			BS_EXCEPT(InvalidParametersException, "Provided number of faces is out of range. Face: " + 
-				toString(firstSurfaceDesc->getFirstArraySlice() + firstSurfaceDesc->getNumArraySlices()) + ". Max num faces: " + toString(firstSurfaceDesc->getTexture()->getNumFaces()));
-		}
+			if ((firstSurfaceDesc->getFirstArraySlice() + firstSurfaceDesc->getNumArraySlices()) >= firstTexProps.getNumFaces())
+			{
+				BS_EXCEPT(InvalidParametersException, "Provided number of faces is out of range. Face: " +
+					toString(firstSurfaceDesc->getFirstArraySlice() + firstSurfaceDesc->getNumArraySlices()) + ". Max num faces: " + toString(firstTexProps.getNumFaces()));
+			}
 
 
-		if(firstSurfaceDesc->getMostDetailedMip() >= firstSurfaceDesc->getTexture()->getNumMipmaps())
-		{
-			BS_EXCEPT(InvalidParametersException, "Provided number of mip maps is out of range. Mip level: " + 
-				toString(firstSurfaceDesc->getMostDetailedMip()) + ". Max num mipmaps: " + toString(firstSurfaceDesc->getTexture()->getNumMipmaps()));
-		}
+			if (firstSurfaceDesc->getMostDetailedMip() >= firstTexProps.getNumMipmaps())
+			{
+				BS_EXCEPT(InvalidParametersException, "Provided number of mip maps is out of range. Mip level: " +
+					toString(firstSurfaceDesc->getMostDetailedMip()) + ". Max num mipmaps: " + toString(firstTexProps.getNumMipmaps()));
+			}
 
 
-		if(mDepthStencilSurface == nullptr)
-			return;
+			if (mDepthStencilSurface == nullptr)
+				return;
 
 
-		if(mDepthStencilSurface->getTexture()->getWidth() != firstSurfaceDesc->getTexture()->getWidth() ||
-			mDepthStencilSurface->getTexture()->getHeight() != firstSurfaceDesc->getTexture()->getHeight() ||
-			mDepthStencilSurface->getTexture()->getMultisampleCount() != firstSurfaceDesc->getTexture()->getMultisampleCount())
-		{
-			String errorInfo = "\nWidth: " + toString(mDepthStencilSurface->getTexture()->getWidth()) + "/" + toString(firstSurfaceDesc->getTexture()->getWidth());
-			errorInfo += "\nHeight: " + toString(mDepthStencilSurface->getTexture()->getHeight()) + "/" + toString(firstSurfaceDesc->getTexture()->getHeight());
-			errorInfo += "\nMultisample Count: " + toString(mDepthStencilSurface->getTexture()->getMultisampleCount()) + "/" + toString(firstSurfaceDesc->getTexture()->getMultisampleCount());
+			const TextureProperties& depthTexProps = mDepthStencilSurface->getTexture()->getProperties();
+			if (depthTexProps.getWidth() != firstTexProps.getWidth() ||
+				depthTexProps.getHeight() != firstTexProps.getHeight() ||
+				depthTexProps.getMultisampleCount() != firstTexProps.getMultisampleCount())
+			{
+				String errorInfo = "\nWidth: " + toString(depthTexProps.getWidth()) + "/" + toString(firstTexProps.getWidth());
+				errorInfo += "\nHeight: " + toString(depthTexProps.getHeight()) + "/" + toString(firstTexProps.getHeight());
+				errorInfo += "\nMultisample Count: " + toString(depthTexProps.getMultisampleCount()) + "/" + toString(firstTexProps.getMultisampleCount());
 
 
-			BS_EXCEPT(InvalidParametersException, "Provided texture and depth stencil buffer don't match!" + errorInfo);
+				BS_EXCEPT(InvalidParametersException, "Provided texture and depth stencil buffer don't match!" + errorInfo);
+			}
 		}
 		}
 	}
 	}
 
 

+ 2 - 33
BansheeCore/Source/BsRenderSystem.cpp

@@ -7,7 +7,7 @@
 #include "BsRenderWindow.h"
 #include "BsRenderWindow.h"
 #include "BsPixelBuffer.h"
 #include "BsPixelBuffer.h"
 #include "BsOcclusionQuery.h"
 #include "BsOcclusionQuery.h"
-#include "BsGpuResource.h"
+#include "BsResource.h"
 #include "BsCoreThread.h"
 #include "BsCoreThread.h"
 #include "BsMesh.h"
 #include "BsMesh.h"
 #include "BsProfilerCPU.h"
 #include "BsProfilerCPU.h"
@@ -17,7 +17,7 @@ using namespace std::placeholders;
 
 
 namespace BansheeEngine 
 namespace BansheeEngine 
 {
 {
-    static const TexturePtr sNullTexPtr;
+    static const SPtr<TextureCore> sNullTexPtr;
 
 
     RenderSystem::RenderSystem()
     RenderSystem::RenderSystem()
         : mCullingMode(CULL_COUNTERCLOCKWISE)
         : mCullingMode(CULL_COUNTERCLOCKWISE)
@@ -221,35 +221,4 @@ namespace BansheeEngine
 
 
 		BS_INC_RENDER_STAT(NumPresents);
 		BS_INC_RENDER_STAT(NumPresents);
 	}
 	}
-
-	void RenderSystem::writeSubresource(GpuResourcePtr resource, UINT32 subresourceIdx, const GpuResourceDataPtr& data, bool discardEntireBuffer, AsyncOp& asyncOp)
-	{
-		THROW_IF_NOT_CORE_THREAD;
-
-		gProfilerCPU().beginSample("writeSubresource");
-
-		resource->writeSubresource(subresourceIdx, *data, discardEntireBuffer);
-
-		gProfilerCPU().endSample("writeSubresource");
-
-		gProfilerCPU().beginSample("writeSubresourceB");
-
-		data->_unlock();
-		asyncOp._completeOperation();
-
-		gProfilerCPU().endSample("writeSubresourceB");
-	}
-
-	void RenderSystem::readSubresource(GpuResourcePtr resource, UINT32 subresourceIdx, GpuResourceDataPtr& data, AsyncOp& asyncOp)
-	{
-		THROW_IF_NOT_CORE_THREAD;
-
-		gProfilerCPU().beginSample("readSubresource");
-
-		resource->readSubresource(subresourceIdx, *data);
-		data->_unlock();
-		asyncOp._completeOperation();
-
-		gProfilerCPU().endSample("readSubresource");
-	}
 }
 }

+ 30 - 25
BansheeCore/Source/BsRenderTexture.cpp

@@ -15,11 +15,13 @@ namespace BansheeEngine
 
 
 		if (texture != nullptr)
 		if (texture != nullptr)
 		{
 		{
-			mWidth = texture->getWidth();
-			mHeight = texture->getHeight();
-			mColorDepth = BansheeEngine::PixelUtil::getNumElemBits(texture->getFormat());
-			mHwGamma = texture->isHardwareGammaEnabled();
-			mMultisampleCount = texture->getMultisampleCount();
+			const TextureProperties& props = texture->getProperties();
+
+			mWidth = props.getWidth();
+			mHeight = props.getHeight();
+			mColorDepth = BansheeEngine::PixelUtil::getNumElemBits(props.getFormat());
+			mHwGamma = props.isHardwareGammaEnabled();
+			mMultisampleCount = props.getMultisampleCount();
 		}
 		}
 
 
 		mActive = true;
 		mActive = true;
@@ -41,24 +43,24 @@ namespace BansheeEngine
 		const RENDER_SURFACE_DESC& colorSurface = mDesc.colorSurface;
 		const RENDER_SURFACE_DESC& colorSurface = mDesc.colorSurface;
 		if (colorSurface.texture != nullptr)
 		if (colorSurface.texture != nullptr)
 		{
 		{
-			TexturePtr texture = colorSurface.texture;
+			SPtr<TextureCore> texture = colorSurface.texture->getCore();
 
 
-			if (texture->getUsage() != TU_RENDERTARGET)
+			if (texture->getProperties().getUsage() != TU_RENDERTARGET)
 				BS_EXCEPT(InvalidParametersException, "Provided texture is not created with render target usage.");
 				BS_EXCEPT(InvalidParametersException, "Provided texture is not created with render target usage.");
 
 
-			mColorSurface = Texture::requestView(texture, colorSurface.mipLevel, 1,
+			mColorSurface = TextureCore::requestView(texture, colorSurface.mipLevel, 1,
 				colorSurface.face, 1, GVU_RENDERTARGET);
 				colorSurface.face, 1, GVU_RENDERTARGET);
 		}
 		}
 
 
 		const RENDER_SURFACE_DESC& depthStencilSurface = mDesc.depthStencilSurface;
 		const RENDER_SURFACE_DESC& depthStencilSurface = mDesc.depthStencilSurface;
 		if (depthStencilSurface.texture != nullptr)
 		if (depthStencilSurface.texture != nullptr)
 		{
 		{
-			TexturePtr texture = depthStencilSurface.texture;
+			SPtr<TextureCore> texture = depthStencilSurface.texture->getCore();
 
 
-			if (texture->getUsage() != TU_DEPTHSTENCIL)
+			if (texture->getProperties().getUsage() != TU_DEPTHSTENCIL)
 				BS_EXCEPT(InvalidParametersException, "Provided texture is not created with depth stencil usage.");
 				BS_EXCEPT(InvalidParametersException, "Provided texture is not created with depth stencil usage.");
 
 
-			mDepthStencilSurface = Texture::requestView(texture, depthStencilSurface.mipLevel, 1,
+			mDepthStencilSurface = TextureCore::requestView(texture, depthStencilSurface.mipLevel, 1,
 				depthStencilSurface.face, 1, GVU_DEPTHSTENCIL);
 				depthStencilSurface.face, 1, GVU_DEPTHSTENCIL);
 		}
 		}
 
 
@@ -67,30 +69,30 @@ namespace BansheeEngine
 		assert(mColorSurface != nullptr);
 		assert(mColorSurface != nullptr);
 		assert(mColorSurface->getTexture() != nullptr);
 		assert(mColorSurface->getTexture() != nullptr);
 
 
-		if (mColorSurface->getTexture()->getTextureType() != TEX_TYPE_2D)
-			BS_EXCEPT(NotImplementedException, "Render textures are currently only implemented for 2D surfaces.");
+		SPtr<TextureCore> colorTexture = mColorSurface->getTexture();
+		const TextureProperties& texProps = colorTexture->getProperties();
 
 
-		if ((mColorSurface->getFirstArraySlice() + mColorSurface->getNumArraySlices()) > mColorSurface->getTexture()->getNumFaces())
+		if ((mColorSurface->getFirstArraySlice() + mColorSurface->getNumArraySlices()) > texProps.getNumFaces())
 		{
 		{
 			BS_EXCEPT(InvalidParametersException, "Provided number of faces is out of range. Face: " +
 			BS_EXCEPT(InvalidParametersException, "Provided number of faces is out of range. Face: " +
 				toString(mColorSurface->getFirstArraySlice() + mColorSurface->getNumArraySlices()) +
 				toString(mColorSurface->getFirstArraySlice() + mColorSurface->getNumArraySlices()) +
-				". Max num faces: " + toString(mColorSurface->getTexture()->getNumFaces()));
+				". Max num faces: " + toString(texProps.getNumFaces()));
 		}
 		}
 
 
-		if (mColorSurface->getMostDetailedMip() > mColorSurface->getTexture()->getNumMipmaps())
+		if (mColorSurface->getMostDetailedMip() > texProps.getNumMipmaps())
 		{
 		{
 			BS_EXCEPT(InvalidParametersException, "Provided number of mip maps is out of range. Mip level: " +
 			BS_EXCEPT(InvalidParametersException, "Provided number of mip maps is out of range. Mip level: " +
-				toString(mColorSurface->getMostDetailedMip()) + ". Max num mipmaps: " + toString(mColorSurface->getTexture()->getNumMipmaps()));
+				toString(mColorSurface->getMostDetailedMip()) + ". Max num mipmaps: " + toString(texProps.getNumMipmaps()));
 		}
 		}
 	}
 	}
 
 
 	void RenderTextureCore::destroy()
 	void RenderTextureCore::destroy()
 	{
 	{
 		if (mColorSurface != nullptr)
 		if (mColorSurface != nullptr)
-			Texture::releaseView(mColorSurface);
+			TextureCore::releaseView(mColorSurface);
 
 
 		if (mDepthStencilSurface != nullptr)
 		if (mDepthStencilSurface != nullptr)
-			Texture::releaseView(mDepthStencilSurface);
+			TextureCore::releaseView(mDepthStencilSurface);
 
 
 		RenderTargetCore::destroy();
 		RenderTargetCore::destroy();
 	}
 	}
@@ -122,13 +124,16 @@ namespace BansheeEngine
 		if (mColorSurface == nullptr || mDepthStencilSurface == nullptr)
 		if (mColorSurface == nullptr || mDepthStencilSurface == nullptr)
 			return;
 			return;
 
 
-		if (mColorSurface->getTexture()->getWidth() != mDepthStencilSurface->getTexture()->getWidth() ||
-			mColorSurface->getTexture()->getHeight() != mDepthStencilSurface->getTexture()->getHeight() ||
-			mColorSurface->getTexture()->getMultisampleCount() != mDepthStencilSurface->getTexture()->getMultisampleCount())
+		const TextureProperties& colorProps = mColorSurface->getTexture()->getProperties();
+		const TextureProperties& depthProps = mDepthStencilSurface->getTexture()->getProperties();
+
+		if (colorProps.getWidth() != depthProps.getWidth() ||
+			colorProps.getHeight() != depthProps.getHeight() ||
+			colorProps.getMultisampleCount() != depthProps.getMultisampleCount())
 		{
 		{
-			String errorInfo = "\nWidth: " + toString(mColorSurface->getTexture()->getWidth()) + "/" + toString(mDepthStencilSurface->getTexture()->getWidth());
-			errorInfo += "\nHeight: " + toString(mColorSurface->getTexture()->getHeight()) + "/" + toString(mDepthStencilSurface->getTexture()->getHeight());
-			errorInfo += "\nMultisample Count: " + toString(mColorSurface->getTexture()->getMultisampleCount()) + "/" + toString(mDepthStencilSurface->getTexture()->getMultisampleCount());
+			String errorInfo = "\nWidth: " + toString(colorProps.getWidth()) + "/" + toString(depthProps.getWidth());
+			errorInfo += "\nHeight: " + toString(colorProps.getHeight()) + "/" + toString(depthProps.getHeight());
+			errorInfo += "\nMultisample Count: " + toString(colorProps.getMultisampleCount()) + "/" + toString(depthProps.getMultisampleCount());
 
 
 			BS_EXCEPT(InvalidParametersException, "Provided texture and depth stencil buffer don't match!" + errorInfo);
 			BS_EXCEPT(InvalidParametersException, "Provided texture and depth stencil buffer don't match!" + errorInfo);
 		}
 		}

+ 272 - 206
BansheeCore/Source/BsTexture.cpp

@@ -11,105 +11,58 @@
 
 
 namespace BansheeEngine 
 namespace BansheeEngine 
 {
 {
-    Texture::Texture()
-        :mHeight(32), mWidth(32), mDepth(1), mNumMipmaps(0),
-		 mHwGamma(false), mMultisampleCount(0), mTextureType(TEX_TYPE_2D), 
-		 mFormat(PF_UNKNOWN), mUsage(TU_DEFAULT)
-    {
-        
-    }
+	TextureProperties::TextureProperties()
+		:mHeight(32), mWidth(32), mDepth(1), mNumMipmaps(0),
+		mHwGamma(false), mMultisampleCount(0), mTextureType(TEX_TYPE_2D),
+		mFormat(PF_UNKNOWN), mUsage(TU_DEFAULT)
+	{
+		mFormat = TextureManager::instance().getNativeFormat(mTextureType, mFormat, mUsage, mHwGamma);
+	}
 
 
-	void Texture::initialize(TextureType textureType, UINT32 width, UINT32 height, UINT32 depth, UINT32 numMipmaps, 
+	TextureProperties::TextureProperties(TextureType textureType, UINT32 width, UINT32 height, UINT32 depth, UINT32 numMipmaps,
 		PixelFormat format, int usage, bool hwGamma, UINT32 multisampleCount)
 		PixelFormat format, int usage, bool hwGamma, UINT32 multisampleCount)
+		:mHeight(height), mWidth(width), mDepth(depth), mNumMipmaps(numMipmaps),
+		mHwGamma(hwGamma), mMultisampleCount(multisampleCount), mTextureType(textureType),
+		mFormat(format), mUsage(usage)
 	{
 	{
-		mTextureType = textureType;
-		mWidth = width;
-		mHeight = height;
-		mDepth = depth;
-		mNumMipmaps = numMipmaps;
-		mUsage = usage;
-		mHwGamma = hwGamma;
-		mMultisampleCount = multisampleCount;
-
-		// Adjust format if required
-		mFormat = TextureManager::instance().getNativeFormat(mTextureType, format, mUsage, hwGamma);
-		mSize = getNumFaces() * PixelUtil::getMemorySize(mWidth, mHeight, mDepth, mFormat);
-
-		// Allocate CPU buffers if needed
-		if ((usage & TU_CPUCACHED) != 0)
-			createCPUBuffers();
-
-		Resource::initialize();
+		mFormat = TextureManager::instance().getNativeFormat(mTextureType, mFormat, mUsage, mHwGamma);
 	}
 	}
 
 
-    bool Texture::hasAlpha() const
-    {
-        return PixelUtil::hasAlpha(mFormat);
-    }
-
-	UINT32 Texture::calculateSize() const
+	bool TextureProperties::hasAlpha() const
 	{
 	{
-        return getNumFaces() * PixelUtil::getMemorySize(mWidth, mHeight, mDepth, mFormat);
+		return PixelUtil::hasAlpha(mFormat);
 	}
 	}
 
 
-	UINT32 Texture::getNumFaces() const
+	UINT32 TextureProperties::getNumFaces() const
 	{
 	{
 		return getTextureType() == TEX_TYPE_CUBE_MAP ? 6 : 1;
 		return getTextureType() == TEX_TYPE_CUBE_MAP ? 6 : 1;
 	}
 	}
 
 
-	void Texture::_writeSubresourceSim(UINT32 subresourceIdx, const GpuResourceData& data, bool discardEntireBuffer)
+	void TextureProperties::mapFromSubresourceIdx(UINT32 subresourceIdx, UINT32& face, UINT32& mip) const
 	{
 	{
-		if ((mUsage & TU_CPUCACHED) == 0)
-			return;
-
-		if (subresourceIdx >= (UINT32)mCPUSubresourceData.size())
-		{
-			LOGERR("Invalid subresource index: " + toString(subresourceIdx) + ". Supported range: 0 .. " + toString(mCPUSubresourceData.size()));
-			return;
-		}
-
-		if (data.getTypeId() != TID_PixelData)
-		{
-			LOGERR("Invalid GpuResourceData type. Only PixelData is supported.");
-			return;
-		}
-
-		const PixelData& pixelData = static_cast<const PixelData&>(data);
-
-		UINT32 mipLevel;
-		UINT32 face;
-		mapFromSubresourceIdx(subresourceIdx, face, mipLevel);
-
-		UINT32 mipWidth, mipHeight, mipDepth;
-		PixelUtil::getSizeForMipLevel(getWidth(), getHeight(), getDepth(),
-			mipLevel, mipWidth, mipHeight, mipDepth);
-
-		if (pixelData.getWidth() != mipWidth || pixelData.getHeight() != mipHeight ||
-			pixelData.getDepth() != mipDepth || pixelData.getFormat() != getFormat())
-		{
-			LOGERR("Provided buffer is not of valid dimensions or format in order to read from this texture.");
-			return;
-		}
-
-		if (mCPUSubresourceData[subresourceIdx]->getSize() != pixelData.getSize())
-			BS_EXCEPT(InternalErrorException, "Buffer sizes don't match.");
+		UINT32 numMipmaps = getNumMipmaps() + 1;
 
 
-		UINT8* dest = mCPUSubresourceData[subresourceIdx]->getData();
-		UINT8* src = pixelData.getData();
+		face = Math::floorToInt((subresourceIdx) / (float)numMipmaps);
+		mip = subresourceIdx % numMipmaps;
+	}
 
 
-		memcpy(dest, src, pixelData.getSize());
+	UINT32 TextureProperties::mapToSubresourceIdx(UINT32 face, UINT32 mip) const
+	{
+		return face * (getNumMipmaps() + 1) + mip;
 	}
 	}
 
 
-	void Texture::writeSubresource(UINT32 subresourceIdx, const GpuResourceData& data, bool discardEntireBuffer)
+	TextureCore::TextureCore(TextureType textureType, UINT32 width, UINT32 height, UINT32 depth, UINT32 numMipmaps,
+		PixelFormat format, int usage, bool hwGamma, UINT32 multisampleCount)
+		:mProperties(textureType, width, height, depth, numMipmaps, format, usage, hwGamma, multisampleCount)
+	{ }
+
+	void TextureCore::writeSubresource(UINT32 subresourceIdx, const PixelData& pixelData, bool discardEntireBuffer)
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
-		if(data.getTypeId() != TID_PixelData)
-			BS_EXCEPT(InvalidParametersException, "Invalid GpuResourceData type. Only PixelData is supported.");
-
 		if(discardEntireBuffer)
 		if(discardEntireBuffer)
 		{
 		{
-			if(mUsage != TU_DYNAMIC)
+			if(mProperties.getUsage() != TU_DYNAMIC)
 			{
 			{
 				LOGWRN("Buffer discard is enabled but buffer was not created as dynamic. Disabling discard.");
 				LOGWRN("Buffer discard is enabled but buffer was not created as dynamic. Disabling discard.");
 				discardEntireBuffer = false;
 				discardEntireBuffer = false;
@@ -117,41 +70,36 @@ namespace BansheeEngine
 		}
 		}
 		else
 		else
 		{
 		{
-			if(mUsage == TU_DYNAMIC)
+			if (mProperties.getUsage() == TU_DYNAMIC)
 			{
 			{
 				LOGWRN("Buffer discard is not enabled but buffer was not created as dynamic. Enabling discard.");
 				LOGWRN("Buffer discard is not enabled but buffer was not created as dynamic. Enabling discard.");
 				discardEntireBuffer = true;
 				discardEntireBuffer = true;
 			}
 			}
 		}
 		}
 
 
-		const PixelData& pixelData = static_cast<const PixelData&>(data);
-
 		UINT32 face = 0;
 		UINT32 face = 0;
 		UINT32 mip = 0;
 		UINT32 mip = 0;
-		mapFromSubresourceIdx(subresourceIdx, face, mip);
+		mProperties.mapFromSubresourceIdx(subresourceIdx, face, mip);
 
 
 		writeData(pixelData, mip, face, discardEntireBuffer);
 		writeData(pixelData, mip, face, discardEntireBuffer);
 	}
 	}
 
 
-	void Texture::readSubresource(UINT32 subresourceIdx, GpuResourceData& data)
+	void TextureCore::readSubresource(UINT32 subresourceIdx, PixelData& data)
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
-		if(data.getTypeId() != TID_PixelData)
-			BS_EXCEPT(InvalidParametersException, "Invalid GpuResourceData type. Only PixelData is supported.");
-
 		UINT32 face = 0;
 		UINT32 face = 0;
 		UINT32 mip = 0;
 		UINT32 mip = 0;
-		mapFromSubresourceIdx(subresourceIdx, face, mip);
+		mProperties.mapFromSubresourceIdx(subresourceIdx, face, mip);
 
 
 		PixelData& pixelData = static_cast<PixelData&>(data);
 		PixelData& pixelData = static_cast<PixelData&>(data);
 
 
 		UINT32 mipWidth, mipHeight, mipDepth;
 		UINT32 mipWidth, mipHeight, mipDepth;
-		PixelUtil::getSizeForMipLevel(getWidth(), getHeight(), getDepth(),
+		PixelUtil::getSizeForMipLevel(mProperties.getWidth(), mProperties.getHeight(), mProperties.getDepth(),
 			mip, mipWidth, mipHeight, mipDepth);
 			mip, mipWidth, mipHeight, mipDepth);
 
 
 		if (pixelData.getWidth() != mipWidth || pixelData.getHeight() != mipHeight ||
 		if (pixelData.getWidth() != mipWidth || pixelData.getHeight() != mipHeight ||
-			pixelData.getDepth() != mipDepth || pixelData.getFormat() != getFormat())
+			pixelData.getDepth() != mipDepth || pixelData.getFormat() != mProperties.getFormat())
 		{
 		{
 			BS_EXCEPT(RenderingAPIException, "Provided buffer is not of valid dimensions or format in order to read from this texture.");
 			BS_EXCEPT(RenderingAPIException, "Provided buffer is not of valid dimensions or format in order to read from this texture.");
 		}
 		}
@@ -159,114 +107,37 @@ namespace BansheeEngine
 		readData(pixelData, mip, face);
 		readData(pixelData, mip, face);
 	}
 	}
 
 
-	PixelDataPtr Texture::allocateSubresourceBuffer(UINT32 subresourceIdx) const
-	{
-		UINT32 face = 0;
-		UINT32 mip = 0;
-		mapFromSubresourceIdx(subresourceIdx, face, mip);
-
-		UINT32 numMips = getNumMipmaps();
-		UINT32 width = getWidth();
-		UINT32 height = getHeight();
-		UINT32 depth = getDepth();
-
-		UINT32 totalSize = PixelUtil::getMemorySize(width, height, depth, mFormat);
-
-		for(UINT32 j = 0; j < mip; j++)
-		{
-			totalSize = PixelUtil::getMemorySize(width, height, depth, mFormat);
-
-			if(width != 1) width /= 2;
-			if(height != 1) height /= 2;
-			if(depth != 1) depth /= 2;
-		}
-
-		PixelDataPtr dst = bs_shared_ptr<PixelData, PoolAlloc>(width, height, depth, getFormat());
-
-		dst->allocateInternalBuffer();
-
-		return dst;
-	}
-
-	void Texture::mapFromSubresourceIdx(UINT32 subresourceIdx, UINT32& face, UINT32& mip) const
-	{
-		UINT32 numMipmaps = getNumMipmaps() + 1;
-
-		face = Math::floorToInt((subresourceIdx) / (float)numMipmaps);
-		mip = subresourceIdx % numMipmaps;
-	}
-
-	UINT32 Texture::mapToSubresourceIdx(UINT32 face, UINT32 mip) const
-	{
-		return face * (getNumMipmaps() + 1) + mip;
-	}
-
-	void Texture::readDataSim(PixelData& dest, UINT32 mipLevel, UINT32 face)
-	{
-		if ((mUsage & TU_CPUCACHED) == 0)
-		{
-			LOGERR("Attempting to read CPU data from a texture that is created without CPU caching.");
-			return;
-		}
-
-		UINT32 mipWidth, mipHeight, mipDepth;
-		PixelUtil::getSizeForMipLevel(getWidth(), getHeight(), getDepth(), 
-			mipLevel, mipWidth, mipHeight, mipDepth);
-
-		if (dest.getWidth() != mipWidth || dest.getHeight() != mipHeight ||
-			dest.getDepth() != mipDepth || dest.getFormat() != getFormat())
-		{
-			LOGERR("Provided buffer is not of valid dimensions or format in order to read from this texture.");
-			return;
-		}
-
-		UINT32 subresourceIdx = mapToSubresourceIdx(face, mipLevel);
-		if (subresourceIdx >= (UINT32)mCPUSubresourceData.size())
-		{
-			LOGERR("Invalid subresource index: " + toString(subresourceIdx) + ". Supported range: 0 .. " + toString(mCPUSubresourceData.size()));
-			return;
-		}
-
-		if (mCPUSubresourceData[subresourceIdx]->getSize() != dest.getSize())
-			BS_EXCEPT(InternalErrorException, "Buffer sizes don't match.");
-
-		UINT8* srcPtr = mCPUSubresourceData[subresourceIdx]->getData();
-		UINT8* destPtr = dest.getData();
-
-		memcpy(destPtr, srcPtr, dest.getSize());
-	}
-
-	PixelData Texture::lock(GpuLockOptions options, UINT32 mipLevel, UINT32 face)
+	PixelData TextureCore::lock(GpuLockOptions options, UINT32 mipLevel, UINT32 face)
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
-		if(mipLevel < 0 || mipLevel > mNumMipmaps)
-			BS_EXCEPT(InvalidParametersException, "Invalid mip level: " + toString(mipLevel) + ". Min is 0, max is " + toString(getNumMipmaps()));
+		if (mipLevel < 0 || mipLevel > mProperties.getNumMipmaps())
+			BS_EXCEPT(InvalidParametersException, "Invalid mip level: " + toString(mipLevel) + ". Min is 0, max is " + toString(mProperties.getNumMipmaps()));
 
 
-		if(face < 0 || face >= getNumFaces())
-			BS_EXCEPT(InvalidParametersException, "Invalid face index: " + toString(face) + ". Min is 0, max is " + toString(getNumFaces()));
+		if (face < 0 || face >= mProperties.getNumFaces())
+			BS_EXCEPT(InvalidParametersException, "Invalid face index: " + toString(face) + ". Min is 0, max is " + toString(mProperties.getNumFaces()));
 
 
 		return lockImpl(options, mipLevel, face);
 		return lockImpl(options, mipLevel, face);
 	}
 	}
 
 
-	void Texture::unlock()
+	void TextureCore::unlock()
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
 		unlockImpl();
 		unlockImpl();
 	}
 	}
 
 
-	void Texture::copy(UINT32 srcSubresourceIdx, UINT32 destSubresourceIdx, TexturePtr& target)
+	void TextureCore::copy(UINT32 srcSubresourceIdx, UINT32 destSubresourceIdx, const SPtr<TextureCore>& target)
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
-		if (target->getTextureType() != this->getTextureType())
+		if (target->mProperties.getTextureType() != mProperties.getTextureType())
 			BS_EXCEPT(InvalidParametersException, "Source and destination textures must be of same type and must have the same usage and type.");
 			BS_EXCEPT(InvalidParametersException, "Source and destination textures must be of same type and must have the same usage and type.");
 
 
-		if (getFormat() != target->getFormat()) // Note: It might be okay to use different formats of the same size
+		if (mProperties.getFormat() != target->mProperties.getFormat()) // Note: It might be okay to use different formats of the same size
 			BS_EXCEPT(InvalidParametersException, "Source and destination texture formats must match.");
 			BS_EXCEPT(InvalidParametersException, "Source and destination texture formats must match.");
 
 
-		if (target->getMultisampleCount() > 0 && getMultisampleCount() != target->getMultisampleCount())
+		if (target->mProperties.getMultisampleCount() > 0 && mProperties.getMultisampleCount() != target->mProperties.getMultisampleCount())
 			BS_EXCEPT(InvalidParametersException, "When copying to a multisampled texture, source texture must have the same number of samples.");
 			BS_EXCEPT(InvalidParametersException, "When copying to a multisampled texture, source texture must have the same number of samples.");
 
 
 		UINT32 srcFace = 0;
 		UINT32 srcFace = 0;
@@ -275,28 +146,28 @@ namespace BansheeEngine
 		UINT32 destFace = 0;
 		UINT32 destFace = 0;
 		UINT32 destMipLevel = 0;
 		UINT32 destMipLevel = 0;
 
 
-		mapFromSubresourceIdx(srcSubresourceIdx, srcFace, srcMipLevel);
-		target->mapFromSubresourceIdx(destSubresourceIdx, destFace, destMipLevel);
+		mProperties.mapFromSubresourceIdx(srcSubresourceIdx, srcFace, srcMipLevel);
+		target->mProperties.mapFromSubresourceIdx(destSubresourceIdx, destFace, destMipLevel);
 
 
-		if (destFace >= getNumFaces())
+		if (destFace >= mProperties.getNumFaces())
 			BS_EXCEPT(InvalidParametersException, "Invalid destination face index");
 			BS_EXCEPT(InvalidParametersException, "Invalid destination face index");
 
 
-		if (srcFace >= target->getNumFaces())
+		if (srcFace >= target->mProperties.getNumFaces())
 			BS_EXCEPT(InvalidParametersException, "Invalid destination face index");
 			BS_EXCEPT(InvalidParametersException, "Invalid destination face index");
 
 
-		if (srcMipLevel > getNumMipmaps())
-			BS_EXCEPT(InvalidParametersException, "Source mip level out of range. Valid range is [0, " + toString(getNumMipmaps()) + "]");
+		if (srcMipLevel > mProperties.getNumMipmaps())
+			BS_EXCEPT(InvalidParametersException, "Source mip level out of range. Valid range is [0, " + toString(mProperties.getNumMipmaps()) + "]");
 
 
-		if (destMipLevel > target->getNumMipmaps())
-			BS_EXCEPT(InvalidParametersException, "Destination mip level out of range. Valid range is [0, " + toString(target->getNumMipmaps()) + "]");
+		if (destMipLevel > target->mProperties.getNumMipmaps())
+			BS_EXCEPT(InvalidParametersException, "Destination mip level out of range. Valid range is [0, " + toString(target->mProperties.getNumMipmaps()) + "]");
 
 
-		UINT32 srcMipWidth = mWidth >> srcMipLevel;
-		UINT32 srcMipHeight = mHeight >> srcMipLevel;
-		UINT32 srcMipDepth = mDepth >> srcMipLevel;
+		UINT32 srcMipWidth = mProperties.getWidth() >> srcMipLevel;
+		UINT32 srcMipHeight = mProperties.getHeight() >> srcMipLevel;
+		UINT32 srcMipDepth = mProperties.getDepth() >> srcMipLevel;
 
 
-		UINT32 dstMipWidth = target->getWidth() >> destMipLevel;
-		UINT32 dstMipHeight = target->getHeight() >> destMipLevel;
-		UINT32 dstMipDepth = target->getDepth() >> destMipLevel;
+		UINT32 dstMipWidth = target->mProperties.getWidth() >> destMipLevel;
+		UINT32 dstMipHeight = target->mProperties.getHeight() >> destMipLevel;
+		UINT32 dstMipDepth = target->mProperties.getDepth() >> destMipLevel;
 
 
 		if (srcMipWidth != dstMipWidth || srcMipHeight != dstMipHeight || srcMipDepth != dstMipDepth)
 		if (srcMipWidth != dstMipWidth || srcMipHeight != dstMipHeight || srcMipDepth != dstMipDepth)
 			BS_EXCEPT(InvalidParametersException, "Source and destination sizes must match");
 			BS_EXCEPT(InvalidParametersException, "Source and destination sizes must match");
@@ -308,7 +179,7 @@ namespace BansheeEngine
 	/* 								TEXTURE VIEW                      		*/
 	/* 								TEXTURE VIEW                      		*/
 	/************************************************************************/
 	/************************************************************************/
 
 
-	TextureViewPtr Texture::createView()
+	TextureViewPtr TextureCore::createView()
 	{
 	{
 		TextureViewPtr viewPtr = bs_core_ptr<TextureView, PoolAlloc>(new (bs_alloc<TextureView, PoolAlloc>()) TextureView());
 		TextureViewPtr viewPtr = bs_core_ptr<TextureView, PoolAlloc>(new (bs_alloc<TextureView, PoolAlloc>()) TextureView());
 		viewPtr->_setThisPtr(viewPtr);
 		viewPtr->_setThisPtr(viewPtr);
@@ -316,12 +187,12 @@ namespace BansheeEngine
 		return viewPtr;
 		return viewPtr;
 	}
 	}
 
 
-	void Texture::clearBufferViews()
+	void TextureCore::clearBufferViews()
 	{
 	{
 		mTextureViews.clear();
 		mTextureViews.clear();
 	}
 	}
 
 
-	TextureViewPtr Texture::requestView(TexturePtr texture, UINT32 mostDetailMip, UINT32 numMips, UINT32 firstArraySlice, UINT32 numArraySlices, GpuViewUsage usage)
+	TextureViewPtr TextureCore::requestView(const SPtr<TextureCore>& texture, UINT32 mostDetailMip, UINT32 numMips, UINT32 firstArraySlice, UINT32 numArraySlices, GpuViewUsage usage)
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
@@ -335,7 +206,7 @@ namespace BansheeEngine
 		key.usage = usage;
 		key.usage = usage;
 
 
 		auto iterFind = texture->mTextureViews.find(key);
 		auto iterFind = texture->mTextureViews.find(key);
-		if(iterFind == texture->mTextureViews.end())
+		if (iterFind == texture->mTextureViews.end())
 		{
 		{
 			TextureViewPtr newView = texture->createView();
 			TextureViewPtr newView = texture->createView();
 			newView->initialize(texture, key);
 			newView->initialize(texture, key);
@@ -348,23 +219,23 @@ namespace BansheeEngine
 		return iterFind->second->view;
 		return iterFind->second->view;
 	}
 	}
 
 
-	void Texture::releaseView(TextureViewPtr view)
+	void TextureCore::releaseView(const TextureViewPtr& view)
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
 		assert(view != nullptr);
 		assert(view != nullptr);
 
 
-		TexturePtr texture = view->getTexture();
+		SPtr<TextureCore> texture = view->getTexture();
 
 
 		auto iterFind = texture->mTextureViews.find(view->getDesc());
 		auto iterFind = texture->mTextureViews.find(view->getDesc());
-		if(iterFind == texture->mTextureViews.end())
+		if (iterFind == texture->mTextureViews.end())
 		{
 		{
 			BS_EXCEPT(InternalErrorException, "Trying to release a texture view that doesn't exist!");
 			BS_EXCEPT(InternalErrorException, "Trying to release a texture view that doesn't exist!");
 		}
 		}
 
 
 		iterFind->second->refCount--;
 		iterFind->second->refCount--;
 
 
-		if(iterFind->second->refCount == 0)
+		if (iterFind->second->refCount == 0)
 		{
 		{
 			TextureViewReference* toRemove = iterFind->second;
 			TextureViewReference* toRemove = iterFind->second;
 
 
@@ -374,25 +245,199 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
+	Texture::Texture()
+	{
+
+	}
+
+	Texture::Texture(TextureType textureType, UINT32 width, UINT32 height, UINT32 depth, UINT32 numMipmaps,
+		PixelFormat format, int usage, bool hwGamma, UINT32 multisampleCount)
+		:mProperties(textureType, width, height, depth, numMipmaps, format, usage, hwGamma, multisampleCount)
+    {
+        
+    }
+
+	void Texture::initialize()
+	{
+		mSize = calculateSize();
+
+		// Allocate CPU buffers if needed
+		if ((mProperties.getUsage() & TU_CPUCACHED) != 0)
+			createCPUBuffers();
+
+		Resource::initialize();
+	}
+
+	SPtr<CoreObjectCore> Texture::createCore() const
+	{
+		const TextureProperties& props = getProperties();
+
+		return TextureCoreManager::instance().createTextureInternal(props.getTextureType(), props.getWidth(), props.getHeight(),
+			props.getDepth(), props.getNumMipmaps(), props.getFormat(), props.getUsage(), props.isHardwareGammaEnabled(), props.getMultisampleCount());
+	}
+
+	AsyncOp Texture::writeSubresource(CoreAccessor& accessor, UINT32 subresourceIdx, const PixelDataPtr& data, bool discardEntireBuffer)
+	{
+		updateCPUBuffers(subresourceIdx, *data);
+
+		data->_lock();
+
+		std::function<void(const SPtr<TextureCore>&, UINT32, const PixelDataPtr&, bool, AsyncOp&)> func =
+			[&](const SPtr<TextureCore>& texture, UINT32 _subresourceIdx, const PixelDataPtr& _pixData, bool _discardEntireBuffer, AsyncOp& asyncOp)
+		{
+			texture->writeSubresource(_subresourceIdx, *_pixData, _discardEntireBuffer);
+			_pixData->_unlock();
+			asyncOp._completeOperation();
+
+		};
+
+		return accessor.queueReturnCommand(std::bind(func, getCore(), subresourceIdx,
+			data, discardEntireBuffer, std::placeholders::_1));
+	}
+
+	AsyncOp Texture::readSubresource(CoreAccessor& accessor, UINT32 subresourceIdx, const PixelDataPtr& data)
+	{
+		data->_lock();
+
+		std::function<void(const SPtr<TextureCore>&, UINT32, const PixelDataPtr&, AsyncOp&)> func =
+			[&](const SPtr<TextureCore>& texture, UINT32 _subresourceIdx, const PixelDataPtr& _pixData, AsyncOp& asyncOp)
+		{
+			texture->readSubresource(_subresourceIdx, *_pixData);
+			_pixData->_unlock();
+			asyncOp._completeOperation();
+
+		};
+
+		return accessor.queueReturnCommand(std::bind(func, getCore(), subresourceIdx,
+			data, std::placeholders::_1));
+	}
+
+	UINT32 Texture::calculateSize() const
+	{
+		return mProperties.getNumFaces() * PixelUtil::getMemorySize(mProperties.getWidth(),
+			mProperties.getHeight(), mProperties.getDepth(), mProperties.getFormat());
+	}
+
+	void Texture::updateCPUBuffers(UINT32 subresourceIdx, const PixelData& pixelData)
+	{
+		if ((mProperties.getUsage() & TU_CPUCACHED) == 0)
+			return;
+
+		if (subresourceIdx >= (UINT32)mCPUSubresourceData.size())
+		{
+			LOGERR("Invalid subresource index: " + toString(subresourceIdx) + ". Supported range: 0 .. " + toString(mCPUSubresourceData.size()));
+			return;
+		}
+
+		UINT32 mipLevel;
+		UINT32 face;
+		mProperties.mapFromSubresourceIdx(subresourceIdx, face, mipLevel);
+
+		UINT32 mipWidth, mipHeight, mipDepth;
+		PixelUtil::getSizeForMipLevel(mProperties.getWidth(), mProperties.getHeight(), mProperties.getDepth(),
+			mipLevel, mipWidth, mipHeight, mipDepth);
+
+		if (pixelData.getWidth() != mipWidth || pixelData.getHeight() != mipHeight ||
+			pixelData.getDepth() != mipDepth || pixelData.getFormat() != mProperties.getFormat())
+		{
+			LOGERR("Provided buffer is not of valid dimensions or format in order to read from this texture.");
+			return;
+		}
+
+		if (mCPUSubresourceData[subresourceIdx]->getSize() != pixelData.getSize())
+			BS_EXCEPT(InternalErrorException, "Buffer sizes don't match.");
+
+		UINT8* dest = mCPUSubresourceData[subresourceIdx]->getData();
+		UINT8* src = pixelData.getData();
+
+		memcpy(dest, src, pixelData.getSize());
+	}
+
+	PixelDataPtr Texture::allocateSubresourceBuffer(UINT32 subresourceIdx) const
+	{
+		UINT32 face = 0;
+		UINT32 mip = 0;
+		mProperties.mapFromSubresourceIdx(subresourceIdx, face, mip);
+
+		UINT32 numMips = mProperties.getNumMipmaps();
+		UINT32 width = mProperties.getWidth();
+		UINT32 height = mProperties.getHeight();
+		UINT32 depth = mProperties.getDepth();
+
+		UINT32 totalSize = PixelUtil::getMemorySize(width, height, depth, mProperties.getFormat());
+
+		for(UINT32 j = 0; j < mip; j++)
+		{
+			totalSize = PixelUtil::getMemorySize(width, height, depth, mProperties.getFormat());
+
+			if(width != 1) width /= 2;
+			if(height != 1) height /= 2;
+			if(depth != 1) depth /= 2;
+		}
+
+		PixelDataPtr dst = bs_shared_ptr<PixelData, PoolAlloc>(width, height, depth, mProperties.getFormat());
+
+		dst->allocateInternalBuffer();
+
+		return dst;
+	}
+
+
+
+	void Texture::readData(PixelData& dest, UINT32 mipLevel, UINT32 face)
+	{
+		if ((mProperties.getUsage() & TU_CPUCACHED) == 0)
+		{
+			LOGERR("Attempting to read CPU data from a texture that is created without CPU caching.");
+			return;
+		}
+
+		UINT32 mipWidth, mipHeight, mipDepth;
+		PixelUtil::getSizeForMipLevel(mProperties.getWidth(), mProperties.getHeight(), mProperties.getDepth(),
+			mipLevel, mipWidth, mipHeight, mipDepth);
+
+		if (dest.getWidth() != mipWidth || dest.getHeight() != mipHeight ||
+			dest.getDepth() != mipDepth || dest.getFormat() != mProperties.getFormat())
+		{
+			LOGERR("Provided buffer is not of valid dimensions or format in order to read from this texture.");
+			return;
+		}
+
+		UINT32 subresourceIdx = mProperties.mapToSubresourceIdx(face, mipLevel);
+		if (subresourceIdx >= (UINT32)mCPUSubresourceData.size())
+		{
+			LOGERR("Invalid subresource index: " + toString(subresourceIdx) + ". Supported range: 0 .. " + toString(mCPUSubresourceData.size()));
+			return;
+		}
+
+		if (mCPUSubresourceData[subresourceIdx]->getSize() != dest.getSize())
+			BS_EXCEPT(InternalErrorException, "Buffer sizes don't match.");
+
+		UINT8* srcPtr = mCPUSubresourceData[subresourceIdx]->getData();
+		UINT8* destPtr = dest.getData();
+
+		memcpy(destPtr, srcPtr, dest.getSize());
+	}
+
 	void Texture::createCPUBuffers()
 	void Texture::createCPUBuffers()
 	{
 	{
-		UINT32 numFaces = getNumFaces();
-		UINT32 numMips = getNumMipmaps();
+		UINT32 numFaces = mProperties.getNumFaces();
+		UINT32 numMips = mProperties.getNumMipmaps();
 
 
 		UINT32 numSubresources = numFaces * numMips;
 		UINT32 numSubresources = numFaces * numMips;
 		mCPUSubresourceData.resize(numSubresources);
 		mCPUSubresourceData.resize(numSubresources);
 
 
 		for (UINT32 i = 0; i < numFaces; i++)
 		for (UINT32 i = 0; i < numFaces; i++)
 		{
 		{
-			UINT32 curWidth = mWidth;
-			UINT32 curHeight = mHeight;
-			UINT32 curDepth = mDepth;
+			UINT32 curWidth = mProperties.getWidth();
+			UINT32 curHeight = mProperties.getHeight();
+			UINT32 curDepth = mProperties.getDepth();
 
 
-			for (UINT32 j = 0; j < mNumMipmaps; j++)
+			for (UINT32 j = 0; j < mProperties.getNumMipmaps(); j++)
 			{
 			{
-				UINT32 subresourceIdx = mapToSubresourceIdx(i, j);
+				UINT32 subresourceIdx = mProperties.mapToSubresourceIdx(i, j);
 
 
-				mCPUSubresourceData[subresourceIdx] = bs_shared_ptr<PixelData>(curWidth, curHeight, curDepth, mFormat);
+				mCPUSubresourceData[subresourceIdx] = bs_shared_ptr<PixelData>(curWidth, curHeight, curDepth, mProperties.getFormat());
 				mCPUSubresourceData[subresourceIdx]->allocateInternalBuffer();
 				mCPUSubresourceData[subresourceIdx]->allocateInternalBuffer();
 
 
 				if (curWidth > 1)
 				if (curWidth > 1)
@@ -407,6 +452,11 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
+	SPtr<TextureCore> Texture::getCore() const
+	{
+		return std::static_pointer_cast<TextureCore>(mCoreSpecific);
+	}
+
 	/************************************************************************/
 	/************************************************************************/
 	/* 								SERIALIZATION                      		*/
 	/* 								SERIALIZATION                      		*/
 	/************************************************************************/
 	/************************************************************************/
@@ -458,6 +508,22 @@ namespace BansheeEngine
 
 
 	const HTexture& Texture::dummy()
 	const HTexture& Texture::dummy()
 	{
 	{
-		return TextureCoreManager::instance().getDummyTexture();
+		static HTexture dummyTexture;
+		if (!dummyTexture)
+		{
+			dummyTexture = create(TEX_TYPE_2D, 2, 2, 0, PF_R8G8B8A8);
+
+			UINT32 subresourceIdx = dummyTexture->getProperties().mapToSubresourceIdx(0, 0);
+			PixelDataPtr data = dummyTexture->allocateSubresourceBuffer(subresourceIdx);
+
+			data->setColorAt(Color::Red, 0, 0);
+			data->setColorAt(Color::Red, 0, 1);
+			data->setColorAt(Color::Red, 1, 0);
+			data->setColorAt(Color::Red, 1, 1);
+
+			dummyTexture->writeSubresource(gCoreAccessor(), subresourceIdx, data, false);
+		}
+
+		return dummyTexture;
 	}
 	}
 }
 }

+ 15 - 23
BansheeCore/Source/BsTextureManager.cpp

@@ -9,16 +9,19 @@ namespace BansheeEngine
     TexturePtr TextureManager::createTexture(TextureType texType, UINT32 width, UINT32 height, UINT32 depth, int numMipmaps,
     TexturePtr TextureManager::createTexture(TextureType texType, UINT32 width, UINT32 height, UINT32 depth, int numMipmaps,
         PixelFormat format, int usage, bool hwGamma, UINT32 multisampleCount)
         PixelFormat format, int usage, bool hwGamma, UINT32 multisampleCount)
     {
     {
-        TexturePtr ret = createTextureImpl();
+		Texture* tex = new (bs_alloc<Texture>()) Texture(texType, width, height, depth, numMipmaps, format, usage, hwGamma, multisampleCount);
+		TexturePtr ret = bs_core_ptr<Texture, GenAlloc>(tex);
+
 		ret->_setThisPtr(ret);
 		ret->_setThisPtr(ret);
-		ret->initialize(texType, width, height, depth, static_cast<size_t>(numMipmaps), format, usage, hwGamma, multisampleCount);
+		ret->initialize();
 
 
 		return ret;
 		return ret;
     }
     }
 
 
 	TexturePtr TextureManager::_createEmpty()
 	TexturePtr TextureManager::_createEmpty()
 	{
 	{
-		TexturePtr texture = createTextureImpl();
+		Texture* tex = new (bs_alloc<Texture>()) Texture();
+		TexturePtr texture = bs_core_ptr<Texture, GenAlloc>(tex);
 		texture->_setThisPtr(texture);
 		texture->_setThisPtr(texture);
 
 
 		return texture;
 		return texture;
@@ -68,39 +71,28 @@ namespace BansheeEngine
 		return newRT;
 		return newRT;
 	}
 	}
 
 
-	SPtr<RenderTextureCore> TextureCoreManager::createRenderTexture(const RENDER_TEXTURE_DESC& desc)
+	SPtr<TextureCore> TextureCoreManager::createTexture(TextureType texType, UINT32 width, UINT32 height, UINT32 depth,
+		int numMips, PixelFormat format, int usage, bool hwGammaCorrection, UINT32 multisampleCount)
 	{
 	{
-		SPtr<RenderTextureCore> newRT = createRenderTextureInternal(desc);
+		SPtr<TextureCore> newRT = createTextureInternal(texType, width, height, depth, numMips, format, usage, hwGammaCorrection, multisampleCount);
 		newRT->initialize();
 		newRT->initialize();
 
 
 		return newRT;
 		return newRT;
 	}
 	}
 
 
-	SPtr<MultiRenderTextureCore> TextureCoreManager::createMultiRenderTexture(const MULTI_RENDER_TEXTURE_DESC& desc)
+	SPtr<RenderTextureCore> TextureCoreManager::createRenderTexture(const RENDER_TEXTURE_DESC& desc)
 	{
 	{
-		SPtr<MultiRenderTextureCore> newRT = createMultiRenderTextureInternal(desc);
+		SPtr<RenderTextureCore> newRT = createRenderTextureInternal(desc);
 		newRT->initialize();
 		newRT->initialize();
 
 
 		return newRT;
 		return newRT;
 	}
 	}
 
 
-	void TextureCoreManager::onStartUp()
+	SPtr<MultiRenderTextureCore> TextureCoreManager::createMultiRenderTexture(const MULTI_RENDER_TEXTURE_DESC& desc)
 	{
 	{
-		// Internally this will call our createTextureImpl virtual method. But since this is guaranteed
-		// to be the last class in the hierarchy, we can call a virtual method from constructor.
-		mDummyTexture = Texture::create(TEX_TYPE_2D, 2, 2, 0, PF_R8G8B8A8);
-
-		UINT32 subresourceIdx = mDummyTexture->mapToSubresourceIdx(0, 0);
-		PixelDataPtr data = mDummyTexture->allocateSubresourceBuffer(subresourceIdx);
-
-		data->setColorAt(Color::Red, 0, 0);
-		data->setColorAt(Color::Red, 0, 1);
-		data->setColorAt(Color::Red, 1, 0);
-		data->setColorAt(Color::Red, 1, 1);
-
-		AsyncOp op;
+		SPtr<MultiRenderTextureCore> newRT = createMultiRenderTextureInternal(desc);
+		newRT->initialize();
 
 
-		data->_lock();
-		RenderSystem::instance().writeSubresource(mDummyTexture.getInternalPtr(), mDummyTexture->mapToSubresourceIdx(0, 0), data, false, op);
+		return newRT;
 	}
 	}
 }
 }

+ 1 - 1
BansheeCore/Source/BsTextureView.cpp

@@ -29,7 +29,7 @@ namespace BansheeEngine
 	TextureView::~TextureView()
 	TextureView::~TextureView()
 	{ }
 	{ }
 
 
-	void TextureView::initialize(TexturePtr texture, TEXTURE_VIEW_DESC& _desc)
+	void TextureView::initialize(const SPtr<TextureCore>& texture, TEXTURE_VIEW_DESC& _desc)
 	{
 	{
 		mOwnerTexture = texture;
 		mOwnerTexture = texture;
 		mDesc = _desc;
 		mDesc = _desc;

+ 3 - 3
BansheeD3D11RenderSystem/Include/BsD3D11RenderSystem.h

@@ -48,12 +48,12 @@ namespace BansheeEngine
 		/**
 		/**
 		 * @copydoc	RenderSystem::setTexture
 		 * @copydoc	RenderSystem::setTexture
 		 */
 		 */
-		void setTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const TexturePtr &texPtr);
+		void setTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const SPtr<TextureCore>& texPtr);
 
 
 		/**
 		/**
 		 * @copydoc	RenderSystem::setLoadStoreTexture
 		 * @copydoc	RenderSystem::setLoadStoreTexture
 		 */
 		 */
-		void setLoadStoreTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const TexturePtr& texPtr,
+		void setLoadStoreTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const SPtr<TextureCore>& texPtr,
 			const TextureSurface& surface);
 			const TextureSurface& surface);
 
 
 		/**
 		/**
@@ -255,7 +255,7 @@ namespace BansheeEngine
 		D3D11HLSLProgramFactory* mHLSLFactory;
 		D3D11HLSLProgramFactory* mHLSLFactory;
 		D3D11InputLayoutManager* mIAManager;
 		D3D11InputLayoutManager* mIAManager;
 
 
-		std::pair<TexturePtr, TextureViewPtr> mBoundUAVs[D3D11_PS_CS_UAV_REGISTER_COUNT];
+		std::pair<SPtr<TextureCore>, TextureViewPtr> mBoundUAVs[D3D11_PS_CS_UAV_REGISTER_COUNT];
 
 
 		UINT32 mStencilRef;
 		UINT32 mStencilRef;
 		Rect2 mViewportNorm;
 		Rect2 mViewportNorm;

+ 1 - 1
BansheeD3D11RenderSystem/Include/BsD3D11RenderWindow.h

@@ -159,7 +159,7 @@ namespace BansheeEngine
 		ID3D11Texture2D* mBackBuffer;
 		ID3D11Texture2D* mBackBuffer;
 		ID3D11RenderTargetView*	mRenderTargetView;
 		ID3D11RenderTargetView*	mRenderTargetView;
 		TextureViewPtr mDepthStencilView;
 		TextureViewPtr mDepthStencilView;
-		TexturePtr mDepthStencilBuffer;
+		SPtr<TextureCore> mDepthStencilBuffer;
 
 
 		IDXGISwapChain*	mSwapChain;
 		IDXGISwapChain*	mSwapChain;
 		DXGI_SWAP_CHAIN_DESC mSwapChainDesc;
 		DXGI_SWAP_CHAIN_DESC mSwapChainDesc;

+ 10 - 9
BansheeD3D11RenderSystem/Include/BsD3D11Texture.h

@@ -8,10 +8,10 @@ namespace BansheeEngine
 	/**
 	/**
 	 * @brief	DirectX 11 implementation of a texture.
 	 * @brief	DirectX 11 implementation of a texture.
 	 */
 	 */
-	class D3D11Texture : public Texture
+	class D3D11TextureCore : public TextureCore
 	{
 	{
 	public:
 	public:
-		~D3D11Texture();
+		~D3D11TextureCore();
 
 
 		/**
 		/**
 		 * @brief	Returns internal DX11 texture resource object.
 		 * @brief	Returns internal DX11 texture resource object.
@@ -29,19 +29,20 @@ namespace BansheeEngine
 		DXGI_FORMAT getDXGIFormat() const { return mDXGIFormat; }
 		DXGI_FORMAT getDXGIFormat() const { return mDXGIFormat; }
 
 
 	protected:
 	protected:
-		friend class D3D11TextureManager;
+		friend class D3D11TextureCoreManager;
 
 
-		D3D11Texture();
+		D3D11TextureCore(TextureType textureType, UINT32 width, UINT32 height, UINT32 depth, UINT32 numMipmaps,
+			PixelFormat format, int usage, bool hwGamma, UINT32 multisampleCount);
 
 
 		/**
 		/**
-		* @copydoc	Texture::initialize_internal()
+		* @copydoc	CoreObjectCore::initialize()
 		*/
 		*/
-		void initialize_internal();
+		void initialize();
 
 
 		/**
 		/**
-		* @copydoc Texture::destroy_internal()
+		* @copydoc CoreObjectCore::destroy()
 		*/
 		*/
-		void destroy_internal();
+		void destroy();
 
 
 		/**
 		/**
 		 * @copydoc Texture::lockImpl
 		 * @copydoc Texture::lockImpl
@@ -56,7 +57,7 @@ namespace BansheeEngine
 		/**
 		/**
 		 * @copydoc Texture::copyImpl
 		 * @copydoc Texture::copyImpl
 		 */
 		 */
-		void copyImpl(UINT32 srcFace, UINT32 srcMipLevel, UINT32 destFace, UINT32 destMipLevel, TexturePtr& target);
+		void copyImpl(UINT32 srcFace, UINT32 srcMipLevel, UINT32 destFace, UINT32 destMipLevel, const SPtr<TextureCore>& target);
 
 
 		/**
 		/**
 		 * @copydoc Texture::readData
 		 * @copydoc Texture::readData

+ 8 - 6
BansheeD3D11RenderSystem/Include/BsD3D11TextureManager.h

@@ -17,11 +17,6 @@ namespace BansheeEngine
 		PixelFormat getNativeFormat(TextureType ttype, PixelFormat format, int usage, bool hwGamma);
 		PixelFormat getNativeFormat(TextureType ttype, PixelFormat format, int usage, bool hwGamma);
 
 
 	protected:		
 	protected:		
-		/**
-		 * @copydoc	TextureManager::createTextureImpl
-		 */
-		TexturePtr createTextureImpl();
-
 		/**
 		/**
 		 * @copydoc	TextureManager::createRenderTextureImpl
 		 * @copydoc	TextureManager::createRenderTextureImpl
 		 */
 		 */
@@ -38,7 +33,14 @@ namespace BansheeEngine
 	 */
 	 */
 	class BS_D3D11_EXPORT D3D11TextureCoreManager : public TextureCoreManager
 	class BS_D3D11_EXPORT D3D11TextureCoreManager : public TextureCoreManager
 	{
 	{
-	protected:		
+	protected:
+		/**
+		 * @copydoc	TextureCoreManager::createTextureInternal
+		 */
+		SPtr<TextureCore> createTextureInternal(TextureType texType, UINT32 width, UINT32 height, UINT32 depth,
+			int numMips, PixelFormat format, int usage = TU_DEFAULT, bool hwGammaCorrection = false,
+			UINT32 multisampleCount = 0);
+
 		/**
 		/**
 		 * @copydoc	TextureCoreManager::createRenderTextureInternal
 		 * @copydoc	TextureCoreManager::createRenderTextureInternal
 		 */
 		 */

+ 5 - 5
BansheeD3D11RenderSystem/Include/BsD3D11TextureView.h

@@ -36,7 +36,7 @@ namespace BansheeEngine
 		ID3D11DepthStencilView*	getDSV() const { return mDSV; }
 		ID3D11DepthStencilView*	getDSV() const { return mDSV; }
 
 
 	protected:
 	protected:
-		friend class D3D11Texture;
+		friend class D3D11TextureCore;
 
 
 		D3D11TextureView();
 		D3D11TextureView();
 
 
@@ -65,7 +65,7 @@ namespace BansheeEngine
 		 *							array elements for 1D and 2D array textures, number of slices for 3D textures,
 		 *							array elements for 1D and 2D array textures, number of slices for 3D textures,
 		 *							and number of cubes for cube textures.
 		 *							and number of cubes for cube textures.
 		 */
 		 */
-		ID3D11ShaderResourceView* createSRV(D3D11Texture* texture, 
+		ID3D11ShaderResourceView* createSRV(D3D11TextureCore* texture, 
 			UINT32 mostDetailMip, UINT32 numMips, UINT32 firstArraySlice, UINT32 numArraySlices);
 			UINT32 mostDetailMip, UINT32 numMips, UINT32 firstArraySlice, UINT32 numArraySlices);
 
 
 		/**
 		/**
@@ -81,7 +81,7 @@ namespace BansheeEngine
 		 *							array elements for 1D and 2D array textures, number of slices for 3D textures,
 		 *							array elements for 1D and 2D array textures, number of slices for 3D textures,
 		 *							and number of cubes for cube textures.
 		 *							and number of cubes for cube textures.
 		 */
 		 */
-		ID3D11RenderTargetView* createRTV(D3D11Texture* texture, 
+		ID3D11RenderTargetView* createRTV(D3D11TextureCore* texture, 
 			UINT32 mipSlice, UINT32 firstArraySlice, UINT32 numArraySlices);
 			UINT32 mipSlice, UINT32 firstArraySlice, UINT32 numArraySlices);
 
 
 		/**
 		/**
@@ -97,7 +97,7 @@ namespace BansheeEngine
 		 *							array elements for 1D and 2D array textures, number of slices for 3D textures,
 		 *							array elements for 1D and 2D array textures, number of slices for 3D textures,
 		 *							and number of cubes for cube textures.
 		 *							and number of cubes for cube textures.
 		 */
 		 */
-		ID3D11UnorderedAccessView* createUAV(D3D11Texture* texture, 
+		ID3D11UnorderedAccessView* createUAV(D3D11TextureCore* texture, 
 			UINT32 mipSlice, UINT32 firstArraySlice, UINT32 numArraySlices);
 			UINT32 mipSlice, UINT32 firstArraySlice, UINT32 numArraySlices);
 
 
 		/**
 		/**
@@ -113,7 +113,7 @@ namespace BansheeEngine
 		 *							array elements for 1D and 2D array textures, number of slices for 3D textures,
 		 *							array elements for 1D and 2D array textures, number of slices for 3D textures,
 		 *							and number of cubes for cube textures.
 		 *							and number of cubes for cube textures.
 		 */
 		 */
-		ID3D11DepthStencilView* createDSV(D3D11Texture* texture, 
+		ID3D11DepthStencilView* createDSV(D3D11TextureCore* texture, 
 			UINT32 mipSlice, UINT32 firstArraySlice, UINT32 numArraySlices);
 			UINT32 mipSlice, UINT32 firstArraySlice, UINT32 numArraySlices);
 
 
 		ID3D11ShaderResourceView* mSRV;
 		ID3D11ShaderResourceView* mSRV;

+ 8 - 8
BansheeD3D11RenderSystem/Source/BsD3D11RenderSystem.cpp

@@ -265,7 +265,7 @@ namespace BansheeEngine
 		BS_INC_RENDER_STAT(NumDepthStencilStateChanges);
 		BS_INC_RENDER_STAT(NumDepthStencilStateChanges);
 	}
 	}
 
 
-	void D3D11RenderSystem::setTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const TexturePtr &texPtr)
+	void D3D11RenderSystem::setTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const SPtr<TextureCore>& texPtr)
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
@@ -275,7 +275,7 @@ namespace BansheeEngine
 		ID3D11ShaderResourceView* viewArray[1];
 		ID3D11ShaderResourceView* viewArray[1];
 		if(texPtr != nullptr && enabled)
 		if(texPtr != nullptr && enabled)
 		{
 		{
-			D3D11Texture* d3d11Texture = static_cast<D3D11Texture*>(texPtr.get());
+			D3D11TextureCore* d3d11Texture = static_cast<D3D11TextureCore*>(texPtr.get());
 			viewArray[0] = d3d11Texture->getSRV();
 			viewArray[0] = d3d11Texture->getSRV();
 		}
 		}
 		else
 		else
@@ -308,7 +308,7 @@ namespace BansheeEngine
 		BS_INC_RENDER_STAT(NumTextureBinds);
 		BS_INC_RENDER_STAT(NumTextureBinds);
 	}
 	}
 
 
-	void D3D11RenderSystem::setLoadStoreTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const TexturePtr& texPtr,
+	void D3D11RenderSystem::setLoadStoreTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const SPtr<TextureCore>& texPtr,
 		const TextureSurface& surface)
 		const TextureSurface& surface)
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
@@ -319,8 +319,8 @@ namespace BansheeEngine
 		ID3D11UnorderedAccessView* viewArray[1];
 		ID3D11UnorderedAccessView* viewArray[1];
 		if (texPtr != nullptr && enabled)
 		if (texPtr != nullptr && enabled)
 		{
 		{
-			D3D11Texture* d3d11Texture = static_cast<D3D11Texture*>(texPtr.get());
-			TextureViewPtr texView = Texture::requestView(texPtr, surface.mipLevel, 1, 
+			D3D11TextureCore* d3d11Texture = static_cast<D3D11TextureCore*>(texPtr.get());
+			TextureViewPtr texView = TextureCore::requestView(texPtr, surface.mipLevel, 1, 
 				surface.arraySlice, surface.numArraySlices, GVU_RANDOMWRITE);
 				surface.arraySlice, surface.numArraySlices, GVU_RANDOMWRITE);
 
 
 			D3D11TextureView* d3d11texView = static_cast<D3D11TextureView*>(texView.get());
 			D3D11TextureView* d3d11texView = static_cast<D3D11TextureView*>(texView.get());
@@ -338,7 +338,7 @@ namespace BansheeEngine
 			if (mBoundUAVs[unit].second != nullptr)
 			if (mBoundUAVs[unit].second != nullptr)
 				mBoundUAVs[unit].first->releaseView(mBoundUAVs[unit].second);
 				mBoundUAVs[unit].first->releaseView(mBoundUAVs[unit].second);
 
 
-			mBoundUAVs[unit] = std::pair<TexturePtr, TextureViewPtr>();
+			mBoundUAVs[unit] = std::pair<SPtr<TextureCore>, TextureViewPtr>();
 		}
 		}
 
 
 		if (gptype == GPT_FRAGMENT_PROGRAM)
 		if (gptype == GPT_FRAGMENT_PROGRAM)
@@ -582,7 +582,7 @@ namespace BansheeEngine
 				if (!texture.isLoaded())
 				if (!texture.isLoaded())
 					setTexture(gptype, iter->second.slot, false, nullptr);
 					setTexture(gptype, iter->second.slot, false, nullptr);
 				else
 				else
-					setTexture(gptype, iter->second.slot, true, texture.getInternalPtr());
+					setTexture(gptype, iter->second.slot, true, texture->getCore());
 			}
 			}
 			else
 			else
 			{
 			{
@@ -591,7 +591,7 @@ namespace BansheeEngine
 				if (!texture.isLoaded())
 				if (!texture.isLoaded())
 					setLoadStoreTexture(gptype, iter->second.slot, false, nullptr, surface);
 					setLoadStoreTexture(gptype, iter->second.slot, false, nullptr, surface);
 				else
 				else
-					setLoadStoreTexture(gptype, iter->second.slot, true, texture.getInternalPtr(), surface);
+					setLoadStoreTexture(gptype, iter->second.slot, true, texture->getCore(), surface);
 			}
 			}
 		}
 		}
 
 

+ 5 - 5
BansheeD3D11RenderSystem/Source/BsD3D11RenderWindow.cpp

@@ -264,7 +264,7 @@ namespace BansheeEngine
 
 
 		if (mDepthStencilView != nullptr)
 		if (mDepthStencilView != nullptr)
 		{
 		{
-			Texture::releaseView(mDepthStencilView);
+			TextureCore::releaseView(mDepthStencilView);
 			mDepthStencilView = nullptr;
 			mDepthStencilView = nullptr;
 		}
 		}
 
 
@@ -686,17 +686,17 @@ namespace BansheeEngine
 			BS_EXCEPT(RenderingAPIException, "Unable to create rendertagert view\nError Description:" + errorDescription);
 			BS_EXCEPT(RenderingAPIException, "Unable to create rendertagert view\nError Description:" + errorDescription);
 		}
 		}
 
 
-		mDepthStencilBuffer = TextureManager::instance().createTexture(TEX_TYPE_2D, 
-			BBDesc.Width, BBDesc.Height, 0, PF_D24S8, TU_DEPTHSTENCIL, false, 
+		mDepthStencilBuffer = TextureCoreManager::instance().createTexture(TEX_TYPE_2D, 
+			BBDesc.Width, BBDesc.Height, 0, 0, PF_D24S8, TU_DEPTHSTENCIL, false, 
 			getProperties().getMultisampleCount());
 			getProperties().getMultisampleCount());
 
 
 		if(mDepthStencilView != nullptr)
 		if(mDepthStencilView != nullptr)
 		{
 		{
-			Texture::releaseView(mDepthStencilView);
+			TextureCore::releaseView(mDepthStencilView);
 			mDepthStencilView = nullptr;
 			mDepthStencilView = nullptr;
 		}
 		}
 
 
-		mDepthStencilView = Texture::requestView(mDepthStencilBuffer, 0, 1, 0, 1, GVU_DEPTHSTENCIL);
+		mDepthStencilView = TextureCore::requestView(mDepthStencilBuffer, 0, 1, 0, 1, GVU_DEPTHSTENCIL);
 	}
 	}
 
 
 	void D3D11RenderWindowCore::destroySizeDependedD3DResources()
 	void D3D11RenderWindowCore::destroySizeDependedD3DResources()

+ 137 - 117
BansheeD3D11RenderSystem/Source/BsD3D11Texture.cpp

@@ -11,20 +11,22 @@
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
-	D3D11Texture::D3D11Texture()
-		: Texture(), m1DTex(nullptr), m2DTex(nullptr), m3DTex(nullptr), 
+	D3D11TextureCore::D3D11TextureCore(TextureType textureType, UINT32 width, UINT32 height, UINT32 depth, UINT32 numMipmaps,
+		PixelFormat format, int usage, bool hwGamma, UINT32 multisampleCount)
+		: TextureCore(textureType, width, height, depth, numMipmaps, format, usage, hwGamma, multisampleCount),
+		m1DTex(nullptr), m2DTex(nullptr), m3DTex(nullptr), 
 		mTex(nullptr), mShaderResourceView(nullptr), mStagingBuffer(nullptr), 
 		mTex(nullptr), mShaderResourceView(nullptr), mStagingBuffer(nullptr), 
 		mLockedSubresourceIdx(-1), mLockedForReading(false), mStaticBuffer(nullptr)
 		mLockedSubresourceIdx(-1), mLockedForReading(false), mStaticBuffer(nullptr)
 	{ }
 	{ }
 
 
-	D3D11Texture::~D3D11Texture()
+	D3D11TextureCore::~D3D11TextureCore()
 	{ }
 	{ }
 
 
-	void D3D11Texture::initialize_internal()
+	void D3D11TextureCore::initialize()
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
-		switch (getTextureType())
+		switch (mProperties.getTextureType())
 		{
 		{
 		case TEX_TYPE_1D:
 		case TEX_TYPE_1D:
 			create1DTex();
 			create1DTex();
@@ -37,15 +39,14 @@ namespace BansheeEngine
 			create3DTex();
 			create3DTex();
 			break;
 			break;
 		default:
 		default:
-			destroy_internal();
 			BS_EXCEPT(RenderingAPIException, "Unknown texture type");
 			BS_EXCEPT(RenderingAPIException, "Unknown texture type");
 		}
 		}
 
 
 		BS_INC_RENDER_STAT_CAT(ResCreated, RenderStatObject_Texture);
 		BS_INC_RENDER_STAT_CAT(ResCreated, RenderStatObject_Texture);
-		Texture::initialize_internal();
+		TextureCore::initialize();
 	}
 	}
 
 
-	void D3D11Texture::destroy_internal()
+	void D3D11TextureCore::destroy()
 	{
 	{
 		SAFE_RELEASE(mTex);
 		SAFE_RELEASE(mTex);
 		SAFE_RELEASE(mShaderResourceView);
 		SAFE_RELEASE(mShaderResourceView);
@@ -55,20 +56,20 @@ namespace BansheeEngine
 		SAFE_RELEASE(mStagingBuffer);
 		SAFE_RELEASE(mStagingBuffer);
 
 
 		BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_Texture);
 		BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_Texture);
-		Texture::destroy_internal();
+		TextureCore::destroy();
 	}
 	}
 
 
-	void D3D11Texture::copyImpl(UINT32 srcFace, UINT32 srcMipLevel, UINT32 destFace, UINT32 destMipLevel, TexturePtr& target)
+	void D3D11TextureCore::copyImpl(UINT32 srcFace, UINT32 srcMipLevel, UINT32 destFace, UINT32 destMipLevel, const SPtr<TextureCore>& target)
 	{
 	{
-		D3D11Texture* other = static_cast<D3D11Texture*>(target.get());
+		D3D11TextureCore* other = static_cast<D3D11TextureCore*>(target.get());
 
 
-		UINT32 srcResIdx = D3D11CalcSubresource(srcMipLevel, srcFace, getNumMipmaps() + 1);
-		UINT32 destResIdx = D3D11CalcSubresource(destMipLevel, destFace, target->getNumMipmaps() + 1);
+		UINT32 srcResIdx = D3D11CalcSubresource(srcMipLevel, srcFace, mProperties.getNumMipmaps() + 1);
+		UINT32 destResIdx = D3D11CalcSubresource(destMipLevel, destFace, target->getProperties().getNumMipmaps() + 1);
 
 
 		D3D11RenderSystem* rs = static_cast<D3D11RenderSystem*>(RenderSystem::instancePtr());
 		D3D11RenderSystem* rs = static_cast<D3D11RenderSystem*>(RenderSystem::instancePtr());
 		D3D11Device& device = rs->getPrimaryDevice();
 		D3D11Device& device = rs->getPrimaryDevice();
 
 
-		if (getMultisampleCount() != target->getMultisampleCount()) // Resolving from MS to non-MS texture
+		if (mProperties.getMultisampleCount() != target->getProperties().getMultisampleCount()) // Resolving from MS to non-MS texture
 		{
 		{
 			device.getImmediateContext()->ResolveSubresource(other->getDX11Resource(), destResIdx, mTex, srcResIdx, mDXGIFormat);
 			device.getImmediateContext()->ResolveSubresource(other->getDX11Resource(), destResIdx, mTex, srcResIdx, mDXGIFormat);
 		}
 		}
@@ -84,9 +85,9 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
-	PixelData D3D11Texture::lockImpl(GpuLockOptions options, UINT32 mipLevel, UINT32 face)
+	PixelData D3D11TextureCore::lockImpl(GpuLockOptions options, UINT32 mipLevel, UINT32 face)
 	{
 	{
-		if (mMultisampleCount > 0)
+		if (mProperties.getMultisampleCount() > 0)
 			BS_EXCEPT(InvalidStateException, "Multisampled textures cannot be accessed from the CPU directly.");
 			BS_EXCEPT(InvalidStateException, "Multisampled textures cannot be accessed from the CPU directly.");
 
 
 #if BS_PROFILING_ENABLED
 #if BS_PROFILING_ENABLED
@@ -101,11 +102,11 @@ namespace BansheeEngine
 		}
 		}
 #endif
 #endif
 
 
-		UINT32 mipWidth = mWidth >> mipLevel;
-		UINT32 mipHeight = mHeight >> mipLevel;
-		UINT32 mipDepth = mDepth >> mipLevel;
+		UINT32 mipWidth = mProperties.getWidth() >> mipLevel;
+		UINT32 mipHeight = mProperties.getHeight() >> mipLevel;
+		UINT32 mipDepth = mProperties.getDepth() >> mipLevel;
 
 
-		PixelData lockedArea(mipWidth, mipHeight, mipDepth, mFormat);
+		PixelData lockedArea(mipWidth, mipHeight, mipDepth, mProperties.getFormat());
 
 
 		D3D11_MAP flags = D3D11Mappings::getLockOptions(options);
 		D3D11_MAP flags = D3D11Mappings::getLockOptions(options);
 
 
@@ -121,7 +122,7 @@ namespace BansheeEngine
 		}
 		}
 		else
 		else
 		{
 		{
-			if(mUsage == TU_DYNAMIC)
+			if (mProperties.getUsage() == TU_DYNAMIC)
 			{
 			{
 				UINT8* data = (UINT8*)map(mTex, flags, face, mipLevel, rowPitch, slicePitch);
 				UINT8* data = (UINT8*)map(mTex, flags, face, mipLevel, rowPitch, slicePitch);
 				lockedArea.setExternalBuffer(data);
 				lockedArea.setExternalBuffer(data);
@@ -137,22 +138,22 @@ namespace BansheeEngine
 		return lockedArea;
 		return lockedArea;
 	}
 	}
 
 
-	void D3D11Texture::unlockImpl()
+	void D3D11TextureCore::unlockImpl()
 	{
 	{
 		if(mLockedForReading)
 		if(mLockedForReading)
 			unmapstagingbuffer();
 			unmapstagingbuffer();
 		else
 		else
 		{
 		{
-			if(mUsage == TU_DYNAMIC)
+			if (mProperties.getUsage() == TU_DYNAMIC)
 				unmap(mTex);
 				unmap(mTex);
 			else
 			else
 				unmapstaticbuffer();
 				unmapstaticbuffer();
 		}
 		}
 	}
 	}
 
 
-	void D3D11Texture::readData(PixelData& dest, UINT32 mipLevel, UINT32 face)
+	void D3D11TextureCore::readData(PixelData& dest, UINT32 mipLevel, UINT32 face)
 	{
 	{
-		if (mMultisampleCount > 0)
+		if (mProperties.getMultisampleCount() > 0)
 			BS_EXCEPT(InvalidStateException, "Multisampled textures cannot be accessed from the CPU directly.");
 			BS_EXCEPT(InvalidStateException, "Multisampled textures cannot be accessed from the CPU directly.");
 
 
 		PixelData myData = lock(GBL_READ_ONLY, mipLevel, face);
 		PixelData myData = lock(GBL_READ_ONLY, mipLevel, face);
@@ -170,31 +171,33 @@ namespace BansheeEngine
 		unlock();
 		unlock();
 	}
 	}
 
 
-	void D3D11Texture::writeData(const PixelData& src, UINT32 mipLevel, UINT32 face, bool discardWholeBuffer)
+	void D3D11TextureCore::writeData(const PixelData& src, UINT32 mipLevel, UINT32 face, bool discardWholeBuffer)
 	{
 	{
-		if (mMultisampleCount > 0)
+		PixelFormat format = mProperties.getFormat();
+
+		if (mProperties.getMultisampleCount() > 0)
 			BS_EXCEPT(InvalidStateException, "Multisampled textures cannot be accessed from the CPU directly.");
 			BS_EXCEPT(InvalidStateException, "Multisampled textures cannot be accessed from the CPU directly.");
 
 
-		if((mUsage & TU_DYNAMIC) != 0)
+		if ((mProperties.getUsage() & TU_DYNAMIC) != 0)
 		{
 		{
 			PixelData myData = lock(discardWholeBuffer ? GBL_WRITE_ONLY_DISCARD : GBL_WRITE_ONLY, mipLevel, face);
 			PixelData myData = lock(discardWholeBuffer ? GBL_WRITE_ONLY_DISCARD : GBL_WRITE_ONLY, mipLevel, face);
 			PixelUtil::bulkPixelConversion(src, myData);
 			PixelUtil::bulkPixelConversion(src, myData);
 			unlock();
 			unlock();
 		}
 		}
-		else if ((mUsage & TU_DEPTHSTENCIL) == 0)
+		else if ((mProperties.getUsage() & TU_DEPTHSTENCIL) == 0)
 		{
 		{
-			mipLevel = Math::clamp(mipLevel, (UINT32)mipLevel, getNumMipmaps());
-			face = Math::clamp(face, (UINT32)0, mDepth - 1);
+			mipLevel = Math::clamp(mipLevel, (UINT32)mipLevel, mProperties.getNumMipmaps());
+			face = Math::clamp(face, (UINT32)0, mProperties.getDepth() - 1);
 
 
-			if(getTextureType() == TEX_TYPE_3D)
+			if(mProperties.getTextureType() == TEX_TYPE_3D)
 				face = 0;
 				face = 0;
 
 
 			D3D11RenderSystem* rs = static_cast<D3D11RenderSystem*>(RenderSystem::instancePtr());
 			D3D11RenderSystem* rs = static_cast<D3D11RenderSystem*>(RenderSystem::instancePtr());
 			D3D11Device& device = rs->getPrimaryDevice();
 			D3D11Device& device = rs->getPrimaryDevice();
 
 
-			UINT subresourceIdx = D3D11CalcSubresource(mipLevel, face, getNumMipmaps()+1);
-			UINT32 rowWidth = D3D11Mappings::getSizeInBytes(mFormat, src.getWidth());
-			UINT32 sliceWidth = D3D11Mappings::getSizeInBytes(mFormat, src.getWidth(), src.getHeight());
+			UINT subresourceIdx = D3D11CalcSubresource(mipLevel, face, mProperties.getNumMipmaps() + 1);
+			UINT32 rowWidth = D3D11Mappings::getSizeInBytes(format, src.getWidth());
+			UINT32 sliceWidth = D3D11Mappings::getSizeInBytes(format, src.getWidth(), src.getHeight());
 
 
 			device.getImmediateContext()->UpdateSubresource(mTex, subresourceIdx, nullptr, src.getData(), rowWidth, sliceWidth);
 			device.getImmediateContext()->UpdateSubresource(mTex, subresourceIdx, nullptr, src.getData(), rowWidth, sliceWidth);
 
 
@@ -208,38 +211,45 @@ namespace BansheeEngine
 		}
 		}
 		else
 		else
 		{
 		{
-			BS_EXCEPT(RenderingAPIException, "Trying to write into a buffer with unsupported usage: " + toString(mUsage));
+			BS_EXCEPT(RenderingAPIException, "Trying to write into a buffer with unsupported usage: " + toString(mProperties.getUsage()));
 		}
 		}
 	}
 	}
 
 
-	void D3D11Texture::create1DTex()
+	void D3D11TextureCore::create1DTex()
 	{
 	{
+		UINT32 width = mProperties.getWidth();
+		int usage = mProperties.getUsage();
+		UINT32 numMips = mProperties.getNumMipmaps();
+		PixelFormat format = mProperties.getFormat();
+		bool hwGamma = mProperties.isHardwareGammaEnabled();
+		TextureType texType = mProperties.getTextureType();
+
 		// We must have those defined here
 		// We must have those defined here
-		assert(mWidth > 0);
+		assert(width > 0);
 
 
 		// Determine which D3D11 pixel format we'll use
 		// Determine which D3D11 pixel format we'll use
 		HRESULT hr;
 		HRESULT hr;
-		DXGI_FORMAT d3dPF = D3D11Mappings::getPF(D3D11Mappings::getClosestSupportedPF(mFormat, mHwGamma), mHwGamma);
+		DXGI_FORMAT d3dPF = D3D11Mappings::getPF(D3D11Mappings::getClosestSupportedPF(format, hwGamma), hwGamma);
 
 
-		if (mFormat != D3D11Mappings::getPF(d3dPF))
+		if (format != D3D11Mappings::getPF(d3dPF))
 		{
 		{
-			BS_EXCEPT(RenderingAPIException, "Provided pixel format is not supported by the driver: " + toString(mFormat));
+			BS_EXCEPT(RenderingAPIException, "Provided pixel format is not supported by the driver: " + toString(format));
 		}
 		}
 
 
 		D3D11_TEXTURE1D_DESC desc;
 		D3D11_TEXTURE1D_DESC desc;
-		desc.Width			= static_cast<UINT32>(mWidth);
+		desc.Width = static_cast<UINT32>(width);
 		desc.ArraySize		= 1;
 		desc.ArraySize		= 1;
 		desc.Format			= d3dPF;
 		desc.Format			= d3dPF;
 		desc.MiscFlags		= 0;
 		desc.MiscFlags		= 0;
 
 
-		if((mUsage & TU_RENDERTARGET) != 0)
+		if((usage & TU_RENDERTARGET) != 0)
 		{
 		{
 			desc.Usage			= D3D11_USAGE_DEFAULT;
 			desc.Usage			= D3D11_USAGE_DEFAULT;
 			desc.BindFlags		= D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
 			desc.BindFlags		= D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
 			desc.CPUAccessFlags = 0;
 			desc.CPUAccessFlags = 0;
 			desc.MipLevels		= 1;
 			desc.MipLevels		= 1;
 		}
 		}
-		else if((mUsage & TU_DEPTHSTENCIL) != 0)
+		else if ((usage & TU_DEPTHSTENCIL) != 0)
 		{
 		{
 			desc.Usage			= D3D11_USAGE_DEFAULT;
 			desc.Usage			= D3D11_USAGE_DEFAULT;
 			desc.BindFlags		= D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE;
 			desc.BindFlags		= D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE;
@@ -248,16 +258,15 @@ namespace BansheeEngine
 		}
 		}
 		else
 		else
 		{
 		{
-			desc.Usage			= D3D11Mappings::getUsage((GpuBufferUsage)mUsage);
+			desc.Usage			= D3D11Mappings::getUsage((GpuBufferUsage)usage);
 			desc.BindFlags		= D3D11_BIND_SHADER_RESOURCE;
 			desc.BindFlags		= D3D11_BIND_SHADER_RESOURCE;
-			desc.CPUAccessFlags = D3D11Mappings::getAccessFlags((GpuBufferUsage)mUsage);
+			desc.CPUAccessFlags = D3D11Mappings::getAccessFlags((GpuBufferUsage)usage);
 
 
 			// Determine total number of mipmaps including main one (d3d11 convention)
 			// Determine total number of mipmaps including main one (d3d11 convention)
-			UINT32 numMips		= (mNumMipmaps == MIP_UNLIMITED || (1U << mNumMipmaps) > mWidth) ? 0 : mNumMipmaps + 1;
-			desc.MipLevels		= numMips;
+			desc.MipLevels = (numMips == MIP_UNLIMITED || (1U << numMips) > width) ? 0 : numMips + 1;
 		}
 		}
 
 
-		if ((mUsage & TU_LOADSTORE) != 0)
+		if ((usage & TU_LOADSTORE) != 0)
 			desc.BindFlags |= D3D11_BIND_UNORDERED_ACCESS;
 			desc.BindFlags |= D3D11_BIND_UNORDERED_ACCESS;
 
 
 		// Create the texture
 		// Create the texture
@@ -268,7 +277,6 @@ namespace BansheeEngine
 		// Check result and except if failed
 		// Check result and except if failed
 		if (FAILED(hr) || device.hasError())
 		if (FAILED(hr) || device.hasError())
 		{
 		{
-			destroy_internal();
 			String errorDescription = device.getErrorDescription();
 			String errorDescription = device.getErrorDescription();
 			BS_EXCEPT(RenderingAPIException, "Error creating texture\nError Description:" + errorDescription);
 			BS_EXCEPT(RenderingAPIException, "Error creating texture\nError Description:" + errorDescription);
 		}
 		}
@@ -277,24 +285,23 @@ namespace BansheeEngine
 
 
 		if(FAILED(hr) || device.hasError())
 		if(FAILED(hr) || device.hasError())
 		{
 		{
-			destroy_internal();
 			String errorDescription = device.getErrorDescription();
 			String errorDescription = device.getErrorDescription();
 			BS_EXCEPT(RenderingAPIException, "Can't get base texture\nError Description:" + errorDescription);
 			BS_EXCEPT(RenderingAPIException, "Can't get base texture\nError Description:" + errorDescription);
 		}
 		}
 
 
 		m1DTex->GetDesc(&desc);
 		m1DTex->GetDesc(&desc);
 
 
-		if(mNumMipmaps != (desc.MipLevels - 1))
+		if(numMips != (desc.MipLevels - 1))
 		{
 		{
 			BS_EXCEPT(RenderingAPIException, "Driver returned different number of mip maps than requested. " \
 			BS_EXCEPT(RenderingAPIException, "Driver returned different number of mip maps than requested. " \
-				"Requested: " + toString(mNumMipmaps) + ". Got: " + toString(desc.MipLevels - 1) + ".");
+				"Requested: " + toString(numMips) + ". Got: " + toString(desc.MipLevels - 1) + ".");
 		}
 		}
 
 
 		mDXGIFormat = desc.Format;
 		mDXGIFormat = desc.Format;
 		mDimension = D3D11_SRV_DIMENSION_TEXTURE1D;
 		mDimension = D3D11_SRV_DIMENSION_TEXTURE1D;
 
 
 		// Create texture view
 		// Create texture view
-		if((mUsage & TU_DEPTHSTENCIL) == 0)
+		if ((usage & TU_DEPTHSTENCIL) == 0)
 		{
 		{
 			ZeroMemory(&mSRVDesc, sizeof(mSRVDesc));
 			ZeroMemory(&mSRVDesc, sizeof(mSRVDesc));
 			mSRVDesc.Format = desc.Format;
 			mSRVDesc.Format = desc.Format;
@@ -310,28 +317,37 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
-	void D3D11Texture::create2DTex()
+	void D3D11TextureCore::create2DTex()
 	{
 	{
+		UINT32 width = mProperties.getWidth();
+		UINT32 height = mProperties.getHeight();
+		int usage = mProperties.getUsage();
+		UINT32 numMips = mProperties.getNumMipmaps();
+		PixelFormat format = mProperties.getFormat();
+		bool hwGamma = mProperties.isHardwareGammaEnabled();
+		UINT32 sampleCount = mProperties.getMultisampleCount();
+		TextureType texType = mProperties.getTextureType();
+
 		// We must have those defined here
 		// We must have those defined here
-		assert(mWidth > 0 || mHeight > 0);
+		assert(width > 0 || height > 0);
 
 
 		// Determine which D3D11 pixel format we'll use
 		// Determine which D3D11 pixel format we'll use
 		HRESULT hr;
 		HRESULT hr;
-		DXGI_FORMAT d3dPF = D3D11Mappings::getPF(D3D11Mappings::getClosestSupportedPF(mFormat, mHwGamma), mHwGamma);
+		DXGI_FORMAT d3dPF = D3D11Mappings::getPF(D3D11Mappings::getClosestSupportedPF(format, hwGamma), hwGamma);
 
 
-		if (mFormat != D3D11Mappings::getPF(d3dPF))
+		if (format != D3D11Mappings::getPF(d3dPF))
 		{
 		{
-			BS_EXCEPT(RenderingAPIException, "Provided pixel format is not supported by the driver: " + toString(mFormat));
+			BS_EXCEPT(RenderingAPIException, "Provided pixel format is not supported by the driver: " + toString(format));
 		}
 		}
 
 
 		D3D11_TEXTURE2D_DESC desc;
 		D3D11_TEXTURE2D_DESC desc;
-		desc.Width			= static_cast<UINT32>(mWidth);
-		desc.Height			= static_cast<UINT32>(mHeight);
+		desc.Width			= static_cast<UINT32>(width);
+		desc.Height			= static_cast<UINT32>(height);
 		desc.ArraySize		= 1;
 		desc.ArraySize		= 1;
 		desc.Format			= d3dPF;
 		desc.Format			= d3dPF;
 		desc.MiscFlags		= 0;
 		desc.MiscFlags		= 0;
 
 
-		if((mUsage & TU_RENDERTARGET) != 0)
+		if((usage & TU_RENDERTARGET) != 0)
 		{
 		{
 			desc.Usage			= D3D11_USAGE_DEFAULT;
 			desc.Usage			= D3D11_USAGE_DEFAULT;
 			desc.BindFlags		= D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
 			desc.BindFlags		= D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
@@ -340,15 +356,15 @@ namespace BansheeEngine
 
 
 			DXGI_SAMPLE_DESC sampleDesc;
 			DXGI_SAMPLE_DESC sampleDesc;
 			D3D11RenderSystem* rs = static_cast<D3D11RenderSystem*>(RenderSystem::instancePtr());
 			D3D11RenderSystem* rs = static_cast<D3D11RenderSystem*>(RenderSystem::instancePtr());
-			rs->determineMultisampleSettings(mMultisampleCount, d3dPF, &sampleDesc);
+			rs->determineMultisampleSettings(sampleCount, d3dPF, &sampleDesc);
 			desc.SampleDesc		= sampleDesc;
 			desc.SampleDesc		= sampleDesc;
 
 
-			if(getTextureType() == TEX_TYPE_CUBE_MAP)
+			if (texType == TEX_TYPE_CUBE_MAP)
 			{
 			{
 				BS_EXCEPT(NotImplementedException, "Cube map not yet supported as a render target."); // TODO: Will be once I add proper texture array support
 				BS_EXCEPT(NotImplementedException, "Cube map not yet supported as a render target."); // TODO: Will be once I add proper texture array support
 			}
 			}
 		}
 		}
-		else if((mUsage & TU_DEPTHSTENCIL) != 0)
+		else if((usage & TU_DEPTHSTENCIL) != 0)
 		{
 		{
 			desc.Usage			= D3D11_USAGE_DEFAULT;
 			desc.Usage			= D3D11_USAGE_DEFAULT;
 			desc.BindFlags		= D3D11_BIND_DEPTH_STENCIL;
 			desc.BindFlags		= D3D11_BIND_DEPTH_STENCIL;
@@ -357,23 +373,22 @@ namespace BansheeEngine
 
 
 			DXGI_SAMPLE_DESC sampleDesc;
 			DXGI_SAMPLE_DESC sampleDesc;
 			D3D11RenderSystem* rs = static_cast<D3D11RenderSystem*>(RenderSystem::instancePtr());
 			D3D11RenderSystem* rs = static_cast<D3D11RenderSystem*>(RenderSystem::instancePtr());
-			rs->determineMultisampleSettings(mMultisampleCount, d3dPF, &sampleDesc);
+			rs->determineMultisampleSettings(sampleCount, d3dPF, &sampleDesc);
 			desc.SampleDesc		= sampleDesc;
 			desc.SampleDesc		= sampleDesc;
 
 
-			if(getTextureType() == TEX_TYPE_CUBE_MAP)
+			if (texType == TEX_TYPE_CUBE_MAP)
 			{
 			{
 				BS_EXCEPT(NotImplementedException, "Cube map not yet supported as a depth stencil target."); // TODO: Will be once I add proper texture array support
 				BS_EXCEPT(NotImplementedException, "Cube map not yet supported as a depth stencil target."); // TODO: Will be once I add proper texture array support
 			}
 			}
 		}
 		}
 		else
 		else
 		{
 		{
-			desc.Usage			= D3D11Mappings::getUsage((GpuBufferUsage)mUsage);
+			desc.Usage = D3D11Mappings::getUsage((GpuBufferUsage)usage);
 			desc.BindFlags		= D3D11_BIND_SHADER_RESOURCE;
 			desc.BindFlags		= D3D11_BIND_SHADER_RESOURCE;
-			desc.CPUAccessFlags = D3D11Mappings::getAccessFlags((GpuBufferUsage)mUsage);
+			desc.CPUAccessFlags = D3D11Mappings::getAccessFlags((GpuBufferUsage)usage);
 
 
 			// Determine total number of mipmaps including main one (d3d11 convention)
 			// Determine total number of mipmaps including main one (d3d11 convention)
-			UINT32 numMips = (mNumMipmaps == MIP_UNLIMITED || (1U << mNumMipmaps) > mWidth) ? 0 : mNumMipmaps + 1;
-			desc.MipLevels		= numMips;
+			desc.MipLevels		= (numMips == MIP_UNLIMITED || (1U << numMips) > width) ? 0 : numMips + 1;
 
 
 			DXGI_SAMPLE_DESC sampleDesc;
 			DXGI_SAMPLE_DESC sampleDesc;
 			sampleDesc.Count	= 1;
 			sampleDesc.Count	= 1;
@@ -381,13 +396,13 @@ namespace BansheeEngine
 			desc.SampleDesc		= sampleDesc;
 			desc.SampleDesc		= sampleDesc;
 		}
 		}
 
 
-        if (getTextureType() == TEX_TYPE_CUBE_MAP)
+		if (texType == TEX_TYPE_CUBE_MAP)
         {
         {
             desc.MiscFlags      |= D3D11_RESOURCE_MISC_TEXTURECUBE;
             desc.MiscFlags      |= D3D11_RESOURCE_MISC_TEXTURECUBE;
             desc.ArraySize       = 6;
             desc.ArraySize       = 6;
         }
         }
 
 
-		if ((mUsage & TU_LOADSTORE) != 0)
+		if ((usage & TU_LOADSTORE) != 0)
 			desc.BindFlags |= D3D11_BIND_UNORDERED_ACCESS;
 			desc.BindFlags |= D3D11_BIND_UNORDERED_ACCESS;
 
 
 		// Create the texture
 		// Create the texture
@@ -398,7 +413,6 @@ namespace BansheeEngine
 		// Check result and except if failed
 		// Check result and except if failed
 		if (FAILED(hr) || device.hasError())
 		if (FAILED(hr) || device.hasError())
 		{
 		{
-			destroy_internal();
 			String errorDescription = device.getErrorDescription();
 			String errorDescription = device.getErrorDescription();
 			BS_EXCEPT(RenderingAPIException, "Error creating texture\nError Description:" + errorDescription);
 			BS_EXCEPT(RenderingAPIException, "Error creating texture\nError Description:" + errorDescription);
 		}
 		}
@@ -407,30 +421,29 @@ namespace BansheeEngine
 
 
 		if(FAILED(hr) || device.hasError())
 		if(FAILED(hr) || device.hasError())
 		{
 		{
-			destroy_internal();
 			String errorDescription = device.getErrorDescription();
 			String errorDescription = device.getErrorDescription();
 			BS_EXCEPT(RenderingAPIException, "Can't get base texture\nError Description:" + errorDescription);
 			BS_EXCEPT(RenderingAPIException, "Can't get base texture\nError Description:" + errorDescription);
 		}
 		}
 
 
 		m2DTex->GetDesc(&desc);
 		m2DTex->GetDesc(&desc);
 
 
-		if(mNumMipmaps != (desc.MipLevels - 1))
+		if(numMips != (desc.MipLevels - 1))
 		{
 		{
 			BS_EXCEPT(RenderingAPIException, "Driver returned different number of mip maps than requested. " \
 			BS_EXCEPT(RenderingAPIException, "Driver returned different number of mip maps than requested. " \
-				"Requested: " + toString(mNumMipmaps) + ". Got: " + toString(desc.MipLevels - 1) + ".");
+				"Requested: " + toString(numMips) + ". Got: " + toString(desc.MipLevels - 1) + ".");
 		}
 		}
 
 
 		mDXGIFormat = desc.Format;
 		mDXGIFormat = desc.Format;
 
 
 		// Create shader texture view
 		// Create shader texture view
-		if((mUsage & TU_DEPTHSTENCIL) == 0)
+		if((usage & TU_DEPTHSTENCIL) == 0)
 		{
 		{
 			ZeroMemory(&mSRVDesc, sizeof(mSRVDesc));
 			ZeroMemory(&mSRVDesc, sizeof(mSRVDesc));
 			mSRVDesc.Format = desc.Format;
 			mSRVDesc.Format = desc.Format;
 
 
-			if((mUsage & TU_RENDERTARGET) != 0)
+			if((usage & TU_RENDERTARGET) != 0)
 			{
 			{
-				if(mMultisampleCount > 0)
+				if (sampleCount > 0)
 				{
 				{
 					mSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS;
 					mSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS;
 					mSRVDesc.Texture2D.MostDetailedMip = 0;
 					mSRVDesc.Texture2D.MostDetailedMip = 0;
@@ -445,7 +458,7 @@ namespace BansheeEngine
 			}
 			}
 			else
 			else
 			{
 			{
-				switch(getTextureType())
+				switch (texType)
 				{
 				{
 				case TEX_TYPE_CUBE_MAP:
 				case TEX_TYPE_CUBE_MAP:
 					mSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
 					mSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
@@ -472,42 +485,51 @@ namespace BansheeEngine
 		}
 		}
 		else
 		else
 		{
 		{
-			if(mMultisampleCount > 0)
+			if (sampleCount > 0)
 				mDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS;
 				mDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS;
 			else
 			else
 				mDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
 				mDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
 		}
 		}
 	}
 	}
 
 
-	void D3D11Texture::create3DTex()
+	void D3D11TextureCore::create3DTex()
 	{
 	{
+		UINT32 width = mProperties.getWidth();
+		UINT32 height = mProperties.getHeight();
+		UINT32 depth = mProperties.getDepth();
+		int usage = mProperties.getUsage();
+		UINT32 numMips = mProperties.getNumMipmaps();
+		PixelFormat format = mProperties.getFormat();
+		bool hwGamma = mProperties.isHardwareGammaEnabled();
+
 		// We must have those defined here
 		// We must have those defined here
-		assert(mWidth > 0 && mHeight > 0 && mDepth > 0);
+		assert(width > 0 && height > 0 && depth > 0);
 
 
 		// Determine which D3D11 pixel format we'll use
 		// Determine which D3D11 pixel format we'll use
 		HRESULT hr;
 		HRESULT hr;
-		DXGI_FORMAT d3dPF = D3D11Mappings::getPF(D3D11Mappings::getClosestSupportedPF(mFormat, mHwGamma), mHwGamma);
+		DXGI_FORMAT d3dPF = D3D11Mappings::getPF(
+			D3D11Mappings::getClosestSupportedPF(format, hwGamma), hwGamma);
 		
 		
-		if (mFormat != D3D11Mappings::getPF(d3dPF))
+		if (format != D3D11Mappings::getPF(d3dPF))
 		{
 		{
-			BS_EXCEPT(RenderingAPIException, "Provided pixel format is not supported by the driver: " + toString(mFormat));
+			BS_EXCEPT(RenderingAPIException, "Provided pixel format is not supported by the driver: " + toString(format));
 		}
 		}
 
 
 		D3D11_TEXTURE3D_DESC desc;
 		D3D11_TEXTURE3D_DESC desc;
-		desc.Width			= static_cast<UINT32>(mWidth);
-		desc.Height			= static_cast<UINT32>(mHeight);
-		desc.Depth			= static_cast<UINT32>(mDepth);
+		desc.Width = static_cast<UINT32>(width);
+		desc.Height = static_cast<UINT32>(height);
+		desc.Depth = static_cast<UINT32>(depth);
 		desc.Format			= d3dPF;
 		desc.Format			= d3dPF;
 		desc.MiscFlags		= 0;
 		desc.MiscFlags		= 0;
 
 
-		if((mUsage & TU_RENDERTARGET) != 0)
+		if ((mProperties.getUsage() & TU_RENDERTARGET) != 0)
 		{
 		{
 			desc.Usage			= D3D11_USAGE_DEFAULT;
 			desc.Usage			= D3D11_USAGE_DEFAULT;
 			desc.BindFlags		= D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
 			desc.BindFlags		= D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
 			desc.CPUAccessFlags = 0;
 			desc.CPUAccessFlags = 0;
 			desc.MipLevels		= 1;
 			desc.MipLevels		= 1;
 		}
 		}
-		else if((mUsage & TU_DEPTHSTENCIL) != 0)
+		else if ((mProperties.getUsage() & TU_DEPTHSTENCIL) != 0)
 		{
 		{
 			desc.Usage			= D3D11_USAGE_DEFAULT;
 			desc.Usage			= D3D11_USAGE_DEFAULT;
 			desc.BindFlags		= D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE;
 			desc.BindFlags		= D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE;
@@ -516,16 +538,16 @@ namespace BansheeEngine
 		}
 		}
 		else
 		else
 		{
 		{
-			desc.Usage			= D3D11Mappings::getUsage((GpuBufferUsage)mUsage);
+			desc.Usage			= D3D11Mappings::getUsage((GpuBufferUsage)usage);
 			desc.BindFlags		= D3D11_BIND_SHADER_RESOURCE;
 			desc.BindFlags		= D3D11_BIND_SHADER_RESOURCE;
-			desc.CPUAccessFlags = D3D11Mappings::getAccessFlags((GpuBufferUsage)mUsage);
+			desc.CPUAccessFlags = D3D11Mappings::getAccessFlags((GpuBufferUsage)usage);
 
 
 			// Determine total number of mipmaps including main one (d3d11 convention)
 			// Determine total number of mipmaps including main one (d3d11 convention)
-			UINT numMips = (mNumMipmaps == MIP_UNLIMITED || (1U << mNumMipmaps) > std::max(std::max(mWidth, mHeight), mDepth)) ? 0 : mNumMipmaps + 1;
-			desc.MipLevels		= numMips;
+			desc.MipLevels		= (numMips == MIP_UNLIMITED || (1U << numMips)
+				> std::max(std::max(width, height), depth)) ? 0 : numMips + 1;
 		}
 		}
 
 
-		if ((mUsage & TU_LOADSTORE) != 0)
+		if ((usage & TU_LOADSTORE) != 0)
 			desc.BindFlags |= D3D11_BIND_UNORDERED_ACCESS;
 			desc.BindFlags |= D3D11_BIND_UNORDERED_ACCESS;
 
 
 		// Create the texture
 		// Create the texture
@@ -536,7 +558,6 @@ namespace BansheeEngine
 		// Check result and except if failed
 		// Check result and except if failed
 		if (FAILED(hr) || device.hasError())
 		if (FAILED(hr) || device.hasError())
 		{
 		{
-			destroy_internal();
 			String errorDescription = device.getErrorDescription();
 			String errorDescription = device.getErrorDescription();
 			BS_EXCEPT(RenderingAPIException, "Error creating texture\nError Description:" + errorDescription);
 			BS_EXCEPT(RenderingAPIException, "Error creating texture\nError Description:" + errorDescription);
 		}
 		}
@@ -545,7 +566,6 @@ namespace BansheeEngine
 
 
 		if(FAILED(hr) || device.hasError())
 		if(FAILED(hr) || device.hasError())
 		{
 		{
-			destroy_internal();
 			String errorDescription = device.getErrorDescription();
 			String errorDescription = device.getErrorDescription();
 			BS_EXCEPT(RenderingAPIException, "Can't get base texture\nError Description:" + errorDescription);
 			BS_EXCEPT(RenderingAPIException, "Can't get base texture\nError Description:" + errorDescription);
 		}
 		}
@@ -553,16 +573,16 @@ namespace BansheeEngine
 		// Create texture view
 		// Create texture view
 		m3DTex->GetDesc(&desc);
 		m3DTex->GetDesc(&desc);
 
 
-		if(mNumMipmaps != (desc.MipLevels - 1))
+		if (mProperties.getNumMipmaps() != (desc.MipLevels - 1))
 		{
 		{
 			BS_EXCEPT(RenderingAPIException, "Driver returned different number of mip maps than requested. " \
 			BS_EXCEPT(RenderingAPIException, "Driver returned different number of mip maps than requested. " \
-               "Requested: " + toString(mNumMipmaps) + ". Got: " + toString(desc.MipLevels - 1) + ".");
+				"Requested: " + toString(mProperties.getNumMipmaps()) + ". Got: " + toString(desc.MipLevels - 1) + ".");
 		}
 		}
 
 
 		mDXGIFormat = desc.Format;
 		mDXGIFormat = desc.Format;
 		mDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
 		mDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
 
 
-		if((mUsage & TU_DEPTHSTENCIL) == 0)
+		if ((usage & TU_DEPTHSTENCIL) == 0)
 		{
 		{
 			ZeroMemory(&mSRVDesc, sizeof(mSRVDesc));
 			ZeroMemory(&mSRVDesc, sizeof(mSRVDesc));
 			mSRVDesc.Format = desc.Format;
 			mSRVDesc.Format = desc.Format;
@@ -580,21 +600,21 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
-	void* D3D11Texture::map(ID3D11Resource* res, D3D11_MAP flags, UINT32 mipLevel, UINT32 face, UINT32& rowPitch, UINT32& slicePitch)
+	void* D3D11TextureCore::map(ID3D11Resource* res, D3D11_MAP flags, UINT32 mipLevel, UINT32 face, UINT32& rowPitch, UINT32& slicePitch)
 	{
 	{
 		D3D11_MAPPED_SUBRESOURCE pMappedResource;
 		D3D11_MAPPED_SUBRESOURCE pMappedResource;
 		pMappedResource.pData = nullptr;
 		pMappedResource.pData = nullptr;
 
 
-		mipLevel = Math::clamp(mipLevel, (UINT32)mipLevel, getNumMipmaps());
-		face = Math::clamp(face, (UINT32)0, mDepth - 1);
+		mipLevel = Math::clamp(mipLevel, (UINT32)mipLevel, mProperties.getNumMipmaps());
+		face = Math::clamp(face, (UINT32)0, mProperties.getDepth() - 1);
 
 
-		if(getTextureType() == TEX_TYPE_3D)
+		if (mProperties.getTextureType() == TEX_TYPE_3D)
 			face = 0;
 			face = 0;
 
 
 		D3D11RenderSystem* rs = static_cast<D3D11RenderSystem*>(RenderSystem::instancePtr());
 		D3D11RenderSystem* rs = static_cast<D3D11RenderSystem*>(RenderSystem::instancePtr());
 		D3D11Device& device = rs->getPrimaryDevice();
 		D3D11Device& device = rs->getPrimaryDevice();
 
 
-		mLockedSubresourceIdx = D3D11CalcSubresource(mipLevel, face, getNumMipmaps()+1);
+		mLockedSubresourceIdx = D3D11CalcSubresource(mipLevel, face, mProperties.getNumMipmaps() + 1);
 		device.getImmediateContext()->Map(res, mLockedSubresourceIdx, flags, 0, &pMappedResource);
 		device.getImmediateContext()->Map(res, mLockedSubresourceIdx, flags, 0, &pMappedResource);
 
 
 		if (device.hasError())
 		if (device.hasError())
@@ -603,14 +623,14 @@ namespace BansheeEngine
 			BS_EXCEPT(RenderingAPIException, "D3D11 device cannot map texture\nError Description:" + errorDescription);
 			BS_EXCEPT(RenderingAPIException, "D3D11 device cannot map texture\nError Description:" + errorDescription);
 		}
 		}
 
 
-		UINT32 bytesPerPixel = PixelUtil::getNumElemBytes(getFormat());
+		UINT32 bytesPerPixel = PixelUtil::getNumElemBytes(mProperties.getFormat());
 		rowPitch = pMappedResource.RowPitch / bytesPerPixel;
 		rowPitch = pMappedResource.RowPitch / bytesPerPixel;
 		slicePitch = pMappedResource.DepthPitch / bytesPerPixel;
 		slicePitch = pMappedResource.DepthPitch / bytesPerPixel;
 
 
 		return pMappedResource.pData;
 		return pMappedResource.pData;
 	}
 	}
 
 
-	void D3D11Texture::unmap(ID3D11Resource* res)
+	void D3D11TextureCore::unmap(ID3D11Resource* res)
 	{
 	{
 		D3D11RenderSystem* rs = static_cast<D3D11RenderSystem*>(RenderSystem::instancePtr());
 		D3D11RenderSystem* rs = static_cast<D3D11RenderSystem*>(RenderSystem::instancePtr());
 		D3D11Device& device = rs->getPrimaryDevice();
 		D3D11Device& device = rs->getPrimaryDevice();
@@ -623,7 +643,7 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
-	void* D3D11Texture::mapstagingbuffer(D3D11_MAP flags, UINT32 mipLevel, UINT32 face, UINT32& rowPitch, UINT32& slicePitch)
+	void* D3D11TextureCore::mapstagingbuffer(D3D11_MAP flags, UINT32 mipLevel, UINT32 face, UINT32& rowPitch, UINT32& slicePitch)
 	{
 	{
 		// Note: I am creating and destroying a staging resource every time a texture is read. 
 		// Note: I am creating and destroying a staging resource every time a texture is read. 
 		// Consider offering a flag on init that will keep this active all the time (at the cost of double memory).
 		// Consider offering a flag on init that will keep this active all the time (at the cost of double memory).
@@ -639,16 +659,16 @@ namespace BansheeEngine
 		return map(mStagingBuffer, flags, face, mipLevel, rowPitch, slicePitch);
 		return map(mStagingBuffer, flags, face, mipLevel, rowPitch, slicePitch);
 	}
 	}
 
 
-	void D3D11Texture::unmapstagingbuffer()
+	void D3D11TextureCore::unmapstagingbuffer()
 	{
 	{
 		unmap(mStagingBuffer);
 		unmap(mStagingBuffer);
 		SAFE_RELEASE(mStagingBuffer);
 		SAFE_RELEASE(mStagingBuffer);
 	}
 	}
 
 
-	void* D3D11Texture::mapstaticbuffer(PixelData lock, UINT32 mipLevel, UINT32 face)
+	void* D3D11TextureCore::mapstaticbuffer(PixelData lock, UINT32 mipLevel, UINT32 face)
 	{
 	{
 		UINT32 sizeOfImage = lock.getConsecutiveSize();
 		UINT32 sizeOfImage = lock.getConsecutiveSize();
-		mLockedSubresourceIdx = D3D11CalcSubresource(mipLevel, face, getNumMipmaps()+1);
+		mLockedSubresourceIdx = D3D11CalcSubresource(mipLevel, face, mProperties.getNumMipmaps()+1);
 
 
 		mStaticBuffer = bs_new<PixelData, PoolAlloc>(lock.getWidth(), lock.getHeight(), lock.getDepth(), lock.getFormat());
 		mStaticBuffer = bs_new<PixelData, PoolAlloc>(lock.getWidth(), lock.getHeight(), lock.getDepth(), lock.getFormat());
 		mStaticBuffer->allocateInternalBuffer();
 		mStaticBuffer->allocateInternalBuffer();
@@ -656,7 +676,7 @@ namespace BansheeEngine
 		return mStaticBuffer->getData();
 		return mStaticBuffer->getData();
 	}
 	}
 
 
-	void D3D11Texture::unmapstaticbuffer()
+	void D3D11TextureCore::unmapstaticbuffer()
 	{
 	{
 		UINT32 rowWidth = D3D11Mappings::getSizeInBytes(mStaticBuffer->getFormat(), mStaticBuffer->getWidth());
 		UINT32 rowWidth = D3D11Mappings::getSizeInBytes(mStaticBuffer->getFormat(), mStaticBuffer->getWidth());
 		UINT32 sliceWidth = D3D11Mappings::getSizeInBytes(mStaticBuffer->getFormat(), mStaticBuffer->getWidth(), mStaticBuffer->getHeight());
 		UINT32 sliceWidth = D3D11Mappings::getSizeInBytes(mStaticBuffer->getFormat(), mStaticBuffer->getWidth(), mStaticBuffer->getHeight());
@@ -675,11 +695,11 @@ namespace BansheeEngine
 			bs_delete<PoolAlloc>(mStaticBuffer);
 			bs_delete<PoolAlloc>(mStaticBuffer);
 	}
 	}
 
 
-	void D3D11Texture::createStagingBuffer()
+	void D3D11TextureCore::createStagingBuffer()
 	{
 	{
 		D3D11RenderSystem* rs = static_cast<D3D11RenderSystem*>(RenderSystem::instancePtr());
 		D3D11RenderSystem* rs = static_cast<D3D11RenderSystem*>(RenderSystem::instancePtr());
 		D3D11Device& device = rs->getPrimaryDevice();
 		D3D11Device& device = rs->getPrimaryDevice();
-		switch (getTextureType())
+		switch (mProperties.getTextureType())
 		{
 		{
 		case TEX_TYPE_1D:
 		case TEX_TYPE_1D:
 			{
 			{
@@ -724,7 +744,7 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
-	TextureViewPtr D3D11Texture::createView()
+	TextureViewPtr D3D11TextureCore::createView()
 	{
 	{
 		TextureViewPtr viewPtr = bs_core_ptr<D3D11TextureView, PoolAlloc>(new (bs_alloc<D3D11TextureView, PoolAlloc>()) D3D11TextureView());
 		TextureViewPtr viewPtr = bs_core_ptr<D3D11TextureView, PoolAlloc>(new (bs_alloc<D3D11TextureView, PoolAlloc>()) D3D11TextureView());
 		viewPtr->_setThisPtr(viewPtr);
 		viewPtr->_setThisPtr(viewPtr);

+ 9 - 7
BansheeD3D11RenderSystem/Source/BsD3D11TextureManager.cpp

@@ -7,13 +7,6 @@
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
-	TexturePtr D3D11TextureManager::createTextureImpl()
-	{
-		D3D11Texture* tex = new (bs_alloc<D3D11Texture, PoolAlloc>()) D3D11Texture(); 
-
-		return bs_core_ptr<D3D11Texture, PoolAlloc>(tex);
-	}
-
 	RenderTexturePtr D3D11TextureManager::createRenderTextureImpl(const RENDER_TEXTURE_DESC& desc)
 	RenderTexturePtr D3D11TextureManager::createRenderTextureImpl(const RENDER_TEXTURE_DESC& desc)
 	{
 	{
 		D3D11RenderTexture* tex = new (bs_alloc<D3D11RenderTexture, PoolAlloc>()) D3D11RenderTexture(desc);
 		D3D11RenderTexture* tex = new (bs_alloc<D3D11RenderTexture, PoolAlloc>()) D3D11RenderTexture(desc);
@@ -36,6 +29,15 @@ namespace BansheeEngine
 		return D3D11Mappings::getPF(d3dPF);
 		return D3D11Mappings::getPF(d3dPF);
 	}
 	}
 
 
+	SPtr<TextureCore> D3D11TextureCoreManager::createTextureInternal(TextureType texType, UINT32 width, UINT32 height, UINT32 depth,
+		int numMips, PixelFormat format, int usage, bool hwGammaCorrection, UINT32 multisampleCount)
+	{
+		D3D11TextureCore* tex = new (bs_alloc<D3D11TextureCore>()) D3D11TextureCore(texType, 
+			width, height, depth, numMips, format, usage, hwGammaCorrection, multisampleCount);
+
+		return bs_shared_ptr<D3D11TextureCore, GenAlloc>(tex);
+	}
+
 	SPtr<RenderTextureCore> D3D11TextureCoreManager::createRenderTextureInternal(const RENDER_TEXTURE_DESC& desc)
 	SPtr<RenderTextureCore> D3D11TextureCoreManager::createRenderTextureInternal(const RENDER_TEXTURE_DESC& desc)
 	{
 	{
 		return bs_shared_ptr<D3D11RenderTextureCore>(desc);
 		return bs_shared_ptr<D3D11RenderTextureCore>(desc);

+ 15 - 12
BansheeD3D11RenderSystem/Source/BsD3D11TextureView.cpp

@@ -16,7 +16,7 @@ namespace BansheeEngine
 
 
 	void D3D11TextureView::initialize_internal()
 	void D3D11TextureView::initialize_internal()
 	{
 	{
-		D3D11Texture* d3d11Texture = static_cast<D3D11Texture*>(mOwnerTexture.get());
+		D3D11TextureCore* d3d11Texture = static_cast<D3D11TextureCore*>(mOwnerTexture.get());
 
 
 		if((mDesc.usage & GVU_RANDOMWRITE) != 0)
 		if((mDesc.usage & GVU_RANDOMWRITE) != 0)
 			mUAV = createUAV(d3d11Texture, mDesc.mostDetailMip, mDesc.firstArraySlice, mDesc.numArraySlices);
 			mUAV = createUAV(d3d11Texture, mDesc.mostDetailMip, mDesc.firstArraySlice, mDesc.numArraySlices);
@@ -42,13 +42,14 @@ namespace BansheeEngine
 		TextureView::destroy_internal();
 		TextureView::destroy_internal();
 	}
 	}
 
 
-	ID3D11ShaderResourceView* D3D11TextureView::createSRV(D3D11Texture* texture, 
+	ID3D11ShaderResourceView* D3D11TextureView::createSRV(D3D11TextureCore* texture, 
 		UINT32 mostDetailMip, UINT32 numMips, UINT32 firstArraySlice, UINT32 numArraySlices)
 		UINT32 mostDetailMip, UINT32 numMips, UINT32 firstArraySlice, UINT32 numArraySlices)
 	{
 	{
 		D3D11_SHADER_RESOURCE_VIEW_DESC desc;
 		D3D11_SHADER_RESOURCE_VIEW_DESC desc;
 		ZeroMemory(&desc, sizeof(desc));
 		ZeroMemory(&desc, sizeof(desc));
 
 
-		switch(texture->getTextureType())
+		const TextureProperties& texProps = texture->getProperties();
+		switch (texProps.getTextureType())
 		{
 		{
 		case TEX_TYPE_1D:
 		case TEX_TYPE_1D:
 			desc.Texture1D.MipLevels = numMips;
 			desc.Texture1D.MipLevels = numMips;
@@ -56,7 +57,7 @@ namespace BansheeEngine
 			desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D;
 			desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D;
 			break;
 			break;
 		case TEX_TYPE_2D:
 		case TEX_TYPE_2D:
-			if (texture->getMultisampleCount() > 0)
+			if (texProps.getMultisampleCount() > 0)
 			{
 			{
 				desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS;
 				desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS;
 			}
 			}
@@ -97,20 +98,21 @@ namespace BansheeEngine
 		return srv;
 		return srv;
 	}
 	}
 
 
-	ID3D11RenderTargetView* D3D11TextureView::createRTV(D3D11Texture* texture, 
+	ID3D11RenderTargetView* D3D11TextureView::createRTV(D3D11TextureCore* texture,
 		UINT32 mipSlice, UINT32 firstArraySlice, UINT32 numArraySlices)
 		UINT32 mipSlice, UINT32 firstArraySlice, UINT32 numArraySlices)
 	{
 	{
 		D3D11_RENDER_TARGET_VIEW_DESC desc;
 		D3D11_RENDER_TARGET_VIEW_DESC desc;
 		ZeroMemory(&desc, sizeof(desc));
 		ZeroMemory(&desc, sizeof(desc));
 
 
-		switch(texture->getTextureType())
+		const TextureProperties& texProps = texture->getProperties();
+		switch (texProps.getTextureType())
 		{
 		{
 		case TEX_TYPE_1D:
 		case TEX_TYPE_1D:
 			desc.Texture1D.MipSlice = mipSlice;
 			desc.Texture1D.MipSlice = mipSlice;
 			desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1D;
 			desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1D;
 			break;
 			break;
 		case TEX_TYPE_2D:
 		case TEX_TYPE_2D:
-			if (texture->getMultisampleCount() > 0)
+			if (texProps.getMultisampleCount() > 0)
 			{
 			{
 				desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS;
 				desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS;
 			}
 			}
@@ -152,13 +154,13 @@ namespace BansheeEngine
 		return rtv;
 		return rtv;
 	}
 	}
 
 
-	ID3D11UnorderedAccessView* D3D11TextureView::createUAV(D3D11Texture* texture,
+	ID3D11UnorderedAccessView* D3D11TextureView::createUAV(D3D11TextureCore* texture,
 		UINT32 mipSlice, UINT32 firstArraySlice, UINT32 numArraySlices)
 		UINT32 mipSlice, UINT32 firstArraySlice, UINT32 numArraySlices)
 	{
 	{
 		D3D11_UNORDERED_ACCESS_VIEW_DESC desc;
 		D3D11_UNORDERED_ACCESS_VIEW_DESC desc;
 		ZeroMemory(&desc, sizeof(desc));
 		ZeroMemory(&desc, sizeof(desc));
 
 
-		switch(texture->getTextureType())
+		switch(texture->getProperties().getTextureType())
 		{
 		{
 		case TEX_TYPE_1D:
 		case TEX_TYPE_1D:
 			desc.Texture1D.MipSlice = mipSlice;
 			desc.Texture1D.MipSlice = mipSlice;
@@ -200,20 +202,21 @@ namespace BansheeEngine
 		return uav;
 		return uav;
 	}
 	}
 
 
-	ID3D11DepthStencilView* D3D11TextureView::createDSV(D3D11Texture* texture, 
+	ID3D11DepthStencilView* D3D11TextureView::createDSV(D3D11TextureCore* texture,
 		UINT32 mipSlice, UINT32 firstArraySlice, UINT32 numArraySlices)
 		UINT32 mipSlice, UINT32 firstArraySlice, UINT32 numArraySlices)
 	{
 	{
 		D3D11_DEPTH_STENCIL_VIEW_DESC desc;
 		D3D11_DEPTH_STENCIL_VIEW_DESC desc;
 		ZeroMemory(&desc, sizeof(desc));
 		ZeroMemory(&desc, sizeof(desc));
 
 
-		switch(texture->getTextureType())
+		const TextureProperties& texProps = texture->getProperties();
+		switch (texProps.getTextureType())
 		{
 		{
 		case TEX_TYPE_1D:
 		case TEX_TYPE_1D:
 			desc.Texture1D.MipSlice = mipSlice;
 			desc.Texture1D.MipSlice = mipSlice;
 			desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE1D;
 			desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE1D;
 			break;
 			break;
 		case TEX_TYPE_2D:
 		case TEX_TYPE_2D:
-			if (texture->getMultisampleCount() > 0)
+			if (texProps.getMultisampleCount() > 0)
 			{
 			{
 				desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS;
 				desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS;
 			}
 			}

+ 2 - 2
BansheeD3D9RenderSystem/Include/BsD3D9PixelBuffer.h

@@ -25,7 +25,7 @@ namespace BansheeEngine
 		};
 		};
 
 
 	public:
 	public:
-		D3D9PixelBuffer(GpuBufferUsage usage, D3D9Texture* ownerTexture);
+		D3D9PixelBuffer(GpuBufferUsage usage, D3D9TextureCore* ownerTexture);
 		~D3D9PixelBuffer();
 		~D3D9PixelBuffer();
 
 
 		/**
 		/**
@@ -137,7 +137,7 @@ namespace BansheeEngine
 		bool mDoMipmapGen;
 		bool mDoMipmapGen;
 		bool mHWMipmaps;
 		bool mHWMipmaps;
 
 
-		D3D9Texture* mOwnerTexture;
+		D3D9TextureCore* mOwnerTexture;
 		DWORD mLockFlags;
 		DWORD mLockFlags;
 	};
 	};
 };
 };

+ 1 - 2
BansheeD3D9RenderSystem/Include/BsD3D9Prerequisites.h

@@ -29,7 +29,7 @@ namespace BansheeEngine
 	class D3D9RenderSystem;
 	class D3D9RenderSystem;
 	class D3D9RenderWindow;
 	class D3D9RenderWindow;
 	class D3D9RenderWindowCore;
 	class D3D9RenderWindowCore;
-	class D3D9Texture;
+	class D3D9TextureCore;
 	class D3D9TextureManager;
 	class D3D9TextureManager;
 	class D3D9Driver;
 	class D3D9Driver;
 	class D3D9DriverList;
 	class D3D9DriverList;
@@ -48,7 +48,6 @@ namespace BansheeEngine
 	class D3D9Resource;
 	class D3D9Resource;
 
 
 	typedef std::shared_ptr<D3D9RenderWindow> D3D9RenderWindowPtr;
 	typedef std::shared_ptr<D3D9RenderWindow> D3D9RenderWindowPtr;
-	typedef std::shared_ptr<D3D9Texture> D3D9TexturePtr;
 
 
 	/**
 	/**
 	 * @brief	Type IDs used for RTTI.
 	 * @brief	Type IDs used for RTTI.

+ 2 - 2
BansheeD3D9RenderSystem/Include/BsD3D9RenderSystem.h

@@ -73,12 +73,12 @@ namespace BansheeEngine
 		/**
 		/**
 		 * @copydoc RenderSystem::setTexture()
 		 * @copydoc RenderSystem::setTexture()
 		 */
 		 */
-		void setTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const TexturePtr &texPtr);
+		void setTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const SPtr<TextureCore>& texPtr);
 
 
 		/**
 		/**
 		 * @copydoc RenderSystem::setLoadStoreTexture()
 		 * @copydoc RenderSystem::setLoadStoreTexture()
 		 */
 		 */
-		void setLoadStoreTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const TexturePtr& texPtr,
+		void setLoadStoreTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const SPtr<TextureCore>& texPtr,
 			const TextureSurface& surface);
 			const TextureSurface& surface);
 
 
 		/**
 		/**

+ 16 - 15
BansheeD3D9RenderSystem/Include/BsD3D9Texture.h

@@ -12,7 +12,7 @@ namespace BansheeEngine
 	/**
 	/**
 	 * @brief	DirectX 9 implementation of a texture.
 	 * @brief	DirectX 9 implementation of a texture.
 	 */
 	 */
-	class BS_D3D9_EXPORT D3D9Texture : public Texture, public D3D9Resource
+	class BS_D3D9_EXPORT D3D9TextureCore : public TextureCore, public D3D9Resource
 	{
 	{
 	protected:
 	protected:
 		/**
 		/**
@@ -29,7 +29,7 @@ namespace BansheeEngine
 		};
 		};
 
 
 	public:
 	public:
-		~D3D9Texture();
+		~D3D9TextureCore();
 
 
 		/**
 		/**
 		 * @copydoc Texture::isBindableAsShaderResource
 		 * @copydoc Texture::isBindableAsShaderResource
@@ -54,7 +54,7 @@ namespace BansheeEngine
 		/**
 		/**
 		 * @brief	Indicates whether the hardware gamma is enabled and supported.
 		 * @brief	Indicates whether the hardware gamma is enabled and supported.
 		 */
 		 */
-		bool isHardwareGammaReadToBeUsed() const { return mHwGamma && mHwGammaReadSupported; }
+		bool isHardwareGammaReadToBeUsed() const { return mProperties.isHardwareGammaEnabled() && mHwGammaReadSupported; }
 					
 					
 		/**
 		/**
 		 * @brief	Returns a hardware pixel buffer for a certain face and level of the texture.
 		 * @brief	Returns a hardware pixel buffer for a certain face and level of the texture.
@@ -88,43 +88,44 @@ namespace BansheeEngine
 		virtual void notifyOnDeviceReset(IDirect3DDevice9* d3d9Device);
 		virtual void notifyOnDeviceReset(IDirect3DDevice9* d3d9Device);
 
 
 	protected:	
 	protected:	
-		friend class D3D9TextureManager;
+		friend class D3D9TextureCoreManager;
 		friend class D3D9PixelBuffer;
 		friend class D3D9PixelBuffer;
 
 
-		D3D9Texture();
+		D3D9TextureCore(TextureType textureType, UINT32 width, UINT32 height, UINT32 depth, UINT32 numMipmaps,
+			PixelFormat format, int usage, bool hwGamma, UINT32 multisampleCount);
 
 
 		/**
 		/**
-		 * @copydoc Texture::initialize_internal()
+		 * @copydoc TextureCore::initialize
 		 */
 		 */
-		void initialize_internal();	
+		void initialize();
 		
 		
 		/**
 		/**
-		 * @copydoc Texture::destroy_internal()
+		 * @copydoc TextureCore::destroy
 		 */
 		 */
-		void destroy_internal();
+		void destroy();
 
 
 		/**
 		/**
-		 * @copydoc Texture::lock
+		 * @copydoc TextureCore::lock
 		 */
 		 */
 		PixelData lockImpl(GpuLockOptions options, UINT32 mipLevel = 0, UINT32 face = 0);
 		PixelData lockImpl(GpuLockOptions options, UINT32 mipLevel = 0, UINT32 face = 0);
 
 
 		/**
 		/**
-		 * @copydoc Texture::unlock
+		 * @copydoc TextureCore::unlock
 		 */
 		 */
 		void unlockImpl();
 		void unlockImpl();
 
 
 		/**
 		/**
-		 * @copydoc Texture::copy
+		 * @copydoc TextureCore::copy
 		 */
 		 */
-		void copyImpl(UINT32 srcFace, UINT32 srcMipLevel, UINT32 destFace, UINT32 destMipLevel, TexturePtr& target);
+		void copyImpl(UINT32 srcFace, UINT32 srcMipLevel, UINT32 destFace, UINT32 destMipLevel, const SPtr<TextureCore>& target);
 
 
 		/**
 		/**
-		 * @copydoc Texture::readData
+		 * @copydoc TextureCore::readData
 		 */
 		 */
 		void readData(PixelData& dest, UINT32 mipLevel = 0, UINT32 face = 0);
 		void readData(PixelData& dest, UINT32 mipLevel = 0, UINT32 face = 0);
 
 
 		/**
 		/**
-		 * @copydoc Texture::writeData
+		 * @copydoc TextureCore::writeData
 		 */
 		 */
 		void writeData(const PixelData& src, UINT32 mipLevel = 0, UINT32 face = 0, bool discardWholeBuffer = false);
 		void writeData(const PixelData& src, UINT32 mipLevel = 0, UINT32 face = 0, bool discardWholeBuffer = false);
 
 

+ 7 - 5
BansheeD3D9RenderSystem/Include/BsD3D9TextureManager.h

@@ -21,11 +21,6 @@ namespace BansheeEngine
 		PixelFormat getNativeFormat(TextureType ttype, PixelFormat format, int usage, bool hwGamma);
 		PixelFormat getNativeFormat(TextureType ttype, PixelFormat format, int usage, bool hwGamma);
 
 
 	protected:	
 	protected:	
-		/**
-		 * @copydoc TextureManager::createTextureImpl
-		 */
-		TexturePtr createTextureImpl();
-
 		/**
 		/**
 		 * @copydoc TextureManager::createRenderTextureImpl
 		 * @copydoc TextureManager::createRenderTextureImpl
 		 */
 		 */
@@ -43,6 +38,13 @@ namespace BansheeEngine
 	class BS_D3D9_EXPORT D3D9TextureCoreManager : public TextureCoreManager
 	class BS_D3D9_EXPORT D3D9TextureCoreManager : public TextureCoreManager
 	{
 	{
 	protected:		
 	protected:		
+		/**
+		 * @copydoc	TextureCoreManager::createTextureInternal
+		 */
+		SPtr<TextureCore> createTextureInternal(TextureType texType, UINT32 width, UINT32 height, UINT32 depth,
+			int numMips, PixelFormat format, int usage = TU_DEFAULT, bool hwGammaCorrection = false,
+			UINT32 multisampleCount = 0);
+
 		/**
 		/**
 		 * @copydoc	TextureCoreManager::createRenderTextureInternal
 		 * @copydoc	TextureCoreManager::createRenderTextureInternal
 		 */
 		 */

+ 4 - 4
BansheeD3D9RenderSystem/Source/BsD3D9MultiRenderTexture.cpp

@@ -21,8 +21,8 @@ namespace BansheeEngine
 		{
 		{
 			if (mColorSurfaces[i] != nullptr)
 			if (mColorSurfaces[i] != nullptr)
 			{
 			{
-				D3D9Texture* d3d9texture = static_cast<D3D9Texture*>(mColorSurfaces[i]->getTexture().get());
-				if (d3d9texture->getTextureType() != TEX_TYPE_3D)
+				D3D9TextureCore* d3d9texture = static_cast<D3D9TextureCore*>(mColorSurfaces[i]->getTexture().get());
+				if (d3d9texture->getProperties().getTextureType() != TEX_TYPE_3D)
 				{
 				{
 					D3D9PixelBuffer* pixelBuffer = static_cast<D3D9PixelBuffer*>(
 					D3D9PixelBuffer* pixelBuffer = static_cast<D3D9PixelBuffer*>(
 						d3d9texture->getBuffer(mColorSurfaces[i]->getDesc().firstArraySlice, mColorSurfaces[i]->getDesc().mostDetailMip).get());
 						d3d9texture->getBuffer(mColorSurfaces[i]->getDesc().firstArraySlice, mColorSurfaces[i]->getDesc().mostDetailMip).get());
@@ -39,9 +39,9 @@ namespace BansheeEngine
 
 
 		if (mDepthStencilSurface != nullptr)
 		if (mDepthStencilSurface != nullptr)
 		{
 		{
-			D3D9Texture* d3d9DepthStencil = static_cast<D3D9Texture*>(mDepthStencilSurface->getTexture().get());
+			D3D9TextureCore* d3d9DepthStencil = static_cast<D3D9TextureCore*>(mDepthStencilSurface->getTexture().get());
 
 
-			if (d3d9DepthStencil->getTextureType() != TEX_TYPE_3D)
+			if (d3d9DepthStencil->getProperties().getTextureType() != TEX_TYPE_3D)
 			{
 			{
 				D3D9PixelBuffer* pixelBuffer = static_cast<D3D9PixelBuffer*>(
 				D3D9PixelBuffer* pixelBuffer = static_cast<D3D9PixelBuffer*>(
 					d3d9DepthStencil->getBuffer(mDepthStencilSurface->getDesc().firstArraySlice, mDepthStencilSurface->getDesc().mostDetailMip).get());
 					d3d9DepthStencil->getBuffer(mDepthStencilSurface->getDesc().firstArraySlice, mDepthStencilSurface->getDesc().mostDetailMip).get());

+ 1 - 1
BansheeD3D9RenderSystem/Source/BsD3D9PixelBuffer.cpp

@@ -34,7 +34,7 @@ namespace BansheeEngine
 		return pbox;
 		return pbox;
 	}
 	}
 
 
-	D3D9PixelBuffer::D3D9PixelBuffer(GpuBufferUsage usage, D3D9Texture* ownerTexture)
+	D3D9PixelBuffer::D3D9PixelBuffer(GpuBufferUsage usage, D3D9TextureCore* ownerTexture)
 		:PixelBuffer(0, 0, 0, PF_UNKNOWN, usage, false),
 		:PixelBuffer(0, 0, 0, PF_UNKNOWN, usage, false),
 		 mDoMipmapGen(0), mHWMipmaps(0), mOwnerTexture(ownerTexture)
 		 mDoMipmapGen(0), mHWMipmaps(0), mOwnerTexture(ownerTexture)
 	{ }
 	{ }

+ 5 - 5
BansheeD3D9RenderSystem/Source/BsD3D9RenderSystem.cpp

@@ -299,7 +299,7 @@ namespace BansheeEngine
 			if(!texture.isLoaded())
 			if(!texture.isLoaded())
 				setTexture(gptype, iter->second.slot, false, nullptr);
 				setTexture(gptype, iter->second.slot, false, nullptr);
 			else
 			else
-				setTexture(gptype, iter->second.slot, true, texture.getInternalPtr());
+				setTexture(gptype, iter->second.slot, true, texture->getCore());
 		}
 		}
 
 
 		// Read all the buffer data so we can assign it. Not the most efficient way of accessing data
 		// Read all the buffer data so we can assign it. Not the most efficient way of accessing data
@@ -438,7 +438,7 @@ namespace BansheeEngine
 		BS_INC_RENDER_STAT(NumGpuParamBufferBinds);
 		BS_INC_RENDER_STAT(NumGpuParamBufferBinds);
 	}
 	}
 
 
-	void D3D9RenderSystem::setTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const TexturePtr& tex)
+	void D3D9RenderSystem::setTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const SPtr<TextureCore>& tex)
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
@@ -457,7 +457,7 @@ namespace BansheeEngine
 		}
 		}
 
 
 		HRESULT hr;
 		HRESULT hr;
-		D3D9TexturePtr dt = std::static_pointer_cast<D3D9Texture>(tex);
+		SPtr<D3D9TextureCore> dt = std::static_pointer_cast<D3D9TextureCore>(tex);
 		if (enabled && (dt != nullptr))
 		if (enabled && (dt != nullptr))
 		{
 		{
 			IDirect3DBaseTexture9 *pTex = dt->getTexture_internal();
 			IDirect3DBaseTexture9 *pTex = dt->getTexture_internal();
@@ -472,7 +472,7 @@ namespace BansheeEngine
 
 
 				// set stage desc.
 				// set stage desc.
 				mTexStageDesc[unit].pTex = pTex;
 				mTexStageDesc[unit].pTex = pTex;
-				mTexStageDesc[unit].texType = D3D9Mappings::get(dt->getTextureType());
+				mTexStageDesc[unit].texType = D3D9Mappings::get(dt->getProperties().getTextureType());
 
 
 				// Set gamma now too
 				// Set gamma now too
 				if (dt->isHardwareGammaReadToBeUsed())
 				if (dt->isHardwareGammaReadToBeUsed())
@@ -516,7 +516,7 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
-	void D3D9RenderSystem::setLoadStoreTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const TexturePtr& texPtr,
+	void D3D9RenderSystem::setLoadStoreTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const SPtr<TextureCore>& texPtr,
 		const TextureSurface& surface)
 		const TextureSurface& surface)
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;

+ 2 - 2
BansheeD3D9RenderSystem/Source/BsD3D9RenderTexture.cpp

@@ -23,12 +23,12 @@ namespace BansheeEngine
 
 
 	void D3D9RenderTextureCore::initializeSurfaces()
 	void D3D9RenderTextureCore::initializeSurfaces()
 	{
 	{
-		D3D9Texture* d3d9texture = static_cast<D3D9Texture*>(mColorSurface->getTexture().get());
+		D3D9TextureCore* d3d9texture = static_cast<D3D9TextureCore*>(mColorSurface->getTexture().get());
 		D3D9PixelBuffer* pixelBuffer = static_cast<D3D9PixelBuffer*>(
 		D3D9PixelBuffer* pixelBuffer = static_cast<D3D9PixelBuffer*>(
 			d3d9texture->getBuffer(mColorSurface->getFirstArraySlice(), mColorSurface->getMostDetailedMip()).get());
 			d3d9texture->getBuffer(mColorSurface->getFirstArraySlice(), mColorSurface->getMostDetailedMip()).get());
 		mDX9ColorSurface = pixelBuffer->getSurface(D3D9RenderSystem::getActiveD3D9Device());
 		mDX9ColorSurface = pixelBuffer->getSurface(D3D9RenderSystem::getActiveD3D9Device());
 
 
-		D3D9Texture* d3d9DepthStencil = static_cast<D3D9Texture*>(mDepthStencilSurface->getTexture().get());
+		D3D9TextureCore* d3d9DepthStencil = static_cast<D3D9TextureCore*>(mDepthStencilSurface->getTexture().get());
 		D3D9PixelBuffer* depthStencilBuffer = static_cast<D3D9PixelBuffer*>(
 		D3D9PixelBuffer* depthStencilBuffer = static_cast<D3D9PixelBuffer*>(
 			d3d9DepthStencil->getBuffer(mDepthStencilSurface->getFirstArraySlice(), mDepthStencilSurface->getMostDetailedMip()).get());
 			d3d9DepthStencil->getBuffer(mDepthStencilSurface->getFirstArraySlice(), mDepthStencilSurface->getMostDetailedMip()).get());
 		mDX9DepthStencilSurface = depthStencilBuffer->getSurface(D3D9RenderSystem::getActiveD3D9Device());
 		mDX9DepthStencilSurface = depthStencilBuffer->getSurface(D3D9RenderSystem::getActiveD3D9Device());

+ 162 - 141
BansheeD3D9RenderSystem/Source/BsD3D9Texture.cpp

@@ -13,18 +13,18 @@
 
 
 namespace BansheeEngine 
 namespace BansheeEngine 
 {
 {
-	
-    D3D9Texture::D3D9Texture()
-        :Texture(), mD3DPool(D3DPOOL_MANAGED), mDynamicTextures(false),
-		mHwGammaReadSupported(false), mHwGammaWriteSupported(false), mMultisampleType(D3DMULTISAMPLE_NONE),
-		mMultisampleQuality(0), mIsBindableAsShaderResource(true)
+	D3D9TextureCore::D3D9TextureCore(TextureType textureType, UINT32 width, UINT32 height, UINT32 depth, UINT32 numMipmaps,
+		PixelFormat format, int usage, bool hwGamma, UINT32 multisampleCount)
+		:TextureCore(textureType, width, height, depth, numMipmaps, format, usage, hwGamma, multisampleCount),
+		mD3DPool(D3DPOOL_MANAGED), mDynamicTextures(false), mHwGammaReadSupported(false), mHwGammaWriteSupported(false), 
+		mMultisampleType(D3DMULTISAMPLE_NONE), mMultisampleQuality(0), mIsBindableAsShaderResource(true)
 	{ }
 	{ }
 	
 	
-	D3D9Texture::~D3D9Texture()
+	D3D9TextureCore::~D3D9TextureCore()
 	{	
 	{	
 	}
 	}
 
 
-	void D3D9Texture::initialize_internal()
+	void D3D9TextureCore::initialize()
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
@@ -36,10 +36,10 @@ namespace BansheeEngine
 		}
 		}
 
 
 		BS_INC_RENDER_STAT_CAT(ResCreated, RenderStatObject_Texture);
 		BS_INC_RENDER_STAT_CAT(ResCreated, RenderStatObject_Texture);
-		Texture::initialize_internal();
+		TextureCore::initialize();
 	}
 	}
 
 
-	void D3D9Texture::destroy_internal()
+	void D3D9TextureCore::destroy()
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
@@ -62,25 +62,25 @@ namespace BansheeEngine
 		mSurfaceList.clear();
 		mSurfaceList.clear();
 
 
 		BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_Texture);
 		BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_Texture);
-		Texture::destroy_internal();
+		TextureCore::destroy();
 	}
 	}
 
 
-	PixelData D3D9Texture::lockImpl(GpuLockOptions options, UINT32 mipLevel, UINT32 face)
+	PixelData D3D9TextureCore::lockImpl(GpuLockOptions options, UINT32 mipLevel, UINT32 face)
 	{
 	{
-		if (mMultisampleCount > 0)
+		if (mProperties.getMultisampleCount() > 0)
 			BS_EXCEPT(InvalidStateException, "Multisampled textures cannot be accessed from the CPU directly.");
 			BS_EXCEPT(InvalidStateException, "Multisampled textures cannot be accessed from the CPU directly.");
 
 
 		if(mLockedBuffer != nullptr)
 		if(mLockedBuffer != nullptr)
 			BS_EXCEPT(InternalErrorException, "Trying to lock a buffer that's already locked.");
 			BS_EXCEPT(InternalErrorException, "Trying to lock a buffer that's already locked.");
 
 
-		if(getUsage() == TU_DEPTHSTENCIL)
+		if (mProperties.getUsage() == TU_DEPTHSTENCIL)
 			BS_EXCEPT(InternalErrorException, "Cannot lock a depth stencil texture.");
 			BS_EXCEPT(InternalErrorException, "Cannot lock a depth stencil texture.");
 
 
-		UINT32 mipWidth = mWidth >> mipLevel;
-		UINT32 mipHeight = mHeight >> mipLevel;
-		UINT32 mipDepth = mDepth >> mipLevel;
+		UINT32 mipWidth = mProperties.getWidth() >> mipLevel;
+		UINT32 mipHeight = mProperties.getHeight() >> mipLevel;
+		UINT32 mipDepth = mProperties.getDepth() >> mipLevel;
 
 
-		PixelData lockedArea(mipWidth, mipHeight, mipDepth, mFormat);
+		PixelData lockedArea(mipWidth, mipHeight, mipDepth, mProperties.getFormat());
 
 
 		mLockedBuffer = getBuffer(face, mipLevel);
 		mLockedBuffer = getBuffer(face, mipLevel);
 		lockedArea.setExternalBuffer((UINT8*)mLockedBuffer->lock(options));
 		lockedArea.setExternalBuffer((UINT8*)mLockedBuffer->lock(options));
@@ -88,7 +88,7 @@ namespace BansheeEngine
 		return lockedArea;
 		return lockedArea;
 	}
 	}
 	
 	
-	void D3D9Texture::unlockImpl()
+	void D3D9TextureCore::unlockImpl()
 	{
 	{
 		if(mLockedBuffer == nullptr)
 		if(mLockedBuffer == nullptr)
 			BS_EXCEPT(InternalErrorException, "Trying to unlock a buffer that's not locked.");
 			BS_EXCEPT(InternalErrorException, "Trying to unlock a buffer that's not locked.");
@@ -97,19 +97,19 @@ namespace BansheeEngine
 		mLockedBuffer = nullptr;
 		mLockedBuffer = nullptr;
 	}
 	}
 
 
-	void D3D9Texture::readData(PixelData& dest, UINT32 mipLevel, UINT32 face)
+	void D3D9TextureCore::readData(PixelData& dest, UINT32 mipLevel, UINT32 face)
 	{
 	{
-		if (mMultisampleCount > 0)
+		if (mProperties.getMultisampleCount() > 0)
 			BS_EXCEPT(InvalidStateException, "Multisampled textures cannot be accessed from the CPU directly.");
 			BS_EXCEPT(InvalidStateException, "Multisampled textures cannot be accessed from the CPU directly.");
 
 
-		if (mUsage == TU_DEPTHSTENCIL || mUsage == TU_RENDERTARGET) // Render targets cannot be locked normally
+		if (mProperties.getUsage() == TU_DEPTHSTENCIL || mProperties.getUsage() == TU_RENDERTARGET) // Render targets cannot be locked normally
 		{
 		{
 			IDirect3DDevice9* device = D3D9RenderSystem::getActiveD3D9Device();
 			IDirect3DDevice9* device = D3D9RenderSystem::getActiveD3D9Device();
 
 
 			D3D9PixelBuffer* sourceBuffer = static_cast<D3D9PixelBuffer*>(getBuffer(face, mipLevel).get());
 			D3D9PixelBuffer* sourceBuffer = static_cast<D3D9PixelBuffer*>(getBuffer(face, mipLevel).get());
 			
 			
-			UINT32 mipWidth = mWidth >> mipLevel;
-			UINT32 mipHeight = mHeight >> mipLevel;
+			UINT32 mipWidth = mProperties.getWidth() >> mipLevel;
+			UINT32 mipHeight = mProperties.getHeight() >> mipLevel;
 			D3DFORMAT format = chooseD3DFormat(device);
 			D3DFORMAT format = chooseD3DFormat(device);
 
 
 			// Note: I'm allocating and releasing a texture every time we read.
 			// Note: I'm allocating and releasing a texture every time we read.
@@ -141,7 +141,7 @@ namespace BansheeEngine
 				BS_EXCEPT(RenderingAPIException, "Failed to retrieve render target data: " + msg);
 				BS_EXCEPT(RenderingAPIException, "Failed to retrieve render target data: " + msg);
 			}
 			}
 
 
-			PixelData myData(mipWidth, mipHeight, 1, mFormat);
+			PixelData myData(mipWidth, mipHeight, 1, mProperties.getFormat());
 
 
 			D3DLOCKED_RECT lrect;
 			D3DLOCKED_RECT lrect;
 			hr = stagingSurface->LockRect(&lrect, nullptr, D3DLOCK_READONLY);
 			hr = stagingSurface->LockRect(&lrect, nullptr, D3DLOCK_READONLY);
@@ -188,12 +188,12 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
-	void D3D9Texture::writeData(const PixelData& src, UINT32 mipLevel, UINT32 face, bool discardWholeBuffer)
+	void D3D9TextureCore::writeData(const PixelData& src, UINT32 mipLevel, UINT32 face, bool discardWholeBuffer)
 	{
 	{
-		if (mMultisampleCount > 0)
+		if (mProperties.getMultisampleCount() > 0)
 			BS_EXCEPT(InvalidStateException, "Multisampled textures cannot be accessed from the CPU directly.");
 			BS_EXCEPT(InvalidStateException, "Multisampled textures cannot be accessed from the CPU directly.");
 
 
-		if(mUsage == TU_DYNAMIC || mUsage == TU_STATIC)
+		if (mProperties.getUsage() == TU_DYNAMIC || mProperties.getUsage() == TU_STATIC)
 		{
 		{
 			PixelData myData = lock(discardWholeBuffer ? GBL_WRITE_ONLY_DISCARD : GBL_WRITE_ONLY, mipLevel, face);
 			PixelData myData = lock(discardWholeBuffer ? GBL_WRITE_ONLY_DISCARD : GBL_WRITE_ONLY, mipLevel, face);
 			PixelUtil::bulkPixelConversion(src, myData);
 			PixelUtil::bulkPixelConversion(src, myData);
@@ -201,19 +201,21 @@ namespace BansheeEngine
 		}
 		}
 		else
 		else
 		{
 		{
-			BS_EXCEPT(RenderingAPIException, "Trying to write into a buffer with unsupported usage: " + toString(mUsage));
+			BS_EXCEPT(RenderingAPIException, "Trying to write into a buffer with unsupported usage: " + toString(mProperties.getUsage()));
 		}
 		}
 	}
 	}
 	
 	
-	void D3D9Texture::copyImpl(UINT32 srcFace, UINT32 srcMipLevel, UINT32 destFace, UINT32 destMipLevel, TexturePtr& target)
+	void D3D9TextureCore::copyImpl(UINT32 srcFace, UINT32 srcMipLevel, UINT32 destFace, UINT32 destMipLevel, const SPtr<TextureCore>& target)
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
-		if (getTextureType() == TEX_TYPE_1D || getTextureType() == TEX_TYPE_3D)
+		TextureType texType = mProperties.getTextureType();
+
+		if (texType == TEX_TYPE_1D || texType == TEX_TYPE_3D)
 			BS_EXCEPT(NotImplementedException, "Copy not implemented for 1D and 3D textures yet.");
 			BS_EXCEPT(NotImplementedException, "Copy not implemented for 1D and 3D textures yet.");
 
 
         HRESULT hr;
         HRESULT hr;
-		D3D9Texture *other = static_cast<D3D9Texture*>(target.get());
+		D3D9TextureCore* other = static_cast<D3D9TextureCore*>(target.get());
 
 
 		for (auto& resPair : mMapDeviceToTextureResources)
 		for (auto& resPair : mMapDeviceToTextureResources)
 		{
 		{
@@ -223,7 +225,7 @@ namespace BansheeEngine
 			IDirect3DSurface9 *sourceSurface = nullptr;
 			IDirect3DSurface9 *sourceSurface = nullptr;
 			IDirect3DSurface9 *destSurface = nullptr;
 			IDirect3DSurface9 *destSurface = nullptr;
 
 
-			if (getTextureType() == TEX_TYPE_2D && srcTextureResource->pNormTex != nullptr && dstTextureResource->pNormTex != nullptr)
+			if (texType == TEX_TYPE_2D && srcTextureResource->pNormTex != nullptr && dstTextureResource->pNormTex != nullptr)
 			{			
 			{			
 				if(FAILED(hr = srcTextureResource->pNormTex->GetSurfaceLevel(srcMipLevel, &sourceSurface)))
 				if(FAILED(hr = srcTextureResource->pNormTex->GetSurfaceLevel(srcMipLevel, &sourceSurface)))
 				{
 				{
@@ -237,7 +239,7 @@ namespace BansheeEngine
 					BS_EXCEPT(RenderingAPIException, "Cannot retrieve destination surface for copy: " + msg);
 					BS_EXCEPT(RenderingAPIException, "Cannot retrieve destination surface for copy: " + msg);
 				}
 				}
 			}
 			}
-			else if (getTextureType() == TEX_TYPE_CUBE_MAP && srcTextureResource->pCubeTex != nullptr && dstTextureResource->pCubeTex != nullptr)
+			else if (texType == TEX_TYPE_CUBE_MAP && srcTextureResource->pCubeTex != nullptr && dstTextureResource->pCubeTex != nullptr)
 			{				
 			{				
 				IDirect3DSurface9 *sourceSurface = nullptr;
 				IDirect3DSurface9 *sourceSurface = nullptr;
 				if (FAILED(hr = srcTextureResource->pCubeTex->GetCubeMapSurface((D3DCUBEMAP_FACES)srcFace, srcMipLevel, &sourceSurface)))
 				if (FAILED(hr = srcTextureResource->pCubeTex->GetCubeMapSurface((D3DCUBEMAP_FACES)srcFace, srcMipLevel, &sourceSurface)))
@@ -274,7 +276,7 @@ namespace BansheeEngine
 		}		
 		}		
 	}
 	}
 	
 	
-	D3D9Texture::TextureResources* D3D9Texture::getTextureResources(IDirect3DDevice9* d3d9Device)
+	D3D9TextureCore::TextureResources* D3D9TextureCore::getTextureResources(IDirect3DDevice9* d3d9Device)
 	{		
 	{		
 		auto iterFind = mMapDeviceToTextureResources.find(d3d9Device);
 		auto iterFind = mMapDeviceToTextureResources.find(d3d9Device);
 
 
@@ -284,7 +286,7 @@ namespace BansheeEngine
 		return iterFind->second;
 		return iterFind->second;
 	}
 	}
 
 
-	D3D9Texture::TextureResources* D3D9Texture::allocateTextureResources(IDirect3DDevice9* d3d9Device)
+	D3D9TextureCore::TextureResources* D3D9TextureCore::allocateTextureResources(IDirect3DDevice9* d3d9Device)
 	{
 	{
 		assert(mMapDeviceToTextureResources.find(d3d9Device) == mMapDeviceToTextureResources.end());
 		assert(mMapDeviceToTextureResources.find(d3d9Device) == mMapDeviceToTextureResources.end());
 
 
@@ -302,7 +304,7 @@ namespace BansheeEngine
 		return textureResources;
 		return textureResources;
 	}
 	}
 	
 	
-	void D3D9Texture::freeTextureResources(IDirect3DDevice9* d3d9Device, D3D9Texture::TextureResources* textureResources)
+	void D3D9TextureCore::freeTextureResources(IDirect3DDevice9* d3d9Device, D3D9TextureCore::TextureResources* textureResources)
 	{		
 	{		
 		D3D9_DEVICE_ACCESS_CRITICAL_SECTION
 		D3D9_DEVICE_ACCESS_CRITICAL_SECTION
 
 
@@ -323,14 +325,16 @@ namespace BansheeEngine
 		SAFE_RELEASE(textureResources->pDepthStencilSurface);
 		SAFE_RELEASE(textureResources->pDepthStencilSurface);
 	}
 	}
 	
 	
-	UINT32 D3D9Texture::calculateSize() const
+	UINT32 D3D9TextureCore::calculateSize() const
 	{
 	{
-		UINT32 instanceSize = getNumFaces() * PixelUtil::getMemorySize(mWidth, mHeight, mDepth, mFormat);
+		UINT32 instanceSize = mProperties.getNumFaces() * 
+			PixelUtil::getMemorySize(mProperties.getWidth(), mProperties.getHeight(), 
+			mProperties.getDepth(), mProperties.getFormat());
 
 
 		return instanceSize * (UINT32)mMapDeviceToTextureResources.size();
 		return instanceSize * (UINT32)mMapDeviceToTextureResources.size();
 	}
 	}
 	
 	
-	void D3D9Texture::determinePool()
+	void D3D9TextureCore::determinePool()
 	{
 	{
 		if (useDefaultPool())
 		if (useDefaultPool())
 			mD3DPool = D3DPOOL_DEFAULT;
 			mD3DPool = D3DPOOL_DEFAULT;
@@ -338,9 +342,9 @@ namespace BansheeEngine
 			mD3DPool = D3DPOOL_MANAGED;
 			mD3DPool = D3DPOOL_MANAGED;
 	}
 	}
 	
 	
-	void D3D9Texture::createInternalResources(IDirect3DDevice9* d3d9Device)
+	void D3D9TextureCore::createInternalResources(IDirect3DDevice9* d3d9Device)
 	{		
 	{		
-		switch (getTextureType())
+		switch (mProperties.getTextureType())
 		{
 		{
 		case TEX_TYPE_1D:
 		case TEX_TYPE_1D:
 		case TEX_TYPE_2D:
 		case TEX_TYPE_2D:
@@ -353,32 +357,39 @@ namespace BansheeEngine
 			createVolumeTex(d3d9Device);
 			createVolumeTex(d3d9Device);
 			break;
 			break;
 		default:
 		default:
-			destroy_internal();
 			BS_EXCEPT(InternalErrorException, "Unknown texture type.");
 			BS_EXCEPT(InternalErrorException, "Unknown texture type.");
 		}
 		}
 	}
 	}
 
 
-	void D3D9Texture::createNormTex(IDirect3DDevice9* d3d9Device)
+	void D3D9TextureCore::createNormTex(IDirect3DDevice9* d3d9Device)
 	{
 	{
-		assert(mWidth > 0 || mHeight > 0);
+		UINT32 width = mProperties.getWidth();
+		UINT32 height = mProperties.getHeight();
+		int texUsage = mProperties.getUsage();
+		UINT32 origNumMips = mProperties.getNumMipmaps();
+		PixelFormat format = mProperties.getFormat();
+		bool hwGamma = mProperties.isHardwareGammaEnabled();
+		UINT32 sampleCount = mProperties.getMultisampleCount();
+
+		assert(width > 0 || height > 0);
 
 
 		D3DFORMAT d3dPF = chooseD3DFormat(d3d9Device);
 		D3DFORMAT d3dPF = chooseD3DFormat(d3d9Device);
-		if(mFormat != D3D9Mappings::_getPF(d3dPF))
+		if (format != D3D9Mappings::_getPF(d3dPF))
 		{
 		{
-			BS_EXCEPT(RenderingAPIException, "Provided pixel format is not supported by the driver: " + toString(mFormat));
+			BS_EXCEPT(RenderingAPIException, "Provided pixel format is not supported by the driver: " + toString(format));
 		}
 		}
 
 
 		// Use D3DX to help us create the texture, this way it can adjust any relevant sizes
 		// Use D3DX to help us create the texture, this way it can adjust any relevant sizes
-		UINT numMips = (mNumMipmaps == MIP_UNLIMITED) ? D3DX_DEFAULT : mNumMipmaps + 1;
+		UINT numMips = (origNumMips == MIP_UNLIMITED) ? D3DX_DEFAULT : origNumMips + 1;
 
 
 		DWORD usage = 0;
 		DWORD usage = 0;
-		if((mUsage & TU_RENDERTARGET) != 0)
+		if ((texUsage & TU_RENDERTARGET) != 0)
 			usage = D3DUSAGE_RENDERTARGET;
 			usage = D3DUSAGE_RENDERTARGET;
-		else if((mUsage & TU_DEPTHSTENCIL) != 0)
+		else if ((texUsage & TU_DEPTHSTENCIL) != 0)
 			usage = D3DUSAGE_DEPTHSTENCIL;
 			usage = D3DUSAGE_DEPTHSTENCIL;
 
 
 		// Check dynamic textures
 		// Check dynamic textures
-		if (mUsage & TU_DYNAMIC)
+		if (texUsage & TU_DYNAMIC)
 		{
 		{
 			if (canUseDynamicTextures(d3d9Device, usage, D3DRTYPE_TEXTURE, d3dPF))
 			if (canUseDynamicTextures(d3d9Device, usage, D3DRTYPE_TEXTURE, d3dPF))
 			{
 			{
@@ -392,18 +403,18 @@ namespace BansheeEngine
 		}
 		}
 
 
 		// Check sRGB support
 		// Check sRGB support
-		if (mHwGamma)
+		if (hwGamma)
 		{
 		{
 			mHwGammaReadSupported = canUseHardwareGammaCorrection(d3d9Device, usage, D3DRTYPE_TEXTURE, d3dPF, false);
 			mHwGammaReadSupported = canUseHardwareGammaCorrection(d3d9Device, usage, D3DRTYPE_TEXTURE, d3dPF, false);
-			if (mUsage & TU_RENDERTARGET)
+			if (texUsage & TU_RENDERTARGET)
 				mHwGammaWriteSupported = canUseHardwareGammaCorrection(d3d9Device, usage, D3DRTYPE_TEXTURE, d3dPF, true);
 				mHwGammaWriteSupported = canUseHardwareGammaCorrection(d3d9Device, usage, D3DRTYPE_TEXTURE, d3dPF, true);
 		}
 		}
 
 
 		// Check multisample level
 		// Check multisample level
-		if ((mUsage & TU_RENDERTARGET) != 0 || (mUsage & TU_DEPTHSTENCIL) != 0)
+		if ((texUsage & TU_RENDERTARGET) != 0 || (texUsage & TU_DEPTHSTENCIL) != 0)
 		{
 		{
 			D3D9RenderSystem* rsys = static_cast<D3D9RenderSystem*>(BansheeEngine::RenderSystem::instancePtr());
 			D3D9RenderSystem* rsys = static_cast<D3D9RenderSystem*>(BansheeEngine::RenderSystem::instancePtr());
-			rsys->determineMultisampleSettings(d3d9Device, mMultisampleCount, d3dPF, false, &mMultisampleType, &mMultisampleQuality);
+			rsys->determineMultisampleSettings(d3d9Device, sampleCount, d3dPF, false, &mMultisampleType, &mMultisampleQuality);
 		}
 		}
 		else
 		else
 		{
 		{
@@ -415,7 +426,7 @@ namespace BansheeEngine
 		const D3DCAPS9& rkCurCaps = device->getD3D9DeviceCaps();			
 		const D3DCAPS9& rkCurCaps = device->getD3D9DeviceCaps();			
 
 
 		// Check if mip maps are supported on hardware
 		// Check if mip maps are supported on hardware
-		if (numMips > 1 && (!(rkCurCaps.TextureCaps & D3DPTEXTURECAPS_MIPMAP) || (mUsage & TU_RENDERTARGET) != 0 || (mUsage & TU_DEPTHSTENCIL) != 0))
+		if (numMips > 1 && (!(rkCurCaps.TextureCaps & D3DPTEXTURECAPS_MIPMAP) || (texUsage & TU_RENDERTARGET) != 0 || (texUsage & TU_DEPTHSTENCIL) != 0))
 		{
 		{
 			BS_EXCEPT(InvalidParametersException, "Invalid number of mipmaps. Maximum allowed is: 0");
 			BS_EXCEPT(InvalidParametersException, "Invalid number of mipmaps. Maximum allowed is: 0");
 		}
 		}
@@ -430,10 +441,10 @@ namespace BansheeEngine
 		else
 		else
 			textureResources = allocateTextureResources(d3d9Device);
 			textureResources = allocateTextureResources(d3d9Device);
 
 
-		if ((mUsage & TU_RENDERTARGET) != 0 && (mMultisampleType != D3DMULTISAMPLE_NONE))
+		if ((texUsage & TU_RENDERTARGET) != 0 && (mMultisampleType != D3DMULTISAMPLE_NONE))
 		{
 		{
 			// Create AA surface
 			// Create AA surface
-			HRESULT hr = d3d9Device->CreateRenderTarget(mWidth, mHeight, d3dPF, 
+			HRESULT hr = d3d9Device->CreateRenderTarget(width, height, d3dPF, 
 				mMultisampleType, mMultisampleQuality,
 				mMultisampleType, mMultisampleQuality,
 				FALSE,
 				FALSE,
 				&textureResources->pMultisampleSurface, NULL);
 				&textureResources->pMultisampleSurface, NULL);
@@ -445,7 +456,6 @@ namespace BansheeEngine
 			hr = textureResources->pMultisampleSurface->GetDesc(&desc);
 			hr = textureResources->pMultisampleSurface->GetDesc(&desc);
 			if (FAILED(hr))
 			if (FAILED(hr))
 			{
 			{
-				destroy_internal();
 				BS_EXCEPT(RenderingAPIException, "Can't get texture description: " + String(DXGetErrorDescription(hr)));
 				BS_EXCEPT(RenderingAPIException, "Can't get texture description: " + String(DXGetErrorDescription(hr)));
 			}
 			}
 
 
@@ -453,10 +463,10 @@ namespace BansheeEngine
 
 
 			mIsBindableAsShaderResource = false; // Cannot bind AA surfaces
 			mIsBindableAsShaderResource = false; // Cannot bind AA surfaces
 		}
 		}
-		else if ((mUsage & TU_DEPTHSTENCIL) != 0 && (mMultisampleType != D3DMULTISAMPLE_NONE))
+		else if ((texUsage & TU_DEPTHSTENCIL) != 0 && (mMultisampleType != D3DMULTISAMPLE_NONE))
 		{
 		{
 			// Create AA depth stencil surface
 			// Create AA depth stencil surface
-			HRESULT hr = d3d9Device->CreateDepthStencilSurface(mWidth, mHeight, d3dPF, 
+			HRESULT hr = d3d9Device->CreateDepthStencilSurface(width, height, d3dPF, 
 				mMultisampleType, mMultisampleQuality,
 				mMultisampleType, mMultisampleQuality,
 				FALSE, 
 				FALSE, 
 				&textureResources->pDepthStencilSurface, NULL);
 				&textureResources->pDepthStencilSurface, NULL);
@@ -469,7 +479,6 @@ namespace BansheeEngine
 			hr = textureResources->pDepthStencilSurface->GetDesc(&desc);
 			hr = textureResources->pDepthStencilSurface->GetDesc(&desc);
 			if (FAILED(hr))
 			if (FAILED(hr))
 			{
 			{
-				destroy_internal();
 				BS_EXCEPT(RenderingAPIException, "Can't get texture description: " + String(DXGetErrorDescription(hr)));
 				BS_EXCEPT(RenderingAPIException, "Can't get texture description: " + String(DXGetErrorDescription(hr)));
 			}
 			}
 
 
@@ -480,19 +489,17 @@ namespace BansheeEngine
 		else
 		else
 		{
 		{
 			// Create normal texture
 			// Create normal texture
-			HRESULT hr = D3DXCreateTexture(d3d9Device, (UINT)mWidth, (UINT)mHeight,	numMips,
+			HRESULT hr = D3DXCreateTexture(d3d9Device, (UINT)width, (UINT)height, numMips,
 				usage, d3dPF, mD3DPool, &textureResources->pNormTex);
 				usage, d3dPF, mD3DPool, &textureResources->pNormTex);
 
 
 			if (FAILED(hr))
 			if (FAILED(hr))
 			{
 			{
-				destroy_internal();
 				BS_EXCEPT(RenderingAPIException, "Error creating texture: " + String(DXGetErrorDescription(hr)));
 				BS_EXCEPT(RenderingAPIException, "Error creating texture: " + String(DXGetErrorDescription(hr)));
 			}
 			}
 
 
 			hr = textureResources->pNormTex->QueryInterface(IID_IDirect3DBaseTexture9, (void **)&textureResources->pBaseTex);
 			hr = textureResources->pNormTex->QueryInterface(IID_IDirect3DBaseTexture9, (void **)&textureResources->pBaseTex);
 			if (FAILED(hr))
 			if (FAILED(hr))
 			{
 			{
-				destroy_internal();
 				BS_EXCEPT(RenderingAPIException, "Can't get base texture: " + String(DXGetErrorDescription(hr)));
 				BS_EXCEPT(RenderingAPIException, "Can't get base texture: " + String(DXGetErrorDescription(hr)));
 			}
 			}
 
 
@@ -501,7 +508,6 @@ namespace BansheeEngine
 			hr = textureResources->pNormTex->GetLevelDesc(0, &desc);
 			hr = textureResources->pNormTex->GetLevelDesc(0, &desc);
 			if (FAILED(hr))
 			if (FAILED(hr))
 			{
 			{
-				destroy_internal();
 				BS_EXCEPT(RenderingAPIException, "Can't get texture description: " + String(DXGetErrorDescription(hr)));
 				BS_EXCEPT(RenderingAPIException, "Can't get texture description: " + String(DXGetErrorDescription(hr)));
 			}
 			}
 
 
@@ -509,24 +515,31 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 	
 	
-	void D3D9Texture::createCubeTex(IDirect3DDevice9* d3d9Device)
+	void D3D9TextureCore::createCubeTex(IDirect3DDevice9* d3d9Device)
 	{
 	{
-		assert(mWidth > 0 || mHeight > 0);
+		UINT32 width = mProperties.getWidth();
+		UINT32 height = mProperties.getHeight();
+		int texUsage = mProperties.getUsage();
+		UINT32 origNumMips = mProperties.getNumMipmaps();
+		PixelFormat format = mProperties.getFormat();
+		bool hwGamma = mProperties.isHardwareGammaEnabled();
+
+		assert(width > 0 || height > 0);
 
 
 		D3DFORMAT d3dPF = chooseD3DFormat(d3d9Device);
 		D3DFORMAT d3dPF = chooseD3DFormat(d3d9Device);
-		if(mFormat != D3D9Mappings::_getPF(d3dPF))
+		if (format != D3D9Mappings::_getPF(d3dPF))
 		{
 		{
-			BS_EXCEPT(RenderingAPIException, "Provided pixel format is not supported by the driver: " + toString(mFormat));
+			BS_EXCEPT(RenderingAPIException, "Provided pixel format is not supported by the driver: " + toString(format));
 		}
 		}
 
 
 		// Use D3DX to help us create the texture, this way it can adjust any relevant sizes
 		// Use D3DX to help us create the texture, this way it can adjust any relevant sizes
-		DWORD usage = (mUsage & TU_RENDERTARGET) ? D3DUSAGE_RENDERTARGET : 0;
-		usage |= (mUsage & TU_DEPTHSTENCIL) ? D3DUSAGE_DEPTHSTENCIL : 0;
+		DWORD usage = (texUsage & TU_RENDERTARGET) ? D3DUSAGE_RENDERTARGET : 0;
+		usage |= (texUsage & TU_DEPTHSTENCIL) ? D3DUSAGE_DEPTHSTENCIL : 0;
 
 
-		UINT numMips = (mNumMipmaps == MIP_UNLIMITED) ? D3DX_DEFAULT : mNumMipmaps + 1;
+		UINT numMips = (origNumMips == MIP_UNLIMITED) ? D3DX_DEFAULT : origNumMips + 1;
 
 
 		// Check dynamic textures
 		// Check dynamic textures
-		if (mUsage & TU_DYNAMIC)
+		if (texUsage & TU_DYNAMIC)
 		{
 		{
 			if (canUseDynamicTextures(d3d9Device, usage, D3DRTYPE_CUBETEXTURE, d3dPF))
 			if (canUseDynamicTextures(d3d9Device, usage, D3DRTYPE_CUBETEXTURE, d3dPF))
 			{
 			{
@@ -540,10 +553,10 @@ namespace BansheeEngine
 		}
 		}
 
 
 		// Check sRGB support
 		// Check sRGB support
-		if (mHwGamma)
+		if (hwGamma)
 		{
 		{
 			mHwGammaReadSupported = canUseHardwareGammaCorrection(d3d9Device, usage, D3DRTYPE_CUBETEXTURE, d3dPF, false);
 			mHwGammaReadSupported = canUseHardwareGammaCorrection(d3d9Device, usage, D3DRTYPE_CUBETEXTURE, d3dPF, false);
-			if (mUsage & TU_RENDERTARGET)
+			if (texUsage & TU_RENDERTARGET)
 				mHwGammaWriteSupported = canUseHardwareGammaCorrection(d3d9Device, usage, D3DRTYPE_CUBETEXTURE, d3dPF, true);
 				mHwGammaWriteSupported = canUseHardwareGammaCorrection(d3d9Device, usage, D3DRTYPE_CUBETEXTURE, d3dPF, true);
 		}
 		}
 
 
@@ -571,19 +584,17 @@ namespace BansheeEngine
 			textureResources = allocateTextureResources(d3d9Device);
 			textureResources = allocateTextureResources(d3d9Device);
 
 
 		// Create the texture
 		// Create the texture
-		HRESULT hr = D3DXCreateCubeTexture(d3d9Device, (UINT)mWidth, numMips,
+		HRESULT hr = D3DXCreateCubeTexture(d3d9Device, (UINT)width, numMips,
 				usage, d3dPF, mD3DPool, &textureResources->pCubeTex);
 				usage, d3dPF, mD3DPool, &textureResources->pCubeTex);
 
 
 		if (FAILED(hr))
 		if (FAILED(hr))
 		{
 		{
-			destroy_internal();
 			BS_EXCEPT(RenderingAPIException, "Error creating texture: " + String(DXGetErrorDescription(hr)));
 			BS_EXCEPT(RenderingAPIException, "Error creating texture: " + String(DXGetErrorDescription(hr)));
 		}
 		}
 
 
 		hr = textureResources->pCubeTex->QueryInterface(IID_IDirect3DBaseTexture9, (void **)&textureResources->pBaseTex);
 		hr = textureResources->pCubeTex->QueryInterface(IID_IDirect3DBaseTexture9, (void **)&textureResources->pBaseTex);
 		if (FAILED(hr))
 		if (FAILED(hr))
 		{
 		{
-			destroy_internal();
 			BS_EXCEPT(RenderingAPIException, "Can't get base texture: " + String(DXGetErrorDescription(hr)));
 			BS_EXCEPT(RenderingAPIException, "Can't get base texture: " + String(DXGetErrorDescription(hr)));
 		}
 		}
 		
 		
@@ -592,35 +603,42 @@ namespace BansheeEngine
 		hr = textureResources->pCubeTex->GetLevelDesc(0, &desc);
 		hr = textureResources->pCubeTex->GetLevelDesc(0, &desc);
 		if (FAILED(hr))
 		if (FAILED(hr))
 		{
 		{
-			destroy_internal();
 			BS_EXCEPT(RenderingAPIException, "Can't get texture description: " + String(DXGetErrorDescription(hr)));
 			BS_EXCEPT(RenderingAPIException, "Can't get texture description: " + String(DXGetErrorDescription(hr)));
 		}
 		}
 
 
 		setFinalAttributes(d3d9Device, textureResources, desc.Width, desc.Height, 1, D3D9Mappings::_getPF(desc.Format));		
 		setFinalAttributes(d3d9Device, textureResources, desc.Width, desc.Height, 1, D3D9Mappings::_getPF(desc.Format));		
 	}
 	}
 	
 	
-	void D3D9Texture::createVolumeTex(IDirect3DDevice9* d3d9Device)
+	void D3D9TextureCore::createVolumeTex(IDirect3DDevice9* d3d9Device)
 	{
 	{
-		assert(mWidth > 0 && mHeight > 0 && mDepth>0);
+		UINT32 width = mProperties.getWidth();
+		UINT32 height = mProperties.getHeight();
+		UINT32 depth = mProperties.getDepth();
+		int texUsage = mProperties.getUsage();
+		UINT32 origNumMips = mProperties.getNumMipmaps();
+		PixelFormat format = mProperties.getFormat();
+		bool hwGamma = mProperties.isHardwareGammaEnabled();
+
+		assert(width > 0 && height > 0 && depth > 0);
 
 
-		if (mUsage & TU_RENDERTARGET)
+		if (texUsage & TU_RENDERTARGET)
 			BS_EXCEPT(RenderingAPIException, "D3D9 Volume texture can not be created as render target !!");
 			BS_EXCEPT(RenderingAPIException, "D3D9 Volume texture can not be created as render target !!");
 
 
-		if (mUsage & TU_DEPTHSTENCIL)
+		if (texUsage & TU_DEPTHSTENCIL)
 			BS_EXCEPT(RenderingAPIException, "D3D9 Volume texture can not be created as a depth stencil target !!");
 			BS_EXCEPT(RenderingAPIException, "D3D9 Volume texture can not be created as a depth stencil target !!");
 
 
 		D3DFORMAT d3dPF = chooseD3DFormat(d3d9Device);
 		D3DFORMAT d3dPF = chooseD3DFormat(d3d9Device);
-		if(mFormat != D3D9Mappings::_getPF(d3dPF))
+		if(format != D3D9Mappings::_getPF(d3dPF))
 		{
 		{
-			BS_EXCEPT(RenderingAPIException, "Provided pixel format is not supported by the driver: " + toString(mFormat));
+			BS_EXCEPT(RenderingAPIException, "Provided pixel format is not supported by the driver: " + toString(format));
 		}
 		}
 
 
 		// Use D3DX to help us create the texture, this way it can adjust any relevant sizes
 		// Use D3DX to help us create the texture, this way it can adjust any relevant sizes
-		DWORD usage = (mUsage & TU_RENDERTARGET) ? D3DUSAGE_RENDERTARGET : 0;
-		UINT numMips = (mNumMipmaps == MIP_UNLIMITED) ? D3DX_DEFAULT : mNumMipmaps + 1;
+		DWORD usage = (texUsage & TU_RENDERTARGET) ? D3DUSAGE_RENDERTARGET : 0;
+		UINT numMips = (origNumMips == MIP_UNLIMITED) ? D3DX_DEFAULT : origNumMips + 1;
 
 
 		// Check dynamic textures
 		// Check dynamic textures
-		if (mUsage & TU_DYNAMIC)
+		if (texUsage & TU_DYNAMIC)
 		{
 		{
 			if (canUseDynamicTextures(d3d9Device, usage, D3DRTYPE_VOLUMETEXTURE, d3dPF))
 			if (canUseDynamicTextures(d3d9Device, usage, D3DRTYPE_VOLUMETEXTURE, d3dPF))
 			{
 			{
@@ -634,10 +652,10 @@ namespace BansheeEngine
 		}
 		}
 
 
 		// Check sRGB support
 		// Check sRGB support
-		if (mHwGamma)
+		if (hwGamma)
 		{
 		{
 			mHwGammaReadSupported = canUseHardwareGammaCorrection(d3d9Device, usage, D3DRTYPE_VOLUMETEXTURE, d3dPF, false);
 			mHwGammaReadSupported = canUseHardwareGammaCorrection(d3d9Device, usage, D3DRTYPE_VOLUMETEXTURE, d3dPF, false);
-			if (mUsage & TU_RENDERTARGET)
+			if (texUsage & TU_RENDERTARGET)
 				mHwGammaWriteSupported = canUseHardwareGammaCorrection(d3d9Device, usage, D3DRTYPE_VOLUMETEXTURE, d3dPF, true);
 				mHwGammaWriteSupported = canUseHardwareGammaCorrection(d3d9Device, usage, D3DRTYPE_VOLUMETEXTURE, d3dPF, true);
 		}
 		}
 
 
@@ -661,19 +679,17 @@ namespace BansheeEngine
 			textureResources = allocateTextureResources(d3d9Device);
 			textureResources = allocateTextureResources(d3d9Device);
 
 
 		// Create the texture
 		// Create the texture
-		HRESULT hr = D3DXCreateVolumeTexture(d3d9Device, (UINT)mWidth, (UINT)mHeight, (UINT)mDepth,
+		HRESULT hr = D3DXCreateVolumeTexture(d3d9Device, (UINT)width, (UINT)height, (UINT)depth,
 				numMips, usage, d3dPF, mD3DPool, &textureResources->pVolumeTex);
 				numMips, usage, d3dPF, mD3DPool, &textureResources->pVolumeTex);
 
 
 		if (FAILED(hr))
 		if (FAILED(hr))
 		{
 		{
-			destroy_internal();
 			BS_EXCEPT(RenderingAPIException, "Error creating texture: " + String(DXGetErrorDescription(hr)));
 			BS_EXCEPT(RenderingAPIException, "Error creating texture: " + String(DXGetErrorDescription(hr)));
 		}
 		}
 
 
 		hr = textureResources->pVolumeTex->QueryInterface(IID_IDirect3DBaseTexture9, (void**)&textureResources->pBaseTex);
 		hr = textureResources->pVolumeTex->QueryInterface(IID_IDirect3DBaseTexture9, (void**)&textureResources->pBaseTex);
 		if (FAILED(hr))
 		if (FAILED(hr))
 		{
 		{
-			destroy_internal();
 			BS_EXCEPT(RenderingAPIException, "Can't get base texture: " + String(DXGetErrorDescription(hr)));
 			BS_EXCEPT(RenderingAPIException, "Can't get base texture: " + String(DXGetErrorDescription(hr)));
 		}
 		}
 		
 		
@@ -682,40 +698,40 @@ namespace BansheeEngine
 		hr = textureResources->pVolumeTex->GetLevelDesc(0, &desc);
 		hr = textureResources->pVolumeTex->GetLevelDesc(0, &desc);
 		if (FAILED(hr))
 		if (FAILED(hr))
 		{
 		{
-			destroy_internal();
 			BS_EXCEPT(RenderingAPIException, "Can't get texture description: " + String(DXGetErrorDescription(hr)));
 			BS_EXCEPT(RenderingAPIException, "Can't get texture description: " + String(DXGetErrorDescription(hr)));
 		}
 		}
 
 
 		setFinalAttributes(d3d9Device, textureResources, desc.Width, desc.Height, desc.Depth, D3D9Mappings::_getPF(desc.Format));
 		setFinalAttributes(d3d9Device, textureResources, desc.Width, desc.Height, desc.Depth, D3D9Mappings::_getPF(desc.Format));
 	}
 	}
 
 
-	void D3D9Texture::setFinalAttributes(IDirect3DDevice9* d3d9Device, TextureResources* textureResources,
+	void D3D9TextureCore::setFinalAttributes(IDirect3DDevice9* d3d9Device, TextureResources* textureResources,
 		UINT32 width, UINT32 height, UINT32 depth, PixelFormat format)
 		UINT32 width, UINT32 height, UINT32 depth, PixelFormat format)
 	{ 
 	{ 
-		if(width != mWidth || height != mHeight || depth != mDepth)
+		if(width != mProperties.getWidth() || height != mProperties.getHeight() || depth != mProperties.getDepth())
 		{
 		{
 			BS_EXCEPT(InternalErrorException, "Wanted and created textures sizes don't match!" \
 			BS_EXCEPT(InternalErrorException, "Wanted and created textures sizes don't match!" \
-				"Width: " + toString(width) + "/" + toString(mWidth) +
-				"Height: " + toString(height) + "/" + toString(mHeight) +
-				"Depth: " + toString(depth) + "/" + toString(mDepth));
+				"Width: " + toString(width) + "/" + toString(mProperties.getWidth()) +
+				"Height: " + toString(height) + "/" + toString(mProperties.getHeight()) +
+				"Depth: " + toString(depth) + "/" + toString(mProperties.getDepth()));
 		}
 		}
 
 
-		if(format != mFormat)
+		if(format != mProperties.getFormat())
 		{
 		{
-			BS_EXCEPT(InternalErrorException, "Wanted and created texture formats don't match! " + toString(format) + "/" + toString(mFormat));
+			BS_EXCEPT(InternalErrorException, "Wanted and created texture formats don't match! " + 
+				toString(format) + "/" + toString(mProperties.getFormat()));
 		}
 		}
 		
 		
 		createSurfaceList(d3d9Device, textureResources);
 		createSurfaceList(d3d9Device, textureResources);
 	}
 	}
 	
 	
-	D3DTEXTUREFILTERTYPE D3D9Texture::getBestFilterMethod(IDirect3DDevice9* d3d9Device)
+	D3DTEXTUREFILTERTYPE D3D9TextureCore::getBestFilterMethod(IDirect3DDevice9* d3d9Device)
 	{
 	{
 		D3D9Device* device = D3D9RenderSystem::getDeviceManager()->getDeviceFromD3D9Device(d3d9Device);
 		D3D9Device* device = D3D9RenderSystem::getDeviceManager()->getDeviceFromD3D9Device(d3d9Device);
 		const D3DCAPS9& deviceCaps = device->getD3D9DeviceCaps();			
 		const D3DCAPS9& deviceCaps = device->getD3D9DeviceCaps();			
 		
 		
 		DWORD filterCaps = 0;
 		DWORD filterCaps = 0;
 
 
-		switch (getTextureType())
+		switch (mProperties.getTextureType())
 		{
 		{
 		case TEX_TYPE_1D:		
 		case TEX_TYPE_1D:		
 			// Same as 2D
 			// Same as 2D
@@ -748,7 +764,7 @@ namespace BansheeEngine
 		return D3DTEXF_POINT;
 		return D3DTEXF_POINT;
 	}
 	}
 	
 	
-	bool D3D9Texture::canUseDynamicTextures(IDirect3DDevice9* d3d9Device, DWORD srcUsage, D3DRESOURCETYPE srcType, 
+	bool D3D9TextureCore::canUseDynamicTextures(IDirect3DDevice9* d3d9Device, DWORD srcUsage, D3DRESOURCETYPE srcType, 
 		D3DFORMAT srcFormat)
 		D3DFORMAT srcFormat)
 	{		
 	{		
 		IDirect3D9* pD3D = nullptr;
 		IDirect3D9* pD3D = nullptr;
@@ -770,7 +786,7 @@ namespace BansheeEngine
 		return hr == D3D_OK;
 		return hr == D3D_OK;
 	}
 	}
 	
 	
-	bool D3D9Texture::canUseHardwareGammaCorrection(IDirect3DDevice9* d3d9Device, DWORD srcUsage, 
+	bool D3D9TextureCore::canUseHardwareGammaCorrection(IDirect3DDevice9* d3d9Device, DWORD srcUsage, 
 		D3DRESOURCETYPE srcType, D3DFORMAT srcFormat, bool forwriting)
 		D3DRESOURCETYPE srcType, D3DFORMAT srcFormat, bool forwriting)
 	{
 	{
 		IDirect3D9* pD3D = nullptr;
 		IDirect3D9* pD3D = nullptr;
@@ -799,7 +815,7 @@ namespace BansheeEngine
 		return hr == D3D_OK;
 		return hr == D3D_OK;
 	}
 	}
 	
 	
-	bool D3D9Texture::canAutoGenMipmaps(IDirect3DDevice9* d3d9Device, DWORD srcUsage, D3DRESOURCETYPE srcType, D3DFORMAT srcFormat)
+	bool D3D9TextureCore::canAutoGenMipmaps(IDirect3DDevice9* d3d9Device, DWORD srcUsage, D3DRESOURCETYPE srcType, D3DFORMAT srcFormat)
 	{
 	{
 		IDirect3D9* pD3D = nullptr;
 		IDirect3D9* pD3D = nullptr;
 
 
@@ -827,30 +843,34 @@ namespace BansheeEngine
 			return false;
 			return false;
 	}
 	}
 	
 	
-	D3DFORMAT D3D9Texture::chooseD3DFormat(IDirect3DDevice9* d3d9Device)
+	D3DFORMAT D3D9TextureCore::chooseD3DFormat(IDirect3DDevice9* d3d9Device)
 	{		
 	{		
 		// Choose frame buffer pixel format in case PF_UNKNOWN was requested
 		// Choose frame buffer pixel format in case PF_UNKNOWN was requested
-		if(mFormat == PF_UNKNOWN)
+		if(mProperties.getFormat() == PF_UNKNOWN)
 		{	
 		{	
 			D3D9Device* device = D3D9RenderSystem::getDeviceManager()->getDeviceFromD3D9Device(d3d9Device);
 			D3D9Device* device = D3D9RenderSystem::getDeviceManager()->getDeviceFromD3D9Device(d3d9Device);
 			
 			
-			if((mUsage & TU_DEPTHSTENCIL) != 0)
+			if((mProperties.getUsage() & TU_DEPTHSTENCIL) != 0)
 				return device->getDepthStencilFormat();
 				return device->getDepthStencilFormat();
 			else
 			else
 				return device->getBackBufferFormat();		
 				return device->getBackBufferFormat();		
 		}
 		}
 
 
 		// Choose closest supported D3D format as a D3D format
 		// Choose closest supported D3D format as a D3D format
-		return D3D9Mappings::_getPF(D3D9Mappings::_getClosestSupportedPF(mFormat));
+		return D3D9Mappings::_getPF(D3D9Mappings::_getClosestSupportedPF(mProperties.getFormat()));
 	}
 	}
 	
 	
-	void D3D9Texture::createSurfaceList(IDirect3DDevice9* d3d9Device, TextureResources* textureResources)
+	void D3D9TextureCore::createSurfaceList(IDirect3DDevice9* d3d9Device, TextureResources* textureResources)
 	{
 	{
+		int texUsage = mProperties.getUsage();
+		TextureType texType = mProperties.getTextureType();
+		UINT32 numMips = mProperties.getNumMipmaps();
+
 		assert(textureResources != nullptr);
 		assert(textureResources != nullptr);
 
 
 		// Need to know static / dynamic
 		// Need to know static / dynamic
 		UINT32 usage;
 		UINT32 usage;
-		if ((mUsage & TU_DYNAMIC) && mDynamicTextures)
+		if ((texUsage & TU_DYNAMIC) && mDynamicTextures)
 		{
 		{
 			usage = GBU_DYNAMIC;
 			usage = GBU_DYNAMIC;
 		}
 		}
@@ -859,23 +879,23 @@ namespace BansheeEngine
 			usage = GBU_STATIC;
 			usage = GBU_STATIC;
 		}
 		}
 
 
-		if (mUsage & TU_RENDERTARGET)
+		if (texUsage & TU_RENDERTARGET)
 		{
 		{
 			usage |= TU_RENDERTARGET;
 			usage |= TU_RENDERTARGET;
 		}
 		}
-		else if(mUsage & TU_DEPTHSTENCIL)
+		else if (texUsage & TU_DEPTHSTENCIL)
 		{
 		{
 			usage |= TU_RENDERTARGET;
 			usage |= TU_RENDERTARGET;
 		}
 		}
 		
 		
-		UINT32 surfaceCount  = static_cast<UINT32>((getNumFaces() * (mNumMipmaps + 1)));
+		UINT32 surfaceCount = static_cast<UINT32>((mProperties.getNumFaces() * (numMips + 1)));
 		bool updateOldList = mSurfaceList.size() == surfaceCount;
 		bool updateOldList = mSurfaceList.size() == surfaceCount;
 		if(!updateOldList)
 		if(!updateOldList)
 		{			
 		{			
 			mSurfaceList.clear();
 			mSurfaceList.clear();
-			for(UINT32 face = 0; face < getNumFaces(); face++)
+			for (UINT32 face = 0; face < mProperties.getNumFaces(); face++)
 			{
 			{
-				for(UINT32 mip = 0; mip <= mNumMipmaps; mip++)
+				for (UINT32 mip = 0; mip <= numMips; mip++)
 				{
 				{
 					mSurfaceList.push_back(bs_shared_ptr<D3D9PixelBuffer>((GpuBufferUsage)usage, this));
 					mSurfaceList.push_back(bs_shared_ptr<D3D9PixelBuffer>((GpuBufferUsage)usage, this));
 				}
 				}
@@ -885,19 +905,19 @@ namespace BansheeEngine
 		IDirect3DSurface9* surface = nullptr;
 		IDirect3DSurface9* surface = nullptr;
 		IDirect3DVolume9* volume = nullptr;
 		IDirect3DVolume9* volume = nullptr;
 
 
-		if((mUsage & TU_RENDERTARGET) != 0 && (mMultisampleType != D3DMULTISAMPLE_NONE))
+		if ((texUsage & TU_RENDERTARGET) != 0 && (mMultisampleType != D3DMULTISAMPLE_NONE))
 		{
 		{
 			assert(textureResources->pMultisampleSurface);
 			assert(textureResources->pMultisampleSurface);
-			assert(getTextureType() == TEX_TYPE_2D);
+			assert(texUsage == TEX_TYPE_2D);
 
 
 			D3D9PixelBuffer* currPixelBuffer = static_cast<D3D9PixelBuffer*>(mSurfaceList[0].get());
 			D3D9PixelBuffer* currPixelBuffer = static_cast<D3D9PixelBuffer*>(mSurfaceList[0].get());
 
 
 			currPixelBuffer->bind(d3d9Device, textureResources->pMultisampleSurface, textureResources->pBaseTex);
 			currPixelBuffer->bind(d3d9Device, textureResources->pMultisampleSurface, textureResources->pBaseTex);
 		}
 		}
-		else if((mUsage & TU_DEPTHSTENCIL) != 0 && (mMultisampleType != D3DMULTISAMPLE_NONE))
+		else if ((texUsage & TU_DEPTHSTENCIL) != 0 && (mMultisampleType != D3DMULTISAMPLE_NONE))
 		{
 		{
 			assert(textureResources->pDepthStencilSurface);
 			assert(textureResources->pDepthStencilSurface);
-			assert(getTextureType() == TEX_TYPE_2D);
+			assert(texUsage == TEX_TYPE_2D);
 
 
 			D3D9PixelBuffer* currPixelBuffer = static_cast<D3D9PixelBuffer*>(mSurfaceList[0].get());
 			D3D9PixelBuffer* currPixelBuffer = static_cast<D3D9PixelBuffer*>(mSurfaceList[0].get());
 
 
@@ -908,19 +928,19 @@ namespace BansheeEngine
 			assert(textureResources->pBaseTex);
 			assert(textureResources->pBaseTex);
 
 
 			UINT32 numCreatedMips = textureResources->pBaseTex->GetLevelCount() - 1;
 			UINT32 numCreatedMips = textureResources->pBaseTex->GetLevelCount() - 1;
-			if(numCreatedMips != mNumMipmaps)
+			if (numCreatedMips != numMips)
 			{
 			{
 				BS_EXCEPT(InternalErrorException, "Number of created and wanted mip map levels doesn't match: " + 
 				BS_EXCEPT(InternalErrorException, "Number of created and wanted mip map levels doesn't match: " + 
-					toString(numCreatedMips) + "/" + toString(mNumMipmaps));
+					toString(numCreatedMips) + "/" + toString(numMips));
 			}
 			}
 
 
-			switch(getTextureType()) 
+			switch(texType) 
 			{
 			{
 			case TEX_TYPE_2D:
 			case TEX_TYPE_2D:
 			case TEX_TYPE_1D:
 			case TEX_TYPE_1D:
 				assert(textureResources->pNormTex);
 				assert(textureResources->pNormTex);
 
 
-				for(UINT32 mip = 0; mip <= mNumMipmaps; mip++)
+				for (UINT32 mip = 0; mip <= numMips; mip++)
 				{
 				{
 					if(textureResources->pNormTex->GetSurfaceLevel(static_cast<UINT>(mip), &surface) != D3D_OK)
 					if(textureResources->pNormTex->GetSurfaceLevel(static_cast<UINT>(mip), &surface) != D3D_OK)
 						BS_EXCEPT(RenderingAPIException, "Get surface level failed");
 						BS_EXCEPT(RenderingAPIException, "Get surface level failed");
@@ -938,12 +958,12 @@ namespace BansheeEngine
 
 
 				for(UINT32 face = 0; face < 6; face++)
 				for(UINT32 face = 0; face < 6; face++)
 				{
 				{
-					for(UINT32 mip = 0; mip <= mNumMipmaps; mip++)
+					for (UINT32 mip = 0; mip <= numMips; mip++)
 					{
 					{
 						if(textureResources->pCubeTex->GetCubeMapSurface((D3DCUBEMAP_FACES)face, static_cast<UINT>(mip), &surface) != D3D_OK)
 						if(textureResources->pCubeTex->GetCubeMapSurface((D3DCUBEMAP_FACES)face, static_cast<UINT>(mip), &surface) != D3D_OK)
 							BS_EXCEPT(RenderingAPIException, "Get cubemap surface failed");
 							BS_EXCEPT(RenderingAPIException, "Get cubemap surface failed");
 
 
-						UINT32 idx = face*(mNumMipmaps + 1) + mip;
+						UINT32 idx = face*(numMips + 1) + mip;
 						D3D9PixelBuffer* currPixelBuffer = static_cast<D3D9PixelBuffer*>(mSurfaceList[idx].get());
 						D3D9PixelBuffer* currPixelBuffer = static_cast<D3D9PixelBuffer*>(mSurfaceList[idx].get());
 
 
 						currPixelBuffer->bind(d3d9Device, surface, textureResources->pBaseTex);
 						currPixelBuffer->bind(d3d9Device, surface, textureResources->pBaseTex);
@@ -955,7 +975,7 @@ namespace BansheeEngine
 			case TEX_TYPE_3D:
 			case TEX_TYPE_3D:
 				assert(textureResources->pVolumeTex);
 				assert(textureResources->pVolumeTex);
 
 
-				for(UINT32 mip = 0; mip <= mNumMipmaps; mip++)
+				for (UINT32 mip = 0; mip <= numMips; mip++)
 				{
 				{
 					if(textureResources->pVolumeTex->GetVolumeLevel(static_cast<UINT>(mip), &volume) != D3D_OK)
 					if(textureResources->pVolumeTex->GetVolumeLevel(static_cast<UINT>(mip), &volume) != D3D_OK)
 						BS_EXCEPT(RenderingAPIException, "Get volume level failed");	
 						BS_EXCEPT(RenderingAPIException, "Get volume level failed");	
@@ -970,16 +990,16 @@ namespace BansheeEngine
 		}		
 		}		
 	}
 	}
 
 
-	PixelBufferPtr D3D9Texture::getBuffer(UINT32 face, UINT32 mipmap) 
+	PixelBufferPtr D3D9TextureCore::getBuffer(UINT32 face, UINT32 mipmap) 
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
-		if(face >= getNumFaces())
+		if(face >= mProperties.getNumFaces())
 			BS_EXCEPT(InvalidParametersException, "A three dimensional cube has six faces");
 			BS_EXCEPT(InvalidParametersException, "A three dimensional cube has six faces");
-		if(mipmap > mNumMipmaps)
+		if (mipmap > mProperties.getNumMipmaps())
 			BS_EXCEPT(InvalidParametersException, "Mipmap index out of range");
 			BS_EXCEPT(InvalidParametersException, "Mipmap index out of range");
 
 
-		UINT32 idx = face*(mNumMipmaps+1) + mipmap;
+		UINT32 idx = face*(mProperties.getNumMipmaps() + 1) + mipmap;
 
 
 		IDirect3DDevice9* d3d9Device = D3D9RenderSystem::getActiveD3D9Device();
 		IDirect3DDevice9* d3d9Device = D3D9RenderSystem::getActiveD3D9Device();
 		TextureResources* textureResources = getTextureResources(d3d9Device);
 		TextureResources* textureResources = getTextureResources(d3d9Device);
@@ -994,12 +1014,13 @@ namespace BansheeEngine
 		return mSurfaceList[idx];
 		return mSurfaceList[idx];
 	}
 	}
 
 
-	bool D3D9Texture::useDefaultPool()
+	bool D3D9TextureCore::useDefaultPool()
 	{
 	{
-		return (mUsage & TU_RENDERTARGET) || (mUsage & TU_DEPTHSTENCIL) || ((mUsage & TU_DYNAMIC) && mDynamicTextures);
+		int usage = mProperties.getUsage();
+		return (usage & TU_RENDERTARGET) || (usage & TU_DEPTHSTENCIL) || ((usage & TU_DYNAMIC) && mDynamicTextures);
 	}
 	}
 	
 	
-	void D3D9Texture::notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device) 
+	void D3D9TextureCore::notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device) 
 	{		
 	{		
 		D3D9_DEVICE_ACCESS_CRITICAL_SECTION
 		D3D9_DEVICE_ACCESS_CRITICAL_SECTION
 
 
@@ -1007,7 +1028,7 @@ namespace BansheeEngine
 			createInternalResources(d3d9Device);
 			createInternalResources(d3d9Device);
 	}
 	}
 
 
-	void D3D9Texture::notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device) 
+	void D3D9TextureCore::notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device) 
 	{				
 	{				
 		D3D9_DEVICE_ACCESS_CRITICAL_SECTION
 		D3D9_DEVICE_ACCESS_CRITICAL_SECTION
 
 
@@ -1033,7 +1054,7 @@ namespace BansheeEngine
 		}	
 		}	
 	}
 	}
 
 
-	void D3D9Texture::notifyOnDeviceLost(IDirect3DDevice9* d3d9Device) 
+	void D3D9TextureCore::notifyOnDeviceLost(IDirect3DDevice9* d3d9Device) 
 	{		
 	{		
 		D3D9_DEVICE_ACCESS_CRITICAL_SECTION
 		D3D9_DEVICE_ACCESS_CRITICAL_SECTION
 
 
@@ -1049,7 +1070,7 @@ namespace BansheeEngine
 		}		
 		}		
 	}
 	}
 
 
-	void D3D9Texture::notifyOnDeviceReset(IDirect3DDevice9* d3d9Device) 
+	void D3D9TextureCore::notifyOnDeviceReset(IDirect3DDevice9* d3d9Device) 
 	{		
 	{		
 		D3D9_DEVICE_ACCESS_CRITICAL_SECTION
 		D3D9_DEVICE_ACCESS_CRITICAL_SECTION
 
 
@@ -1059,7 +1080,7 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
-	IDirect3DBaseTexture9* D3D9Texture::getTexture_internal()
+	IDirect3DBaseTexture9* D3D9TextureCore::getTexture_internal()
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
@@ -1079,7 +1100,7 @@ namespace BansheeEngine
 		return textureResources->pBaseTex;
 		return textureResources->pBaseTex;
 	}
 	}
 
 
-	IDirect3DTexture9* D3D9Texture::getNormTexture_internal()
+	IDirect3DTexture9* D3D9TextureCore::getNormTexture_internal()
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
@@ -1098,7 +1119,7 @@ namespace BansheeEngine
 		return textureResources->pNormTex;
 		return textureResources->pNormTex;
 	}
 	}
 
 
-	IDirect3DCubeTexture9* D3D9Texture::getCubeTexture_internal()
+	IDirect3DCubeTexture9* D3D9TextureCore::getCubeTexture_internal()
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 

+ 9 - 7
BansheeD3D9RenderSystem/Source/BsD3D9TextureManager.cpp

@@ -15,13 +15,6 @@ namespace BansheeEngine
 	D3D9TextureManager::~D3D9TextureManager()
 	D3D9TextureManager::~D3D9TextureManager()
 	{ }
 	{ }
 
 
-    TexturePtr D3D9TextureManager::createTextureImpl()
-    {
-		D3D9Texture* tex = new (bs_alloc<D3D9Texture, PoolAlloc>()) D3D9Texture();
-
-		return bs_core_ptr<D3D9Texture, PoolAlloc>(tex);
-    }
-
 	RenderTexturePtr D3D9TextureManager::createRenderTextureImpl(const RENDER_TEXTURE_DESC& desc)
 	RenderTexturePtr D3D9TextureManager::createRenderTextureImpl(const RENDER_TEXTURE_DESC& desc)
 	{
 	{
 		D3D9RenderTexture* tex = new (bs_alloc<D3D9RenderTexture, PoolAlloc>()) D3D9RenderTexture(desc);
 		D3D9RenderTexture* tex = new (bs_alloc<D3D9RenderTexture, PoolAlloc>()) D3D9RenderTexture(desc);
@@ -53,6 +46,15 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
+	SPtr<TextureCore> D3D9TextureCoreManager::createTextureInternal(TextureType texType, UINT32 width, UINT32 height, UINT32 depth,
+		int numMips, PixelFormat format, int usage, bool hwGammaCorrection, UINT32 multisampleCount)
+	{
+		D3D9TextureCore* tex = new (bs_alloc<D3D9TextureCore>()) D3D9TextureCore(texType,
+			width, height, depth, numMips, format, usage, hwGammaCorrection, multisampleCount);
+
+		return bs_shared_ptr<D3D9TextureCore, GenAlloc>(tex);
+	}
+
 	SPtr<RenderTextureCore> D3D9TextureCoreManager::createRenderTextureInternal(const RENDER_TEXTURE_DESC& desc)
 	SPtr<RenderTextureCore> D3D9TextureCoreManager::createRenderTextureInternal(const RENDER_TEXTURE_DESC& desc)
 	{
 	{
 		return bs_shared_ptr<D3D9RenderTextureCore>(desc);
 		return bs_shared_ptr<D3D9RenderTextureCore>(desc);

+ 3 - 4
BansheeEditor/Source/BsScenePicking.cpp

@@ -286,21 +286,20 @@ namespace BansheeEngine
 		SPtr<RenderTextureCore> rtt = std::static_pointer_cast<RenderTextureCore>(target);
 		SPtr<RenderTextureCore> rtt = std::static_pointer_cast<RenderTextureCore>(target);
 		TexturePtr outputTexture = rtt->getBindableColorTexture();
 		TexturePtr outputTexture = rtt->getBindableColorTexture();
 
 
-		if (position.x < 0 || position.x >= (INT32)outputTexture->getWidth() ||
-			position.y < 0 || position.y >= (INT32)outputTexture->getHeight())
+		if (position.x < 0 || position.x >= (INT32)outputTexture->getProperties().getWidth() ||
+			position.y < 0 || position.y >= (INT32)outputTexture->getProperties().getHeight())
 		{
 		{
 			asyncOp._completeOperation(Vector<UINT32>());
 			asyncOp._completeOperation(Vector<UINT32>());
 			return;
 			return;
 		}
 		}
 
 
 		PixelDataPtr outputPixelData = outputTexture->allocateSubresourceBuffer(0);
 		PixelDataPtr outputPixelData = outputTexture->allocateSubresourceBuffer(0);
-		GpuResourceDataPtr outputData = outputPixelData;
 		AsyncOp unused;
 		AsyncOp unused;
 
 
 		RenderSystem& rs = RenderSystem::instance();
 		RenderSystem& rs = RenderSystem::instance();
 
 
 		rs.endFrame();
 		rs.endFrame();
-		rs.readSubresource(outputTexture, 0, outputData, unused);
+		outputTexture->getCore()->readSubresource(0, *outputPixelData);
 
 
 		Map<UINT32, UINT32> selectionScores;
 		Map<UINT32, UINT32> selectionScores;
 		UINT32 numPixels = outputPixelData->getWidth() * outputPixelData->getHeight();
 		UINT32 numPixels = outputPixelData->getWidth() * outputPixelData->getHeight();

+ 1 - 1
BansheeEditorExec/BsEditorExec.cpp

@@ -11,7 +11,7 @@ int CALLBACK WinMain(
 	_In_  int nCmdShow
 	_In_  int nCmdShow
 	)
 	)
 {
 {
-	EditorApplication::startUp(RenderSystemPlugin::DX9);
+	EditorApplication::startUp(RenderSystemPlugin::OpenGL);
 	EditorApplication::instance().runMainLoop();
 	EditorApplication::instance().runMainLoop();
 	EditorApplication::shutDown();
 	EditorApplication::shutDown();
 
 

+ 10 - 10
BansheeEngine/Source/BsBuiltinResources.cpp

@@ -218,34 +218,34 @@ namespace BansheeEngine
 		HTexture cursorSizeWETex = getCursorTexture(CursorSizeWETex);
 		HTexture cursorSizeWETex = getCursorTexture(CursorSizeWETex);
 
 
 		mCursorArrow = cursorArrowTex->allocateSubresourceBuffer(0);
 		mCursorArrow = cursorArrowTex->allocateSubresourceBuffer(0);
-		gCoreAccessor().readSubresource(cursorArrowTex.getInternalPtr(), 0, mCursorArrow);
+		cursorArrowTex->readSubresource(gCoreAccessor(), 0, mCursorArrow);
 
 
 		mCursorArrowDrag = cursorArrowDragTex->allocateSubresourceBuffer(0);
 		mCursorArrowDrag = cursorArrowDragTex->allocateSubresourceBuffer(0);
-		gCoreAccessor().readSubresource(cursorArrowDragTex.getInternalPtr(), 0, mCursorArrowDrag);
+		cursorArrowDragTex->readSubresource(gCoreAccessor(), 0, mCursorArrowDrag);
 
 
 		mCursorArrowLeftRight = cursorArrowLeftRightTex->allocateSubresourceBuffer(0);
 		mCursorArrowLeftRight = cursorArrowLeftRightTex->allocateSubresourceBuffer(0);
-		gCoreAccessor().readSubresource(cursorArrowLeftRightTex.getInternalPtr(), 0, mCursorArrowLeftRight);
+		cursorArrowLeftRightTex->readSubresource(gCoreAccessor(), 0, mCursorArrowLeftRight);
 
 
 		mCursorIBeam = cursorIBeamTex->allocateSubresourceBuffer(0);
 		mCursorIBeam = cursorIBeamTex->allocateSubresourceBuffer(0);
-		gCoreAccessor().readSubresource(cursorIBeamTex.getInternalPtr(), 0, mCursorIBeam);
+		cursorIBeamTex->readSubresource(gCoreAccessor(), 0, mCursorIBeam);
 
 
 		mCursorDeny = cursorDenyTex->allocateSubresourceBuffer(0);
 		mCursorDeny = cursorDenyTex->allocateSubresourceBuffer(0);
-		gCoreAccessor().readSubresource(cursorDenyTex.getInternalPtr(), 0, mCursorDeny);
+		cursorDenyTex->readSubresource(gCoreAccessor(), 0, mCursorDeny);
 
 
 		mCursorWait = cursorWaitTex->allocateSubresourceBuffer(0);
 		mCursorWait = cursorWaitTex->allocateSubresourceBuffer(0);
-		gCoreAccessor().readSubresource(cursorWaitTex.getInternalPtr(), 0, mCursorWait);
+		cursorWaitTex->readSubresource(gCoreAccessor(), 0, mCursorWait);
 
 
 		mCursorSizeNESW = cursorSizeNESWTex->allocateSubresourceBuffer(0);
 		mCursorSizeNESW = cursorSizeNESWTex->allocateSubresourceBuffer(0);
-		gCoreAccessor().readSubresource(cursorSizeNESWTex.getInternalPtr(), 0, mCursorSizeNESW);
+		cursorSizeNESWTex->readSubresource(gCoreAccessor(), 0, mCursorSizeNESW);
 
 
 		mCursorSizeNS = cursorSizeNSTex->allocateSubresourceBuffer(0);
 		mCursorSizeNS = cursorSizeNSTex->allocateSubresourceBuffer(0);
-		gCoreAccessor().readSubresource(cursorSizeNSTex.getInternalPtr(), 0, mCursorSizeNS);
+		cursorSizeNSTex->readSubresource(gCoreAccessor(), 0, mCursorSizeNS);
 
 
 		mCursorSizeNWSE = cursorSizeNWSETex->allocateSubresourceBuffer(0);
 		mCursorSizeNWSE = cursorSizeNWSETex->allocateSubresourceBuffer(0);
-		gCoreAccessor().readSubresource(cursorSizeNWSETex.getInternalPtr(), 0, mCursorSizeNWSE);
+		cursorSizeNWSETex->readSubresource(gCoreAccessor(), 0, mCursorSizeNWSE);
 
 
 		mCursorSizeWE = cursorSizeWETex->allocateSubresourceBuffer(0);
 		mCursorSizeWE = cursorSizeWETex->allocateSubresourceBuffer(0);
-		gCoreAccessor().readSubresource(cursorSizeWETex.getInternalPtr(), 0, mCursorSizeWE);
+		cursorSizeWETex->readSubresource(gCoreAccessor(), 0, mCursorSizeWE);
 
 
 		gCoreAccessor().submitToCoreThread(true);
 		gCoreAccessor().submitToCoreThread(true);
 
 

+ 4 - 4
BansheeEngine/Source/BsGUIButtonBase.cpp

@@ -122,8 +122,8 @@ namespace BansheeEngine
 		{
 		{
 			IMAGE_SPRITE_DESC contentImgDesc;
 			IMAGE_SPRITE_DESC contentImgDesc;
 			contentImgDesc.texture = mContent.getImage().getInternalPtr();
 			contentImgDesc.texture = mContent.getImage().getInternalPtr();
-			contentImgDesc.width = mContent.getImage()->getTexture()->getWidth();
-			contentImgDesc.height = mContent.getImage()->getTexture()->getHeight();
+			contentImgDesc.width = mContent.getImage()->getWidth();
+			contentImgDesc.height = mContent.getImage()->getHeight();
 
 
 			mContentImageSprite->update(contentImgDesc);
 			mContentImageSprite->update(contentImgDesc);
 		}
 		}
@@ -144,8 +144,8 @@ namespace BansheeEngine
 		const HSpriteTexture& activeTex = getActiveTexture();
 		const HSpriteTexture& activeTex = getActiveTexture();
 		if(SpriteTexture::checkIsLoaded(activeTex))
 		if(SpriteTexture::checkIsLoaded(activeTex))
 		{
 		{
-			imageWidth = activeTex->getTexture()->getWidth();
-			imageHeight = activeTex->getTexture()->getHeight();
+			imageWidth = activeTex->getWidth();
+			imageHeight = activeTex->getHeight();
 		}
 		}
 
 
 		Vector2I contentSize = GUIHelper::calcOptimalContentsSize(mContent, *_getStyle(), _getLayoutOptions());
 		Vector2I contentSize = GUIHelper::calcOptimalContentsSize(mContent, *_getStyle(), _getLayoutOptions());

+ 2 - 2
BansheeEngine/Source/BsGUIHelper.cpp

@@ -22,8 +22,8 @@ namespace BansheeEngine
 		UINT32 contentHeight = style.margins.top + style.margins.bottom + style.contentOffset.top + style.contentOffset.bottom;
 		UINT32 contentHeight = style.margins.top + style.margins.bottom + style.contentOffset.top + style.contentOffset.bottom;
 		if(content.getImage() != nullptr)
 		if(content.getImage() != nullptr)
 		{
 		{
-			contentWidth += content.getImage()->getTexture()->getWidth();
-			contentHeight += content.getImage()->getTexture()->getHeight();
+			contentWidth += content.getImage()->getWidth();
+			contentHeight += content.getImage()->getHeight();
 		}
 		}
 
 
 		return Vector2I(std::max((UINT32)textContentBounds.x, contentWidth), std::max((UINT32)textContentBounds.y, contentHeight));
 		return Vector2I(std::max((UINT32)textContentBounds.x, contentWidth), std::max((UINT32)textContentBounds.y, contentHeight));

+ 2 - 2
BansheeEngine/Source/BsGUIInputBox.cpp

@@ -315,8 +315,8 @@ namespace BansheeEngine
 		const HSpriteTexture& activeTex = getActiveTexture();
 		const HSpriteTexture& activeTex = getActiveTexture();
 		if(SpriteTexture::checkIsLoaded(activeTex))
 		if(SpriteTexture::checkIsLoaded(activeTex))
 		{
 		{
-			imageWidth = activeTex->getTexture()->getWidth();
-			imageHeight = activeTex->getTexture()->getHeight();
+			imageWidth = activeTex->getWidth();
+			imageHeight = activeTex->getHeight();
 		}
 		}
 
 
 		Vector2I contentSize = GUIHelper::calcOptimalContentsSize(mText, *_getStyle(), _getLayoutOptions());
 		Vector2I contentSize = GUIHelper::calcOptimalContentsSize(mText, *_getStyle(), _getLayoutOptions());

+ 4 - 5
BansheeEngine/Source/BsGUIManager.cpp

@@ -603,12 +603,11 @@ namespace BansheeEngine
 		}
 		}
 
 
 		const HTexture& tex = mCaretTexture->getTexture();
 		const HTexture& tex = mCaretTexture->getTexture();
-		UINT32 subresourceIdx = tex->mapToSubresourceIdx(0, 0);
+		UINT32 subresourceIdx = tex->getProperties().mapToSubresourceIdx(0, 0);
 		PixelDataPtr data = tex->allocateSubresourceBuffer(subresourceIdx);
 		PixelDataPtr data = tex->allocateSubresourceBuffer(subresourceIdx);
 
 
 		data->setColorAt(mCaretColor, 0, 0);
 		data->setColorAt(mCaretColor, 0, 0);
-
-		gCoreAccessor().writeSubresource(tex.getInternalPtr(), tex->mapToSubresourceIdx(0, 0), data);
+		tex->writeSubresource(gCoreAccessor(), subresourceIdx, data, false);
 	}
 	}
 
 
 	void GUIManager::updateTextSelectionTexture()
 	void GUIManager::updateTextSelectionTexture()
@@ -621,12 +620,12 @@ namespace BansheeEngine
 		}
 		}
 
 
 		const HTexture& tex = mTextSelectionTexture->getTexture();
 		const HTexture& tex = mTextSelectionTexture->getTexture();
-		UINT32 subresourceIdx = tex->mapToSubresourceIdx(0, 0);
+		UINT32 subresourceIdx = tex->getProperties().mapToSubresourceIdx(0, 0);
 		PixelDataPtr data = tex->allocateSubresourceBuffer(subresourceIdx);
 		PixelDataPtr data = tex->allocateSubresourceBuffer(subresourceIdx);
 
 
 		data->setColorAt(mTextSelectionColor, 0, 0);
 		data->setColorAt(mTextSelectionColor, 0, 0);
 
 
-		gCoreAccessor().writeSubresource(tex.getInternalPtr(), tex->mapToSubresourceIdx(0, 0), data);
+		tex->writeSubresource(gCoreAccessor(), subresourceIdx, data, false);
 	}
 	}
 
 
 	void GUIManager::onMouseDragEnded(const PointerEvent& event, DragCallbackInfo& dragInfo)
 	void GUIManager::onMouseDragEnded(const PointerEvent& event, DragCallbackInfo& dragInfo)

+ 1 - 1
BansheeEngine/Source/BsGUIScrollBarHandle.cpp

@@ -122,7 +122,7 @@ namespace BansheeEngine
 		HSpriteTexture activeTex = getActiveTexture();
 		HSpriteTexture activeTex = getActiveTexture();
 
 
 		if(SpriteTexture::checkIsLoaded(activeTex))
 		if(SpriteTexture::checkIsLoaded(activeTex))
-			return Vector2I(activeTex->getTexture()->getWidth(), activeTex->getTexture()->getHeight());
+			return Vector2I(activeTex->getWidth(), activeTex->getHeight());
 
 
 		return Vector2I();
 		return Vector2I();
 	}
 	}

+ 4 - 4
BansheeEngine/Source/BsGUITexture.cpp

@@ -142,8 +142,8 @@ namespace BansheeEngine
 		if (SpriteTexture::checkIsLoaded(mActiveTexture))
 		if (SpriteTexture::checkIsLoaded(mActiveTexture))
 		{
 		{
 			mDesc.texture = mActiveTexture.getInternalPtr();
 			mDesc.texture = mActiveTexture.getInternalPtr();
-			optimalWidth = (float)mDesc.texture->getTexture()->getWidth();
-			optimalHeight = (float)mDesc.texture->getTexture()->getHeight();
+			optimalWidth = (float)mDesc.texture->getWidth();
+			optimalHeight = (float)mDesc.texture->getHeight();
 		}
 		}
 
 
 		switch (mScaleMode)
 		switch (mScaleMode)
@@ -210,7 +210,7 @@ namespace BansheeEngine
 		else
 		else
 		{
 		{
 			if (SpriteTexture::checkIsLoaded(mActiveTexture))
 			if (SpriteTexture::checkIsLoaded(mActiveTexture))
-				optimalSize.x = mActiveTexture->getTexture()->getWidth();
+				optimalSize.x = mActiveTexture->getWidth();
 			else
 			else
 				optimalSize.x = _getLayoutOptions().maxWidth;
 				optimalSize.x = _getLayoutOptions().maxWidth;
 		}
 		}
@@ -220,7 +220,7 @@ namespace BansheeEngine
 		else
 		else
 		{
 		{
 			if (SpriteTexture::checkIsLoaded(mActiveTexture))
 			if (SpriteTexture::checkIsLoaded(mActiveTexture))
-				optimalSize.y = mActiveTexture->getTexture()->getHeight();
+				optimalSize.y = mActiveTexture->getHeight();
 			else
 			else
 				optimalSize.y = _getLayoutOptions().maxHeight;
 				optimalSize.y = _getLayoutOptions().maxHeight;
 		}
 		}

+ 2 - 2
BansheeEngine/Source/BsImageSprite.cpp

@@ -177,8 +177,8 @@ namespace BansheeEngine
 			renderElem.vertices[34] = Vector2(topRightStart, bottomStart + bottomBorder);
 			renderElem.vertices[34] = Vector2(topRightStart, bottomStart + bottomBorder);
 			renderElem.vertices[35] = Vector2(topRightStart + rightBorder, bottomStart + bottomBorder);
 			renderElem.vertices[35] = Vector2(topRightStart + rightBorder, bottomStart + bottomBorder);
 
 
-			float invWidth = 1.0f / (float)desc.texture->getTexture()->getWidth();
-			float invHeight = 1.0f / (float)desc.texture->getTexture()->getHeight();
+			float invWidth = 1.0f / (float)desc.texture->getTexture()->getProperties().getWidth();
+			float invHeight = 1.0f / (float)desc.texture->getTexture()->getProperties().getHeight();
 
 
 			float uvLeftBorder = desc.borderLeft * invWidth;
 			float uvLeftBorder = desc.borderLeft * invWidth;
 			float uvRightBorder = desc.borderRight * invWidth;
 			float uvRightBorder = desc.borderRight * invWidth;

+ 2 - 2
BansheeEngine/Source/BsSpriteTexture.cpp

@@ -35,12 +35,12 @@ namespace BansheeEngine
 
 
 	UINT32 SpriteTexture::getWidth() const
 	UINT32 SpriteTexture::getWidth() const
 	{
 	{
-		return Math::roundToInt(mAtlasTexture->getWidth() * mUVScale.x);
+		return Math::roundToInt(mAtlasTexture->getProperties().getWidth() * mUVScale.x);
 	}
 	}
 
 
 	UINT32 SpriteTexture::getHeight() const
 	UINT32 SpriteTexture::getHeight() const
 	{
 	{
-		return Math::roundToInt(mAtlasTexture->getHeight() * mUVScale.y);
+		return Math::roundToInt(mAtlasTexture->getProperties().getHeight() * mUVScale.y);
 	}
 	}
 
 
 	HSpriteTexture SpriteTexture::create(const HTexture& texture)
 	HSpriteTexture SpriteTexture::create(const HTexture& texture)

+ 4 - 8
BansheeFontImporter/Source/BsFontImporter.cpp

@@ -275,23 +275,19 @@ namespace BansheeEngine
 				HTexture newTex = Texture::create(TEX_TYPE_2D, pageIter->width, pageIter->height, 0, PF_R8G8);
 				HTexture newTex = Texture::create(TEX_TYPE_2D, pageIter->width, pageIter->height, 0, PF_R8G8);
 				newTex.synchronize(); // TODO - Required due to a bug in allocateSubresourceBuffer
 				newTex.synchronize(); // TODO - Required due to a bug in allocateSubresourceBuffer
 
 
-				UINT32 subresourceIdx = newTex->mapToSubresourceIdx(0, 0);
+				UINT32 subresourceIdx = newTex->getProperties().mapToSubresourceIdx(0, 0);
 
 
 				// It's possible the formats no longer match
 				// It's possible the formats no longer match
-				if(newTex->getFormat() != pixelData->getFormat())
+				if (newTex->getProperties().getFormat() != pixelData->getFormat())
 				{
 				{
 					PixelDataPtr temp = newTex->allocateSubresourceBuffer(subresourceIdx);
 					PixelDataPtr temp = newTex->allocateSubresourceBuffer(subresourceIdx);
 					PixelUtil::bulkPixelConversion(*pixelData, *temp);
 					PixelUtil::bulkPixelConversion(*pixelData, *temp);
 
 
-					temp->_lock();
-					gCoreThread().queueReturnCommand(std::bind(&RenderSystem::writeSubresource, 
-						RenderSystem::instancePtr(), newTex.getInternalPtr(), subresourceIdx, temp, false, _1));
+					newTex->writeSubresource(gCoreAccessor(), subresourceIdx, temp, false);
 				}
 				}
 				else
 				else
 				{
 				{
-					pixelData->_lock();
-					gCoreThread().queueReturnCommand(std::bind(&RenderSystem::writeSubresource, 
-						RenderSystem::instancePtr(), newTex.getInternalPtr(), subresourceIdx, pixelData, false, _1));
+					newTex->writeSubresource(gCoreAccessor(), subresourceIdx, pixelData, false);
 				}
 				}
 
 
 				newTex->setName(L"FontPage" + toWString((UINT32)fontData.texturePages.size()));
 				newTex->setName(L"FontPage" + toWString((UINT32)fontData.texturePages.size()));

+ 2 - 3
BansheeFreeImgImporter/Source/BsFreeImgImporter.cpp

@@ -161,13 +161,12 @@ namespace BansheeEngine
 		newTexture->synchronize(); // TODO - Required due to a bug in allocateSubresourceBuffer
 		newTexture->synchronize(); // TODO - Required due to a bug in allocateSubresourceBuffer
 		for (UINT32 mip = 0; mip < (UINT32)mipLevels.size(); ++mip)
 		for (UINT32 mip = 0; mip < (UINT32)mipLevels.size(); ++mip)
 		{
 		{
-			UINT32 subresourceIdx = newTexture->mapToSubresourceIdx(0, mip);
+			UINT32 subresourceIdx = newTexture->getProperties().mapToSubresourceIdx(0, mip);
 			PixelDataPtr dst = newTexture->allocateSubresourceBuffer(subresourceIdx);
 			PixelDataPtr dst = newTexture->allocateSubresourceBuffer(subresourceIdx);
 
 
 			PixelUtil::bulkPixelConversion(*mipLevels[mip], *dst);
 			PixelUtil::bulkPixelConversion(*mipLevels[mip], *dst);
 
 
-			dst->_lock();
-			gCoreThread().queueReturnCommand(std::bind(&RenderSystem::writeSubresource, RenderSystem::instancePtr(), newTexture, subresourceIdx, dst, false, _1));
+			newTexture->writeSubresource(gCoreAccessor(), subresourceIdx, dst, false);
 		}
 		}
 
 
 		fileData->close();
 		fileData->close();

+ 1 - 1
BansheeGLRenderSystem/Include/BsGLPrerequisites.h

@@ -8,7 +8,7 @@ namespace BansheeEngine
 
 
     class GLSupport;
     class GLSupport;
     class GLRenderSystem;
     class GLRenderSystem;
-    class GLTexture;
+    class GLTextureCore;
 	class GLVertexBuffer;
 	class GLVertexBuffer;
 	class GLVertexBufferCore;
 	class GLVertexBufferCore;
     class GLTextureManager;
     class GLTextureManager;

+ 2 - 2
BansheeGLRenderSystem/Include/BsGLRenderSystem.h

@@ -61,12 +61,12 @@ namespace BansheeEngine
 		/**
 		/**
 		 * @copydoc RenderSystem::setTexture()
 		 * @copydoc RenderSystem::setTexture()
 		 */
 		 */
-        void setTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const TexturePtr &tex);
+		void setTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const SPtr<TextureCore>& tex);
 
 
 		/**
 		/**
 		 * @copydoc	RenderSystem::setLoadStoreTexture
 		 * @copydoc	RenderSystem::setLoadStoreTexture
 		 */
 		 */
-		void setLoadStoreTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const TexturePtr& texPtr,
+		void setLoadStoreTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const SPtr<TextureCore>& texPtr,
 			const TextureSurface& surface);
 			const TextureSurface& surface);
         
         
 		/**
 		/**

+ 15 - 16
BansheeGLRenderSystem/Include/BsGLTexture.h

@@ -11,10 +11,10 @@ namespace BansheeEngine
 	/**
 	/**
 	 * @brief	OpenGL implementation of a texture.
 	 * @brief	OpenGL implementation of a texture.
 	 */
 	 */
-    class BS_RSGL_EXPORT GLTexture : public Texture
+    class BS_RSGL_EXPORT GLTextureCore : public TextureCore
     {
     {
     public:
     public:
-        virtual ~GLTexture();      
+		virtual ~GLTextureCore();
 
 
 		/**
 		/**
 		 * @brief	Returns OpenGL texture target type
 		 * @brief	Returns OpenGL texture target type
@@ -43,42 +43,43 @@ namespace BansheeEngine
 		std::shared_ptr<GLPixelBuffer> getBuffer(UINT32 face, UINT32 mipmap);
 		std::shared_ptr<GLPixelBuffer> getBuffer(UINT32 face, UINT32 mipmap);
 
 
     protected:
     protected:
-		friend class GLTextureManager;
+		friend class GLTextureCoreManager;
 
 
-		GLTexture(GLSupport& support);
+		GLTextureCore(GLSupport& support, TextureType textureType, UINT32 width, UINT32 height, UINT32 depth, UINT32 numMipmaps,
+			PixelFormat format, int usage, bool hwGamma, UINT32 multisampleCount);
 
 
 		/**
 		/**
-		 * @copydoc Texture::initialize_internal
+		 * @copydoc TextureCore::initialize
 		 */
 		 */
-		void initialize_internal();
+		void initialize();
 
 
 		/**
 		/**
-		 * @copydoc Texture::destroy_internal
+		 * @copydoc TextureCore::destroy
 		 */
 		 */
-		void destroy_internal();
+		void destroy();
 
 
 		/**
 		/**
-		 * @copydoc Texture::lock
+		 * @copydoc TextureCore::lock
 		 */
 		 */
 		PixelData lockImpl(GpuLockOptions options, UINT32 mipLevel = 0, UINT32 face = 0);
 		PixelData lockImpl(GpuLockOptions options, UINT32 mipLevel = 0, UINT32 face = 0);
 
 
 		/**
 		/**
-		 * @copydoc Texture::unlock
+		 * @copydoc TextureCore::unlock
 		 */
 		 */
 		void unlockImpl();
 		void unlockImpl();
 
 
 		/**
 		/**
-		 * @copydoc Texture::copy
+		 * @copydoc TextureCore::copy
 		 */
 		 */
-		void copyImpl(UINT32 srcFace, UINT32 srcMipLevel, UINT32 destFace, UINT32 destMipLevel, TexturePtr& target);
+		void copyImpl(UINT32 srcFace, UINT32 srcMipLevel, UINT32 destFace, UINT32 destMipLevel, const SPtr<TextureCore>& target);
 
 
 		/**
 		/**
-		 * @copydoc Texture::readData
+		 * @copydoc TextureCore::readData
 		 */
 		 */
 		void readData(PixelData& dest, UINT32 mipLevel = 0, UINT32 face = 0);
 		void readData(PixelData& dest, UINT32 mipLevel = 0, UINT32 face = 0);
 
 
 		/**
 		/**
-		 * @copydoc Texture::writeData
+		 * @copydoc TextureCore::writeData
 		 */
 		 */
 		void writeData(const PixelData& src, UINT32 mipLevel = 0, UINT32 face = 0, bool discardWholeBuffer = false);
 		void writeData(const PixelData& src, UINT32 mipLevel = 0, UINT32 face = 0, bool discardWholeBuffer = false);
 
 
@@ -96,6 +97,4 @@ namespace BansheeEngine
 		
 		
 		Vector<std::shared_ptr<GLPixelBuffer>>mSurfaceList;
 		Vector<std::shared_ptr<GLPixelBuffer>>mSurfaceList;
     };
     };
-
-	typedef std::shared_ptr<GLTexture> GLTexturePtr;
 }
 }

+ 7 - 5
BansheeGLRenderSystem/Include/BsGLTextureManager.h

@@ -23,11 +23,6 @@ namespace BansheeEngine
 		PixelFormat getNativeFormat(TextureType ttype, PixelFormat format, int usage, bool hwGamma);
 		PixelFormat getNativeFormat(TextureType ttype, PixelFormat format, int usage, bool hwGamma);
 
 
 	protected:
 	protected:
-		/**
-		 * @copydoc	TextureManager::createTextureImpl
-		 */
-		TexturePtr createTextureImpl();
-
 		/**
 		/**
 		 * @copydoc	TextureManager::createRenderTextureImpl
 		 * @copydoc	TextureManager::createRenderTextureImpl
 		 */
 		 */
@@ -50,6 +45,13 @@ namespace BansheeEngine
 		GLTextureCoreManager(GLSupport& support);
 		GLTextureCoreManager(GLSupport& support);
 
 
 	protected:		
 	protected:		
+		/**
+		 * @copydoc	TextureCoreManager::createTextureInternal
+		 */
+		SPtr<TextureCore> createTextureInternal(TextureType texType, UINT32 width, UINT32 height, UINT32 depth,
+			int numMips, PixelFormat format, int usage = TU_DEFAULT, bool hwGammaCorrection = false,
+			UINT32 multisampleCount = 0);
+
 		/**
 		/**
 		 * @copydoc	TextureCoreManager::createRenderTextureInternal
 		 * @copydoc	TextureCoreManager::createRenderTextureInternal
 		 */
 		 */

+ 4 - 4
BansheeGLRenderSystem/Source/BsGLMultiRenderTexture.cpp

@@ -23,11 +23,11 @@ namespace BansheeEngine
 		{
 		{
 			if (mColorSurfaces[i] != nullptr)
 			if (mColorSurfaces[i] != nullptr)
 			{
 			{
-				GLTexture* glColorSurface = static_cast<GLTexture*>(mColorSurfaces[i]->getTexture().get());
+				GLTextureCore* glColorSurface = static_cast<GLTextureCore*>(mColorSurfaces[i]->getTexture().get());
 				GLPixelBufferPtr colorBuffer = nullptr;
 				GLPixelBufferPtr colorBuffer = nullptr;
 				GLSurfaceDesc surfaceDesc;
 				GLSurfaceDesc surfaceDesc;
 
 
-				if (glColorSurface->getTextureType() != TEX_TYPE_3D)
+				if (glColorSurface->getProperties().getTextureType() != TEX_TYPE_3D)
 				{
 				{
 					surfaceDesc.zoffset = 0;
 					surfaceDesc.zoffset = 0;
 					colorBuffer = glColorSurface->getBuffer(mColorSurfaces[i]->getFirstArraySlice(),
 					colorBuffer = glColorSurface->getBuffer(mColorSurfaces[i]->getFirstArraySlice(),
@@ -52,10 +52,10 @@ namespace BansheeEngine
 
 
 		if (mDepthStencilSurface != nullptr)
 		if (mDepthStencilSurface != nullptr)
 		{
 		{
-			GLTexture* glDepthStencilSurface = static_cast<GLTexture*>(mDepthStencilSurface->getTexture().get());
+			GLTextureCore* glDepthStencilSurface = static_cast<GLTextureCore*>(mDepthStencilSurface->getTexture().get());
 			GLPixelBufferPtr depthStencilBuffer = nullptr;
 			GLPixelBufferPtr depthStencilBuffer = nullptr;
 
 
-			if (glDepthStencilSurface->getTextureType() != TEX_TYPE_3D)
+			if (glDepthStencilSurface->getProperties().getTextureType() != TEX_TYPE_3D)
 			{
 			{
 				depthStencilBuffer = glDepthStencilSurface->getBuffer(mDepthStencilSurface->getDesc().firstArraySlice,
 				depthStencilBuffer = glDepthStencilSurface->getBuffer(mDepthStencilSurface->getDesc().firstArraySlice,
 					mDepthStencilSurface->getDesc().mostDetailMip);
 					mDepthStencilSurface->getDesc().mostDetailMip);

+ 6 - 6
BansheeGLRenderSystem/Source/BsGLRenderSystem.cpp

@@ -263,7 +263,7 @@ namespace BansheeEngine
 				if (!texture.isLoaded())
 				if (!texture.isLoaded())
 					setTexture(gptype, iter->second.slot, false, nullptr);
 					setTexture(gptype, iter->second.slot, false, nullptr);
 				else
 				else
-					setTexture(gptype, iter->second.slot, true, texture.getInternalPtr());
+					setTexture(gptype, iter->second.slot, true, texture->getCore());
 			}
 			}
 			else
 			else
 			{
 			{
@@ -272,7 +272,7 @@ namespace BansheeEngine
 				if (!texture.isLoaded())
 				if (!texture.isLoaded())
 					setLoadStoreTexture(gptype, iter->second.slot, false, nullptr, surface);
 					setLoadStoreTexture(gptype, iter->second.slot, false, nullptr, surface);
 				else
 				else
-					setLoadStoreTexture(gptype, iter->second.slot, true, texture.getInternalPtr(), surface);
+					setLoadStoreTexture(gptype, iter->second.slot, true, texture->getCore(), surface);
 			}
 			}
 		}
 		}
 
 
@@ -412,13 +412,13 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
-	void GLRenderSystem::setTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const TexturePtr &texPtr)
+	void GLRenderSystem::setTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const SPtr<TextureCore>& texPtr)
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
 		unit = getGLTextureUnit(gptype, unit);
 		unit = getGLTextureUnit(gptype, unit);
 
 
-		GLTexturePtr tex = std::static_pointer_cast<GLTexture>(texPtr);
+		SPtr<GLTextureCore> tex = std::static_pointer_cast<GLTextureCore>(texPtr);
 
 
 		GLenum lastTextureType = mTextureTypes[unit];
 		GLenum lastTextureType = mTextureTypes[unit];
 
 
@@ -470,7 +470,7 @@ namespace BansheeEngine
 		BS_INC_RENDER_STAT(NumSamplerBinds);
 		BS_INC_RENDER_STAT(NumSamplerBinds);
 	}
 	}
 
 
-	void GLRenderSystem::setLoadStoreTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const TexturePtr& texPtr,
+	void GLRenderSystem::setLoadStoreTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const SPtr<TextureCore>& texPtr,
 		const TextureSurface& surface)
 		const TextureSurface& surface)
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
@@ -478,7 +478,7 @@ namespace BansheeEngine
 		// TODO - OpenGL can't bind a certain subset of faces like DX11, only zero, one or all, so I'm ignoring numSlices parameter
 		// TODO - OpenGL can't bind a certain subset of faces like DX11, only zero, one or all, so I'm ignoring numSlices parameter
 		if (texPtr != nullptr)
 		if (texPtr != nullptr)
 		{
 		{
-			GLTexturePtr tex = std::static_pointer_cast<GLTexture>(texPtr);
+			SPtr<GLTextureCore> tex = std::static_pointer_cast<GLTextureCore>(texPtr);
 			glBindImageTexture(unit, tex->getGLID(), surface.mipLevel, surface.numArraySlices > 1, 
 			glBindImageTexture(unit, tex->getGLID(), surface.mipLevel, surface.numArraySlices > 1, 
 				surface.arraySlice, tex->getGLFormat(), GL_READ_WRITE);
 				surface.arraySlice, tex->getGLFormat(), GL_READ_WRITE);
 		}
 		}

+ 4 - 4
BansheeGLRenderSystem/Source/BsGLRenderTexture.cpp

@@ -39,12 +39,12 @@ namespace BansheeEngine
 
 
 		mFB = bs_new<GLFrameBufferObject, PoolAlloc>();
 		mFB = bs_new<GLFrameBufferObject, PoolAlloc>();
 
 
-		GLTexture* glTexture = static_cast<GLTexture*>(mColorSurface->getTexture().get());
+		GLTextureCore* glTexture = static_cast<GLTextureCore*>(mColorSurface->getTexture().get());
 
 
 		GLSurfaceDesc surfaceDesc;
 		GLSurfaceDesc surfaceDesc;
 		surfaceDesc.numSamples = getProperties().getMultisampleCount();
 		surfaceDesc.numSamples = getProperties().getMultisampleCount();
 
 
-		if (glTexture->getTextureType() != TEX_TYPE_3D)
+		if (glTexture->getProperties().getTextureType() != TEX_TYPE_3D)
 		{
 		{
 			surfaceDesc.zoffset = 0;
 			surfaceDesc.zoffset = 0;
 			surfaceDesc.buffer = glTexture->getBuffer(mColorSurface->getFirstArraySlice(), mColorSurface->getMostDetailedMip());
 			surfaceDesc.buffer = glTexture->getBuffer(mColorSurface->getFirstArraySlice(), mColorSurface->getMostDetailedMip());
@@ -57,10 +57,10 @@ namespace BansheeEngine
 
 
 		mFB->bindSurface(0, surfaceDesc);
 		mFB->bindSurface(0, surfaceDesc);
 
 
-		GLTexture* glDepthStencilTexture = static_cast<GLTexture*>(mDepthStencilSurface->getTexture().get());
+		GLTextureCore* glDepthStencilTexture = static_cast<GLTextureCore*>(mDepthStencilSurface->getTexture().get());
 		GLPixelBufferPtr depthStencilBuffer = nullptr;
 		GLPixelBufferPtr depthStencilBuffer = nullptr;
 
 
-		if (glDepthStencilTexture->getTextureType() != TEX_TYPE_3D)
+		if (glDepthStencilTexture->getProperties().getTextureType() != TEX_TYPE_3D)
 		{
 		{
 			depthStencilBuffer = glDepthStencilTexture->getBuffer(mDepthStencilSurface->getFirstArraySlice(),
 			depthStencilBuffer = glDepthStencilTexture->getBuffer(mDepthStencilSurface->getFirstArraySlice(),
 				mDepthStencilSurface->getMostDetailedMip());
 				mDepthStencilSurface->getMostDetailedMip());

+ 70 - 61
BansheeGLRenderSystem/Source/BsGLTexture.cpp

@@ -11,33 +11,43 @@
 
 
 namespace BansheeEngine 
 namespace BansheeEngine 
 {
 {
-    GLTexture::GLTexture(GLSupport& support) 
-		: Texture(), mTextureID(0), mGLSupport(support), mGLFormat(0)
+	GLTextureCore::GLTextureCore(GLSupport& support, TextureType textureType, UINT32 width, UINT32 height, 
+		UINT32 depth, UINT32 numMipmaps, PixelFormat format, int usage, bool hwGamma, UINT32 multisampleCount)
+		: TextureCore(textureType, width, height, depth, numMipmaps, format, usage, hwGamma, multisampleCount),
+		mTextureID(0), mGLSupport(support), mGLFormat(0)
     { }
     { }
 
 
-    GLTexture::~GLTexture()
+	GLTextureCore::~GLTextureCore()
     { }
     { }
 
 
-	void GLTexture::initialize_internal()
+	void GLTextureCore::initialize()
 	{
 	{
+		UINT32 width = mProperties.getWidth();
+		UINT32 height = mProperties.getHeight();
+		UINT32 depth = mProperties.getDepth();
+		TextureType texType = mProperties.getTextureType();
+		PixelFormat pixFormat = mProperties.getFormat();
+		int usage = mProperties.getUsage();
+		UINT32 numMips = mProperties.getNumMipmaps();
+
 		// Check requested number of mipmaps
 		// Check requested number of mipmaps
-		UINT32 maxMips = PixelUtil::getMaxMipmaps(mWidth, mHeight, mDepth, mFormat);
-		if(mNumMipmaps > maxMips)
+		UINT32 maxMips = PixelUtil::getMaxMipmaps(width, height, depth, mProperties.getFormat());
+		if (numMips > maxMips)
 			BS_EXCEPT(InvalidParametersException, "Invalid number of mipmaps. Maximum allowed is: " + toString(maxMips));
 			BS_EXCEPT(InvalidParametersException, "Invalid number of mipmaps. Maximum allowed is: " + toString(maxMips));
 
 
-		if((mUsage & TU_RENDERTARGET) != 0)
+		if ((usage & TU_RENDERTARGET) != 0)
 		{
 		{
-			if(mTextureType != TEX_TYPE_2D)
+			if (texType != TEX_TYPE_2D)
 				BS_EXCEPT(NotImplementedException, "Only 2D render targets are supported at the moment");
 				BS_EXCEPT(NotImplementedException, "Only 2D render targets are supported at the moment");
 		}
 		}
 
 
-		if((mUsage & TU_DEPTHSTENCIL) != 0)
+		if ((usage & TU_DEPTHSTENCIL) != 0)
 		{
 		{
-			if(mTextureType != TEX_TYPE_2D)
+			if (texType != TEX_TYPE_2D)
 				BS_EXCEPT(NotImplementedException, "Only 2D depth stencil targets are supported at the moment");
 				BS_EXCEPT(NotImplementedException, "Only 2D depth stencil targets are supported at the moment");
 
 
-			if(!PixelUtil::isDepth(mFormat))
-				BS_EXCEPT(NotImplementedException, "Supplied format is not a depth stencil format. Format: " + toString(mFormat));
+			if (!PixelUtil::isDepth(pixFormat))
+				BS_EXCEPT(NotImplementedException, "Supplied format is not a depth stencil format. Format: " + toString(pixFormat));
 		}
 		}
 
 
 		// Generate texture handle
 		// Generate texture handle
@@ -47,37 +57,35 @@ namespace BansheeEngine
 		glBindTexture(getGLTextureTarget(), mTextureID);
 		glBindTexture(getGLTextureTarget(), mTextureID);
 
 
 		// This needs to be set otherwise the texture doesn't get rendered
 		// This needs to be set otherwise the texture doesn't get rendered
-		glTexParameteri(getGLTextureTarget(), GL_TEXTURE_MAX_LEVEL, mNumMipmaps);
+		glTexParameteri(getGLTextureTarget(), GL_TEXTURE_MAX_LEVEL, numMips);
 
 
 		// Allocate internal buffer so that glTexSubImageXD can be used
 		// Allocate internal buffer so that glTexSubImageXD can be used
-		mGLFormat = GLPixelUtil::getClosestGLInternalFormat(mFormat, mHwGamma);
-		UINT32 width = mWidth;
-		UINT32 height = mHeight;
-		UINT32 depth = mDepth;
+		mGLFormat = GLPixelUtil::getClosestGLInternalFormat(pixFormat, mProperties.isHardwareGammaEnabled());
 
 
-		if(PixelUtil::isCompressed(mFormat))
+		if (PixelUtil::isCompressed(pixFormat))
 		{
 		{
-			if((mUsage & TU_RENDERTARGET) != 0)
+			if((usage & TU_RENDERTARGET) != 0)
 				BS_EXCEPT(InvalidParametersException, "Cannot use a compressed format for a render target.");
 				BS_EXCEPT(InvalidParametersException, "Cannot use a compressed format for a render target.");
 
 
-			if((mUsage & TU_DEPTHSTENCIL) != 0)
+			if ((usage & TU_DEPTHSTENCIL) != 0)
 				BS_EXCEPT(InvalidParametersException, "Cannot use a compressed format for a depth stencil target.");
 				BS_EXCEPT(InvalidParametersException, "Cannot use a compressed format for a depth stencil target.");
 		}
 		}
 
 
-		if((mUsage & TU_RENDERTARGET) != 0 && mTextureType == TEX_TYPE_2D && mMultisampleCount > 0)
+		UINT32 sampleCount = mProperties.getMultisampleCount();
+		if ((usage & TU_RENDERTARGET) != 0 && mProperties.getTextureType() == TEX_TYPE_2D && sampleCount > 0)
 		{
 		{
-			glTexImage2DMultisample(GL_TEXTURE_2D, mMultisampleCount, mGLFormat, width, height, GL_FALSE);
+			glTexImage2DMultisample(GL_TEXTURE_2D, sampleCount, mGLFormat, width, height, GL_FALSE);
 		}
 		}
-		else if((mUsage & TU_DEPTHSTENCIL) != 0)
+		else if ((usage & TU_DEPTHSTENCIL) != 0)
 		{
 		{
-			if(mMultisampleCount > 0)
+			if (sampleCount > 0)
 			{
 			{
-				glTexImage2DMultisample(GL_TEXTURE_2D, mMultisampleCount, mGLFormat,
+				glTexImage2DMultisample(GL_TEXTURE_2D, sampleCount, mGLFormat,
 					width, height, GL_FALSE);
 					width, height, GL_FALSE);
 			}
 			}
 			else
 			else
 			{
 			{
-				GLenum depthStencilFormat = GLPixelUtil::getDepthStencilTypeFromFormat(mFormat);
+				GLenum depthStencilFormat = GLPixelUtil::getDepthStencilTypeFromFormat(pixFormat);
 
 
 				glTexImage2D(GL_TEXTURE_2D, 0, mGLFormat,
 				glTexImage2D(GL_TEXTURE_2D, 0, mGLFormat,
 					width, height, 0, 
 					width, height, 0, 
@@ -86,13 +94,13 @@ namespace BansheeEngine
 		}
 		}
 		else
 		else
 		{
 		{
-			GLenum baseFormat = GLPixelUtil::getGLOriginFormat(mFormat);
-			GLenum baseDataType = GLPixelUtil::getGLOriginDataType(mFormat);
+			GLenum baseFormat = GLPixelUtil::getGLOriginFormat(pixFormat);
+			GLenum baseDataType = GLPixelUtil::getGLOriginDataType(pixFormat);
 
 
 			// Run through this process to pre-generate mipmap pyramid
 			// Run through this process to pre-generate mipmap pyramid
-			for(UINT32 mip = 0; mip <= mNumMipmaps; mip++)
+			for (UINT32 mip = 0; mip <= numMips; mip++)
 			{
 			{
-				switch(mTextureType)
+				switch (texType)
 				{
 				{
 				case TEX_TYPE_1D:
 				case TEX_TYPE_1D:
 					glTexImage1D(GL_TEXTURE_1D, mip, mGLFormat, width, 0,
 					glTexImage1D(GL_TEXTURE_1D, mip, mGLFormat, width, 0,
@@ -134,18 +142,18 @@ namespace BansheeEngine
 #if BS_DEBUG_MODE
 #if BS_DEBUG_MODE
 		if(buffer != nullptr)
 		if(buffer != nullptr)
 		{
 		{
-			if(mFormat != buffer->getFormat())
+			if(pixFormat != buffer->getFormat())
 			{
 			{
-				BS_EXCEPT(InternalErrorException, "Could not create a texture buffer with wanted format: " + toString(mFormat));
+				BS_EXCEPT(InternalErrorException, "Could not create a texture buffer with wanted format: " + toString(pixFormat));
 			}
 			}
 		}
 		}
 #endif
 #endif
 
 
 		BS_INC_RENDER_STAT_CAT(ResCreated, RenderStatObject_Texture);
 		BS_INC_RENDER_STAT_CAT(ResCreated, RenderStatObject_Texture);
-		Texture::initialize_internal();
+		TextureCore::initialize();
 	}
 	}
 
 
-	void GLTexture::destroy_internal()
+	void GLTextureCore::destroy()
 	{
 	{
 		mSurfaceList.clear();
 		mSurfaceList.clear();
 		glDeleteTextures(1, &mTextureID);
 		glDeleteTextures(1, &mTextureID);
@@ -153,17 +161,17 @@ namespace BansheeEngine
 		clearBufferViews();
 		clearBufferViews();
 
 
 		BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_Texture);
 		BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_Texture);
-		Texture::destroy_internal();
+		TextureCore::destroy();
 	}
 	}
 
 
-    GLenum GLTexture::getGLTextureTarget() const
+    GLenum GLTextureCore::getGLTextureTarget() const
     {
     {
-        switch(mTextureType)
+		switch (mProperties.getTextureType())
         {
         {
             case TEX_TYPE_1D:
             case TEX_TYPE_1D:
                 return GL_TEXTURE_1D;
                 return GL_TEXTURE_1D;
             case TEX_TYPE_2D:
             case TEX_TYPE_2D:
-				if(mMultisampleCount > 0)
+				if (mProperties.getMultisampleCount() > 0)
 					return GL_TEXTURE_2D_MULTISAMPLE;
 					return GL_TEXTURE_2D_MULTISAMPLE;
 				else
 				else
 					return GL_TEXTURE_2D;
 					return GL_TEXTURE_2D;
@@ -176,26 +184,26 @@ namespace BansheeEngine
         };
         };
     }
     }
 
 
-	GLuint GLTexture::getGLID() const
+	GLuint GLTextureCore::getGLID() const
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
 		return mTextureID;
 		return mTextureID;
 	}
 	}
 
 
-	PixelData GLTexture::lockImpl(GpuLockOptions options, UINT32 mipLevel, UINT32 face)
+	PixelData GLTextureCore::lockImpl(GpuLockOptions options, UINT32 mipLevel, UINT32 face)
 	{
 	{
-		if (mMultisampleCount > 0)
+		if (mProperties.getMultisampleCount() > 0)
 			BS_EXCEPT(InvalidStateException, "Multisampled textures cannot be accessed from the CPU directly.");
 			BS_EXCEPT(InvalidStateException, "Multisampled textures cannot be accessed from the CPU directly.");
 
 
 		if(mLockedBuffer != nullptr)
 		if(mLockedBuffer != nullptr)
 			BS_EXCEPT(InternalErrorException, "Trying to lock a buffer that's already locked.");
 			BS_EXCEPT(InternalErrorException, "Trying to lock a buffer that's already locked.");
 
 
-		UINT32 mipWidth = mWidth >> mipLevel;
-		UINT32 mipHeight = mHeight >> mipLevel;
-		UINT32 mipDepth = mDepth >> mipLevel;
+		UINT32 mipWidth = mProperties.getWidth() >> mipLevel;
+		UINT32 mipHeight = mProperties.getHeight() >> mipLevel;
+		UINT32 mipDepth = mProperties.getDepth() >> mipLevel;
 
 
-		PixelData lockedArea(mipWidth, mipHeight, mipDepth, mFormat);
+		PixelData lockedArea(mipWidth, mipHeight, mipDepth, mProperties.getFormat());
 
 
 		mLockedBuffer = getBuffer(face, mipLevel);
 		mLockedBuffer = getBuffer(face, mipLevel);
 		lockedArea.setExternalBuffer((UINT8*)mLockedBuffer->lock(options));
 		lockedArea.setExternalBuffer((UINT8*)mLockedBuffer->lock(options));
@@ -203,7 +211,7 @@ namespace BansheeEngine
 		return lockedArea;
 		return lockedArea;
 	}
 	}
 
 
-	void GLTexture::unlockImpl()
+	void GLTextureCore::unlockImpl()
 	{
 	{
 		if(mLockedBuffer == nullptr)
 		if(mLockedBuffer == nullptr)
 			BS_EXCEPT(InternalErrorException, "Trying to unlock a buffer that's not locked.");
 			BS_EXCEPT(InternalErrorException, "Trying to unlock a buffer that's not locked.");
@@ -213,42 +221,43 @@ namespace BansheeEngine
 	}
 	}
 
 
 
 
-	void GLTexture::readData(PixelData& dest, UINT32 mipLevel, UINT32 face)
+	void GLTextureCore::readData(PixelData& dest, UINT32 mipLevel, UINT32 face)
 	{
 	{
-		if (mMultisampleCount > 0)
+		if (mProperties.getMultisampleCount() > 0)
 			BS_EXCEPT(InvalidStateException, "Multisampled textures cannot be accessed from the CPU directly.");
 			BS_EXCEPT(InvalidStateException, "Multisampled textures cannot be accessed from the CPU directly.");
 
 
 		getBuffer(face, mipLevel)->download(dest);
 		getBuffer(face, mipLevel)->download(dest);
 	}
 	}
 
 
-	void GLTexture::writeData(const PixelData& src, UINT32 mipLevel, UINT32 face, bool discardWholeBuffer)
+	void GLTextureCore::writeData(const PixelData& src, UINT32 mipLevel, UINT32 face, bool discardWholeBuffer)
 	{
 	{
-		if (mMultisampleCount > 0)
+		if (mProperties.getMultisampleCount() > 0)
 			BS_EXCEPT(InvalidStateException, "Multisampled textures cannot be accessed from the CPU directly.");
 			BS_EXCEPT(InvalidStateException, "Multisampled textures cannot be accessed from the CPU directly.");
 
 
 		getBuffer(face, mipLevel)->upload(src, src.getExtents());
 		getBuffer(face, mipLevel)->upload(src, src.getExtents());
 	}
 	}
 
 
-	void GLTexture::copyImpl(UINT32 srcFace, UINT32 srcMipLevel, UINT32 destFace, UINT32 destMipLevel, TexturePtr& target)
+	void GLTextureCore::copyImpl(UINT32 srcFace, UINT32 srcMipLevel, UINT32 destFace, UINT32 destMipLevel, const SPtr<TextureCore>& target)
 	{
 	{
-		size_t numMips = std::min(getNumMipmaps(), target->getNumMipmaps());
+		size_t numMips = std::min(mProperties.getNumMipmaps(), target->getProperties().getNumMipmaps());
 
 
-		GLTexture* destTex = static_cast<GLTexture*>(target.get());
+		GLTextureCore* destTex = static_cast<GLTextureCore*>(target.get());
 		GLTextureBuffer *src = static_cast<GLTextureBuffer*>(getBuffer(srcFace, srcMipLevel).get());
 		GLTextureBuffer *src = static_cast<GLTextureBuffer*>(getBuffer(srcFace, srcMipLevel).get());
 
 
 		destTex->getBuffer(destFace, destMipLevel)->blitFromTexture(src);
 		destTex->getBuffer(destFace, destMipLevel)->blitFromTexture(src);
 	}
 	}
 
 
-	void GLTexture::createSurfaceList()
+	void GLTextureCore::createSurfaceList()
 	{
 	{
 		mSurfaceList.clear();
 		mSurfaceList.clear();
 		
 		
-		for(UINT32 face = 0; face < getNumFaces(); face++)
+		for (UINT32 face = 0; face < mProperties.getNumFaces(); face++)
 		{
 		{
-			for(UINT32 mip = 0; mip <= getNumMipmaps(); mip++)
+			for (UINT32 mip = 0; mip <= mProperties.getNumMipmaps(); mip++)
 			{
 			{
                 GLPixelBuffer *buf = bs_new<GLTextureBuffer, PoolAlloc>(getGLTextureTarget(), mTextureID, face, mip,
                 GLPixelBuffer *buf = bs_new<GLTextureBuffer, PoolAlloc>(getGLTextureTarget(), mTextureID, face, mip,
-						static_cast<GpuBufferUsage>(mUsage), mHwGamma, mMultisampleCount);
+					static_cast<GpuBufferUsage>(mProperties.getUsage()), 
+					mProperties.isHardwareGammaEnabled(), mProperties.getMultisampleCount());
 
 
 				mSurfaceList.push_back(bs_shared_ptr<GLPixelBuffer, PoolAlloc>(buf));
 				mSurfaceList.push_back(bs_shared_ptr<GLPixelBuffer, PoolAlloc>(buf));
                 if(buf->getWidth() == 0 || buf->getHeight() == 0 || buf->getDepth() == 0)
                 if(buf->getWidth() == 0 || buf->getHeight() == 0 || buf->getDepth() == 0)
@@ -263,17 +272,17 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 	
 	
-	std::shared_ptr<GLPixelBuffer> GLTexture::getBuffer(UINT32 face, UINT32 mipmap)
+	std::shared_ptr<GLPixelBuffer> GLTextureCore::getBuffer(UINT32 face, UINT32 mipmap)
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
-		if(face >= getNumFaces())
+		if(face >= mProperties.getNumFaces())
 			BS_EXCEPT(InvalidParametersException, "Face index out of range");
 			BS_EXCEPT(InvalidParametersException, "Face index out of range");
 
 
-		if(mipmap > mNumMipmaps)
+		if (mipmap > mProperties.getNumMipmaps())
 			BS_EXCEPT(InvalidParametersException, "Mipmap index out of range");
 			BS_EXCEPT(InvalidParametersException, "Mipmap index out of range");
 
 
-		unsigned int idx = face*(mNumMipmaps+1) + mipmap;
+		unsigned int idx = face * (mProperties.getNumMipmaps() + 1) + mipmap;
 		assert(idx < mSurfaceList.size());
 		assert(idx < mSurfaceList.size());
 		return mSurfaceList[idx];
 		return mSurfaceList[idx];
 	}
 	}

+ 10 - 8
BansheeGLRenderSystem/Source/BsGLTextureManager.cpp

@@ -6,7 +6,7 @@
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
-    GLTextureManager::GLTextureManager( GLSupport& support)
+    GLTextureManager::GLTextureManager(GLSupport& support)
         :TextureManager(), mGLSupport(support)
         :TextureManager(), mGLSupport(support)
     {
     {
 
 
@@ -15,13 +15,6 @@ namespace BansheeEngine
     GLTextureManager::~GLTextureManager()
     GLTextureManager::~GLTextureManager()
     {
     {
 
 
-    }
-
-    TexturePtr GLTextureManager::createTextureImpl()
-    {
-        GLTexture* tex = new (bs_alloc<GLTexture, PoolAlloc>()) GLTexture(mGLSupport);
-
-		return bs_core_ptr<GLTexture, PoolAlloc>(tex);
     }
     }
 
 
 	RenderTexturePtr GLTextureManager::createRenderTextureImpl(const RENDER_TEXTURE_DESC& desc)
 	RenderTexturePtr GLTextureManager::createRenderTextureImpl(const RENDER_TEXTURE_DESC& desc)
@@ -71,6 +64,15 @@ namespace BansheeEngine
 		:mGLSupport(support)
 		:mGLSupport(support)
 	{ }
 	{ }
 
 
+	SPtr<TextureCore> GLTextureCoreManager::createTextureInternal(TextureType texType, UINT32 width, UINT32 height, UINT32 depth,
+		int numMips, PixelFormat format, int usage, bool hwGammaCorrection, UINT32 multisampleCount)
+	{
+		GLTextureCore* tex = new (bs_alloc<GLTextureCore>()) GLTextureCore(mGLSupport, texType,
+			width, height, depth, numMips, format, usage, hwGammaCorrection, multisampleCount);
+
+		return bs_shared_ptr<GLTextureCore, GenAlloc>(tex);
+	}
+
 	SPtr<RenderTextureCore> GLTextureCoreManager::createRenderTextureInternal(const RENDER_TEXTURE_DESC& desc)
 	SPtr<RenderTextureCore> GLTextureCoreManager::createRenderTextureInternal(const RENDER_TEXTURE_DESC& desc)
 	{
 	{
 		return bs_shared_ptr<GLRenderTextureCore>(desc);
 		return bs_shared_ptr<GLRenderTextureCore>(desc);

+ 7 - 7
SBansheeEngine/Source/BsScriptTexture.cpp

@@ -26,42 +26,42 @@ namespace BansheeEngine
 	void ScriptTexture::internal_getPixelFormat(ScriptTexture* thisPtr, PixelFormat* value)
 	void ScriptTexture::internal_getPixelFormat(ScriptTexture* thisPtr, PixelFormat* value)
 	{
 	{
 		HTexture texture = static_resource_cast<Texture>(thisPtr->getNativeHandle());
 		HTexture texture = static_resource_cast<Texture>(thisPtr->getNativeHandle());
-		*value = texture->getFormat();
+		*value = texture->getProperties().getFormat();
 	}
 	}
 
 
 	void ScriptTexture::internal_getUsage(ScriptTexture* thisPtr, TextureUsage* value)
 	void ScriptTexture::internal_getUsage(ScriptTexture* thisPtr, TextureUsage* value)
 	{
 	{
 		HTexture texture = static_resource_cast<Texture>(thisPtr->getNativeHandle());
 		HTexture texture = static_resource_cast<Texture>(thisPtr->getNativeHandle());
-		*value = (TextureUsage)texture->getUsage();
+		*value = (TextureUsage)texture->getProperties().getUsage();
 	}
 	}
 
 
 	void ScriptTexture::internal_getWidth(ScriptTexture* thisPtr, int* value)
 	void ScriptTexture::internal_getWidth(ScriptTexture* thisPtr, int* value)
 	{
 	{
 		HTexture texture = static_resource_cast<Texture>(thisPtr->getNativeHandle());
 		HTexture texture = static_resource_cast<Texture>(thisPtr->getNativeHandle());
-		*value = (TextureUsage)texture->getWidth();
+		*value = (TextureUsage)texture->getProperties().getWidth();
 	}
 	}
 
 
 	void ScriptTexture::internal_getHeight(ScriptTexture* thisPtr, int* value)
 	void ScriptTexture::internal_getHeight(ScriptTexture* thisPtr, int* value)
 	{
 	{
 		HTexture texture = static_resource_cast<Texture>(thisPtr->getNativeHandle());
 		HTexture texture = static_resource_cast<Texture>(thisPtr->getNativeHandle());
-		*value = (TextureUsage)texture->getHeight();
+		*value = (TextureUsage)texture->getProperties().getHeight();
 	}
 	}
 
 
 	void ScriptTexture::internal_getGammaCorrection(ScriptTexture* thisPtr, bool* value)
 	void ScriptTexture::internal_getGammaCorrection(ScriptTexture* thisPtr, bool* value)
 	{
 	{
 		HTexture texture = static_resource_cast<Texture>(thisPtr->getNativeHandle());
 		HTexture texture = static_resource_cast<Texture>(thisPtr->getNativeHandle());
-		*value = (TextureUsage)texture->isHardwareGammaEnabled();
+		*value = (TextureUsage)texture->getProperties().isHardwareGammaEnabled();
 	}
 	}
 
 
 	void ScriptTexture::internal_getSampleCount(ScriptTexture* thisPtr, int* value)
 	void ScriptTexture::internal_getSampleCount(ScriptTexture* thisPtr, int* value)
 	{
 	{
 		HTexture texture = static_resource_cast<Texture>(thisPtr->getNativeHandle());
 		HTexture texture = static_resource_cast<Texture>(thisPtr->getNativeHandle());
-		*value = (TextureUsage)texture->getMultisampleCount();
+		*value = (TextureUsage)texture->getProperties().getMultisampleCount();
 	}
 	}
 
 
 	void ScriptTexture::internal_getMipmapCount(ScriptTexture* thisPtr, int* value)
 	void ScriptTexture::internal_getMipmapCount(ScriptTexture* thisPtr, int* value)
 	{
 	{
 		HTexture texture = static_resource_cast<Texture>(thisPtr->getNativeHandle());
 		HTexture texture = static_resource_cast<Texture>(thisPtr->getNativeHandle());
-		*value = (TextureUsage)texture->getNumMipmaps();
+		*value = (TextureUsage)texture->getProperties().getNumMipmaps();
 	}
 	}
 }
 }

+ 6 - 6
SBansheeEngine/Source/BsScriptTexture2D.cpp

@@ -44,11 +44,11 @@ namespace BansheeEngine
 	MonoObject* ScriptTexture2D::internal_getPixels(ScriptTexture2D* thisPtr, UINT32 mipLevel)
 	MonoObject* ScriptTexture2D::internal_getPixels(ScriptTexture2D* thisPtr, UINT32 mipLevel)
 	{
 	{
 		HTexture texture = thisPtr->mTexture;
 		HTexture texture = thisPtr->mTexture;
-		UINT32 subresourceIdx = texture->mapToSubresourceIdx(0, mipLevel);
+		UINT32 subresourceIdx = texture->getProperties().mapToSubresourceIdx(0, mipLevel);
 
 
 		PixelDataPtr pixelData = thisPtr->mTexture->allocateSubresourceBuffer(subresourceIdx);
 		PixelDataPtr pixelData = thisPtr->mTexture->allocateSubresourceBuffer(subresourceIdx);
 
 
-		thisPtr->mTexture->readDataSim(*pixelData, mipLevel);
+		thisPtr->mTexture->readData(*pixelData, mipLevel);
 
 
 		return ScriptPixelData::create(pixelData);
 		return ScriptPixelData::create(pixelData);
 	}
 	}
@@ -56,11 +56,11 @@ namespace BansheeEngine
 	MonoObject* ScriptTexture2D::internal_getGPUPixels(ScriptTexture2D* thisPtr, UINT32 mipLevel)
 	MonoObject* ScriptTexture2D::internal_getGPUPixels(ScriptTexture2D* thisPtr, UINT32 mipLevel)
 	{
 	{
 		HTexture texture = thisPtr->mTexture;
 		HTexture texture = thisPtr->mTexture;
-		UINT32 subresourceIdx = texture->mapToSubresourceIdx(0, mipLevel);
+		UINT32 subresourceIdx = texture->getProperties().mapToSubresourceIdx(0, mipLevel);
 
 
 		PixelDataPtr readData = texture->allocateSubresourceBuffer(subresourceIdx);
 		PixelDataPtr readData = texture->allocateSubresourceBuffer(subresourceIdx);
 
 
-		AsyncOp asyncOp = gCoreAccessor().readSubresource(texture.getInternalPtr(), subresourceIdx, readData);
+		AsyncOp asyncOp = texture->readSubresource(gCoreAccessor(), subresourceIdx, readData);
 
 
 		std::function<MonoObject*(const AsyncOp&, const PixelDataPtr&)> asyncOpToMono =
 		std::function<MonoObject*(const AsyncOp&, const PixelDataPtr&)> asyncOpToMono =
 			[&](const AsyncOp& op, const PixelDataPtr& returnValue)
 			[&](const AsyncOp& op, const PixelDataPtr& returnValue)
@@ -78,9 +78,9 @@ namespace BansheeEngine
 		if (scriptPixelData != nullptr)
 		if (scriptPixelData != nullptr)
 		{
 		{
 			HTexture texture = thisPtr->mTexture;
 			HTexture texture = thisPtr->mTexture;
-			UINT32 subresourceIdx = texture->mapToSubresourceIdx(0, mipLevel);
+			UINT32 subresourceIdx = texture->getProperties().mapToSubresourceIdx(0, mipLevel);
 
 
-			gCoreAccessor().writeSubresource(texture.getInternalPtr(), subresourceIdx, scriptPixelData->getInternalValue());
+			texture->writeSubresource(gCoreAccessor(), subresourceIdx, scriptPixelData->getInternalValue(), false);
 		}
 		}
 	}
 	}
 
 

+ 6 - 6
SBansheeEngine/Source/BsScriptTexture3D.cpp

@@ -44,11 +44,11 @@ namespace BansheeEngine
 	MonoObject* ScriptTexture3D::internal_getPixels(ScriptTexture3D* thisPtr, UINT32 mipLevel)
 	MonoObject* ScriptTexture3D::internal_getPixels(ScriptTexture3D* thisPtr, UINT32 mipLevel)
 	{
 	{
 		HTexture texture = thisPtr->mTexture;
 		HTexture texture = thisPtr->mTexture;
-		UINT32 subresourceIdx = texture->mapToSubresourceIdx(0, mipLevel);
+		UINT32 subresourceIdx = texture->getProperties().mapToSubresourceIdx(0, mipLevel);
 
 
 		PixelDataPtr pixelData = thisPtr->mTexture->allocateSubresourceBuffer(subresourceIdx);
 		PixelDataPtr pixelData = thisPtr->mTexture->allocateSubresourceBuffer(subresourceIdx);
 
 
-		thisPtr->mTexture->readDataSim(*pixelData, mipLevel);
+		thisPtr->mTexture->readData(*pixelData, mipLevel);
 
 
 		return ScriptPixelData::create(pixelData);
 		return ScriptPixelData::create(pixelData);
 	}
 	}
@@ -56,11 +56,11 @@ namespace BansheeEngine
 	MonoObject* ScriptTexture3D::internal_getGPUPixels(ScriptTexture3D* thisPtr, UINT32 mipLevel)
 	MonoObject* ScriptTexture3D::internal_getGPUPixels(ScriptTexture3D* thisPtr, UINT32 mipLevel)
 	{
 	{
 		HTexture texture = thisPtr->mTexture;
 		HTexture texture = thisPtr->mTexture;
-		UINT32 subresourceIdx = texture->mapToSubresourceIdx(0, mipLevel);
+		UINT32 subresourceIdx = texture->getProperties().mapToSubresourceIdx(0, mipLevel);
 
 
 		PixelDataPtr readData = texture->allocateSubresourceBuffer(subresourceIdx);
 		PixelDataPtr readData = texture->allocateSubresourceBuffer(subresourceIdx);
 
 
-		AsyncOp asyncOp = gCoreAccessor().readSubresource(texture.getInternalPtr(), subresourceIdx, readData);
+		AsyncOp asyncOp = texture->readSubresource(gCoreAccessor(), subresourceIdx, readData);
 
 
 		std::function<MonoObject*(const AsyncOp&, const PixelDataPtr&)> asyncOpToMono =
 		std::function<MonoObject*(const AsyncOp&, const PixelDataPtr&)> asyncOpToMono =
 			[&](const AsyncOp& op, const PixelDataPtr& returnValue)
 			[&](const AsyncOp& op, const PixelDataPtr& returnValue)
@@ -78,9 +78,9 @@ namespace BansheeEngine
 		if (scriptPixelData != nullptr)
 		if (scriptPixelData != nullptr)
 		{
 		{
 			HTexture texture = thisPtr->mTexture;
 			HTexture texture = thisPtr->mTexture;
-			UINT32 subresourceIdx = texture->mapToSubresourceIdx(0, mipLevel);
+			UINT32 subresourceIdx = texture->getProperties().mapToSubresourceIdx(0, mipLevel);
 
 
-			gCoreAccessor().writeSubresource(texture.getInternalPtr(), subresourceIdx, scriptPixelData->getInternalValue());
+			texture->writeSubresource(gCoreAccessor(), subresourceIdx, scriptPixelData->getInternalValue(), false);
 		}
 		}
 	}
 	}
 
 

+ 6 - 7
SBansheeEngine/Source/BsScriptTextureCube.cpp

@@ -44,11 +44,11 @@ namespace BansheeEngine
 	MonoObject* ScriptTextureCube::internal_getPixels(ScriptTextureCube* thisPtr, UINT32 face, UINT32 mipLevel)
 	MonoObject* ScriptTextureCube::internal_getPixels(ScriptTextureCube* thisPtr, UINT32 face, UINT32 mipLevel)
 	{
 	{
 		HTexture texture = thisPtr->mTexture;
 		HTexture texture = thisPtr->mTexture;
-		UINT32 subresourceIdx = texture->mapToSubresourceIdx(face, mipLevel);
+		UINT32 subresourceIdx = texture->getProperties().mapToSubresourceIdx(face, mipLevel);
 
 
 		PixelDataPtr pixelData = thisPtr->mTexture->allocateSubresourceBuffer(subresourceIdx);
 		PixelDataPtr pixelData = thisPtr->mTexture->allocateSubresourceBuffer(subresourceIdx);
 
 
-		thisPtr->mTexture->readDataSim(*pixelData, mipLevel, face);
+		thisPtr->mTexture->readData(*pixelData, mipLevel, face);
 
 
 		return ScriptPixelData::create(pixelData);
 		return ScriptPixelData::create(pixelData);
 	}
 	}
@@ -56,11 +56,10 @@ namespace BansheeEngine
 	MonoObject* ScriptTextureCube::internal_getGPUPixels(ScriptTextureCube* thisPtr, UINT32 face, UINT32 mipLevel)
 	MonoObject* ScriptTextureCube::internal_getGPUPixels(ScriptTextureCube* thisPtr, UINT32 face, UINT32 mipLevel)
 	{
 	{
 		HTexture texture = thisPtr->mTexture;
 		HTexture texture = thisPtr->mTexture;
-		UINT32 subresourceIdx = texture->mapToSubresourceIdx(face, mipLevel);
+		UINT32 subresourceIdx = texture->getProperties().mapToSubresourceIdx(face, mipLevel);
 
 
 		PixelDataPtr readData = texture->allocateSubresourceBuffer(subresourceIdx);
 		PixelDataPtr readData = texture->allocateSubresourceBuffer(subresourceIdx);
-
-		AsyncOp asyncOp = gCoreAccessor().readSubresource(texture.getInternalPtr(), subresourceIdx, readData);
+		AsyncOp asyncOp = texture->readSubresource(gCoreAccessor(), subresourceIdx, readData);
 
 
 		std::function<MonoObject*(const AsyncOp&, const PixelDataPtr&)> asyncOpToMono =
 		std::function<MonoObject*(const AsyncOp&, const PixelDataPtr&)> asyncOpToMono =
 			[&](const AsyncOp& op, const PixelDataPtr& returnValue)
 			[&](const AsyncOp& op, const PixelDataPtr& returnValue)
@@ -78,9 +77,9 @@ namespace BansheeEngine
 		if (scriptPixelData != nullptr)
 		if (scriptPixelData != nullptr)
 		{
 		{
 			HTexture texture = thisPtr->mTexture;
 			HTexture texture = thisPtr->mTexture;
-			UINT32 subresourceIdx = texture->mapToSubresourceIdx(face, mipLevel);
+			UINT32 subresourceIdx = texture->getProperties().mapToSubresourceIdx(face, mipLevel);
 
 
-			gCoreAccessor().writeSubresource(texture.getInternalPtr(), subresourceIdx, scriptPixelData->getInternalValue());
+			texture->writeSubresource(gCoreAccessor(), subresourceIdx, scriptPixelData->getInternalValue(), false);
 		}
 		}
 	}
 	}
 
 

+ 2 - 3
TODO.txt

@@ -24,11 +24,10 @@ Disallow CoreObject creation from core thread
  - Add asserts in CoreObject::destroy and CoreObject::initialize
  - Add asserts in CoreObject::destroy and CoreObject::initialize
  - Possibly also add asserts to CoreThread::queueCommand and CoreThread::queueReturnCommand
  - Possibly also add asserts to CoreThread::queueCommand and CoreThread::queueReturnCommand
 
 
-After I refactor Texture remove write/read subresource from core accessor
- - Also get rid of GpuResource class
-
 Since Mesh refactor when I select/deselect a gizmo the entire render texture flashes white for one frame (might be related to RT refactor instead)
 Since Mesh refactor when I select/deselect a gizmo the entire render texture flashes white for one frame (might be related to RT refactor instead)
 
 
+There seems to be a threading issue with frame alloc freeing due to CoreObject syncing. Sometimes I get crashes in frame alloc relating to unfreed memory
+
 -----------------
 -----------------