Browse Source

Work on DX11 textures and HardwarePixelBuffer.
Doesn't compile but commiting before i delete DX11 HardwarePixelBuffer just in case I need it later

Marko Pintera 13 years ago
parent
commit
c2cba92975
27 changed files with 2475 additions and 844 deletions
  1. 6 0
      CamelotD3D11RenderSystem/CamelotD3D11RenderSystem.vcxproj
  2. 18 0
      CamelotD3D11RenderSystem/CamelotD3D11RenderSystem.vcxproj.filters
  3. 86 0
      CamelotD3D11RenderSystem/Include/CmD3D11HardwarePixelBuffer.h
  4. 4 1
      CamelotD3D11RenderSystem/Include/CmD3D11Mappings.h
  5. 23 0
      CamelotD3D11RenderSystem/Include/CmD3D11RenderTexture.h
  6. 81 0
      CamelotD3D11RenderSystem/Include/CmD3D11Texture.h
  7. 4 4
      CamelotD3D11RenderSystem/Source/CmD3D11HardwareBuffer.cpp
  8. 765 0
      CamelotD3D11RenderSystem/Source/CmD3D11HardwarePixelBuffer.cpp
  9. 42 3
      CamelotD3D11RenderSystem/Source/CmD3D11Mappings.cpp
  10. 6 0
      CamelotD3D11RenderSystem/Source/CmD3D11RenderTexture.cpp
  11. 732 732
      CamelotD3D11RenderSystem/Source/CmD3D11RenderWindow.cpp
  12. 584 0
      CamelotD3D11RenderSystem/Source/CmD3D11Texture.cpp
  13. 52 53
      CamelotD3D9Renderer/Include/CmD3D9HardwarePixelBuffer.h
  14. 3 3
      CamelotD3D9Renderer/Source/CmD3D9HardwareIndexBuffer.cpp
  15. 1 1
      CamelotD3D9Renderer/Source/CmD3D9HardwarePixelBuffer.cpp
  16. 3 3
      CamelotD3D9Renderer/Source/CmD3D9HardwareVertexBuffer.cpp
  17. 14 0
      CamelotGLRenderer/Include/CmGLDepthStencilBuffer.h
  18. 2 2
      CamelotGLRenderer/Source/CmGLHardwareIndexBuffer.cpp
  19. 2 2
      CamelotGLRenderer/Source/CmGLHardwareVertexBuffer.cpp
  20. 21 0
      CamelotRenderer/Include/CmCommon.h
  21. 1 18
      CamelotRenderer/Include/CmHardwareBuffer.h
  22. 0 1
      CamelotRenderer/Include/CmHardwarePixelBuffer.h
  23. 7 17
      CamelotRenderer/Include/CmTexture.h
  24. 2 2
      CamelotRenderer/Source/CmHardwarePixelBuffer.cpp
  25. 1 1
      CamelotRenderer/Source/CmTexture.cpp
  26. 13 1
      CamelotRenderer/TODO.txt
  27. 2 0
      CamelotUtility/Include/CmPixelData.h

+ 6 - 0
CamelotD3D11RenderSystem/CamelotD3D11RenderSystem.vcxproj

@@ -154,13 +154,16 @@
     <ClInclude Include="Include\CmD3D11GpuProgram.h" />
     <ClInclude Include="Include\CmD3D11GpuProgram.h" />
     <ClInclude Include="Include\CmD3D11GpuProgramManager.h" />
     <ClInclude Include="Include\CmD3D11GpuProgramManager.h" />
     <ClInclude Include="Include\CmD3D11HardwareBuffer.h" />
     <ClInclude Include="Include\CmD3D11HardwareBuffer.h" />
+    <ClInclude Include="Include\CmD3D11HardwarePixelBuffer.h" />
     <ClInclude Include="Include\CmD3D11HLSLProgram.h" />
     <ClInclude Include="Include\CmD3D11HLSLProgram.h" />
     <ClInclude Include="Include\CmD3D11HardwareIndexBuffer.h" />
     <ClInclude Include="Include\CmD3D11HardwareIndexBuffer.h" />
     <ClInclude Include="Include\CmD3D11Mappings.h" />
     <ClInclude Include="Include\CmD3D11Mappings.h" />
     <ClInclude Include="Include\CmD3D11Prerequisites.h" />
     <ClInclude Include="Include\CmD3D11Prerequisites.h" />
     <ClInclude Include="Include\CmD3D11HardwareVertexBuffer.h" />
     <ClInclude Include="Include\CmD3D11HardwareVertexBuffer.h" />
     <ClInclude Include="Include\CmD3D11RenderSystem.h" />
     <ClInclude Include="Include\CmD3D11RenderSystem.h" />
+    <ClInclude Include="Include\CmD3D11RenderTexture.h" />
     <ClInclude Include="Include\CmD3D11RenderWindow.h" />
     <ClInclude Include="Include\CmD3D11RenderWindow.h" />
+    <ClInclude Include="Include\CmD3D11Texture.h" />
     <ClInclude Include="Include\CmD3D11VertexDeclaration.h" />
     <ClInclude Include="Include\CmD3D11VertexDeclaration.h" />
     <ClInclude Include="Include\CmD3D11VideoMode.h" />
     <ClInclude Include="Include\CmD3D11VideoMode.h" />
     <ClInclude Include="Include\CmD3D11VideoModeList.h" />
     <ClInclude Include="Include\CmD3D11VideoModeList.h" />
@@ -174,12 +177,15 @@
     <ClCompile Include="Source\CmD3D11HardwareBuffer.cpp" />
     <ClCompile Include="Source\CmD3D11HardwareBuffer.cpp" />
     <ClCompile Include="Source\CmD3D11HardwareBufferManager.cpp" />
     <ClCompile Include="Source\CmD3D11HardwareBufferManager.cpp" />
     <ClCompile Include="Source\CmD3D11HardwareConstantBuffer.cpp" />
     <ClCompile Include="Source\CmD3D11HardwareConstantBuffer.cpp" />
+    <ClCompile Include="Source\CmD3D11HardwarePixelBuffer.cpp" />
     <ClCompile Include="Source\CmD3D11HLSLProgram.cpp" />
     <ClCompile Include="Source\CmD3D11HLSLProgram.cpp" />
     <ClCompile Include="Source\CmD3D11HardwareIndexBuffer.cpp" />
     <ClCompile Include="Source\CmD3D11HardwareIndexBuffer.cpp" />
     <ClCompile Include="Source\CmD3D11Mappings.cpp" />
     <ClCompile Include="Source\CmD3D11Mappings.cpp" />
     <ClCompile Include="Source\CmD3D11HardwareVertexBuffer.cpp" />
     <ClCompile Include="Source\CmD3D11HardwareVertexBuffer.cpp" />
     <ClCompile Include="Source\CmD3D11RenderSystem.cpp" />
     <ClCompile Include="Source\CmD3D11RenderSystem.cpp" />
+    <ClCompile Include="Source\CmD3D11RenderTexture.cpp" />
     <ClCompile Include="Source\CmD3D11RenderWindow.cpp" />
     <ClCompile Include="Source\CmD3D11RenderWindow.cpp" />
+    <ClCompile Include="Source\CmD3D11Texture.cpp" />
     <ClCompile Include="Source\CmD3D11VertexDeclaration.cpp" />
     <ClCompile Include="Source\CmD3D11VertexDeclaration.cpp" />
     <ClCompile Include="Source\CmD3D11VideoMode.cpp" />
     <ClCompile Include="Source\CmD3D11VideoMode.cpp" />
     <ClCompile Include="Source\CmD3D11VideoModeList.cpp" />
     <ClCompile Include="Source\CmD3D11VideoModeList.cpp" />

+ 18 - 0
CamelotD3D11RenderSystem/CamelotD3D11RenderSystem.vcxproj.filters

@@ -69,6 +69,15 @@
     <ClInclude Include="Include\CmD3D11RenderWindow.h">
     <ClInclude Include="Include\CmD3D11RenderWindow.h">
       <Filter>Header Files</Filter>
       <Filter>Header Files</Filter>
     </ClInclude>
     </ClInclude>
+    <ClInclude Include="Include\CmD3D11HardwarePixelBuffer.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\CmD3D11Texture.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\CmD3D11RenderTexture.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\CmD3D11GpuProgram.cpp">
     <ClCompile Include="Source\CmD3D11GpuProgram.cpp">
@@ -122,5 +131,14 @@
     <ClCompile Include="Source\CmD3D11RenderWindow.cpp">
     <ClCompile Include="Source\CmD3D11RenderWindow.cpp">
       <Filter>Source Files</Filter>
       <Filter>Source Files</Filter>
     </ClCompile>
     </ClCompile>
+    <ClCompile Include="Source\CmD3D11HardwarePixelBuffer.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\CmD3D11Texture.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\CmD3D11RenderTexture.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   </ItemGroup>
 </Project>
 </Project>

+ 86 - 0
CamelotD3D11RenderSystem/Include/CmD3D11HardwarePixelBuffer.h

@@ -0,0 +1,86 @@
+#pragma once
+
+#include "CmD3D11Prerequisites.h"
+#include "CmHardwarePixelBuffer.h"
+
+namespace CamelotEngine
+{
+	class CM_D3D11_EXPORT D3D11HardwarePixelBuffer : public HardwarePixelBuffer
+	{
+	public:
+		D3D11HardwarePixelBuffer(D3D11Texture* parentTexture, D3D11Device& device, UINT32 subresourceIndex,
+			UINT32 width, UINT32 height, UINT32 depth, UINT32 face, PixelFormat format, HardwareBuffer::Usage usage);
+
+		/// @copydoc HardwarePixelBuffer::blit
+		void blit(const HardwarePixelBufferPtr& src, const Box& srcBox, const Box& dstBox);
+
+		/// @copydoc HardwarePixelBuffer::blitFromMemory
+		void blitFromMemory(const PixelData& src, const Box& dstBox);
+
+		/// @copydoc HardwarePixelBuffer::blitToMemory
+		void blitToMemory(const Box& srcBox, const PixelData& dst);
+
+		/// Internal function to update mipmaps on update of level 0
+		void _genMipmaps();
+
+		~D3D11HardwarePixelBuffer();
+
+		/// Get rendertarget for z slice
+		RenderTexture *getRenderTarget(UINT32 zoffset);
+
+		/// Notify TextureBuffer of destruction of render target
+		virtual void _clearSliceRTT(UINT32 zoffset)
+		{
+			if (mSliceTRT.size() > zoffset)
+			{
+				mSliceTRT[zoffset] = 0;
+			}
+		}
+
+		D3D11Texture * getParentTexture() const;
+		UINT32 getSubresourceIndex() const;
+		UINT32 getFace() const;
+
+	protected:
+		/// Lock a box
+		PixelData lockImpl(const Box lockBox, LockOptions options);
+
+		/// Unlock a box
+		void unlockImpl(void);
+
+		/// D3DDevice pointer
+		D3D11Device& mDevice;
+
+		D3D11Texture* mParentTexture;
+		UINT32 mSubresourceIndex;
+
+		// if the usage is static - alloc at lock then use device UpdateSubresource when unlock and free memory
+		UINT8* mDataForStaticUsageLock; 
+
+		UINT32 mFace;
+
+		Box mLockBox;
+		PixelData mCurrentLock;
+		LockOptions mCurrentLockOptions;
+
+		D3D11_BOX convertBoxToDx11Box(const Box &inBox) const;
+
+		/// Util functions to convert a D3D locked box to a pixel box
+		void fromD3DLock(PixelData &rval, const DXGI_MAPPED_RECT &lrect);
+
+		/// Render targets
+		typedef vector<RenderTexture*>::type SliceTRT;
+		SliceTRT mSliceTRT;
+
+		void createStagingBuffer();
+		bool mUsingStagingBuffer;
+		ID3D11Resource *mStagingBuffer;
+
+		void* _map(ID3D11Resource *res, D3D11_MAP flags);
+		void* _mapstagingbuffer(D3D11_MAP flags);
+		void* _mapstaticbuffer(PixelData lock);
+		void _unmap(ID3D11Resource *res);
+		void _unmapstagingbuffer(bool copyback = true);
+		void _unmapstaticbuffer();
+	};
+}

+ 4 - 1
CamelotD3D11RenderSystem/Include/CmD3D11Mappings.h

@@ -56,6 +56,7 @@ namespace CamelotEngine
 		static void get(const Color& inColour, float * outColour );
 		static void get(const Color& inColour, float * outColour );
 		static bool isMappingWrite(D3D11_MAP map);
 		static bool isMappingWrite(D3D11_MAP map);
 		static bool isMappingRead(D3D11_MAP map);
 		static bool isMappingRead(D3D11_MAP map);
+		static D3D11_BOX toDx11Box(const Box &inBox);
 
 
 		/// utility method, convert D3D11 pixel format to Ogre pixel format
 		/// utility method, convert D3D11 pixel format to Ogre pixel format
 		static PixelFormat _getPF(DXGI_FORMAT d3dPF);
 		static PixelFormat _getPF(DXGI_FORMAT d3dPF);
@@ -75,9 +76,11 @@ namespace CamelotEngine
 
 
 		static TextureType _getTexType(D3D11_SRV_DIMENSION type);
 		static TextureType _getTexType(D3D11_SRV_DIMENSION type);
 
 
-		static size_t _getSizeInBytes(PixelFormat pf, size_t xcount = 1, size_t ycount = 1);
+		static UINT32 _getSizeInBytes(PixelFormat pf, UINT32 xcount = 1, UINT32 ycount = 1);
 
 
 		static UINT _getTextureBindFlags(DXGI_FORMAT format, bool isdynamic);
 		static UINT _getTextureBindFlags(DXGI_FORMAT format, bool isdynamic);
 		static UINT _getTextureMiscFlags(UINT bindflags, TextureType textype, bool isdynamic);
 		static UINT _getTextureMiscFlags(UINT bindflags, TextureType textype, bool isdynamic);
+
+		static D3D11_MAP _getLockOptions(LockOptions lockOptions);
 	};
 	};
 }
 }

+ 23 - 0
CamelotD3D11RenderSystem/Include/CmD3D11RenderTexture.h

@@ -0,0 +1,23 @@
+#pragma once
+
+#include "CmD3D11Prerequisites.h"
+#include "CmRenderTexture.h"
+
+namespace CamelotEngine
+{
+	class D3D11RenderTexture : public RenderTexture
+	{
+		D3D11Device& mDevice;
+		ID3D11RenderTargetView* mRenderTargetView;
+		ID3D11DepthStencilView* mDepthStencilView;
+	public:
+		D3D11RenderTexture(const String &name, D3D11HardwarePixelBuffer *buffer, D3D11Device& device);
+		virtual ~D3D11RenderTexture();
+
+		void rebind(D3D11HardwarePixelBuffer *buffer);
+
+		virtual void getCustomAttribute(const String& name, void *pData);
+
+		bool requiresTextureFlipping() const { return false; }
+	};
+}

+ 81 - 0
CamelotD3D11RenderSystem/Include/CmD3D11Texture.h

@@ -0,0 +1,81 @@
+#pragma once
+
+#include "CmD3D11Prerequisites.h"
+#include "CmTexture.h"
+
+namespace CamelotEngine
+{
+	class D3D11Texture : public Texture
+	{
+	public:
+		~D3D11Texture();
+
+		/**
+		 * @copydoc Texture::setRawPixels_internal
+		 */
+		void setRawPixels_internal(const PixelData& data, UINT32 face = 0, UINT32 mip = 0);
+
+		/**
+		 * @copydoc Texture::getRawPixels_internal
+		 */
+		void getRawPixels_internal(UINT32 face, UINT32 mip, AsyncOp& op);
+
+		/**
+		 * @copydoc Texture::copy_internal
+		 */
+		void copy_internal(TexturePtr& target);
+
+		PixelData lock(LockOptions options, UINT32 mipLevel = 0, UINT32 face = 0);
+		void unlock();
+
+		ID3D11Resource* getDX11Resource() const { return mTex; }
+	protected:
+		D3D11Texture();
+
+		ID3D11Texture1D* m1DTex;
+		ID3D11Texture2D* m2DTex;
+		ID3D11Texture3D* m3DTex;	
+		ID3D11Resource* mTex;		
+
+		ID3D11ShaderResourceView* mShaderResourceView;
+		D3D11_SHADER_RESOURCE_VIEW_DESC mSRVDesc;
+
+		ID3D11Resource* mStagingBuffer;
+		PixelData* mStaticBuffer;
+		UINT32 mLockedSubresourceIdx;
+		bool mLockedForReading;
+
+		/// internal method, create a blank normal 1D Dtexture
+		void _create1DTex();
+		/// internal method, create a blank normal 2D texture
+		void _create2DTex();
+		/// internal method, create a blank cube texture
+		void _create3DTex();
+
+		void _createStagingBuffer();
+
+		void* _map(ID3D11Resource* res, D3D11_MAP flags, UINT32 mipLevel, UINT32 face);
+		void _unmap(ID3D11Resource* res);
+
+		void* _mapstagingbuffer(D3D11_MAP flags, UINT32 mipLevel, UINT32 face);
+		void _unmapstagingbuffer();
+		
+		void* _mapstaticbuffer(PixelData lock, UINT32 mipLevel, UINT32 slice);
+		void _unmapstaticbuffer();
+
+		/**
+		 * @brief	Resource::initialize_internal
+		 */
+		void initialize_internal();
+
+		/**
+		 * @copydoc Texture::createInternalResourcesImpl
+		 */
+		void createInternalResourcesImpl();
+		
+		/**
+		 * @copydoc Texture::freeInternalResourcesImpl
+		 */
+		void freeInternalResourcesImpl();
+	};
+}

+ 4 - 4
CamelotD3D11RenderSystem/Source/CmD3D11HardwareBuffer.cpp

@@ -72,7 +72,7 @@ namespace CamelotEngine
 
 
 			switch(options)
 			switch(options)
 			{
 			{
-			case HBL_DISCARD:
+			case HBL_WRITE_ONLY_DISCARD:
 				if (mUsage & HardwareBuffer::HBU_DYNAMIC)
 				if (mUsage & HardwareBuffer::HBU_DYNAMIC)
 				{
 				{
 					// Map cannot be called with MAP_WRITE access, 
 					// Map cannot be called with MAP_WRITE access, 
@@ -92,7 +92,7 @@ namespace CamelotEngine
 					LOGWRN("DISCARD lock is only available on dynamic buffers. Falling back to normal write.");
 					LOGWRN("DISCARD lock is only available on dynamic buffers. Falling back to normal write.");
 				}
 				}
 				break;
 				break;
-			case HBL_NO_OVERWRITE:
+			case HBL_WRITE_ONLY_NO_OVERWRITE:
 				if(mBufferType == INDEX_BUFFER || mBufferType == VERTEX_BUFFER)
 				if(mBufferType == INDEX_BUFFER || mBufferType == VERTEX_BUFFER)
 					mapType = D3D11_MAP_WRITE_NO_OVERWRITE;
 					mapType = D3D11_MAP_WRITE_NO_OVERWRITE;
 				else
 				else
@@ -102,7 +102,7 @@ namespace CamelotEngine
 					LOGWRN("NO_OVERWRITE lock is not available on this (" + toString(mBufferType) + ") buffer type. Falling back to normal write.");
 					LOGWRN("NO_OVERWRITE lock is not available on this (" + toString(mBufferType) + ") buffer type. Falling back to normal write.");
 				}
 				}
 				break;
 				break;
-			case HBL_NORMAL:
+			case HBL_READ_WRITE:
 				if ((mDesc.CPUAccessFlags & D3D11_CPU_ACCESS_READ) != 0 &&
 				if ((mDesc.CPUAccessFlags & D3D11_CPU_ACCESS_READ) != 0 &&
 					(mDesc.CPUAccessFlags & D3D11_CPU_ACCESS_WRITE) != 0)
 					(mDesc.CPUAccessFlags & D3D11_CPU_ACCESS_WRITE) != 0)
 				{
 				{
@@ -154,7 +154,7 @@ namespace CamelotEngine
 			}
 			}
 
 
 			// schedule a copy to the staging
 			// schedule a copy to the staging
-			if (options != HBL_DISCARD)
+			if (options != HBL_WRITE_ONLY_DISCARD)
 				mpTempStagingBuffer->copyData(*this, 0, 0, mSizeInBytes, true);
 				mpTempStagingBuffer->copyData(*this, 0, 0, mSizeInBytes, true);
 
 
 			// register whether we'll need to upload on unlock
 			// register whether we'll need to upload on unlock

+ 765 - 0
CamelotD3D11RenderSystem/Source/CmD3D11HardwarePixelBuffer.cpp

@@ -0,0 +1,765 @@
+#include "CmD3D11HardwarePixelBuffer.h"
+#include "CmD3D11Device.h"
+#include "CmD3D11Mappings.h"
+#include "CmRenderSystem.h"
+#include "CmTexture.h"
+#include "CmDataStream.h"
+
+namespace CamelotEngine
+{
+	D3D11HardwarePixelBuffer::D3D11HardwarePixelBuffer(D3D11Texture* parentTexture, D3D11Device& device, UINT32 subresourceIndex,
+		UINT32 width, UINT32 height, UINT32 depth, UINT32 face, PixelFormat format, HardwareBuffer::Usage usage):
+	HardwarePixelBuffer(width, height, depth, format, usage, false),
+		mParentTexture(parentTexture),
+		mDevice(device),
+		mSubresourceIndex(subresourceIndex),
+		mFace(face),
+		mDataForStaticUsageLock(0),
+		mStagingBuffer(NULL)
+	{
+		if(mUsage & TU_RENDERTARGET)
+		{
+			// Create render target for each slice
+			mSliceTRT.reserve(mDepth);
+			for(UINT32 zoffset = 0; zoffset < mDepth; ++zoffset)
+			{
+				String name;
+				name = "rtt/" + toString((UINT32)mParentTexture) + "/" + toString(mSubresourceIndex);
+
+				RenderTexture *trt = new D3D11RenderTexture(name, this, mDevice);
+				mSliceTRT.push_back(trt);
+				
+				RenderSystem::instance().attachRenderTarget(*trt);
+			}
+		}
+	}
+
+	D3D11HardwarePixelBuffer::~D3D11HardwarePixelBuffer()
+	{
+		if(!mSliceTRT.empty())
+		{	
+			// Delete all render targets that are not yet deleted via _clearSliceRTT
+			for(UINT32 zoffset = 0; zoffset < mDepth; ++zoffset)
+			{
+				if(mSliceTRT[zoffset])
+					RenderSystem::instance().destroyRenderTarget(mSliceTRT[zoffset]);
+			}
+		}
+
+		SAFE_DELETE_ARRAY(mDataForStaticUsageLock);
+		SAFE_RELEASE(mStagingBuffer);
+	}
+  
+	// Util functions to convert a D3D locked box to a pixel box
+	void D3D11HardwarePixelBuffer::fromD3DLock(PixelData& rval, const DXGI_MAPPED_RECT& lrect)
+	{
+		rval.rowPitch = lrect.Pitch / PixelUtil::getNumElemBytes(rval.format);
+		rval.slicePitch = rval.rowPitch * rval.getHeight();
+		assert((lrect.Pitch % PixelUtil::getNumElemBytes(rval.format))==0);
+		rval.data = lrect.pBits;
+	}
+
+	void* D3D11HardwarePixelBuffer::_map(ID3D11Resource *res, D3D11_MAP flags)
+	{
+		D3D11_MAPPED_SUBRESOURCE pMappedResource;
+		pMappedResource.pData = NULL;
+
+		switch(mParentTexture->getTextureType()) 
+		{
+		case TEX_TYPE_1D:
+			{  
+				mDevice.getImmediateContext()->Map(res, static_cast<UINT>(mSubresourceIndex), flags, 0, &pMappedResource);
+				if (mDevice.hasError())
+				{
+					String errorDescription = mDevice.getErrorDescription();
+					CM_EXCEPT(RenderingAPIException, "D3D11 device cannot map 1D texture\nError Description:" + errorDescription);
+				}
+			}
+			break;
+		case TEX_TYPE_CUBE_MAP:
+		case TEX_TYPE_2D:
+			{
+				mDevice.getImmediateContext()->Map(res, D3D11CalcSubresource(static_cast<UINT>(mSubresourceIndex), mFace, mParentTexture->getNumMipmaps()+1), 
+					flags, 0, &pMappedResource);
+				if (mDevice.hasError())
+				{
+					String errorDescription = mDevice.getErrorDescription();
+					CM_EXCEPT(RenderingAPIException, "D3D11 device cannot map 2D texture\nError Description:" + errorDescription);
+				}
+			}
+			break;
+		case TEX_TYPE_2D_ARRAY:
+			{
+				mDevice.getImmediateContext()->Map(res, D3D11CalcSubresource(static_cast<UINT>(mSubresourceIndex), mLockBox.front, mParentTexture->getNumMipmaps()+1), 
+					flags, 0, &pMappedResource);
+				if (mDevice.hasError())
+				{
+					String errorDescription = mDevice.getErrorDescription();
+					CM_EXCEPT(RenderingAPIException, "D3D11 device cannot map 2D texture array\nError Description:" + errorDescription);
+				}
+			}
+			break;
+		case TEX_TYPE_3D:
+			{
+				mDevice.getImmediateContext()->Map(res, static_cast<UINT>(mSubresourceIndex), flags, 0, &pMappedResource);
+
+				if (mDevice.hasError())
+				{
+					String errorDescription = mDevice.getErrorDescription();
+					CM_EXCEPT(RenderingAPIException, "D3D11 device cannot map 3D texture\nError Description:" + errorDescription);
+				}
+			}
+			break;
+		}
+
+		return pMappedResource.pData;
+	}
+
+	void *D3D11HardwarePixelBuffer::_mapstaticbuffer(PixelData lock)
+	{
+		// for static usage just alloc
+		size_t sizeOfImage = lock.getConsecutiveSize();
+		
+		mDataForStaticUsageLock = new UINT8[sizeOfImage];
+		return mDataForStaticUsageLock;
+	}
+  
+	void *D3D11HardwarePixelBuffer::_mapstagingbuffer(D3D11_MAP flags)
+	{
+		if(!mStagingBuffer)
+			createStagingBuffer();
+
+		if(flags == D3D11_MAP_READ_WRITE || flags == D3D11_MAP_READ || flags == D3D11_MAP_WRITE)  
+		{
+			if(mLockBox.getHeight() == mParentTexture->getHeight() && mLockBox.getWidth() == mParentTexture->getWidth())
+				mDevice.getImmediateContext()->CopyResource(mStagingBuffer, mParentTexture->getTextureResource());
+			else
+			{
+				D3D11_BOX dstBoxDx11 = convertBoxToDx11Box(mLockBox);
+				dstBoxDx11.front = 0;
+				dstBoxDx11.back = mLockBox.getDepth();
+
+				unsigned int subresource = D3D11CalcSubresource(mSubresourceIndex, mLockBox.front, mParentTexture->getNumMipmaps()+1);
+				mDevice.getImmediateContext()->CopySubresourceRegion(mStagingBuffer, subresource, mLockBox.left, mLockBox.top, 
+					mSubresourceIndex, mParentTexture->getTextureResource(), subresource, &dstBoxDx11);
+			}
+		}
+		else if(flags == D3D11_MAP_WRITE_DISCARD)
+			flags = D3D11_MAP_WRITE; // stagingbuffer doesn't support discarding
+
+		return _map(mStagingBuffer, flags);
+	}
+ 
+	PixelData D3D11HardwarePixelBuffer::lockImpl(const Box lockBox, LockOptions options)
+	{
+		// Check for misuse
+		if(mUsage & TU_RENDERTARGET)
+			CM_EXCEPT(RenderingAPIException, "DirectX does not allow locking of or directly writing to RenderTargets. Use blitFromMemory if you need the contents.");	
+
+		mLockBox = lockBox;
+
+		// Set extents and format
+		// Note that we do not carry over the left/top/front here, since the returned
+		// PixelBox will be re-based from the locking point onwards
+		PixelData rval(lockBox.getWidth(), lockBox.getHeight(), lockBox.getDepth(), mFormat);
+		// Set locking flags according to options
+		D3D11_MAP  flags = D3D11_MAP_WRITE_DISCARD ;
+		switch(options)
+		{
+		case HBL_WRITE_ONLY_NO_OVERWRITE:
+			flags = D3D11_MAP_WRITE_NO_OVERWRITE;
+			break;
+		case HBL_READ_WRITE:
+			flags = D3D11_MAP_READ_WRITE;
+			break;
+		case HBL_WRITE_ONLY_DISCARD:
+			flags = D3D11_MAP_WRITE_DISCARD;
+			break;
+		case HBL_READ_ONLY:
+			flags = D3D11_MAP_READ;
+			break;
+		case HBL_WRITE_ONLY:
+			flags = D3D11_MAP_WRITE;
+			break;
+		default: 
+			break;
+		};
+
+		size_t offset = 0;
+
+		if(mUsage == HBU_STATIC || mUsage & HBU_DYNAMIC)
+		{
+			if(mUsage == HBU_STATIC || options == HBL_READ_ONLY || options == HBL_READ_WRITE || options == HBL_WRITE_ONLY)
+				rval.data = _mapstagingbuffer(flags);
+			else
+				rval.data = _map(mParentTexture->getTextureResource(), flags);
+
+			// calculate the offset in bytes
+			offset = D3D11Mappings::_getSizeInBytes(rval.format, rval.left, rval.front);
+			// add the offset, so the right memory will be changed
+			//rval.data = static_cast<int*>(rval.data) + offset;
+		}
+		else
+		{
+			size_t sizeOfImage = rval.getConsecutiveSize();
+            mDataForStaticUsageLock = new UINT8[sizeOfImage];
+            rval.data = mDataForStaticUsageLock;
+		}
+		// save without offset
+ 		mCurrentLock = rval;
+		mCurrentLockOptions = options;
+
+		// add the offset, so the right memory will be changed
+		rval.data = static_cast<int*>(rval.data) + offset;
+
+		return rval;
+	}
+
+	void D3D11HardwarePixelBuffer::_unmap(ID3D11Resource *res)
+	{
+		switch(mParentTexture->getTextureType()) {
+		case TEX_TYPE_1D:
+			{
+				mDevice.getImmediateContext()->Unmap(res, mSubresourceIndex);
+			}
+			break;
+		case TEX_TYPE_CUBE_MAP:
+		case TEX_TYPE_2D:
+			{							  
+				mDevice.getImmediateContext()->Unmap(res, D3D11CalcSubresource(static_cast<UINT>(mSubresourceIndex), mFace, mParentTexture->getNumMipmaps()+1));
+			}
+			break;
+		case TEX_TYPE_2D_ARRAY:
+			{
+				mDevice.getImmediateContext()->Unmap(res, D3D11CalcSubresource(static_cast<UINT>(mSubresourceIndex), mLockBox.front, mParentTexture->getNumMipmaps()+1));
+			}
+			break;
+		case TEX_TYPE_3D:
+			{
+				mDevice.getImmediateContext()->Unmap(res, mSubresourceIndex);
+			}
+			break;
+		}
+
+		if (mDevice.hasError())
+		{
+			String errorDescription = mDevice.getErrorDescription();
+			CM_EXCEPT(RenderingAPIException, "D3D11 device unmap resource\nError Description:" + errorDescription);
+		}
+	}
+
+	void D3D11HardwarePixelBuffer::_unmapstaticbuffer()
+	{
+		D3D11_BOX dstBoxDx11 = convertBoxToDx11Box(mLockBox);
+		dstBoxDx11.front = 0;
+		dstBoxDx11.back = mLockBox.getDepth();
+
+		size_t rowWidth = D3D11Mappings::_getSizeInBytes(mCurrentLock.format, mCurrentLock.getWidth());
+
+		switch(mParentTexture->getTextureType()) {
+		case TEX_TYPE_1D:
+			{
+
+				mDevice.getImmediateContext()->UpdateSubresource(mParentTexture->GetTex1D(), 
+					static_cast<UINT>(mSubresourceIndex), &dstBoxDx11, 
+					mDataForStaticUsageLock, rowWidth, 0);
+				if (mDevice.hasError())
+				{
+					String errorDescription = mDevice.getErrorDescription();
+					CM_EXCEPT(RenderingAPIException, "D3D11 device cannot map 1D texture\nError Description:" + errorDescription);
+				}
+			}
+			break;
+		case TEX_TYPE_CUBE_MAP:
+		case TEX_TYPE_2D:
+			{
+				mDevice.getImmediateContext()->UpdateSubresource(mParentTexture->GetTex2D(), 
+					D3D11CalcSubresource(static_cast<UINT>(mSubresourceIndex), mFace, mParentTexture->getNumMipmaps()+1),
+					&dstBoxDx11, 
+					mDataForStaticUsageLock, rowWidth, 0);
+
+				if (mDevice.hasError())
+				{
+					String errorDescription = mDevice.getErrorDescription();
+					CM_EXCEPT(RenderingAPIException, "D3D11 device cannot map 2D texture\nError Description:" + errorDescription);
+				}
+			}
+			break;
+		case TEX_TYPE_2D_ARRAY:
+			{
+				mDevice.getImmediateContext()->UpdateSubresource(mParentTexture->GetTex2D(), 
+					D3D11CalcSubresource(static_cast<UINT>(mSubresourceIndex), mLockBox.front, mParentTexture->getNumMipmaps()+1),
+					&dstBoxDx11, mDataForStaticUsageLock, rowWidth, 0);
+
+				if (mDevice.hasError())
+				{
+					String errorDescription = mDevice.getErrorDescription();
+					CM_EXCEPT(RenderingAPIException, "D3D11 device cannot map 2D texture array\nError Description:" + errorDescription);
+				}
+			}
+			break;
+		case TEX_TYPE_3D:
+			{
+				size_t sliceWidth = D3D11Mappings::_getSizeInBytes(mCurrentLock.format, mCurrentLock.getWidth(), mCurrentLock.getHeight());
+
+				mDevice.getImmediateContext()->UpdateSubresource(mParentTexture->GetTex3D(), static_cast<UINT>(mSubresourceIndex), 
+					&dstBoxDx11, mDataForStaticUsageLock, rowWidth, sliceWidth);
+				if (mDevice.hasError())
+				{
+					String errorDescription = mDevice.getErrorDescription();
+					CM_EXCEPT(RenderingAPIException, "D3D11 device cannot map 3D texture\nError Description:" + errorDescription);
+				}
+			}
+			break;
+		}
+
+		SAFE_DELETE_ARRAY(mDataForStaticUsageLock) ;
+	}
+  
+	void D3D11HardwarePixelBuffer::_unmapstagingbuffer(bool copyback)
+	{
+		_unmap(mStagingBuffer);
+
+		if(copyback)
+		{
+			if(mLockBox.getHeight() == mParentTexture->getHeight() && mLockBox.getWidth() == mParentTexture->getWidth())
+				mDevice.getImmediateContext()->CopyResource(mParentTexture->getTextureResource(), mStagingBuffer);
+			else
+			{
+				D3D11_BOX dstBoxDx11 = convertBoxToDx11Box(mLockBox);
+				dstBoxDx11.front = 0;
+				dstBoxDx11.back = mLockBox.getDepth();
+
+				unsigned int subresource = D3D11CalcSubresource(mSubresourceIndex, mLockBox.front, mParentTexture->getNumMipmaps()+1);
+				mDevice.getImmediateContext()->CopySubresourceRegion(mParentTexture->getTextureResource(), subresource, mLockBox.left, mLockBox.top, mSubresourceIndex, mStagingBuffer, subresource, &dstBoxDx11);
+			}
+		}
+	}
+ 
+	void D3D11HardwarePixelBuffer::unlockImpl(void)
+	{
+		if(mUsage == HBU_STATIC)
+			_unmapstagingbuffer();
+		else if(mUsage & HBU_DYNAMIC)
+ 		{
+			if(mCurrentLockOptions == HBL_READ_ONLY || mCurrentLockOptions == HBL_READ_WRITE || mCurrentLockOptions == HBL_WRITE_ONLY)
+			{
+				size_t sizeinbytes = D3D11Mappings::_getSizeInBytes(mParentTexture->getFormat(), mParentTexture->getWidth(), mParentTexture->getHeight());
+
+				void *data = _map(mParentTexture->getTextureResource(), D3D11_MAP_WRITE_DISCARD);
+
+				memcpy(data, mCurrentLock.data, sizeinbytes);
+
+				// unmap the texture and the staging buffer
+				_unmap(mParentTexture->getTextureResource());
+
+				_unmapstagingbuffer(false);
+ 			}
+			else
+				_unmap(mParentTexture->getTextureResource());
+ 		}
+ 		else
+			_unmapstaticbuffer();
+	}
+
+	D3D11_BOX D3D11HardwarePixelBuffer::convertBoxToDx11Box(const Box &inBox) const
+	{
+		D3D11_BOX res;
+		res.left	= static_cast<UINT>(inBox.left);
+		res.top		= static_cast<UINT>(inBox.top);
+		res.front	= static_cast<UINT>(inBox.front);
+		res.right	= static_cast<UINT>(inBox.right);
+		res.bottom	= static_cast<UINT>(inBox.bottom);
+		res.back	= static_cast<UINT>(inBox.back);
+
+		return res;
+	}
+
+	void D3D11HardwarePixelBuffer::blit(const HardwarePixelBufferPtr &rsrc, const Box &srcBox, const Box &dstBox)
+	{
+		if (
+			(srcBox.getWidth() != dstBox.getWidth())
+			|| (srcBox.getHeight() != dstBox.getHeight())
+			|| (srcBox.getDepth() != dstBox.getDepth())
+			)
+		{
+			CM_EXCEPT(RenderingAPIException, 
+				"D3D11 device cannot copy a subresource - source and dest size are not the same and they have to be the same in DX11.");
+		}
+
+		D3D11_BOX srcBoxDx11 = convertBoxToDx11Box(srcBox);
+		D3D11HardwarePixelBuffer* rsrcDx11 = static_cast<D3D11HardwarePixelBuffer*>(rsrc.get());
+
+		switch(mParentTexture->getTextureType()) {
+		case TEX_TYPE_1D:
+			{
+
+				mDevice.getImmediateContext()->CopySubresourceRegion(
+					mParentTexture->GetTex1D(), 
+					static_cast<UINT>(mSubresourceIndex),
+					static_cast<UINT>(dstBox.left),
+					0,
+					0,
+					rsrcDx11->mParentTexture->GetTex1D(),
+					static_cast<UINT>(rsrcDx11->mSubresourceIndex),
+					&srcBoxDx11);
+				if (mDevice.hasError())
+				{
+					String errorDescription = mDevice.getErrorDescription();
+					CM_EXCEPT(RenderingAPIException, "D3D11 device cannot copy 1d subresource Region\nError Description:" + errorDescription);
+				}			
+			}
+			break;
+		case TEX_TYPE_CUBE_MAP:
+		case TEX_TYPE_2D:
+			{
+				mDevice.getImmediateContext()->CopySubresourceRegion(
+					mParentTexture->GetTex2D(), 
+					D3D11CalcSubresource(static_cast<UINT>(mSubresourceIndex), mFace, mParentTexture->getNumMipmaps()+1),
+					static_cast<UINT>(dstBox.left),
+					static_cast<UINT>(dstBox.top),
+					mFace,
+					rsrcDx11->mParentTexture->GetTex2D(),
+					static_cast<UINT>(rsrcDx11->mSubresourceIndex),
+					&srcBoxDx11);
+				if (mDevice.hasError())
+				{
+					String errorDescription = mDevice.getErrorDescription();
+					CM_EXCEPT(RenderingAPIException, "D3D11 device cannot copy 2d subresource Region\nError Description:" + errorDescription);
+				}
+			}
+			break;
+		case TEX_TYPE_2D_ARRAY:
+			{
+				mDevice.getImmediateContext()->CopySubresourceRegion(
+					mParentTexture->GetTex2D(), 
+					D3D11CalcSubresource(static_cast<UINT>(mSubresourceIndex), srcBox.front, mParentTexture->getNumMipmaps()+1),
+					static_cast<UINT>(dstBox.left),
+					static_cast<UINT>(dstBox.top),
+					srcBox.front,
+					rsrcDx11->mParentTexture->GetTex2D(),
+					static_cast<UINT>(rsrcDx11->mSubresourceIndex),
+					&srcBoxDx11);
+				if (mDevice.hasError())
+				{
+					String errorDescription = mDevice.getErrorDescription();
+					CM_EXCEPT(RenderingAPIException, "D3D11 device cannot copy 2d subresource Region\nError Description:" + errorDescription);
+				}
+			}
+			break;
+		case TEX_TYPE_3D:
+			{
+				mDevice.getImmediateContext()->CopySubresourceRegion(
+					mParentTexture->GetTex3D(), 
+					static_cast<UINT>(mSubresourceIndex),
+					static_cast<UINT>(dstBox.left),
+					static_cast<UINT>(dstBox.top),
+					static_cast<UINT>(dstBox.front),
+					rsrcDx11->mParentTexture->GetTex3D(),
+					static_cast<UINT>(rsrcDx11->mSubresourceIndex),
+					&srcBoxDx11);
+				if (mDevice.hasError())
+				{
+					String errorDescription = mDevice.getErrorDescription();
+					CM_EXCEPT(RenderingAPIException, "D3D11 device cannot copy 3d subresource Region\nError Description:" + errorDescription);
+				}
+			}
+			break;
+		}
+
+		_genMipmaps();
+	}
+ 
+	void D3D11HardwarePixelBuffer::blitFromMemory(const PixelData& src, const Box& dstBox)
+	{
+		bool isCompressed = false;
+		switch(mFormat)
+		{
+		case PF_DXT1:
+		case PF_DXT2:
+		case PF_DXT3:
+		case PF_DXT4:
+		case PF_DXT5:
+			isCompressed = true;
+			break;
+		default:
+
+			break;
+		}
+
+		if (isCompressed && (dstBox.getWidth() % 4 != 0 || dstBox.getHeight() % 4 != 0 ))
+		{
+			return;
+		}
+
+
+		// for scoped deletion of conversion buffer
+		PixelData converted = src;
+
+		D3D11_BOX dstBoxDx11 = convertBoxToDx11Box(dstBox);
+		dstBoxDx11.front = 0;
+		dstBoxDx11.back = converted.getDepth();
+
+		// convert to pixelbuffer's native format if necessary
+		if (src.format != mFormat)
+		{
+			MemoryDataStreamPtr buf(new MemoryDataStream(PixelUtil::getMemorySize(src.getWidth(), src.getHeight(), src.getDepth(), mFormat)));
+			converted = PixelData(src.getWidth(), src.getHeight(), src.getDepth(), mFormat, buf->getPtr());
+			PixelUtil::bulkPixelConversion(src, converted);
+		}
+
+		if (mUsage & HBU_DYNAMIC)
+		{
+			size_t sizeinbytes;
+			if (PixelUtil::isCompressed(converted.format))
+ 			{
+				// D3D wants the width of one row of cells in bytes
+				if (converted.format == PF_DXT1)
+				{
+					// 64 bits (8 bytes) per 4x4 block
+					sizeinbytes = std::max<size_t>(1, converted.getWidth() / 4) * std::max<size_t>(1, converted.getHeight() / 4) * 8;
+				}
+				else
+				{
+					// 128 bits (16 bytes) per 4x4 block
+					sizeinbytes = std::max<size_t>(1, converted.getWidth() / 4) * std::max<size_t>(1, converted.getHeight() / 4) * 16;
+				}
+ 			}
+ 			else
+ 			{
+				sizeinbytes = converted.getHeight() * converted.getWidth() * PixelUtil::getNumElemBytes(converted.format);
+ 			}
+ 
+			const PixelData& locked = lock(dstBox, HBL_WRITE_ONLY_DISCARD);
+
+			memcpy(locked.data, converted.data, sizeinbytes);
+
+			unlock();
+ 		}
+ 		else
+		{
+			size_t rowWidth;
+			if (PixelUtil::isCompressed(converted.format))
+ 			{
+				// D3D wants the width of one row of cells in bytes
+				if (converted.format == PF_DXT1)
+ 				{
+					// 64 bits (8 bytes) per 4x4 block
+					rowWidth = (converted.rowPitch / 4) * 8;
+				}
+				else
+				{
+					// 128 bits (16 bytes) per 4x4 block
+					rowWidth = (converted.rowPitch / 4) * 16;
+ 				}
+ 			}
+			else
+ 			{
+				rowWidth = converted.rowPitch * PixelUtil::getNumElemBytes(converted.format);
+			}
+
+			switch(mParentTexture->getTextureType()) {
+			case TEX_TYPE_1D:
+ 				{
+
+					mDevice.getImmediateContext()->UpdateSubresource( 
+						mParentTexture->GetTex1D(), 
+						0,
+						&dstBoxDx11,
+						converted.data,
+						rowWidth,
+						0 );
+					if (mDevice.hasError())
+					{
+						String errorDescription = mDevice.getErrorDescription();
+						CM_EXCEPT(RenderingAPIException, "D3D11 device cannot update 1d subresource\nError Description:" + errorDescription);
+					}
+ 				}
+				break;
+			case TEX_TYPE_CUBE_MAP:
+			case TEX_TYPE_2D:
+ 				{
+					mDevice.getImmediateContext()->UpdateSubresource( 
+						mParentTexture->GetTex2D(), 
+						D3D11CalcSubresource(static_cast<UINT>(mSubresourceIndex), mFace, mParentTexture->getNumMipmaps()+1),
+						&dstBoxDx11,
+						converted.data,
+						rowWidth,
+						0 );
+					if (mDevice.hasError())
+					{
+						String errorDescription = mDevice.getErrorDescription();
+						CM_EXCEPT(RenderingAPIException, "D3D11 device cannot update 2d subresource\nError Description:" + errorDescription);
+					}
+ 				}
+				break;
+			case TEX_TYPE_2D_ARRAY:
+ 				{
+					mDevice.getImmediateContext()->UpdateSubresource( 
+						mParentTexture->GetTex2D(), 
+						D3D11CalcSubresource(static_cast<UINT>(mSubresourceIndex), src.front, mParentTexture->getNumMipmaps()+1),
+						&dstBoxDx11,
+						converted.data,
+						rowWidth,
+						0 );
+					if (mDevice.hasError())
+ 					{
+						String errorDescription = mDevice.getErrorDescription();
+						CM_EXCEPT(RenderingAPIException, "D3D11 device cannot update 2d array subresource\nError Description:" + errorDescription);
+				}
+				}
+				break;
+			case TEX_TYPE_3D:
+				{
+					// copied from dx9
+					size_t sliceWidth;
+					if (PixelUtil::isCompressed(converted.format))
+					{
+						// D3D wants the width of one slice of cells in bytes
+						if (converted.format == PF_DXT1)
+						{
+							// 64 bits (8 bytes) per 4x4 block
+							sliceWidth = (converted.slicePitch / 16) * 8;
+						}
+						else
+						{
+							// 128 bits (16 bytes) per 4x4 block
+							sliceWidth = (converted.slicePitch / 16) * 16;
+						}
+
+ 					}
+ 					else
+ 					{
+						sliceWidth = converted.slicePitch * PixelUtil::getNumElemBytes(converted.format);
+ 					}
+ 
+					mDevice.getImmediateContext()->UpdateSubresource( 
+						mParentTexture->GetTex3D(), 
+						static_cast<UINT>(mSubresourceIndex),
+						&dstBoxDx11,
+						converted.data,
+						rowWidth,
+						sliceWidth
+						);
+					if (mDevice.hasError())
+					{
+						String errorDescription = mDevice.getErrorDescription();
+						CM_EXCEPT(RenderingAPIException, "D3D11 device cannot update 3d subresource\nError Description:" + errorDescription);
+					}
+ 				}
+				break;
+			}
+ 
+			if (!isCompressed)
+			{
+				_genMipmaps();
+ 			}
+		}	
+ 	}
+
+	void D3D11HardwarePixelBuffer::blitToMemory(const Box &srcBox, const PixelData &dst)
+	{
+		if(mParentTexture->getTextureType() != TEX_TYPE_2D)
+		{
+			CM_EXCEPT(NotImplementedException, "Only implemeted for 2D buffers.");
+		}
+
+		PixelData lockedData = lock(srcBox, HardwareBuffer::HBL_READ_ONLY);
+
+		if(dst.getConsecutiveSize() != lockedData.getConsecutiveSize())
+		{
+			unlock();
+
+			CM_EXCEPT(RenderingAPIException, "Size of the provided buffer (" + toString(dst.getConsecutiveSize()) + "), doesn't "
+				+ "match the size of the texture buffer (" + toString(lockedData.getConsecutiveSize()) + ").");
+		}
+
+		memcpy(dst.data, lockedData.data, lockedData.getConsecutiveSize());
+
+		unlock();
+	}
+  
+	void D3D11HardwarePixelBuffer::_genMipmaps()
+	{
+        if(mParentTexture->HasAutoMipMapGenerationEnabled())
+ 		{
+            ID3D11ShaderResourceView *pShaderResourceView = mParentTexture->getTexture();
+			mDevice.getImmediateContext()->GenerateMips(pShaderResourceView);
+			if (mDevice.hasError())
+			{
+				String errorDescription = mDevice.getErrorDescription();
+				CM_EXCEPT(RenderingAPIException, "D3D11 device cannot generate mips\nError Description:" + errorDescription);
+			}	
+		}
+	}
+    
+	RenderTexture *D3D11HardwarePixelBuffer::getRenderTarget(UINT32 zoffset)
+	{
+		assert(mUsage & TU_RENDERTARGET);
+		assert(zoffset < mDepth);
+		return mSliceTRT[zoffset];
+	}
+
+	D3D11Texture * D3D11HardwarePixelBuffer::getParentTexture() const
+	{
+		return mParentTexture;
+	}
+    
+	UINT32 D3D11HardwarePixelBuffer::getSubresourceIndex() const
+	{
+		return mSubresourceIndex;
+	}
+   
+	UINT32 D3D11HardwarePixelBuffer::getFace() const
+	{
+		return mFace;
+	}
+   
+	void D3D11HardwarePixelBuffer::createStagingBuffer()
+	{
+		switch (mParentTexture->getTextureType())
+		{
+		case TEX_TYPE_1D:
+			{
+				D3D11_TEXTURE1D_DESC desc;
+				mParentTexture->GetTex1D()->GetDesc(&desc);
+
+				desc.BindFlags = 0;
+				desc.MiscFlags = 0;
+				desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ;
+				desc.Usage = D3D11_USAGE_STAGING;
+
+				mDevice.getD3D11Device()->CreateTexture1D(&desc, NULL, (ID3D11Texture1D**)(&mStagingBuffer));
+			} 					
+			break;
+		case TEX_TYPE_2D:
+		case TEX_TYPE_CUBE_MAP:
+		case TEX_TYPE_2D_ARRAY:
+			{
+				D3D11_TEXTURE2D_DESC desc;
+				mParentTexture->GetTex2D()->GetDesc(&desc);
+
+				desc.BindFlags = 0;
+				desc.MiscFlags = 0;
+				desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ;
+				desc.Usage = D3D11_USAGE_STAGING;
+
+				mDevice.getD3D11Device()->CreateTexture2D(&desc, NULL, (ID3D11Texture2D**)(&mStagingBuffer));
+			}
+			break;
+		case TEX_TYPE_3D:
+			{
+				D3D11_TEXTURE3D_DESC desc;
+				mParentTexture->GetTex3D()->GetDesc(&desc);
+
+				desc.BindFlags = 0;
+				desc.MiscFlags = 0;
+				desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ;
+				desc.Usage = D3D11_USAGE_STAGING;
+
+				mDevice.getD3D11Device()->CreateTexture3D(&desc, NULL, (ID3D11Texture3D**)(&mStagingBuffer));
+			}
+			break;
+		}
+	}
+}

+ 42 - 3
CamelotD3D11RenderSystem/Source/CmD3D11Mappings.cpp

@@ -431,6 +431,19 @@ namespace CamelotEngine
 		outColour[3] = inColour.a;	
 		outColour[3] = inColour.a;	
 	}
 	}
 
 
+	D3D11_BOX D3D11Mappings::toDx11Box(const Box &inBox)
+	{
+		D3D11_BOX res;
+		res.left	= static_cast<UINT>(inBox.left);
+		res.top		= static_cast<UINT>(inBox.top);
+		res.front	= static_cast<UINT>(inBox.front);
+		res.right	= static_cast<UINT>(inBox.right);
+		res.bottom	= static_cast<UINT>(inBox.bottom);
+		res.back	= static_cast<UINT>(inBox.back);
+
+		return res;
+	}
+
 	PixelFormat D3D11Mappings::_getPF(DXGI_FORMAT d3dPF)
 	PixelFormat D3D11Mappings::_getPF(DXGI_FORMAT d3dPF)
 	{
 	{
 		switch(d3dPF)
 		switch(d3dPF)
@@ -786,7 +799,7 @@ namespace CamelotEngine
 		}
 		}
 	}
 	}
 	//---------------------------------------------------------------------
 	//---------------------------------------------------------------------
-	size_t D3D11Mappings::_getSizeInBytes(PixelFormat pf, size_t xcount, size_t ycount)
+	UINT32 D3D11Mappings::_getSizeInBytes(PixelFormat pf, UINT32 xcount, UINT32 ycount)
 	{
 	{
 		if(xcount == 0 || ycount == 0)
 		if(xcount == 0 || ycount == 0)
 			return 0;
 			return 0;
@@ -797,12 +810,12 @@ namespace CamelotEngine
 			if (pf == PF_DXT1)
 			if (pf == PF_DXT1)
 			{
 			{
 				// 64 bits (8 bytes) per 4x4 block
 				// 64 bits (8 bytes) per 4x4 block
-				return std::max<size_t>(1, xcount / 4) * std::max<size_t>(1, ycount / 4) * 8;
+				return std::max<UINT32>(1, xcount / 4) * std::max<UINT32>(1, ycount / 4) * 8;
 			}
 			}
 			else
 			else
 			{
 			{
 				// 128 bits (16 bytes) per 4x4 block
 				// 128 bits (16 bytes) per 4x4 block
-				return std::max<size_t>(1, xcount / 4) * std::max<size_t>(1, ycount / 4) * 16;
+				return std::max<UINT32>(1, xcount / 4) * std::max<UINT32>(1, ycount / 4) * 16;
 			}
 			}
 		}
 		}
 		else
 		else
@@ -890,4 +903,30 @@ namespace CamelotEngine
 
 
 		return flags;
 		return flags;
 	}
 	}
+
+	D3D11_MAP D3D11Mappings::_getLockOptions(LockOptions lockOptions)
+	{
+		switch(lockOptions)
+		{
+		case HBL_WRITE_ONLY_NO_OVERWRITE:
+			return D3D11_MAP_WRITE_NO_OVERWRITE;
+			break;
+		case HBL_READ_WRITE:
+			return D3D11_MAP_READ_WRITE;
+			break;
+		case HBL_WRITE_ONLY_DISCARD:
+			return D3D11_MAP_WRITE_DISCARD;
+			break;
+		case HBL_READ_ONLY:
+			return D3D11_MAP_READ;
+			break;
+		case HBL_WRITE_ONLY:
+			return D3D11_MAP_WRITE;
+			break;
+		default: 
+			break;
+		};
+
+		CM_EXCEPT(RenderingAPIException, "Invalid lock option. No DX11 equivalent of: " + toString(lockOptions));
+	}
 }
 }

+ 6 - 0
CamelotD3D11RenderSystem/Source/CmD3D11RenderTexture.cpp

@@ -0,0 +1,6 @@
+#include "CmD3D11RenderTexture.h"
+
+namespace CamelotEngine
+{
+
+}

+ 732 - 732
CamelotD3D11RenderSystem/Source/CmD3D11RenderWindow.cpp

@@ -8,771 +8,771 @@
 
 
 namespace CamelotEngine
 namespace CamelotEngine
 {
 {
-	D3D11RenderWindow::D3D11RenderWindow(D3D11Device& device, IDXGIFactory* DXGIFactory)
-		: RenderWindow()
-		, mDevice(device)
-		, mDXGIFactory(DXGIFactory)
-		, mIsExternal(false)
-		, mSizing(false)
-		, mClosed(false)
-		, mHidden(false)
-		, mSwitchingFullscreen(false)
-		, mDisplayFrequency(0)
-		, mRenderTargetView(nullptr)
-		, mDepthStencilView(nullptr)
-		, mBackBuffer(nullptr)
-		, mSwapChain(nullptr)
-		, mHWnd(0)
-	{
-		ZeroMemory(&mSwapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC));
-	}
-
-	D3D11RenderWindow::~D3D11RenderWindow()
-	{
-		destroy();
+	D3D11RenderWindow::D3D11RenderWindow(D3D11Device& device, IDXGIFactory* DXGIFactory)
+		: RenderWindow()
+		, mDevice(device)
+		, mDXGIFactory(DXGIFactory)
+		, mIsExternal(false)
+		, mSizing(false)
+		, mClosed(false)
+		, mHidden(false)
+		, mSwitchingFullscreen(false)
+		, mDisplayFrequency(0)
+		, mRenderTargetView(nullptr)
+		, mDepthStencilView(nullptr)
+		, mBackBuffer(nullptr)
+		, mSwapChain(nullptr)
+		, mHWnd(0)
+	{
+		ZeroMemory(&mSwapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC));
 	}
 	}
 
 
-	void D3D11RenderWindow::initialize(const String& name, unsigned int width, unsigned int height,
-		bool fullScreen, const NameValuePairList *miscParams)
-	{
-		mFSAAType.Count = 1;
-		mFSAAType.Quality = 0;
-		mFSAA = 0;
-		mFSAAHint = "";
-		mVSync = false;
-		mVSyncInterval = 1;
-		HWND parentHWnd = 0;
-		HWND externalHandle = 0;
-		String title = name;
-		int left = -1; // Defaults to screen center
-		int top = -1; // Defaults to screen center
-		String border = "";
-		bool outerSize = false;
-		bool enableDoubleClick = false;
-
-		unsigned int colourDepth = 32;
-		bool depthBuffer = true;
-
-		if(miscParams)
-		{
-			// Get variable-length params
-			NameValuePairList::const_iterator opt;
-			// vsync	[parseBool]
-			opt = miscParams->find("vsync");
-			if(opt != miscParams->end())
-				mVSync = parseBool(opt->second);
-			// vsyncInterval	[parseUnsignedInt]
-			opt = miscParams->find("vsyncInterval");
-			if(opt != miscParams->end())
-				mVSyncInterval = parseUnsignedInt(opt->second);
-			// hidden	[parseBool]
-			opt = miscParams->find("hidden");
-			if(opt != miscParams->end())
-				mHidden = parseBool(opt->second);
-			// displayFrequency
-			opt = miscParams->find("displayFrequency");
-			if(opt != miscParams->end())
-				mDisplayFrequency = parseUnsignedInt(opt->second);
-			// colourDepth
-			opt = miscParams->find("colourDepth");
-			if(opt != miscParams->end())
-				colourDepth = parseUnsignedInt(opt->second);
-			// depthBuffer [parseBool]
-			opt = miscParams->find("depthBuffer");
-			if(opt != miscParams->end())
-				depthBuffer = parseBool(opt->second);
-			// FSAA type
-			opt = miscParams->find("FSAA");
-			if(opt != miscParams->end())
-				mFSAA = parseUnsignedInt(opt->second);
-			// FSAA quality
-			opt = miscParams->find("FSAAHint");
-			if(opt != miscParams->end())
-				mFSAAHint = opt->second;
-			// sRGB?
-			opt = miscParams->find("gamma");
-			if(opt != miscParams->end())
-				mHwGamma = parseBool(opt->second);
-			// left (x)
-			opt = miscParams->find("left");
-			if(opt != miscParams->end())
-				left = parseInt(opt->second);
-			// top (y)
-			opt = miscParams->find("top");
-			if(opt != miscParams->end())
-				top = parseInt(opt->second);
-			// Window title
-			opt = miscParams->find("title");
-			if(opt != miscParams->end())
-				title = opt->second;
-			// parentWindowHandle		-> parentHWnd
-			opt = miscParams->find("parentWindowHandle");
-			if(opt != miscParams->end())
-				parentHWnd = (HWND)parseUnsignedInt(opt->second);
-			// externalWindowHandle		-> externalHandle
-			opt = miscParams->find("externalWindowHandle");
-			if(opt != miscParams->end())
-				externalHandle = (HWND)parseUnsignedInt(opt->second);
-			// window border style
-			opt = miscParams->find("border");
-			if(opt != miscParams->end())
-				border = opt->second;
-			// set outer dimensions?
-			opt = miscParams->find("outerDimensions");
-			if(opt != miscParams->end())
-				outerSize = parseBool(opt->second);
-			// enable double click messages
-			opt = miscParams->find("enableDoubleClick");
-			if(opt != miscParams->end())
-				enableDoubleClick = parseBool(opt->second);
-		}
-
-		mName = name;
-		mIsFullScreen = fullScreen;
-		mColourDepth = colourDepth;
-		mWidth = mHeight = mLeft = mTop = 0;
-
-		mActive = true;
-		mClosed = false;
-
-		// Destroy current window if any
-		if(mHWnd)
-			destroy();
-
-		if (!externalHandle)
-		{
-			DWORD dwStyle = (mHidden ? 0 : WS_VISIBLE) | WS_CLIPCHILDREN;
-			RECT rc;
-
-			mWidth = width;
-			mHeight = height;
-			mTop = top;
-			mLeft = left;
-
-			if (!fullScreen)
-			{
-				if (parentHWnd)
-				{
-					dwStyle |= WS_CHILD;
-				}
-				else
-				{
-					if (border == "none")
-						dwStyle |= WS_POPUP;
-					else if (border == "fixed")
-						dwStyle |= WS_OVERLAPPED | WS_BORDER | WS_CAPTION |
-						WS_SYSMENU | WS_MINIMIZEBOX;
-					else
-						dwStyle |= WS_OVERLAPPEDWINDOW;
-				}
-
-				if (!outerSize)
-				{
-					// Calculate window dimensions required
-					// to get the requested client area
-					SetRect(&rc, 0, 0, mWidth, mHeight);
-					AdjustWindowRect(&rc, dwStyle, false);
-					mWidth = rc.right - rc.left;
-					mHeight = rc.bottom - rc.top;
-
-					// Clamp width and height to the desktop dimensions
-					int screenw = GetSystemMetrics(SM_CXSCREEN);
-					int screenh = GetSystemMetrics(SM_CYSCREEN);
-					if ((int)mWidth > screenw)
-						mWidth = screenw;
-					if ((int)mHeight > screenh)
-						mHeight = screenh;
-					if (mLeft < 0)
-						mLeft = (screenw - mWidth) / 2;
-					if (mTop < 0)
-						mTop = (screenh - mHeight) / 2;
-				}
-			}
-			else
-			{
-				dwStyle |= WS_POPUP;
-				mTop = mLeft = 0;
-			}
-
-			UINT classStyle = 0;
-			if (enableDoubleClick)
-				classStyle |= CS_DBLCLKS;
-
-			HINSTANCE hInst = NULL;
-
-			// Register the window class
-			// Allow 4 bytes of window data for D3D11RenderWindow pointer
-			WNDCLASS wc = { classStyle, WindowEventUtilities::_WndProc, 0, 0, hInst,
-				LoadIcon(0, IDI_APPLICATION), LoadCursor(NULL, IDC_ARROW),
-				(HBRUSH)GetStockObject(BLACK_BRUSH), 0, "D3D11Wnd" };	
-
-
-			RegisterClass(&wc);
-
-			// Create our main window
-			// Pass pointer to self
-			mIsExternal = false;
-			mHWnd = CreateWindow("D3D11Wnd", title.c_str(), dwStyle,
-				mLeft, mTop, mWidth, mHeight, parentHWnd, 0, hInst, this);
-
-			WindowEventUtilities::_addRenderWindow(this);
-		}
-		else
-		{
-			mHWnd = externalHandle;
-			mIsExternal = true;
-		}
-
-		RECT rc;
-		// top and left represent outer window coordinates
-		GetWindowRect(mHWnd, &rc);
-		mTop = rc.top;
-		mLeft = rc.left;
-		// width and height represent interior drawable area
-		GetClientRect(mHWnd, &rc);
-		mWidth = rc.right;
-		mHeight = rc.bottom;
-
-		_createSwapChain();
-		_createSizeDependedD3DResources();
-		mDXGIFactory->MakeWindowAssociation(mHWnd, NULL);
-		setHidden(mHidden);
+	D3D11RenderWindow::~D3D11RenderWindow()
+	{
+		destroy();
+	}
+
+	void D3D11RenderWindow::initialize(const String& name, unsigned int width, unsigned int height,
+		bool fullScreen, const NameValuePairList *miscParams)
+	{
+		mFSAAType.Count = 1;
+		mFSAAType.Quality = 0;
+		mFSAA = 0;
+		mFSAAHint = "";
+		mVSync = false;
+		mVSyncInterval = 1;
+		HWND parentHWnd = 0;
+		HWND externalHandle = 0;
+		String title = name;
+		int left = -1; // Defaults to screen center
+		int top = -1; // Defaults to screen center
+		String border = "";
+		bool outerSize = false;
+		bool enableDoubleClick = false;
+
+		unsigned int colourDepth = 32;
+		bool depthBuffer = true;
+
+		if(miscParams)
+		{
+			// Get variable-length params
+			NameValuePairList::const_iterator opt;
+			// vsync	[parseBool]
+			opt = miscParams->find("vsync");
+			if(opt != miscParams->end())
+				mVSync = parseBool(opt->second);
+			// vsyncInterval	[parseUnsignedInt]
+			opt = miscParams->find("vsyncInterval");
+			if(opt != miscParams->end())
+				mVSyncInterval = parseUnsignedInt(opt->second);
+			// hidden	[parseBool]
+			opt = miscParams->find("hidden");
+			if(opt != miscParams->end())
+				mHidden = parseBool(opt->second);
+			// displayFrequency
+			opt = miscParams->find("displayFrequency");
+			if(opt != miscParams->end())
+				mDisplayFrequency = parseUnsignedInt(opt->second);
+			// colourDepth
+			opt = miscParams->find("colourDepth");
+			if(opt != miscParams->end())
+				colourDepth = parseUnsignedInt(opt->second);
+			// depthBuffer [parseBool]
+			opt = miscParams->find("depthBuffer");
+			if(opt != miscParams->end())
+				depthBuffer = parseBool(opt->second);
+			// FSAA type
+			opt = miscParams->find("FSAA");
+			if(opt != miscParams->end())
+				mFSAA = parseUnsignedInt(opt->second);
+			// FSAA quality
+			opt = miscParams->find("FSAAHint");
+			if(opt != miscParams->end())
+				mFSAAHint = opt->second;
+			// sRGB?
+			opt = miscParams->find("gamma");
+			if(opt != miscParams->end())
+				mHwGamma = parseBool(opt->second);
+			// left (x)
+			opt = miscParams->find("left");
+			if(opt != miscParams->end())
+				left = parseInt(opt->second);
+			// top (y)
+			opt = miscParams->find("top");
+			if(opt != miscParams->end())
+				top = parseInt(opt->second);
+			// Window title
+			opt = miscParams->find("title");
+			if(opt != miscParams->end())
+				title = opt->second;
+			// parentWindowHandle		-> parentHWnd
+			opt = miscParams->find("parentWindowHandle");
+			if(opt != miscParams->end())
+				parentHWnd = (HWND)parseUnsignedInt(opt->second);
+			// externalWindowHandle		-> externalHandle
+			opt = miscParams->find("externalWindowHandle");
+			if(opt != miscParams->end())
+				externalHandle = (HWND)parseUnsignedInt(opt->second);
+			// window border style
+			opt = miscParams->find("border");
+			if(opt != miscParams->end())
+				border = opt->second;
+			// set outer dimensions?
+			opt = miscParams->find("outerDimensions");
+			if(opt != miscParams->end())
+				outerSize = parseBool(opt->second);
+			// enable double click messages
+			opt = miscParams->find("enableDoubleClick");
+			if(opt != miscParams->end())
+				enableDoubleClick = parseBool(opt->second);
+		}
+
+		mName = name;
+		mIsFullScreen = fullScreen;
+		mColourDepth = colourDepth;
+		mWidth = mHeight = mLeft = mTop = 0;
+
+		mActive = true;
+		mClosed = false;
+
+		// Destroy current window if any
+		if(mHWnd)
+			destroy();
+
+		if (!externalHandle)
+		{
+			DWORD dwStyle = (mHidden ? 0 : WS_VISIBLE) | WS_CLIPCHILDREN;
+			RECT rc;
+
+			mWidth = width;
+			mHeight = height;
+			mTop = top;
+			mLeft = left;
+
+			if (!fullScreen)
+			{
+				if (parentHWnd)
+				{
+					dwStyle |= WS_CHILD;
+				}
+				else
+				{
+					if (border == "none")
+						dwStyle |= WS_POPUP;
+					else if (border == "fixed")
+						dwStyle |= WS_OVERLAPPED | WS_BORDER | WS_CAPTION |
+						WS_SYSMENU | WS_MINIMIZEBOX;
+					else
+						dwStyle |= WS_OVERLAPPEDWINDOW;
+				}
+
+				if (!outerSize)
+				{
+					// Calculate window dimensions required
+					// to get the requested client area
+					SetRect(&rc, 0, 0, mWidth, mHeight);
+					AdjustWindowRect(&rc, dwStyle, false);
+					mWidth = rc.right - rc.left;
+					mHeight = rc.bottom - rc.top;
+
+					// Clamp width and height to the desktop dimensions
+					int screenw = GetSystemMetrics(SM_CXSCREEN);
+					int screenh = GetSystemMetrics(SM_CYSCREEN);
+					if ((int)mWidth > screenw)
+						mWidth = screenw;
+					if ((int)mHeight > screenh)
+						mHeight = screenh;
+					if (mLeft < 0)
+						mLeft = (screenw - mWidth) / 2;
+					if (mTop < 0)
+						mTop = (screenh - mHeight) / 2;
+				}
+			}
+			else
+			{
+				dwStyle |= WS_POPUP;
+				mTop = mLeft = 0;
+			}
+
+			UINT classStyle = 0;
+			if (enableDoubleClick)
+				classStyle |= CS_DBLCLKS;
+
+			HINSTANCE hInst = NULL;
+
+			// Register the window class
+			// Allow 4 bytes of window data for D3D11RenderWindow pointer
+			WNDCLASS wc = { classStyle, WindowEventUtilities::_WndProc, 0, 0, hInst,
+				LoadIcon(0, IDI_APPLICATION), LoadCursor(NULL, IDC_ARROW),
+				(HBRUSH)GetStockObject(BLACK_BRUSH), 0, "D3D11Wnd" };	
+
+
+			RegisterClass(&wc);
+
+			// Create our main window
+			// Pass pointer to self
+			mIsExternal = false;
+			mHWnd = CreateWindow("D3D11Wnd", title.c_str(), dwStyle,
+				mLeft, mTop, mWidth, mHeight, parentHWnd, 0, hInst, this);
+
+			WindowEventUtilities::_addRenderWindow(this);
+		}
+		else
+		{
+			mHWnd = externalHandle;
+			mIsExternal = true;
+		}
+
+		RECT rc;
+		// top and left represent outer window coordinates
+		GetWindowRect(mHWnd, &rc);
+		mTop = rc.top;
+		mLeft = rc.left;
+		// width and height represent interior drawable area
+		GetClientRect(mHWnd, &rc);
+		mWidth = rc.right;
+		mHeight = rc.bottom;
+
+		_createSwapChain();
+		_createSizeDependedD3DResources();
+		mDXGIFactory->MakeWindowAssociation(mHWnd, NULL);
+		setHidden(mHidden);
 	}
 	}
 
 
 	void D3D11RenderWindow::destroy()
 	void D3D11RenderWindow::destroy()
 	{
 	{
-		_destroySizeDependedD3DResources();
-
-		mActive = false;
+		_destroySizeDependedD3DResources();
+
+		mActive = false;
 		mClosed = true;
 		mClosed = true;
 
 
-		SAFE_RELEASE(mSwapChain);
-
-		if (mHWnd && !mIsExternal)
-		{
-			WindowEventUtilities::_removeRenderWindow(this);
-			DestroyWindow(mHWnd);
-		}
-
+		SAFE_RELEASE(mSwapChain);
+
+		if (mHWnd && !mIsExternal)
+		{
+			WindowEventUtilities::_removeRenderWindow(this);
+			DestroyWindow(mHWnd);
+		}
+
 		mHWnd = nullptr;
 		mHWnd = nullptr;
 	}
 	}
 
 
-	void D3D11RenderWindow::swapBuffers(bool waitForVSync)
-	{
-		if(mDevice.getD3D11Device() != nullptr)
-		{
-			HRESULT hr = mSwapChain->Present(waitForVSync ? mVSyncInterval : 0, 0);
-
-			if( FAILED(hr) )
-				CM_EXCEPT(RenderingAPIException, "Error Presenting surfaces");
-		}
+	void D3D11RenderWindow::swapBuffers(bool waitForVSync)
+	{
+		if(mDevice.getD3D11Device() != nullptr)
+		{
+			HRESULT hr = mSwapChain->Present(waitForVSync ? mVSyncInterval : 0, 0);
+
+			if( FAILED(hr) )
+				CM_EXCEPT(RenderingAPIException, "Error Presenting surfaces");
+		}
 	}
 	}
 
 
-	void D3D11RenderWindow::reposition(int top, int left)
-	{
-		if (mHWnd && !mIsFullScreen)
-		{
-			SetWindowPos(mHWnd, 0, top, left, 0, 0,
-				SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
-		}
-	}
-
-	void D3D11RenderWindow::resize(unsigned int width, unsigned int height)
-	{
-		if (mHWnd && !mIsFullScreen)
-		{
-			RECT rc = { 0, 0, width, height };
-			AdjustWindowRect(&rc, GetWindowLong(mHWnd, GWL_STYLE), false);
-			width = rc.right - rc.left;
-			height = rc.bottom - rc.top;
-			SetWindowPos(mHWnd, 0, 0, 0, width, height,
-				SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
-		}
-	}
-
-	void D3D11RenderWindow::windowMovedOrResized()
-	{
-		if (!mHWnd || IsIconic(mHWnd))
-			return;
-
-		RECT rc;
-		// top and left represent outer window position
-		GetWindowRect(mHWnd, &rc);
-		mTop = rc.top;
-		mLeft = rc.left;
-		// width and height represent drawable area only
-		GetClientRect(mHWnd, &rc);
-		unsigned int width = rc.right - rc.left;
-		unsigned int height = rc.bottom - rc.top;
-
-		if (width == 0) 
-			width = 1;
-		if (height == 0)
-			height = 1;
-
-		if (mWidth == width && mHeight == height)
-			return;
-
-		_resizeSwapChainBuffers(width, height);
+	void D3D11RenderWindow::reposition(int top, int left)
+	{
+		if (mHWnd && !mIsFullScreen)
+		{
+			SetWindowPos(mHWnd, 0, top, left, 0, 0,
+				SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
+		}
 	}
 	}
 
 
-	void D3D11RenderWindow::setActive(bool state)
-	{
-		if (mHWnd && mSwapChain)
-		{
-			if (state)
-			{
-				ShowWindow(mHWnd, SW_RESTORE);
-				mSwapChain->SetFullscreenState(mIsFullScreen, nullptr);
-			}
-			else
-			{
-				ShowWindow(mHWnd, SW_SHOWMINIMIZED);
-				mSwapChain->SetFullscreenState(FALSE, nullptr);
-			}
-		}
-
-		RenderWindow::setActive(state);
+	void D3D11RenderWindow::resize(unsigned int width, unsigned int height)
+	{
+		if (mHWnd && !mIsFullScreen)
+		{
+			RECT rc = { 0, 0, width, height };
+			AdjustWindowRect(&rc, GetWindowLong(mHWnd, GWL_STYLE), false);
+			width = rc.right - rc.left;
+			height = rc.bottom - rc.top;
+			SetWindowPos(mHWnd, 0, 0, 0, width, height,
+				SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
+		}
 	}
 	}
 
 
-	void D3D11RenderWindow::setHidden(bool hidden)
-	{
-		mHidden = hidden;
-		if (!mIsExternal)
-		{
-			if (hidden)
-				ShowWindow(mHWnd, SW_HIDE);
-			else
-				ShowWindow(mHWnd, SW_SHOWNORMAL);
-		}
+	void D3D11RenderWindow::windowMovedOrResized()
+	{
+		if (!mHWnd || IsIconic(mHWnd))
+			return;
+
+		RECT rc;
+		// top and left represent outer window position
+		GetWindowRect(mHWnd, &rc);
+		mTop = rc.top;
+		mLeft = rc.left;
+		// width and height represent drawable area only
+		GetClientRect(mHWnd, &rc);
+		unsigned int width = rc.right - rc.left;
+		unsigned int height = rc.bottom - rc.top;
+
+		if (width == 0) 
+			width = 1;
+		if (height == 0)
+			height = 1;
+
+		if (mWidth == width && mHeight == height)
+			return;
+
+		_resizeSwapChainBuffers(width, height);
 	}
 	}
 
 
-	void D3D11RenderWindow::setFullscreen(bool fullScreen, unsigned int width, unsigned int height)
-	{
-		if (fullScreen != mIsFullScreen || width != mWidth || height != mHeight)
-		{
-			if (fullScreen != mIsFullScreen)
-				mSwitchingFullscreen = true;
-
-			DWORD dwStyle = WS_VISIBLE | WS_CLIPCHILDREN;
-
-			bool oldFullscreen = mIsFullScreen;
-			mIsFullScreen = fullScreen;
-
-			if (fullScreen)
-			{
-				dwStyle |= WS_POPUP;
-				mTop = mLeft = 0;
-				mWidth = width;
-				mHeight = height;
-				// need different ordering here
-
-				if (oldFullscreen)
-				{
-					// was previously fullscreen, just changing the resolution
-					SetWindowPos(mHWnd, HWND_TOPMOST, 0, 0, width, height, SWP_NOACTIVATE);
-				}
-				else
-				{
-					SetWindowPos(mHWnd, HWND_TOPMOST, 0, 0, width, height, SWP_NOACTIVATE);
-					//MoveWindow(mHWnd, mLeft, mTop, mWidth, mHeight, FALSE);
-					SetWindowLong(mHWnd, GWL_STYLE, dwStyle);
-					SetWindowPos(mHWnd, 0, 0,0, 0,0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER);
-				}
-			}
-			else
-			{
-				dwStyle |= WS_OVERLAPPEDWINDOW;
-				// Calculate window dimensions required
-				// to get the requested client area
-				RECT rc;
-				SetRect(&rc, 0, 0, width, height);
-				AdjustWindowRect(&rc, dwStyle, false);
-				unsigned int winWidth = rc.right - rc.left;
-				unsigned int winHeight = rc.bottom - rc.top;
-
-				SetWindowLong(mHWnd, GWL_STYLE, dwStyle);
-				SetWindowPos(mHWnd, HWND_NOTOPMOST, 0, 0, winWidth, winHeight,
-					SWP_DRAWFRAME | SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOACTIVATE);
-				// Note that we also set the position in the restoreLostDevice method
-				// via _finishSwitchingFullScreen
-			}
-
-			mSwapChainDesc.Windowed = !fullScreen;
-			mSwapChainDesc.BufferDesc.RefreshRate.Numerator = 0;
-			mSwapChainDesc.BufferDesc.RefreshRate.Denominator=0;
-			mSwapChainDesc.BufferDesc.Height = height;
-			mSwapChainDesc.BufferDesc.Width = width;
-		}
+	void D3D11RenderWindow::setActive(bool state)
+	{
+		if (mHWnd && mSwapChain)
+		{
+			if (state)
+			{
+				ShowWindow(mHWnd, SW_RESTORE);
+				mSwapChain->SetFullscreenState(mIsFullScreen, nullptr);
+			}
+			else
+			{
+				ShowWindow(mHWnd, SW_SHOWMINIMIZED);
+				mSwapChain->SetFullscreenState(FALSE, nullptr);
+			}
+		}
+
+		RenderWindow::setActive(state);
+	}
+
+	void D3D11RenderWindow::setHidden(bool hidden)
+	{
+		mHidden = hidden;
+		if (!mIsExternal)
+		{
+			if (hidden)
+				ShowWindow(mHWnd, SW_HIDE);
+			else
+				ShowWindow(mHWnd, SW_SHOWNORMAL);
+		}
+	}
+
+	void D3D11RenderWindow::setFullscreen(bool fullScreen, unsigned int width, unsigned int height)
+	{
+		if (fullScreen != mIsFullScreen || width != mWidth || height != mHeight)
+		{
+			if (fullScreen != mIsFullScreen)
+				mSwitchingFullscreen = true;
+
+			DWORD dwStyle = WS_VISIBLE | WS_CLIPCHILDREN;
+
+			bool oldFullscreen = mIsFullScreen;
+			mIsFullScreen = fullScreen;
+
+			if (fullScreen)
+			{
+				dwStyle |= WS_POPUP;
+				mTop = mLeft = 0;
+				mWidth = width;
+				mHeight = height;
+				// need different ordering here
+
+				if (oldFullscreen)
+				{
+					// was previously fullscreen, just changing the resolution
+					SetWindowPos(mHWnd, HWND_TOPMOST, 0, 0, width, height, SWP_NOACTIVATE);
+				}
+				else
+				{
+					SetWindowPos(mHWnd, HWND_TOPMOST, 0, 0, width, height, SWP_NOACTIVATE);
+					//MoveWindow(mHWnd, mLeft, mTop, mWidth, mHeight, FALSE);
+					SetWindowLong(mHWnd, GWL_STYLE, dwStyle);
+					SetWindowPos(mHWnd, 0, 0,0, 0,0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER);
+				}
+			}
+			else
+			{
+				dwStyle |= WS_OVERLAPPEDWINDOW;
+				// Calculate window dimensions required
+				// to get the requested client area
+				RECT rc;
+				SetRect(&rc, 0, 0, width, height);
+				AdjustWindowRect(&rc, dwStyle, false);
+				unsigned int winWidth = rc.right - rc.left;
+				unsigned int winHeight = rc.bottom - rc.top;
+
+				SetWindowLong(mHWnd, GWL_STYLE, dwStyle);
+				SetWindowPos(mHWnd, HWND_NOTOPMOST, 0, 0, winWidth, winHeight,
+					SWP_DRAWFRAME | SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOACTIVATE);
+				// Note that we also set the position in the restoreLostDevice method
+				// via _finishSwitchingFullScreen
+			}
+
+			mSwapChainDesc.Windowed = !fullScreen;
+			mSwapChainDesc.BufferDesc.RefreshRate.Numerator = 0;
+			mSwapChainDesc.BufferDesc.RefreshRate.Denominator=0;
+			mSwapChainDesc.BufferDesc.Height = height;
+			mSwapChainDesc.BufferDesc.Width = width;
+		}
 	} 
 	} 
 
 
-	void D3D11RenderWindow::getCustomAttribute( const String& name, void* pData )
-	{
-		// Valid attributes and their equvalent native functions:
-		// D3DDEVICE			: getD3DDevice
-		// WINDOW				: getWindowHandle
-
-		if(name == "WINDOW")
-		{
-			HWND *pWnd = (HWND*)pData;
-			*pWnd = mHWnd;
-			return;
-		}
-
-		if(name == "D3DDEVICE")
-		{
-			ID3D11Device **device = (ID3D11Device **)pData;
-			*device = mDevice.getD3D11Device();
-			return;
-		}
-		else if(name == "isTexture")
-		{
-			bool *b = reinterpret_cast< bool * >( pData );
-			*b = false;
-			return;
-		}
-		else if(name == "ID3D11RenderTargetView")
-		{
-			*static_cast<ID3D11RenderTargetView**>(pData) = mRenderTargetView;
-			return;
-		}
-		else if(name == "ID3D11Texture2D")
-		{
-			ID3D11Texture2D **pBackBuffer = (ID3D11Texture2D**)pData;
-			*pBackBuffer = mBackBuffer;
-			return;
-		}
-		else if(name == "numberOfViews")
-		{
-			unsigned int* n = reinterpret_cast<unsigned int*>(pData);
-			*n = 1;
-			return;
-		}
-		else if(name == "DDBACKBUFFER")
-		{
-			ID3D11Texture2D **ppBackBuffer = (ID3D11Texture2D**) pData;
-			ppBackBuffer[0] = NULL;
-			return;
-		}
-
-		RenderWindow::getCustomAttribute_internal(name, pData);
+	void D3D11RenderWindow::getCustomAttribute( const String& name, void* pData )
+	{
+		// Valid attributes and their equvalent native functions:
+		// D3DDEVICE			: getD3DDevice
+		// WINDOW				: getWindowHandle
+
+		if(name == "WINDOW")
+		{
+			HWND *pWnd = (HWND*)pData;
+			*pWnd = mHWnd;
+			return;
+		}
+
+		if(name == "D3DDEVICE")
+		{
+			ID3D11Device **device = (ID3D11Device **)pData;
+			*device = mDevice.getD3D11Device();
+			return;
+		}
+		else if(name == "isTexture")
+		{
+			bool *b = reinterpret_cast< bool * >( pData );
+			*b = false;
+			return;
+		}
+		else if(name == "ID3D11RenderTargetView")
+		{
+			*static_cast<ID3D11RenderTargetView**>(pData) = mRenderTargetView;
+			return;
+		}
+		else if(name == "ID3D11Texture2D")
+		{
+			ID3D11Texture2D **pBackBuffer = (ID3D11Texture2D**)pData;
+			*pBackBuffer = mBackBuffer;
+			return;
+		}
+		else if(name == "numberOfViews")
+		{
+			unsigned int* n = reinterpret_cast<unsigned int*>(pData);
+			*n = 1;
+			return;
+		}
+		else if(name == "DDBACKBUFFER")
+		{
+			ID3D11Texture2D **ppBackBuffer = (ID3D11Texture2D**) pData;
+			ppBackBuffer[0] = NULL;
+			return;
+		}
+
+		RenderWindow::getCustomAttribute_internal(name, pData);
 	}
 	}
 
 
-	void D3D11RenderWindow::copyContentsToMemory(const PixelData &dst, FrameBuffer buffer)
-	{
-		if(mBackBuffer == nullptr)
-			return;
-
-		// get the backbuffer desc
-		D3D11_TEXTURE2D_DESC BBDesc;
-		mBackBuffer->GetDesc(&BBDesc);
-
-		ID3D11Texture2D *backbuffer = nullptr;
-
-		if(BBDesc.SampleDesc.Quality > 0)
-		{
-			D3D11_TEXTURE2D_DESC desc = BBDesc;
-			desc.Usage = D3D11_USAGE_DEFAULT;
-			desc.CPUAccessFlags = 0;
-			desc.BindFlags = 0;
-			desc.SampleDesc.Quality = 0;
-			desc.SampleDesc.Count = 1;
-
-			HRESULT hr = mDevice.getD3D11Device()->CreateTexture2D(
-				&desc,
-				NULL,
-				&backbuffer);
-
-			if (FAILED(hr) || mDevice.hasError())
-			{
-				String errorDescription = mDevice.getErrorDescription();
-				CM_EXCEPT(RenderingAPIException,
-					"Error creating texture\nError Description:" + errorDescription);
-			}
-
-			mDevice.getImmediateContext()->ResolveSubresource(backbuffer, D3D11CalcSubresource(0, 0, 1), mBackBuffer, D3D11CalcSubresource(0, 0, 1), desc.Format);
-		}
-
-
-		// change the parameters of the texture so we can read it
-		BBDesc.Usage = D3D11_USAGE_STAGING;
-		BBDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
-		BBDesc.BindFlags = 0;
-		BBDesc.SampleDesc.Quality = 0;
-		BBDesc.SampleDesc.Count = 1;
-
-		// create a temp buffer to copy to
-		ID3D11Texture2D * pTempTexture2D;
-		HRESULT hr = mDevice.getD3D11Device()->CreateTexture2D(
-			&BBDesc,
-			NULL,
-			&pTempTexture2D);
-
-		if (FAILED(hr) || mDevice.hasError())
-		{
-			String errorDescription = mDevice.getErrorDescription();
-			CM_EXCEPT(RenderingAPIException,
-				"Error creating texture\nError Description:" + errorDescription);
-		}
-		// copy the back buffer
-		mDevice.getImmediateContext()->CopyResource(pTempTexture2D, backbuffer != NULL ? backbuffer : mBackBuffer);
-
-		// map the copied texture
-		D3D11_MAPPED_SUBRESOURCE mappedTex2D;
-		mDevice.getImmediateContext()->Map(pTempTexture2D, 0,D3D11_MAP_READ, 0, &mappedTex2D);
-
-		// copy the the texture to the dest
-		PixelUtil::bulkPixelConversion(PixelData(mWidth, mHeight, 1, PF_A8B8G8R8, mappedTex2D.pData), dst);
-
-		// unmap the temp buffer
-		mDevice.getImmediateContext()->Unmap(pTempTexture2D, 0);
-
-		// Release the temp buffer
-		SAFE_RELEASE(pTempTexture2D);
-		SAFE_RELEASE(backbuffer);
+	void D3D11RenderWindow::copyContentsToMemory(const PixelData &dst, FrameBuffer buffer)
+	{
+		if(mBackBuffer == nullptr)
+			return;
+
+		// get the backbuffer desc
+		D3D11_TEXTURE2D_DESC BBDesc;
+		mBackBuffer->GetDesc(&BBDesc);
+
+		ID3D11Texture2D *backbuffer = nullptr;
+
+		if(BBDesc.SampleDesc.Quality > 0)
+		{
+			D3D11_TEXTURE2D_DESC desc = BBDesc;
+			desc.Usage = D3D11_USAGE_DEFAULT;
+			desc.CPUAccessFlags = 0;
+			desc.BindFlags = 0;
+			desc.SampleDesc.Quality = 0;
+			desc.SampleDesc.Count = 1;
+
+			HRESULT hr = mDevice.getD3D11Device()->CreateTexture2D(
+				&desc,
+				NULL,
+				&backbuffer);
+
+			if (FAILED(hr) || mDevice.hasError())
+			{
+				String errorDescription = mDevice.getErrorDescription();
+				CM_EXCEPT(RenderingAPIException,
+					"Error creating texture\nError Description:" + errorDescription);
+			}
+
+			mDevice.getImmediateContext()->ResolveSubresource(backbuffer, D3D11CalcSubresource(0, 0, 1), mBackBuffer, D3D11CalcSubresource(0, 0, 1), desc.Format);
+		}
+
+
+		// change the parameters of the texture so we can read it
+		BBDesc.Usage = D3D11_USAGE_STAGING;
+		BBDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
+		BBDesc.BindFlags = 0;
+		BBDesc.SampleDesc.Quality = 0;
+		BBDesc.SampleDesc.Count = 1;
+
+		// create a temp buffer to copy to
+		ID3D11Texture2D * pTempTexture2D;
+		HRESULT hr = mDevice.getD3D11Device()->CreateTexture2D(
+			&BBDesc,
+			NULL,
+			&pTempTexture2D);
+
+		if (FAILED(hr) || mDevice.hasError())
+		{
+			String errorDescription = mDevice.getErrorDescription();
+			CM_EXCEPT(RenderingAPIException,
+				"Error creating texture\nError Description:" + errorDescription);
+		}
+		// copy the back buffer
+		mDevice.getImmediateContext()->CopyResource(pTempTexture2D, backbuffer != NULL ? backbuffer : mBackBuffer);
+
+		// map the copied texture
+		D3D11_MAPPED_SUBRESOURCE mappedTex2D;
+		mDevice.getImmediateContext()->Map(pTempTexture2D, 0,D3D11_MAP_READ, 0, &mappedTex2D);
+
+		// copy the the texture to the dest
+		PixelUtil::bulkPixelConversion(PixelData(mWidth, mHeight, 1, PF_A8B8G8R8, mappedTex2D.pData), dst);
+
+		// unmap the temp buffer
+		mDevice.getImmediateContext()->Unmap(pTempTexture2D, 0);
+
+		// Release the temp buffer
+		SAFE_RELEASE(pTempTexture2D);
+		SAFE_RELEASE(backbuffer);
 	}
 	}
 
 
 	void D3D11RenderWindow::_createSwapChain()
 	void D3D11RenderWindow::_createSwapChain()
 	{
 	{
-		ZeroMemory(&mSwapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC));
-
-		// get the dxgi device
+		ZeroMemory(&mSwapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC));
+
+		// get the dxgi device
 		IDXGIDevice* pDXGIDevice = _queryDxgiDevice();
 		IDXGIDevice* pDXGIDevice = _queryDxgiDevice();
 
 
-		ZeroMemory(&mSwapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC));
-		DXGI_FORMAT format = DXGI_FORMAT_R8G8B8A8_UNORM;
-		mSwapChainDesc.OutputWindow			= mHWnd;
-		mSwapChainDesc.BufferDesc.Width		= mWidth;
-		mSwapChainDesc.BufferDesc.Height	= mHeight;
-		mSwapChainDesc.BufferDesc.Format	= format;
-		mSwapChainDesc.BufferDesc.RefreshRate.Numerator=0;
-		mSwapChainDesc.BufferDesc.RefreshRate.Denominator = 0;
-
-		mSwapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
-		mSwapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
-		mSwapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH ;
-
-		// triple buffer if VSync is on
-		mSwapChainDesc.BufferUsage			= DXGI_USAGE_RENDER_TARGET_OUTPUT;
-		mSwapChainDesc.BufferCount			= mVSync ? 2 : 1;
-		mSwapChainDesc.SwapEffect			= DXGI_SWAP_EFFECT_DISCARD ;
-
-		mSwapChainDesc.OutputWindow 		= mHWnd;
-		mSwapChainDesc.Windowed				= !mIsFullScreen;
-
-		D3D11RenderSystem* rs = static_cast<D3D11RenderSystem*>(RenderSystem::instancePtr());
-		rs->determineFSAASettings(mFSAA, mFSAAHint, format, &mFSAAType);
-		mSwapChainDesc.SampleDesc.Count = mFSAAType.Count;
-		mSwapChainDesc.SampleDesc.Quality = mFSAAType.Quality;
-
-		HRESULT hr;
-
-		// Create swap chain			
-		hr = mDXGIFactory->CreateSwapChain(pDXGIDevice, &mSwapChainDesc, &mSwapChain);
-
-		if (FAILED(hr))
-		{
-			// Try a second time, may fail the first time due to back buffer count,
-			// which will be corrected by the runtime
-			hr = mDXGIFactory->CreateSwapChain(pDXGIDevice, &mSwapChainDesc, &mSwapChain);
-		}
-
-		SAFE_RELEASE(pDXGIDevice);
-
-		if (FAILED(hr))
+		ZeroMemory(&mSwapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC));
+		DXGI_FORMAT format = DXGI_FORMAT_R8G8B8A8_UNORM;
+		mSwapChainDesc.OutputWindow			= mHWnd;
+		mSwapChainDesc.BufferDesc.Width		= mWidth;
+		mSwapChainDesc.BufferDesc.Height	= mHeight;
+		mSwapChainDesc.BufferDesc.Format	= format;
+		mSwapChainDesc.BufferDesc.RefreshRate.Numerator=0;
+		mSwapChainDesc.BufferDesc.RefreshRate.Denominator = 0;
+
+		mSwapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
+		mSwapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
+		mSwapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH ;
+
+		// triple buffer if VSync is on
+		mSwapChainDesc.BufferUsage			= DXGI_USAGE_RENDER_TARGET_OUTPUT;
+		mSwapChainDesc.BufferCount			= mVSync ? 2 : 1;
+		mSwapChainDesc.SwapEffect			= DXGI_SWAP_EFFECT_DISCARD ;
+
+		mSwapChainDesc.OutputWindow 		= mHWnd;
+		mSwapChainDesc.Windowed				= !mIsFullScreen;
+
+		D3D11RenderSystem* rs = static_cast<D3D11RenderSystem*>(RenderSystem::instancePtr());
+		rs->determineFSAASettings(mFSAA, mFSAAHint, format, &mFSAAType);
+		mSwapChainDesc.SampleDesc.Count = mFSAAType.Count;
+		mSwapChainDesc.SampleDesc.Quality = mFSAAType.Quality;
+
+		HRESULT hr;
+
+		// Create swap chain			
+		hr = mDXGIFactory->CreateSwapChain(pDXGIDevice, &mSwapChainDesc, &mSwapChain);
+
+		if (FAILED(hr))
+		{
+			// Try a second time, may fail the first time due to back buffer count,
+			// which will be corrected by the runtime
+			hr = mDXGIFactory->CreateSwapChain(pDXGIDevice, &mSwapChainDesc, &mSwapChain);
+		}
+
+		SAFE_RELEASE(pDXGIDevice);
+
+		if (FAILED(hr))
 			CM_EXCEPT(RenderingAPIException, "Unable to create swap chain");
 			CM_EXCEPT(RenderingAPIException, "Unable to create swap chain");
 	}
 	}
 
 
-	void D3D11RenderWindow::_createSizeDependedD3DResources()
-	{
-		// obtain back buffer
-		SAFE_RELEASE(mBackBuffer);
-
-		HRESULT hr = mSwapChain->GetBuffer(0,  __uuidof( ID3D11Texture2D ), (LPVOID*)&mBackBuffer);
-		if( FAILED(hr) )
-			CM_EXCEPT(RenderingAPIException, "Unable to Get Back Buffer for swap chain");
-
-		// create all other size depended resources
-		assert(mBackBuffer && !mRenderTargetView && !mDepthStencilView);
-
-		// get the backbuffer desc
-		D3D11_TEXTURE2D_DESC BBDesc;
-		mBackBuffer->GetDesc(&BBDesc);
-
-		// create the render target view
-		D3D11_RENDER_TARGET_VIEW_DESC RTVDesc;
-		ZeroMemory( &RTVDesc, sizeof(RTVDesc) );
-
-		RTVDesc.Format = BBDesc.Format;
-		RTVDesc.ViewDimension = mFSAA ? D3D11_RTV_DIMENSION_TEXTURE2DMS : D3D11_RTV_DIMENSION_TEXTURE2D;
-		RTVDesc.Texture2D.MipSlice = 0;
-		hr = mDevice.getD3D11Device()->CreateRenderTargetView(mBackBuffer, &RTVDesc, &mRenderTargetView);
-
-		if( FAILED(hr) )
-		{
-			String errorDescription = mDevice.getErrorDescription();
-			CM_EXCEPT(RenderingAPIException, "Unable to create rendertagert view\nError Description:" + errorDescription);
-		}
-
-		mDepthStencilBuffer = TextureManager::instance().createDepthStencilBuffer(32, BBDesc.Width, BBDesc.Height, mFSAA, mFSAAHint);
-
-		//if(mDepthBufferPoolId != DepthStencilBuffer::POOL_NO_DEPTH)
-		//{
-		//	// Create depth stencil texture
-		//	ID3D11Texture2D* pDepthStencil = NULL;
-		//	D3D11_TEXTURE2D_DESC descDepth;
-
-		//	descDepth.Width = BBDesc.Width;
-		//	descDepth.Height = BBDesc.Height;
-		//	descDepth.MipLevels = 1;
-		//	descDepth.ArraySize = 1;
-		//	descDepth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
-		//	descDepth.SampleDesc.Count = mFSAAType.Count;
-		//	descDepth.SampleDesc.Quality = mFSAAType.Quality;
-		//	descDepth.Usage = D3D11_USAGE_DEFAULT;
-		//	descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL;
-		//	descDepth.CPUAccessFlags = 0;
-		//	descDepth.MiscFlags = 0;
-
-		//	hr = mDevice.getD3D11Device()->CreateTexture2D(&descDepth, NULL, &pDepthStencil);
-		//	if( FAILED(hr) || mDevice.hasError())
-		//	{
-		//		String errorDescription = mDevice.getErrorDescription(hr);
-		//		CM_EXCEPT(RenderingAPIException, "Unable to create depth texture\nError Description:" + errorDescription);
-		//	}
-
-		//	// Create the depth stencil view
-		//	D3D11_DEPTH_STENCIL_VIEW_DESC descDSV;
-		//	ZeroMemory( &descDSV, sizeof(D3D11_DEPTH_STENCIL_VIEW_DESC) );
-
-		//	descDSV.Format =  descDepth.Format;
-		//	descDSV.ViewDimension = mFSAA ? D3D11_DSV_DIMENSION_TEXTURE2DMS : D3D11_DSV_DIMENSION_TEXTURE2D;
-		//	descDSV.Texture2D.MipSlice = 0;
-		//	hr = mDevice.getD3D11Device()->CreateDepthStencilView(pDepthStencil, &descDSV, &mDepthStencilView);
-
-		//	SAFE_RELEASE(pDepthStencil);
-
-		//	if( FAILED(hr) )
-		//	{
-		//		String errorDescription = mDevice.getErrorDescription();
-		//		CM_EXCEPT(RenderingAPIException, 
-		//			"Unable to create depth stencil view\nError Description:" + errorDescription);
-		//	}
-
-		//	D3D11RenderSystem* rsys = static_cast<D3D11RenderSystem*>(RenderSystem::instancePtr());
-		//	DepthStencilBuffer *depthBuf = rsys->_addManualDepthBuffer(mDepthStencilView, mWidth, mHeight, mFSAAType.Count, mFSAAType.Quality);
-
-		//	//Don't forget we want this window to use _this_ depth buffer
-		//	this->attachDepthBuffer(depthBuf);
-		//} 
-	}
-
-	void D3D11RenderWindow::_destroySizeDependedD3DResources()
-	{
-		SAFE_RELEASE(mBackBuffer);
-		SAFE_RELEASE(mRenderTargetView);
-
-		mDepthStencilBuffer = nullptr;
-
-		SAFE_RELEASE(mDepthStencilView);
-	}
-
-	void D3D11RenderWindow::_resizeSwapChainBuffers(unsigned width, unsigned height)
-	{
-		_destroySizeDependedD3DResources();
-
-		// width and height can be zero to autodetect size, therefore do not rely on them
-		UINT Flags = mIsFullScreen ? DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH : 0;
-		mSwapChain->ResizeBuffers(mSwapChainDesc.BufferCount, width, height, mSwapChainDesc.BufferDesc.Format, Flags);
-		mSwapChain->GetDesc(&mSwapChainDesc);
-		mWidth = mSwapChainDesc.BufferDesc.Width;
-		mHeight = mSwapChainDesc.BufferDesc.Height;
-		mIsFullScreen = (0 == mSwapChainDesc.Windowed); // Alt-Enter together with SetWindowAssociation() can change this state
-
-		_createSizeDependedD3DResources();
-
-		mDevice.getImmediateContext()->OMSetRenderTargets(0, 0, 0);
-		// Additional swap chains need their own depth buffer
-		// to support resizing them
-
-		HRESULT hr = mSwapChain->GetBuffer( 0,  __uuidof( ID3D11Texture2D ), (LPVOID*)&mBackBuffer  );
-		if( FAILED(hr) )
-		{
-			CM_EXCEPT(RenderingAPIException, 
-				"Unable to Get Back Buffer for swap chain");
-		}
-
-		// get the backbuffer desc
-		D3D11_TEXTURE2D_DESC BBDesc;
-		mBackBuffer->GetDesc(&BBDesc);
-
-		// create the render target view
-		D3D11_RENDER_TARGET_VIEW_DESC RTVDesc;
-		ZeroMemory( &RTVDesc, sizeof(RTVDesc) );
-
-		RTVDesc.Format = BBDesc.Format;
-		RTVDesc.ViewDimension = mFSAA ? D3D11_RTV_DIMENSION_TEXTURE2DMS : D3D11_RTV_DIMENSION_TEXTURE2D;
-		RTVDesc.Texture2D.MipSlice = 0;
-		hr = mDevice.getD3D11Device()->CreateRenderTargetView(mBackBuffer, &RTVDesc, &mRenderTargetView);
-
-		if(FAILED(hr))
-		{
-			String errorDescription = mDevice.getErrorDescription();
-			CM_EXCEPT(RenderingAPIException, 
-				"Unable to create rendertagert view\nError Description:" + errorDescription);
-		}
-	}
-
-	IDXGIDevice* D3D11RenderWindow::_queryDxgiDevice()
-	{
-		if (mDevice.getD3D11Device() == nullptr)
-		{
-			CM_EXCEPT(RenderingAPIException, "D3D11Device is NULL!");
-		}
-
-		IDXGIDevice* pDXGIDevice = nullptr;
-		HRESULT hr = mDevice.getD3D11Device()->QueryInterface(__uuidof(IDXGIDevice), (void**)&pDXGIDevice);
-		if(FAILED(hr))
-			CM_EXCEPT(RenderingAPIException, "Unable to query a DXGIDevice");
-
-		return pDXGIDevice;
-	}
-
-	void D3D11RenderWindow::_finishSwitchingFullscreen()
-	{
-		if(mIsFullScreen)
-		{
-			// Need to reset the region on the window sometimes, when the 
-			// windowed mode was constrained by desktop 
-			HRGN hRgn = CreateRectRgn(0, 0, mSwapChainDesc.BufferDesc.Width, mSwapChainDesc.BufferDesc.Height);
-			SetWindowRgn(mHWnd, hRgn, FALSE);
-		}
-		else
-		{
-			// When switching back to windowed mode, need to reset window size 
-			// after device has been restored
-			RECT rc;
-			SetRect(&rc, 0, 0, mSwapChainDesc.BufferDesc.Width, mSwapChainDesc.BufferDesc.Height);
-			AdjustWindowRect(&rc, GetWindowLong(mHWnd, GWL_STYLE), false);
-			unsigned int winWidth = rc.right - rc.left;
-			unsigned int winHeight = rc.bottom - rc.top;
-			int screenw = GetSystemMetrics(SM_CXSCREEN);
-			int screenh = GetSystemMetrics(SM_CYSCREEN);
-			int left = (screenw - winWidth) / 2;
-			int top = (screenh - winHeight) / 2;
-			SetWindowPos(mHWnd, HWND_NOTOPMOST, left, top, winWidth, winHeight,
-				SWP_DRAWFRAME | SWP_FRAMECHANGED | SWP_NOACTIVATE);
-		}
-
-		mSwapChain->SetFullscreenState(mIsFullScreen, NULL);
-		mSwitchingFullscreen = false;
+	void D3D11RenderWindow::_createSizeDependedD3DResources()
+	{
+		// obtain back buffer
+		SAFE_RELEASE(mBackBuffer);
+
+		HRESULT hr = mSwapChain->GetBuffer(0,  __uuidof( ID3D11Texture2D ), (LPVOID*)&mBackBuffer);
+		if( FAILED(hr) )
+			CM_EXCEPT(RenderingAPIException, "Unable to Get Back Buffer for swap chain");
+
+		// create all other size depended resources
+		assert(mBackBuffer && !mRenderTargetView && !mDepthStencilView);
+
+		// get the backbuffer desc
+		D3D11_TEXTURE2D_DESC BBDesc;
+		mBackBuffer->GetDesc(&BBDesc);
+
+		// create the render target view
+		D3D11_RENDER_TARGET_VIEW_DESC RTVDesc;
+		ZeroMemory( &RTVDesc, sizeof(RTVDesc) );
+
+		RTVDesc.Format = BBDesc.Format;
+		RTVDesc.ViewDimension = mFSAA ? D3D11_RTV_DIMENSION_TEXTURE2DMS : D3D11_RTV_DIMENSION_TEXTURE2D;
+		RTVDesc.Texture2D.MipSlice = 0;
+		hr = mDevice.getD3D11Device()->CreateRenderTargetView(mBackBuffer, &RTVDesc, &mRenderTargetView);
+
+		if( FAILED(hr) )
+		{
+			String errorDescription = mDevice.getErrorDescription();
+			CM_EXCEPT(RenderingAPIException, "Unable to create rendertagert view\nError Description:" + errorDescription);
+		}
+
+		mDepthStencilBuffer = TextureManager::instance().createDepthStencilBuffer(32, BBDesc.Width, BBDesc.Height, mFSAA, mFSAAHint);
+
+		//if(mDepthBufferPoolId != DepthStencilBuffer::POOL_NO_DEPTH)
+		//{
+		//	// Create depth stencil texture
+		//	ID3D11Texture2D* pDepthStencil = NULL;
+		//	D3D11_TEXTURE2D_DESC descDepth;
+
+		//	descDepth.Width = BBDesc.Width;
+		//	descDepth.Height = BBDesc.Height;
+		//	descDepth.MipLevels = 1;
+		//	descDepth.ArraySize = 1;
+		//	descDepth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
+		//	descDepth.SampleDesc.Count = mFSAAType.Count;
+		//	descDepth.SampleDesc.Quality = mFSAAType.Quality;
+		//	descDepth.Usage = D3D11_USAGE_DEFAULT;
+		//	descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL;
+		//	descDepth.CPUAccessFlags = 0;
+		//	descDepth.MiscFlags = 0;
+
+		//	hr = mDevice.getD3D11Device()->CreateTexture2D(&descDepth, NULL, &pDepthStencil);
+		//	if( FAILED(hr) || mDevice.hasError())
+		//	{
+		//		String errorDescription = mDevice.getErrorDescription(hr);
+		//		CM_EXCEPT(RenderingAPIException, "Unable to create depth texture\nError Description:" + errorDescription);
+		//	}
+
+		//	// Create the depth stencil view
+		//	D3D11_DEPTH_STENCIL_VIEW_DESC descDSV;
+		//	ZeroMemory( &descDSV, sizeof(D3D11_DEPTH_STENCIL_VIEW_DESC) );
+
+		//	descDSV.Format =  descDepth.Format;
+		//	descDSV.ViewDimension = mFSAA ? D3D11_DSV_DIMENSION_TEXTURE2DMS : D3D11_DSV_DIMENSION_TEXTURE2D;
+		//	descDSV.Texture2D.MipSlice = 0;
+		//	hr = mDevice.getD3D11Device()->CreateDepthStencilView(pDepthStencil, &descDSV, &mDepthStencilView);
+
+		//	SAFE_RELEASE(pDepthStencil);
+
+		//	if( FAILED(hr) )
+		//	{
+		//		String errorDescription = mDevice.getErrorDescription();
+		//		CM_EXCEPT(RenderingAPIException, 
+		//			"Unable to create depth stencil view\nError Description:" + errorDescription);
+		//	}
+
+		//	D3D11RenderSystem* rsys = static_cast<D3D11RenderSystem*>(RenderSystem::instancePtr());
+		//	DepthStencilBuffer *depthBuf = rsys->_addManualDepthBuffer(mDepthStencilView, mWidth, mHeight, mFSAAType.Count, mFSAAType.Quality);
+
+		//	//Don't forget we want this window to use _this_ depth buffer
+		//	this->attachDepthBuffer(depthBuf);
+		//} 
+	}
+
+	void D3D11RenderWindow::_destroySizeDependedD3DResources()
+	{
+		SAFE_RELEASE(mBackBuffer);
+		SAFE_RELEASE(mRenderTargetView);
+
+		mDepthStencilBuffer = nullptr;
+
+		SAFE_RELEASE(mDepthStencilView);
+	}
+
+	void D3D11RenderWindow::_resizeSwapChainBuffers(unsigned width, unsigned height)
+	{
+		_destroySizeDependedD3DResources();
+
+		// width and height can be zero to autodetect size, therefore do not rely on them
+		UINT Flags = mIsFullScreen ? DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH : 0;
+		mSwapChain->ResizeBuffers(mSwapChainDesc.BufferCount, width, height, mSwapChainDesc.BufferDesc.Format, Flags);
+		mSwapChain->GetDesc(&mSwapChainDesc);
+		mWidth = mSwapChainDesc.BufferDesc.Width;
+		mHeight = mSwapChainDesc.BufferDesc.Height;
+		mIsFullScreen = (0 == mSwapChainDesc.Windowed); // Alt-Enter together with SetWindowAssociation() can change this state
+
+		_createSizeDependedD3DResources();
+
+		mDevice.getImmediateContext()->OMSetRenderTargets(0, 0, 0);
+		// Additional swap chains need their own depth buffer
+		// to support resizing them
+
+		HRESULT hr = mSwapChain->GetBuffer( 0,  __uuidof( ID3D11Texture2D ), (LPVOID*)&mBackBuffer  );
+		if( FAILED(hr) )
+		{
+			CM_EXCEPT(RenderingAPIException, 
+				"Unable to Get Back Buffer for swap chain");
+		}
+
+		// get the backbuffer desc
+		D3D11_TEXTURE2D_DESC BBDesc;
+		mBackBuffer->GetDesc(&BBDesc);
+
+		// create the render target view
+		D3D11_RENDER_TARGET_VIEW_DESC RTVDesc;
+		ZeroMemory( &RTVDesc, sizeof(RTVDesc) );
+
+		RTVDesc.Format = BBDesc.Format;
+		RTVDesc.ViewDimension = mFSAA ? D3D11_RTV_DIMENSION_TEXTURE2DMS : D3D11_RTV_DIMENSION_TEXTURE2D;
+		RTVDesc.Texture2D.MipSlice = 0;
+		hr = mDevice.getD3D11Device()->CreateRenderTargetView(mBackBuffer, &RTVDesc, &mRenderTargetView);
+
+		if(FAILED(hr))
+		{
+			String errorDescription = mDevice.getErrorDescription();
+			CM_EXCEPT(RenderingAPIException, 
+				"Unable to create rendertagert view\nError Description:" + errorDescription);
+		}
 	}
 	}
 
 
-	bool D3D11RenderWindow::_checkMultiSampleQuality(UINT SampleCount, UINT *outQuality, DXGI_FORMAT format)
-	{
-		if (SUCCEEDED(mDevice.getD3D11Device()->CheckMultisampleQualityLevels(format, SampleCount, outQuality)))
-			return true;
-		else
-			return false;
+	IDXGIDevice* D3D11RenderWindow::_queryDxgiDevice()
+	{
+		if (mDevice.getD3D11Device() == nullptr)
+		{
+			CM_EXCEPT(RenderingAPIException, "D3D11Device is NULL!");
+		}
+
+		IDXGIDevice* pDXGIDevice = nullptr;
+		HRESULT hr = mDevice.getD3D11Device()->QueryInterface(__uuidof(IDXGIDevice), (void**)&pDXGIDevice);
+		if(FAILED(hr))
+			CM_EXCEPT(RenderingAPIException, "Unable to query a DXGIDevice");
+
+		return pDXGIDevice;
+	}
+
+	void D3D11RenderWindow::_finishSwitchingFullscreen()
+	{
+		if(mIsFullScreen)
+		{
+			// Need to reset the region on the window sometimes, when the 
+			// windowed mode was constrained by desktop 
+			HRGN hRgn = CreateRectRgn(0, 0, mSwapChainDesc.BufferDesc.Width, mSwapChainDesc.BufferDesc.Height);
+			SetWindowRgn(mHWnd, hRgn, FALSE);
+		}
+		else
+		{
+			// When switching back to windowed mode, need to reset window size 
+			// after device has been restored
+			RECT rc;
+			SetRect(&rc, 0, 0, mSwapChainDesc.BufferDesc.Width, mSwapChainDesc.BufferDesc.Height);
+			AdjustWindowRect(&rc, GetWindowLong(mHWnd, GWL_STYLE), false);
+			unsigned int winWidth = rc.right - rc.left;
+			unsigned int winHeight = rc.bottom - rc.top;
+			int screenw = GetSystemMetrics(SM_CXSCREEN);
+			int screenh = GetSystemMetrics(SM_CYSCREEN);
+			int left = (screenw - winWidth) / 2;
+			int top = (screenh - winHeight) / 2;
+			SetWindowPos(mHWnd, HWND_NOTOPMOST, left, top, winWidth, winHeight,
+				SWP_DRAWFRAME | SWP_FRAMECHANGED | SWP_NOACTIVATE);
+		}
+
+		mSwapChain->SetFullscreenState(mIsFullScreen, NULL);
+		mSwitchingFullscreen = false;
+	}
+
+	bool D3D11RenderWindow::_checkMultiSampleQuality(UINT SampleCount, UINT *outQuality, DXGI_FORMAT format)
+	{
+		if (SUCCEEDED(mDevice.getD3D11Device()->CheckMultisampleQualityLevels(format, SampleCount, outQuality)))
+			return true;
+		else
+			return false;
 	}
 	}
 }
 }

+ 584 - 0
CamelotD3D11RenderSystem/Source/CmD3D11Texture.cpp

@@ -0,0 +1,584 @@
+#include "CmD3D11Texture.h"
+#include "CmD3D11Mappings.h"
+#include "CmD3D11Device.h"
+#include "CmD3D11RenderSystem.h"
+#include "CmException.h"
+#include "CmAsyncOp.h"
+
+#if CM_DEBUG_MODE
+#define THROW_IF_NOT_RENDER_THREAD throwIfNotRenderThread();
+#else
+#define THROW_IF_NOT_RENDER_THREAD 
+#endif
+
+namespace CamelotEngine
+{
+	D3D11Texture::D3D11Texture()
+		: m1DTex(nullptr)
+		, m2DTex(nullptr)
+		, m3DTex(nullptr)
+		, mTex(nullptr)
+		, mShaderResourceView(nullptr)
+		, mStagingBuffer(nullptr)
+		, mLockedSubresourceIdx(-1)
+		, mLockedForReading(false)
+		, mStaticBuffer(nullptr)
+	{
+		ZeroMemory(&mSRVDesc, sizeof(D3D11_SHADER_RESOURCE_VIEW_DESC));
+	}
+
+	void D3D11Texture::setRawPixels_internal(const PixelData& data, UINT32 face, UINT32 mip)
+	{
+		THROW_IF_NOT_RENDER_THREAD
+
+		if(mip < 0 || mip > mNumMipmaps)
+			CM_EXCEPT(InvalidParametersException, "Invalid mip level: " + toString(mip) + ". Min is 0, max is " + toString(mNumMipmaps));
+
+		if(face < 0 || face > getNumFaces())
+			CM_EXCEPT(InvalidParametersException, "Invalid face index: " + toString(face) + ". Min is 0, max is " + toString(getNumFaces()));
+
+		if(mFormat != data.format)
+			CM_EXCEPT(InvalidParametersException, "Provided PixelData has invalid format. Needed: " + toString(mFormat) + ". Got: " + toString(data.format));
+
+		if(mWidth != data.getWidth() || mHeight != data.getHeight() || mDepth != data.getDepth())
+		{
+			CM_EXCEPT(InvalidParametersException, "Provided PixelData size doesn't match the texture size." \
+				" Width: " + toString(mWidth) + "/" + toString(data.getWidth()) + 
+				" Height: " + toString(mHeight) + "/" + toString(data.getHeight()) + 
+				" Depth: " + toString(mDepth) + "/" + toString(data.getDepth()));
+		}
+
+		PixelData myData = lock(HBL_WRITE_ONLY_DISCARD, mip, face);
+		memcpy(myData.data, data.data, data.getConsecutiveSize());
+		unlock();
+	}
+
+	void D3D11Texture::getRawPixels_internal(UINT32 face, UINT32 mip, AsyncOp& op)
+	{
+		THROW_IF_NOT_RENDER_THREAD;
+
+		if(mip < 0 || mip > mNumMipmaps)
+			CM_EXCEPT(InvalidParametersException, "Invalid mip level: " + toString(mip) + ". Min is 0, max is " + toString(mNumMipmaps));
+
+		if(face < 0 || mip > getNumFaces())
+			CM_EXCEPT(InvalidParametersException, "Invalid face index: " + toString(face) + ". Min is 0, max is " + toString(getNumFaces()));
+
+		UINT32 numMips = getNumMipmaps();
+
+		UINT32 totalSize = 0;
+		UINT32 width = getWidth();
+		UINT32 height = getHeight();
+		UINT32 depth = getDepth();
+
+		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;
+		}
+
+		UINT8* buffer = new UINT8[totalSize]; 
+		PixelDataPtr dst(new PixelData(width, height, depth, getFormat(), buffer, true));
+
+		PixelData myData = lock(HBL_READ_ONLY, mip, face);
+
+#if CM_DEBUG_MODE
+		if(dst->getConsecutiveSize() != myData.getConsecutiveSize())
+		{
+			unlock();
+			CM_EXCEPT(InternalErrorException, "Buffer sizes don't match");
+		}
+#endif
+
+		memcpy(dst->data, myData.data, dst->getConsecutiveSize());
+		unlock();
+
+		op.completeOperation(dst);
+	}
+
+	void D3D11Texture::copy_internal(TexturePtr& target)
+	{
+		if (target->getUsage() != this->getUsage() ||
+			target->getTextureType() != this->getTextureType())
+		{
+			CM_EXCEPT(InvalidParametersException, "Source and destination textures must be of same type and must have the same usage and type.");
+		}
+
+		if(getWidth() != target->getWidth() || getHeight() != target->getHeight() || getDepth() != target->getDepth())
+		{
+			CM_EXCEPT(InvalidParametersException, "Texture sizes don't match." \
+				" Width: " + toString(getWidth()) + "/" + toString(target->getWidth()) + 
+				" Height: " + toString(getHeight()) + "/" + toString(target->getHeight()) + 
+				" Depth: " + toString(getDepth()) + "/" + toString(target->getDepth()));
+		}
+
+		if(getNumFaces() != target->getNumFaces())
+		{
+			CM_EXCEPT(InvalidParametersException, "Number of texture faces doesn't match." \
+				" Num faces: " + toString(getNumFaces()) + "/" + toString(target->getNumFaces()));
+		}
+
+		if(getNumMipmaps() != target->getNumMipmaps())
+		{
+			CM_EXCEPT(InvalidParametersException, "Number of mipmaps doesn't match." \
+				" Num mipmaps: " + toString(getNumMipmaps()) + "/" + toString(target->getNumMipmaps()));
+		}
+
+		// get the target
+		D3D11Texture* other = static_cast<D3D11Texture*>(target.get());
+
+		D3D11Device& device = D3D11RenderSystem::getPrimaryDevice();
+		device.getImmediateContext()->CopyResource(other->getDX11Resource(), mTex);
+
+		if (device.hasError())
+		{
+			String errorDescription = device.getErrorDescription();
+			CM_EXCEPT(RenderingAPIException, "D3D11 device cannot copy resource\nError Description:" + errorDescription);
+		}
+	}
+
+	PixelData D3D11Texture::lock(LockOptions options, UINT32 mipLevel, UINT32 face)
+	{
+		UINT32 mipWidth = mipLevel >> mWidth;
+		UINT32 mipHeight = mipLevel >> mHeight;
+		UINT32 mipDepth = mipLevel >> mDepth;
+
+		PixelData lockedArea(mipWidth, mipHeight, mipDepth, mFormat);
+
+		D3D11_MAP flags = D3D11Mappings::_getLockOptions(options);
+		switch(options)
+		{
+		case HBL_WRITE_ONLY_NO_OVERWRITE:
+			flags = D3D11_MAP_WRITE_NO_OVERWRITE;
+			break;
+		case HBL_READ_WRITE:
+			flags = D3D11_MAP_READ_WRITE;
+			break;
+		case HBL_WRITE_ONLY_DISCARD:
+			flags = D3D11_MAP_WRITE_DISCARD;
+			break;
+		case HBL_READ_ONLY:
+			flags = D3D11_MAP_READ;
+			break;
+		case HBL_WRITE_ONLY:
+			flags = D3D11_MAP_WRITE;
+			break;
+		default: 
+			break;
+		};
+
+		if(flags == D3D11_MAP_READ || flags == D3D11_MAP_READ_WRITE)
+		{
+			lockedArea.data = _mapstagingbuffer(flags, face, mipLevel);
+			mLockedForReading = true;
+		}
+		else
+		{
+			if(mUsage == TU_DYNAMIC)
+				lockedArea.data = _map(mTex, flags, face, mipLevel);
+			else
+				lockedArea.data = _mapstaticbuffer(lockedArea, mipLevel, face);
+
+			mLockedForReading = false;
+		}
+
+		return lockedArea;
+	}
+
+	void D3D11Texture::unlock()
+	{
+		if(mLockedForReading)
+			_unmapstagingbuffer();
+		else
+			_unmap(mTex);
+	}
+
+	void D3D11Texture::initialize_internal()
+	{
+		THROW_IF_NOT_RENDER_THREAD
+
+		createInternalResources();
+
+		Resource::initialize_internal();
+	}
+
+	void D3D11Texture::createInternalResourcesImpl()
+	{
+		// load based on tex.type
+		switch (getTextureType())
+		{
+		case TEX_TYPE_1D:
+			_create1DTex();
+			break;
+		case TEX_TYPE_2D:
+		case TEX_TYPE_CUBE_MAP:
+			_create2DTex();
+			break;
+		case TEX_TYPE_3D:
+			_create3DTex();
+			break;
+		default:
+			freeInternalResources();
+			CM_EXCEPT(RenderingAPIException, "Unknown texture type");
+		}
+	}
+
+	void D3D11Texture::freeInternalResourcesImpl()
+	{
+		SAFE_RELEASE(mTex);
+		SAFE_RELEASE(mShaderResourceView);
+		SAFE_RELEASE(m1DTex);
+		SAFE_RELEASE(m2DTex);
+		SAFE_RELEASE(m3DTex);
+		SAFE_RELEASE(mStagingBuffer);
+	}
+
+	void D3D11Texture::_create1DTex()
+	{
+		// We must have those defined here
+		assert(mWidth > 0 || mHeight > 0);
+
+		// Determine which D3D11 pixel format we'll use
+		HRESULT hr;
+		DXGI_FORMAT d3dPF = D3D11Mappings::_getPF(D3D11Mappings::_getClosestSupportedPF(mFormat));
+
+		// Determine total number of mipmaps including main one (d3d11 convention)
+		UINT32 numMips = (mNumMipmaps == MIP_UNLIMITED || (1U << mNumMipmaps) > mWidth) ? 0 : mNumMipmaps + 1;
+
+		D3D11_TEXTURE1D_DESC desc;
+		desc.Width			= static_cast<UINT32>(mWidth);
+		desc.MipLevels		= numMips;
+		desc.ArraySize		= 1;
+		desc.Format			= d3dPF;
+		desc.Usage			= D3D11Mappings::_getUsage(mUsage);
+		desc.BindFlags		= D3D11_BIND_SHADER_RESOURCE;
+		desc.CPUAccessFlags = D3D11Mappings::_getAccessFlags(mUsage);
+		desc.MiscFlags		= 0;
+
+		// Create the texture
+		D3D11Device& device = D3D11RenderSystem::getPrimaryDevice();
+		hr = device.getD3D11Device()->CreateTexture1D(&desc, nullptr, &m1DTex);
+
+		// Check result and except if failed
+		if (FAILED(hr) || device.hasError())
+		{
+			freeInternalResources();
+			String errorDescription = device.getErrorDescription();
+			CM_EXCEPT(RenderingAPIException, "Error creating texture\nError Description:" + errorDescription);
+		}
+
+		HRESULT hr = m1DTex->QueryInterface(__uuidof(ID3D11Resource), (void **)mTex);
+
+		if(FAILED(hr) || device.hasError())
+		{
+			freeInternalResources();
+			String errorDescription = device.getErrorDescription();
+			CM_EXCEPT(RenderingAPIException, "Can't get base texture\nError Description:" + errorDescription);
+		}
+
+		// Create texture view
+		D3D11_TEXTURE1D_DESC desc;
+
+		m1DTex->GetDesc(&desc);
+		mNumMipmaps = desc.MipLevels - 1;
+
+		ZeroMemory( &mSRVDesc, sizeof(mSRVDesc) );
+		mSRVDesc.Format = desc.Format;
+		mSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D;
+		mSRVDesc.Texture1D.MipLevels = desc.MipLevels;
+		hr = device.getD3D11Device()->CreateShaderResourceView(m1DTex, &mSRVDesc, &mShaderResourceView);
+
+		if (FAILED(hr) || device.hasError())
+		{
+			String errorDescription = device.getErrorDescription(hr);
+			CM_EXCEPT(RenderingAPIException, "D3D11 device can't create shader resource view.\nError Description:" + errorDescription);
+		}
+	}
+
+	void D3D11Texture::_create2DTex()
+	{
+		// We must have those defined here
+		assert(mWidth > 0 || mHeight > 0);
+
+		// Determine which D3D11 pixel format we'll use
+		HRESULT hr;
+		DXGI_FORMAT d3dPF = D3D11Mappings::_getPF(D3D11Mappings::_getClosestSupportedPF(mFormat));
+
+		// Determine total number of mipmaps including main one (d3d11 convention)
+		UINT32 numMips = (mNumMipmaps == MIP_UNLIMITED || (1U << mNumMipmaps) > mWidth) ? 0 : mNumMipmaps + 1;
+
+		DXGI_SAMPLE_DESC sampleDesc;
+		sampleDesc.Count = 1;
+		sampleDesc.Quality = 0;
+
+		D3D11_TEXTURE2D_DESC desc;
+		desc.Width			= static_cast<UINT32>(mWidth);
+		desc.Height			= static_cast<UINT32>(mHeight);
+		desc.MipLevels		= numMips;
+		desc.ArraySize		= 1;
+		desc.Format			= d3dPF;
+		desc.SampleDesc		= sampleDesc;
+		desc.Usage			= D3D11Mappings::_getUsage(mUsage);
+		desc.BindFlags		= D3D11_BIND_SHADER_RESOURCE;
+		desc.CPUAccessFlags = D3D11Mappings::_getAccessFlags(mUsage);
+		desc.MiscFlags		= 0;
+
+        if (this->getTextureType() == TEX_TYPE_CUBE_MAP)
+        {
+                desc.MiscFlags          |= D3D11_RESOURCE_MISC_TEXTURECUBE;
+                desc.ArraySize          = 6;
+        }
+
+		// Create the texture
+		D3D11Device& device = D3D11RenderSystem::getPrimaryDevice();
+		hr = device.getD3D11Device()->CreateTexture2D(&desc, nullptr, &m2DTex);
+
+		// Check result and except if failed
+		if (FAILED(hr) || device.hasError())
+		{
+			freeInternalResources();
+			String errorDescription = device.getErrorDescription();
+			CM_EXCEPT(RenderingAPIException, "Error creating texture\nError Description:" + errorDescription);
+		}
+
+		HRESULT hr = m2DTex->QueryInterface(__uuidof(ID3D11Resource), (void **)mTex);
+
+		if(FAILED(hr) || device.hasError())
+		{
+			freeInternalResources();
+			String errorDescription = device.getErrorDescription();
+			CM_EXCEPT(RenderingAPIException, "Can't get base texture\nError Description:" + errorDescription);
+		}
+
+		// Create texture view
+		D3D11_TEXTURE2D_DESC desc;
+
+		m2DTex->GetDesc(&desc);
+		mNumMipmaps = desc.MipLevels - 1;
+
+		ZeroMemory(&mSRVDesc, sizeof(mSRVDesc));
+		mSRVDesc.Format = desc.Format;
+
+		switch(getTextureType())
+		{
+		case TEX_TYPE_CUBE_MAP:
+			mSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
+			mSRVDesc.TextureCube.MipLevels = desc.MipLevels;
+			mSRVDesc.TextureCube.MostDetailedMip = 0;
+			break;
+
+		case TEX_TYPE_2D:
+			mSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
+			mSRVDesc.Texture2D.MostDetailedMip = 0;
+			mSRVDesc.Texture2D.MipLevels = desc.MipLevels;
+			break;
+		}
+
+		hr = device.getD3D11Device()->CreateShaderResourceView(m2DTex, &mSRVDesc, &mShaderResourceView);
+
+		if (FAILED(hr) || device.hasError())
+		{
+			String errorDescription = device.getErrorDescription(hr);
+			CM_EXCEPT(RenderingAPIException, "D3D11 device can't create shader resource view.\nError Description:" + errorDescription);
+		}
+	}
+
+	void D3D11Texture::_create3DTex()
+	{
+		// We must have those defined here
+		assert(mWidth > 0 && mHeight > 0 && mDepth > 0);
+
+		// Determine which D3D11 pixel format we'll use
+		HRESULT hr;
+		DXGI_FORMAT d3dPF = D3D11Mappings::_getPF(D3D11Mappings::_getClosestSupportedPF(mFormat));
+
+		// 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;
+
+		D3D11_TEXTURE3D_DESC desc;
+		desc.Width			= static_cast<UINT32>(mWidth);
+		desc.Height			= static_cast<UINT32>(mHeight);
+		desc.Depth			= static_cast<UINT32>(mDepth);
+		desc.MipLevels		= numMips;
+		desc.Format			= d3dPF;
+		desc.Usage			= D3D11Mappings::_getUsage(mUsage);
+		desc.BindFlags		= D3D11_BIND_SHADER_RESOURCE;
+		desc.CPUAccessFlags = D3D11Mappings::_getAccessFlags(mUsage);
+		desc.MiscFlags		= 0;
+
+		// Create the texture
+		D3D11Device& device = D3D11RenderSystem::getPrimaryDevice();
+		hr = device.getD3D11Device()->CreateTexture3D(&desc, nullptr, &m3DTex);
+
+		// Check result and except if failed
+		if (FAILED(hr) || device.hasError())
+		{
+			freeInternalResources();
+			String errorDescription = device.getErrorDescription();
+			CM_EXCEPT(RenderingAPIException, "Error creating texture\nError Description:" + errorDescription);
+		}
+
+		HRESULT hr = m3DTex->QueryInterface(__uuidof(ID3D11Resource), (void **)mTex);
+
+		if(FAILED(hr) || device.hasError())
+		{
+			freeInternalResources();
+			String errorDescription = device.getErrorDescription();
+			CM_EXCEPT(RenderingAPIException, "Can't get base texture\nError Description:" + errorDescription);
+		}
+
+		// Create texture view
+		D3D11_TEXTURE3D_DESC desc;
+
+		m3DTex->GetDesc(&desc);
+		mNumMipmaps = desc.MipLevels - 1;
+
+		ZeroMemory(&mSRVDesc, sizeof(mSRVDesc));
+		mSRVDesc.Format = desc.Format;
+		mSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
+		mSRVDesc.Texture3D.MostDetailedMip = 0;
+		mSRVDesc.Texture3D.MipLevels = desc.MipLevels;
+
+		hr = device.getD3D11Device()->CreateShaderResourceView(m2DTex, &mSRVDesc, &mShaderResourceView);
+
+		if (FAILED(hr) || device.hasError())
+		{
+			String errorDescription = device.getErrorDescription(hr);
+			CM_EXCEPT(RenderingAPIException, "D3D11 device can't create shader resource view.\nError Description:" + errorDescription);
+		}
+	}
+
+	void* D3D11Texture::_map(ID3D11Resource* res, D3D11_MAP flags, UINT32 mipLevel, UINT32 face)
+	{
+		D3D11_MAPPED_SUBRESOURCE pMappedResource;
+		pMappedResource.pData = nullptr;
+
+		mipLevel = Math::Clamp(mipLevel, (UINT32)mipLevel, getNumMipmaps());
+		face = Math::Clamp(face, (UINT32)0, mDepth - 1);
+
+		if(getTextureType() == TEX_TYPE_3D)
+			face = 0;
+
+		D3D11Device& device = D3D11RenderSystem::getPrimaryDevice();
+
+		mLockedSubresourceIdx = D3D11CalcSubresource(mipLevel, face, getNumMipmaps()+1);
+		device.getImmediateContext()->Map(res, mLockedSubresourceIdx, flags, 0, &pMappedResource);
+
+		if (device.hasError())
+		{
+			String errorDescription = device.getErrorDescription();
+			CM_EXCEPT(RenderingAPIException, "D3D11 device cannot map texture\nError Description:" + errorDescription);
+		}
+
+		return pMappedResource.pData;
+	}
+
+	void D3D11Texture::_unmap(ID3D11Resource* res)
+	{
+		D3D11Device& device = D3D11RenderSystem::getPrimaryDevice();
+		device.getImmediateContext()->Unmap(res, mLockedSubresourceIdx);
+
+		if (device.hasError())
+		{
+			String errorDescription = device.getErrorDescription();
+			CM_EXCEPT(RenderingAPIException, "D3D11 device unmap resource\nError Description:" + errorDescription);
+		}
+	}
+
+	void* D3D11Texture::_mapstagingbuffer(D3D11_MAP flags, UINT32 mipLevel, UINT32 face)
+	{
+		if(!mStagingBuffer)
+			_createStagingBuffer();
+
+		D3D11Device& device = D3D11RenderSystem::getPrimaryDevice();
+		device.getImmediateContext()->CopyResource(mStagingBuffer, mTex);
+
+		return _map(mStagingBuffer, flags, face, mipLevel);
+	}
+
+	void D3D11Texture::_unmapstagingbuffer()
+	{
+		_unmap(mStagingBuffer);
+	}
+
+	void* D3D11Texture::_mapstaticbuffer(PixelData lock, UINT32 mipLevel, UINT32 face)
+	{
+		UINT32 sizeOfImage = lock.getConsecutiveSize();
+		mLockedSubresourceIdx = D3D11CalcSubresource(mipLevel, face, getNumMipmaps()+1);
+
+		UINT8* bufferData = new UINT8[sizeOfImage];
+		mStaticBuffer = new PixelData(lock.getWidth(), lock.getHeight(), lock.getDepth(), lock.getFormat(), bufferData, true);
+
+		return bufferData;
+	}
+
+	void D3D11Texture::_unmapstaticbuffer()
+	{
+		size_t rowWidth = D3D11Mappings::_getSizeInBytes(mStaticBuffer->getFormat(), mStaticBuffer->getWidth());
+		size_t sliceWidth = D3D11Mappings::_getSizeInBytes(mStaticBuffer->getFormat(), mStaticBuffer->getWidth(), mStaticBuffer->getHeight());
+
+		D3D11Device& device = D3D11RenderSystem::getPrimaryDevice();
+		device.getImmediateContext()->UpdateSubresource(mTex, mLockedSubresourceIdx, nullptr, mStaticBuffer->data, rowWidth, sliceWidth);
+
+		if (device.hasError())
+		{
+			String errorDescription = device.getErrorDescription();
+			CM_EXCEPT(RenderingAPIException, "D3D11 device cannot map texture\nError Description:" + errorDescription);
+		}
+
+		SAFE_DELETE(mStaticBuffer);
+	}
+
+	void D3D11Texture::_createStagingBuffer()
+	{
+		D3D11Device& device = D3D11RenderSystem::getPrimaryDevice();
+		switch (getTextureType())
+		{
+		case TEX_TYPE_1D:
+			{
+				D3D11_TEXTURE1D_DESC desc;
+				m1DTex->GetDesc(&desc);
+
+				desc.BindFlags = 0;
+				desc.MiscFlags = 0;
+				desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ;
+				desc.Usage = D3D11_USAGE_STAGING;
+
+				device.getD3D11Device()->CreateTexture1D(&desc, NULL, (ID3D11Texture1D**)(&mStagingBuffer));
+			} 					
+			break;
+		case TEX_TYPE_2D:
+		case TEX_TYPE_CUBE_MAP:
+		case TEX_TYPE_2D_ARRAY:
+			{
+				D3D11_TEXTURE2D_DESC desc;
+				m2DTex->GetDesc(&desc);
+
+				desc.BindFlags = 0;
+				desc.MiscFlags = 0;
+				desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ;
+				desc.Usage = D3D11_USAGE_STAGING;
+
+				device.getD3D11Device()->CreateTexture2D(&desc, NULL, (ID3D11Texture2D**)(&mStagingBuffer));
+			}
+			break;
+		case TEX_TYPE_3D:
+			{
+				D3D11_TEXTURE3D_DESC desc;
+				m3DTex->GetDesc(&desc);
+
+				desc.BindFlags = 0;
+				desc.MiscFlags = 0;
+				desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ;
+				desc.Usage = D3D11_USAGE_STAGING;
+
+				device.getD3D11Device()->CreateTexture3D(&desc, NULL, (ID3D11Texture3D**)(&mStagingBuffer));
+			}
+			break;
+		}
+	}
+}
+
+#undef THROW_IF_NOT_RENDER_THREAD

+ 52 - 53
CamelotD3D9Renderer/Include/CmD3D9HardwarePixelBuffer.h

@@ -36,8 +36,59 @@ namespace CamelotEngine {
 	class D3D9Texture;
 	class D3D9Texture;
 	class D3D9RenderTexture;
 	class D3D9RenderTexture;
 
 
-	class CM_D3D9_EXPORT D3D9HardwarePixelBuffer: public HardwarePixelBuffer
+	class CM_D3D9_EXPORT D3D9HardwarePixelBuffer : public HardwarePixelBuffer
 	{
 	{
+	public:
+		D3D9HardwarePixelBuffer(HardwareBuffer::Usage usage, 
+			D3D9Texture* ownerTexture);
+		~D3D9HardwarePixelBuffer();
+
+		/// Call this to associate a D3D surface or volume with this pixel buffer
+		void bind(IDirect3DDevice9 *dev, IDirect3DSurface9 *mSurface, IDirect3DSurface9* fsaaSurface,
+			bool writeGamma, UINT32 fsaa, const String& srcName, IDirect3DBaseTexture9 *mipTex);
+		void bind(IDirect3DDevice9 *dev, IDirect3DVolume9 *mVolume, IDirect3DBaseTexture9 *mipTex);
+
+		/// @copydoc HardwarePixelBuffer::blit
+		void blit(const HardwarePixelBufferPtr &src, const Box &srcBox, const Box &dstBox);
+
+		/// @copydoc HardwarePixelBuffer::blitFromMemory
+		void blitFromMemory(const PixelData &src, const Box &dstBox);
+
+		/// @copydoc HardwarePixelBuffer::blitToMemory
+		void blitToMemory(const Box &srcBox, const PixelData &dst);
+
+		/// Internal function to update mipmaps on update of level 0
+		void _genMipmaps(IDirect3DBaseTexture9* mipTex);
+
+		/// Function to set mipmap generation
+		void _setMipmapping(bool doMipmapGen, bool HWMipmaps);
+
+
+		/// Get rendertarget for z slice
+		RenderTexture *getRenderTarget(UINT32 zoffset);
+
+		/// Accessor for surface
+		IDirect3DSurface9 *getSurface(IDirect3DDevice9* d3d9Device);
+
+		/// Accessor for AA surface
+		IDirect3DSurface9 *getFSAASurface(IDirect3DDevice9* d3d9Device);
+
+		/// Notify TextureBuffer of destruction of render target
+		virtual void _clearSliceRTT(UINT32 zoffset);
+
+		/// Release surfaces held by this pixel buffer.
+		void releaseSurfaces(IDirect3DDevice9* d3d9Device);
+
+		/// Destroy resources associated with the given device.
+		void destroyBufferResources(IDirect3DDevice9* d3d9Device);
+
+		// Called when device state is changing. Access to any device should be locked.
+		// Relevant for multi thread application.
+		static void lockDeviceAccess();
+
+		// Called when device state change completed. Access to any device is allowed.
+		// Relevant for multi thread application.
+		static void unlockDeviceAccess();
 	protected:		
 	protected:		
 		struct BufferResources
 		struct BufferResources
 		{			
 		{			
@@ -100,58 +151,6 @@ namespace CamelotEngine {
 		void blitFromMemory(const PixelData &src, const Box &dstBox, BufferResources* dstBufferResources);
 		void blitFromMemory(const PixelData &src, const Box &dstBox, BufferResources* dstBufferResources);
 
 
 		void blitToMemory(const Box &srcBox, const PixelData &dst, BufferResources* srcBufferResources, IDirect3DDevice9* d3d9Device);
 		void blitToMemory(const Box &srcBox, const PixelData &dst, BufferResources* srcBufferResources, IDirect3DDevice9* d3d9Device);
-			
-	public:
-		D3D9HardwarePixelBuffer(HardwareBuffer::Usage usage, 
-			D3D9Texture* ownerTexture);
-		~D3D9HardwarePixelBuffer();
-
-		/// Call this to associate a D3D surface or volume with this pixel buffer
-		void bind(IDirect3DDevice9 *dev, IDirect3DSurface9 *mSurface, IDirect3DSurface9* fsaaSurface,
-				  bool writeGamma, UINT32 fsaa, const String& srcName, IDirect3DBaseTexture9 *mipTex);
-		void bind(IDirect3DDevice9 *dev, IDirect3DVolume9 *mVolume, IDirect3DBaseTexture9 *mipTex);
-		
-		/// @copydoc HardwarePixelBuffer::blit
-        void blit(const HardwarePixelBufferPtr &src, const Box &srcBox, const Box &dstBox);
-		
-		/// @copydoc HardwarePixelBuffer::blitFromMemory
-		void blitFromMemory(const PixelData &src, const Box &dstBox);
-	
-		/// @copydoc HardwarePixelBuffer::blitToMemory
-		void blitToMemory(const Box &srcBox, const PixelData &dst);
-		
-		/// Internal function to update mipmaps on update of level 0
-		void _genMipmaps(IDirect3DBaseTexture9* mipTex);
-		
-		/// Function to set mipmap generation
-		void _setMipmapping(bool doMipmapGen, bool HWMipmaps);
-		
-		
-		/// Get rendertarget for z slice
-		RenderTexture *getRenderTarget(UINT32 zoffset);
-
-		/// Accessor for surface
-		IDirect3DSurface9 *getSurface(IDirect3DDevice9* d3d9Device);
-		
-		/// Accessor for AA surface
-		IDirect3DSurface9 *getFSAASurface(IDirect3DDevice9* d3d9Device);
-
-		/// Notify TextureBuffer of destruction of render target
-        virtual void _clearSliceRTT(UINT32 zoffset);
-
-		/// Release surfaces held by this pixel buffer.
-		void releaseSurfaces(IDirect3DDevice9* d3d9Device);
-
-		/// Destroy resources associated with the given device.
-		void destroyBufferResources(IDirect3DDevice9* d3d9Device);
-
-		// Called when device state is changing. Access to any device should be locked.
-		// Relevant for multi thread application.
-		static void lockDeviceAccess();
-
-		// Called when device state change completed. Access to any device is allowed.
-		// Relevant for multi thread application.
-		static void unlockDeviceAccess();
 	};
 	};
 };
 };
 #endif
 #endif

+ 3 - 3
CamelotD3D9Renderer/Source/CmD3D9HardwareIndexBuffer.cpp

@@ -119,7 +119,7 @@ namespace CamelotEngine {
 						bufferResources->mLockLength = length;
 						bufferResources->mLockLength = length;
 				}
 				}
 			
 			
-				if (bufferResources->mLockOptions != HBL_DISCARD)
+				if (bufferResources->mLockOptions != HBL_WRITE_ONLY_DISCARD)
 					bufferResources->mLockOptions = options;
 					bufferResources->mLockOptions = options;
 
 
 				++it;
 				++it;
@@ -246,7 +246,7 @@ namespace CamelotEngine {
 		bufferResources->mOutOfDate = true;
 		bufferResources->mOutOfDate = true;
 		bufferResources->mLockOffset = 0;
 		bufferResources->mLockOffset = 0;
 		bufferResources->mLockLength = getSizeInBytes();
 		bufferResources->mLockLength = getSizeInBytes();
-		bufferResources->mLockOptions = HBL_NORMAL;
+		bufferResources->mLockOptions = HBL_READ_WRITE;
 		// TODO PORT - I don't know current frame number. Once I add a method for counting frames call it here
 		// TODO PORT - I don't know current frame number. Once I add a method for counting frames call it here
 		//bufferResources->mLastUsedFrame = Root::getSingleton().getNextFrameNumber();
 		//bufferResources->mLastUsedFrame = Root::getSingleton().getNextFrameNumber();
 		bufferResources->mLastUsedFrame = 0;
 		bufferResources->mLastUsedFrame = 0;
@@ -337,7 +337,7 @@ namespace CamelotEngine {
 		bufferResources->mOutOfDate = false;
 		bufferResources->mOutOfDate = false;
 		bufferResources->mLockOffset = mSizeInBytes;
 		bufferResources->mLockOffset = mSizeInBytes;
 		bufferResources->mLockLength = 0;
 		bufferResources->mLockLength = 0;
-		bufferResources->mLockOptions = HBL_NORMAL;
+		bufferResources->mLockOptions = HBL_READ_WRITE;
 
 
 		return true;			
 		return true;			
 	}
 	}

+ 1 - 1
CamelotD3D9Renderer/Source/CmD3D9HardwarePixelBuffer.cpp

@@ -336,7 +336,7 @@ PixelData D3D9HardwarePixelBuffer::lockImpl(const Box lockBox,  LockOptions opti
 	DWORD flags = 0;
 	DWORD flags = 0;
 	switch(options)
 	switch(options)
 	{
 	{
-	case HBL_DISCARD:
+	case HBL_WRITE_ONLY_DISCARD:
 		// D3D only likes D3DLOCK_DISCARD if you created the texture with D3DUSAGE_DYNAMIC
 		// D3D only likes D3DLOCK_DISCARD if you created the texture with D3DUSAGE_DYNAMIC
 		// debug runtime flags this up, could cause problems on some drivers
 		// debug runtime flags this up, could cause problems on some drivers
 		if (mUsage & HBU_DYNAMIC)
 		if (mUsage & HBU_DYNAMIC)

+ 3 - 3
CamelotD3D9Renderer/Source/CmD3D9HardwareVertexBuffer.cpp

@@ -119,7 +119,7 @@ namespace CamelotEngine {
 						bufferResources->mLockLength = length;
 						bufferResources->mLockLength = length;
 				}
 				}
 				
 				
-				if (bufferResources->mLockOptions != HBL_DISCARD)
+				if (bufferResources->mLockOptions != HBL_WRITE_ONLY_DISCARD)
 					bufferResources->mLockOptions = options;					
 					bufferResources->mLockOptions = options;					
 
 
 				++it;
 				++it;
@@ -245,7 +245,7 @@ namespace CamelotEngine {
 		bufferResources->mOutOfDate = true;
 		bufferResources->mOutOfDate = true;
 		bufferResources->mLockOffset = 0;
 		bufferResources->mLockOffset = 0;
 		bufferResources->mLockLength = getSizeInBytes();
 		bufferResources->mLockLength = getSizeInBytes();
-		bufferResources->mLockOptions = HBL_NORMAL;
+		bufferResources->mLockOptions = HBL_READ_WRITE;
 
 
 		// TODO PORT - Don't know what the next frame number is. Add a method for that
 		// TODO PORT - Don't know what the next frame number is. Add a method for that
 		//bufferResources->mLastUsedFrame = Root::getSingleton().getNextFrameNumber();
 		//bufferResources->mLastUsedFrame = Root::getSingleton().getNextFrameNumber();
@@ -336,7 +336,7 @@ namespace CamelotEngine {
 		bufferResources->mOutOfDate = false;
 		bufferResources->mOutOfDate = false;
 		bufferResources->mLockOffset = mSizeInBytes;
 		bufferResources->mLockOffset = mSizeInBytes;
 		bufferResources->mLockLength = 0;
 		bufferResources->mLockLength = 0;
-		bufferResources->mLockOptions = HBL_NORMAL;
+		bufferResources->mLockOptions = HBL_READ_WRITE;
 
 
 		return true;		
 		return true;		
 	}
 	}

+ 14 - 0
CamelotGLRenderer/Include/CmGLDepthStencilBuffer.h

@@ -0,0 +1,14 @@
+#pragma once
+
+#include "CmGLPrerequisites.h"
+#include "CmDepthStencilBuffer.h"
+
+namespace CamelotEngine
+{
+	class CM_RSGL_EXPORT GLDepthStencilBuffer : public DepthStencilBuffer
+	{
+	public:
+		GLDepthStencilBuffer(UINT32 bitDepth, UINT32 width, UINT32 height, UINT32 fsaa, const String &fsaaHint);
+		// TODO - Add GL specific implementation
+	};
+}

+ 2 - 2
CamelotGLRenderer/Source/CmGLHardwareIndexBuffer.cpp

@@ -86,7 +86,7 @@ namespace CamelotEngine {
 				mScratchPtr = retPtr;
 				mScratchPtr = retPtr;
 				mScratchUploadOnUnlock = (options != HBL_READ_ONLY);
 				mScratchUploadOnUnlock = (options != HBL_READ_ONLY);
 
 
-				if (options != HBL_DISCARD)
+				if (options != HBL_WRITE_ONLY_DISCARD)
 				{
 				{
 					// have to read back the data before returning the pointer
 					// have to read back the data before returning the pointer
 					readData(offset, length, retPtr);
 					readData(offset, length, retPtr);
@@ -98,7 +98,7 @@ namespace CamelotEngine {
 		{
 		{
 			glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, mBufferId );
 			glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, mBufferId );
 			// Use glMapBuffer
 			// Use glMapBuffer
-			if(options == HBL_DISCARD)
+			if(options == HBL_WRITE_ONLY_DISCARD)
 			{
 			{
 				// Discard the buffer
 				// Discard the buffer
 				glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mSizeInBytes, NULL, 
 				glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mSizeInBytes, NULL, 

+ 2 - 2
CamelotGLRenderer/Source/CmGLHardwareVertexBuffer.cpp

@@ -88,7 +88,7 @@ namespace CamelotEngine {
 				mScratchPtr = retPtr;
 				mScratchPtr = retPtr;
 				mScratchUploadOnUnlock = (options != HBL_READ_ONLY);
 				mScratchUploadOnUnlock = (options != HBL_READ_ONLY);
 
 
-				if (options != HBL_DISCARD)
+				if (options != HBL_WRITE_ONLY_DISCARD)
 				{
 				{
 					// have to read back the data before returning the pointer
 					// have to read back the data before returning the pointer
 					readData(offset, length, retPtr);
 					readData(offset, length, retPtr);
@@ -101,7 +101,7 @@ namespace CamelotEngine {
 			// Use glMapBuffer
 			// Use glMapBuffer
 			glBindBufferARB( GL_ARRAY_BUFFER_ARB, mBufferId );
 			glBindBufferARB( GL_ARRAY_BUFFER_ARB, mBufferId );
 			// Use glMapBuffer
 			// Use glMapBuffer
-			if(options == HBL_DISCARD)
+			if(options == HBL_WRITE_ONLY_DISCARD)
 			{
 			{
 				// Discard the buffer
 				// Discard the buffer
 				glBufferDataARB(GL_ARRAY_BUFFER_ARB, mSizeInBytes, NULL, 
 				glBufferDataARB(GL_ARRAY_BUFFER_ARB, mSizeInBytes, NULL, 

+ 21 - 0
CamelotRenderer/Include/CmCommon.h

@@ -203,6 +203,27 @@ namespace CamelotEngine {
 		SOP_INVERT
 		SOP_INVERT
 	};
 	};
 
 
+	/// Locking options
+	enum LockOptions
+	{
+        /** Normal mode, ie allows read/write and contents are preserved. */
+        HBL_READ_WRITE,
+		/** Discards the <em>entire</em> buffer while locking; this allows optimisation to be 
+		performed because synchronisation issues are relaxed. 
+		*/
+		HBL_WRITE_ONLY_DISCARD,
+		/** Lock the buffer for reading only. Not allowed in buffers which are created with HBU_WRITE_ONLY. 
+		*/ 
+		HBL_READ_ONLY,
+        /** As HBL_NORMAL, except the application guarantees not to overwrite any 
+        region of the buffer which has already been used in this frame, can allow
+        some optimisation on some APIs. */
+        HBL_WRITE_ONLY_NO_OVERWRITE,
+		/** Lock for writing only */
+		HBL_WRITE_ONLY
+    			
+	};
+
 	/** Texture addressing mode for each texture coordinate. */
 	/** Texture addressing mode for each texture coordinate. */
 	struct UVWAddressingMode
 	struct UVWAddressingMode
 	{
 	{

+ 1 - 18
CamelotRenderer/Include/CmHardwareBuffer.h

@@ -30,6 +30,7 @@ THE SOFTWARE.
 
 
 // Precompiler options
 // Precompiler options
 #include "CmPrerequisites.h"
 #include "CmPrerequisites.h"
+#include "CmCommon.h"
 
 
 namespace CamelotEngine {
 namespace CamelotEngine {
 
 
@@ -115,24 +116,6 @@ namespace CamelotEngine {
                 HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE = 14
                 HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE = 14
 
 
 
 
-		    };
-		    /// Locking options
-		    enum LockOptions
-		    {
-                /** Normal mode, ie allows read/write and contents are preserved. */
-                HBL_NORMAL,
-			    /** Discards the <em>entire</em> buffer while locking; this allows optimisation to be 
-				performed because synchronisation issues are relaxed. 
-			    */
-			    HBL_DISCARD,
-			    /** Lock the buffer for reading only. Not allowed in buffers which are created with HBU_WRITE_ONLY. 
-				*/ 
-			    HBL_READ_ONLY,
-                /** As HBL_NORMAL, except the application guarantees not to overwrite any 
-                region of the buffer which has already been used in this frame, can allow
-                some optimisation on some APIs. */
-                HBL_NO_OVERWRITE
-    			
 		    };
 		    };
 	    protected:
 	    protected:
 		    UINT32 mSizeInBytes;
 		    UINT32 mSizeInBytes;

+ 0 - 1
CamelotRenderer/Include/CmHardwarePixelBuffer.h

@@ -60,7 +60,6 @@ namespace CamelotEngine {
         PixelData mCurrentLock;
         PixelData mCurrentLock;
 		// The current locked box of this surface (entire surface coords)
 		// The current locked box of this surface (entire surface coords)
 		Box mLockedBox;
 		Box mLockedBox;
-
         
         
         /// Internal implementation of lock(), must be overridden in subclasses
         /// Internal implementation of lock(), must be overridden in subclasses
         virtual PixelData lockImpl(const Box lockBox,  LockOptions options) = 0;
         virtual PixelData lockImpl(const Box lockBox,  LockOptions options) = 0;

+ 7 - 17
CamelotRenderer/Include/CmTexture.h

@@ -46,18 +46,10 @@ namespace CamelotEngine {
     enum TextureUsage
     enum TextureUsage
     {
     {
 		/// @copydoc HardwareBuffer::Usage
 		/// @copydoc HardwareBuffer::Usage
-		TU_STATIC = HardwareBuffer::HBU_STATIC,
-		TU_DYNAMIC = HardwareBuffer::HBU_DYNAMIC,
-		TU_WRITE_ONLY = HardwareBuffer::HBU_WRITE_ONLY,
-		TU_STATIC_WRITE_ONLY = HardwareBuffer::HBU_STATIC_WRITE_ONLY, 
-		TU_DYNAMIC_WRITE_ONLY = HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY,
-		TU_DYNAMIC_WRITE_ONLY_DISCARDABLE = HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE,
-		/// this texture will be a render target, i.e. used as a target for render to texture
-		/// setting this flag will ignore all other texture usages
-		TU_RENDERTARGET = 0x200,
-		/// default to automatic mipmap generation static textures
-		TU_DEFAULT = TU_STATIC_WRITE_ONLY
-        
+		TU_STATIC = HardwareBuffer::HBU_STATIC, // Optimal setting if texture is read by the GPU often, and very rarely written by CPU
+		TU_DYNAMIC = HardwareBuffer::HBU_DYNAMIC, // Optimal if the texture is updated by CPU often (e.g. every frame)
+		TU_RENDERTARGET = 0x200, // Used for rendering by the GPU
+		TU_DEFAULT = TU_STATIC
     };
     };
 
 
     /** Enum identifying the texture type
     /** Enum identifying the texture type
@@ -191,7 +183,7 @@ namespace CamelotEngine {
 		 *
 		 *
 		 * @see		Texture::setRawPixels
 		 * @see		Texture::setRawPixels
 		 */
 		 */
-		void setRawPixels_internal(const PixelData& data, UINT32 face = 0, UINT32 mip = 0);
+		virtual void setRawPixels_internal(const PixelData& data, UINT32 face = 0, UINT32 mip = 0);
 
 
 		/**
 		/**
 		 * @brief	Gets raw pixels from the texture. This is a slow operation
 		 * @brief	Gets raw pixels from the texture. This is a slow operation
@@ -219,11 +211,11 @@ namespace CamelotEngine {
 		 *
 		 *
 		 * @see		Texture::getRawPixels
 		 * @see		Texture::getRawPixels
 		 */
 		 */
-		void getRawPixels_internal(UINT32 face, UINT32 mip, AsyncOp& op);
+		virtual void getRawPixels_internal(UINT32 face, UINT32 mip, AsyncOp& op);
 
 
 		/** Copies (and maybe scales to fit) the contents of this texture to
 		/** Copies (and maybe scales to fit) the contents of this texture to
 			another texture. */
 			another texture. */
-		virtual void copy_internal( TexturePtr& target );
+		virtual void copy_internal(TexturePtr& target);
 
 
     protected:
     protected:
 		friend class TextureManager;
 		friend class TextureManager;
@@ -310,9 +302,7 @@ namespace CamelotEngine {
 			PixelFormat format, int usage = TU_DEFAULT,
 			PixelFormat format, int usage = TU_DEFAULT,
 			bool hwGammaCorrection = false, UINT32 fsaa = 0, const String& fsaaHint = StringUtil::BLANK);
 			bool hwGammaCorrection = false, UINT32 fsaa = 0, const String& fsaaHint = StringUtil::BLANK);
     };
     };
-
 	/** @} */
 	/** @} */
-
 }
 }
 
 
 #endif
 #endif

+ 2 - 2
CamelotRenderer/Source/CmHardwarePixelBuffer.cpp

@@ -102,12 +102,12 @@ namespace CamelotEngine
 		}
 		}
 		const PixelData &srclock = src->lock(srcBox, HBL_READ_ONLY);
 		const PixelData &srclock = src->lock(srcBox, HBL_READ_ONLY);
 
 
-		LockOptions method = HBL_NORMAL;
+		LockOptions method = HBL_READ_WRITE;
 		if(dstBox.left == 0 && dstBox.top == 0 && dstBox.front == 0 &&
 		if(dstBox.left == 0 && dstBox.top == 0 && dstBox.front == 0 &&
 		   dstBox.right == mWidth && dstBox.bottom == mHeight &&
 		   dstBox.right == mWidth && dstBox.bottom == mHeight &&
 		   dstBox.back == mDepth)
 		   dstBox.back == mDepth)
 			// Entire buffer -- we can discard the previous contents
 			// Entire buffer -- we can discard the previous contents
-			method = HBL_DISCARD;
+			method = HBL_WRITE_ONLY_DISCARD;
 			
 			
 		const PixelData &dstlock = lock(dstBox, method);
 		const PixelData &dstlock = lock(dstBox, method);
 		if(dstlock.getWidth() != srclock.getWidth() ||
 		if(dstlock.getWidth() != srclock.getWidth() ||

+ 1 - 1
CamelotRenderer/Source/CmTexture.cpp

@@ -123,7 +123,7 @@ namespace CamelotEngine {
 		if(mip < 0 || mip > mNumMipmaps)
 		if(mip < 0 || mip > mNumMipmaps)
 			CM_EXCEPT(InvalidParametersException, "Invalid mip level: " + toString(mip) + ". Min is 0, max is " + toString(mNumMipmaps));
 			CM_EXCEPT(InvalidParametersException, "Invalid mip level: " + toString(mip) + ". Min is 0, max is " + toString(mNumMipmaps));
 
 
-		if(face < 0 || mip > getNumFaces())
+		if(face < 0 || face > getNumFaces())
 			CM_EXCEPT(InvalidParametersException, "Invalid face index: " + toString(face) + ". Min is 0, max is " + toString(getNumFaces()));
 			CM_EXCEPT(InvalidParametersException, "Invalid face index: " + toString(face) + ". Min is 0, max is " + toString(getNumFaces()));
 
 
 		if(mFormat != data.format)
 		if(mFormat != data.format)

+ 13 - 1
CamelotRenderer/TODO.txt

@@ -17,14 +17,25 @@
 
 
 
 
 /////
 /////
+HardwarePixelBuffer should hold a pointer to DX11Texture, and CmDX11Texture should hold a pointer to HardwarePixelBuffer
+
 waitForVsync can probably be moved somewhere other than being directly in RenderSystem? (where is it in DX11?)
 waitForVsync can probably be moved somewhere other than being directly in RenderSystem? (where is it in DX11?)
 
 
 Move createRenderTexture to TextureManager? (also createMultiRenderTexture)
 Move createRenderTexture to TextureManager? (also createMultiRenderTexture)
- - Right now its created with a special texture usage flag, which I don't like
+ - Right now its created with a special texture usage flag, which I don't like (Textures have slices and other weird stuff)
 Drop OpenGL support for low level shaders? (See if cg can translate to GLSL)
 Drop OpenGL support for low level shaders? (See if cg can translate to GLSL)
 
 
 Keeping a list of all render targets in RenderSystem shouldn't be needed (and calling attach/detach renderTarget). Renderer should determine in what order are render targets presented.
 Keeping a list of all render targets in RenderSystem shouldn't be needed (and calling attach/detach renderTarget). Renderer should determine in what order are render targets presented.
 
 
+Constant buffers are created in a weird way. Maybe they should only be created internally by GpuProgramParameters?
+ - Multiple GpuProgramParameters get returned from GpuProgram after createParameters() is called, in a map, each with its own name
+
+
+setDepthBuffer method on RenderTexture
+All render targets need to create DepthStencilBuffer internally, so that getDepthStencilBuffer can return something. Right now only D3D11 render window does this
+Add D3D11DepthStencilBuffer
+ - Remove commented out buffer creation code from D3D11RenderWindow
+
 Make CommandQueue not use mutexes and use atomics instead??
 Make CommandQueue not use mutexes and use atomics instead??
 Make sure that the simulation can't run faster then the render thread! (Block the main thread until previous render finishes)
 Make sure that the simulation can't run faster then the render thread! (Block the main thread until previous render finishes)
 /////
 /////
@@ -169,6 +180,7 @@ Optional TODO:
 After everything is polished
 After everything is polished
  - Each view (i.e. camera) of the scene should be put into its own thread
  - Each view (i.e. camera) of the scene should be put into its own thread
  - How do I handle multiple mesh formats? Some files need animation, other don't. Some would mabye like to use QTangent, others the proper tangent frame.
  - How do I handle multiple mesh formats? Some files need animation, other don't. Some would mabye like to use QTangent, others the proper tangent frame.
+  - Asset postprocessor? Imports a regular mesh using normal importers and then postprocesses it into a specialized format?
  - Load texture mips separately so we can unload HQ textures from far away objects (like UE3)
  - Load texture mips separately so we can unload HQ textures from far away objects (like UE3)
  - Add Unified shader so I can easily switch between HLSL and GLSL shaders (they need same parameters usually, just different code)
  - Add Unified shader so I can easily switch between HLSL and GLSL shaders (they need same parameters usually, just different code)
     - Maybe just add support for Cg and force everyone to use that? - I'd like to be able to just switch out renderer in a single location and that everything keeps on working without 
     - Maybe just add support for Cg and force everyone to use that? - I'd like to be able to just switch out renderer in a single location and that everything keeps on working without 

+ 2 - 0
CamelotUtility/Include/CmPixelData.h

@@ -241,6 +241,8 @@ namespace CamelotEngine
         */
         */
         UINT32 getSliceSkip() const { return slicePitch - (getHeight() * rowPitch); }
         UINT32 getSliceSkip() const { return slicePitch - (getHeight() * rowPitch); }
 
 
+		PixelFormat getFormat() const { return format; }
+
         /** Return whether this buffer is laid out consecutive in memory (ie the pitches
         /** Return whether this buffer is laid out consecutive in memory (ie the pitches
          	are equal to the dimensions)
          	are equal to the dimensions)
         */        
         */