Răsfoiți Sursa

A lot more work on resource views

Marko Pintera 13 ani în urmă
părinte
comite
c4912c2ec1
33 a modificat fișierele cu 527 adăugiri și 72 ștergeri
  1. 2 0
      CamelotD3D11RenderSystem/CamelotD3D11RenderSystem.vcxproj
  2. 6 0
      CamelotD3D11RenderSystem/CamelotD3D11RenderSystem.vcxproj.filters
  3. 1 1
      CamelotD3D11RenderSystem/Include/CmD3D11GpuBuffer.h
  4. 1 1
      CamelotD3D11RenderSystem/Include/CmD3D11GpuBufferView.h
  5. 1 1
      CamelotD3D11RenderSystem/Include/CmD3D11HardwareBufferManager.h
  6. 4 0
      CamelotD3D11RenderSystem/Include/CmD3D11Texture.h
  7. 32 0
      CamelotD3D11RenderSystem/Include/CmD3D11TextureView.h
  8. 4 3
      CamelotD3D11RenderSystem/Source/CmD3D11GpuBuffer.cpp
  9. 10 6
      CamelotD3D11RenderSystem/Source/CmD3D11GpuBufferView.cpp
  10. 1 1
      CamelotD3D11RenderSystem/Source/CmD3D11HardwareBufferManager.cpp
  11. 12 0
      CamelotD3D11RenderSystem/Source/CmD3D11Texture.cpp
  12. 210 0
      CamelotD3D11RenderSystem/Source/CmD3D11TextureView.cpp
  13. 1 1
      CamelotD3D9Renderer/Include/CmD3D9GpuBuffer.h
  14. 1 1
      CamelotD3D9Renderer/Include/CmD3D9HardwareBufferManager.h
  15. 1 1
      CamelotD3D9Renderer/Source/CmD3D9GpuBuffer.cpp
  16. 1 1
      CamelotD3D9Renderer/Source/CmD3D9HardwareBufferManager.cpp
  17. 1 1
      CamelotGLRenderer/Include/CmGLGpuBuffer.h
  18. 1 1
      CamelotGLRenderer/Include/CmGLHardwareBufferManager.h
  19. 1 1
      CamelotGLRenderer/Source/CmGLGpuBuffer.cpp
  20. 1 1
      CamelotGLRenderer/Source/CmGLHardwareBufferManager.cpp
  21. 2 0
      CamelotRenderer/CamelotRenderer.vcxproj
  22. 6 0
      CamelotRenderer/CamelotRenderer.vcxproj.filters
  23. 12 1
      CamelotRenderer/Include/CmCommonEnums.h
  24. 3 3
      CamelotRenderer/Include/CmGpuBuffer.h
  25. 16 28
      CamelotRenderer/Include/CmGpuBufferView.h
  26. 1 1
      CamelotRenderer/Include/CmHardwareBufferManager.h
  27. 26 0
      CamelotRenderer/Include/CmTexture.h
  28. 40 0
      CamelotRenderer/Include/CmTextureView.h
  29. 10 7
      CamelotRenderer/Source/CmGpuBuffer.cpp
  30. 11 10
      CamelotRenderer/Source/CmGpuBufferView.cpp
  31. 72 0
      CamelotRenderer/Source/CmTexture.cpp
  32. 35 0
      CamelotRenderer/Source/CmTextureView.cpp
  33. 1 1
      CamelotRenderer/TODO.txt

+ 2 - 0
CamelotD3D11RenderSystem/CamelotD3D11RenderSystem.vcxproj

@@ -166,6 +166,7 @@
     <ClInclude Include="Include\CmD3D11MultiRenderTexture.h" />
     <ClInclude Include="Include\CmD3D11GpuParamBlock.h" />
     <ClInclude Include="Include\CmD3D11Prerequisites.h" />
+    <ClInclude Include="Include\CmD3D11TextureView.h" />
     <ClInclude Include="Include\CmD3D11VertexBuffer.h" />
     <ClInclude Include="Include\CmD3D11RasterizerState.h" />
     <ClInclude Include="Include\CmD3D11RenderStateManager.h" />
@@ -201,6 +202,7 @@
     <ClCompile Include="Source\CmD3D11InputLayoutManager.cpp" />
     <ClCompile Include="Source\CmD3D11Mappings.cpp" />
     <ClCompile Include="Source\CmD3D11Plugin.cpp" />
+    <ClCompile Include="Source\CmD3D11TextureView.cpp" />
     <ClCompile Include="Source\CmD3D11VertexBuffer.cpp" />
     <ClCompile Include="Source\CmD3D11MultiRenderTexture.cpp" />
     <ClCompile Include="Source\CmD3D11RasterizerState.cpp" />

+ 6 - 0
CamelotD3D11RenderSystem/CamelotD3D11RenderSystem.vcxproj.filters

@@ -120,6 +120,9 @@
     <ClInclude Include="Include\CmD3D11GpuBufferView.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="Include\CmD3D11TextureView.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\CmD3D11GpuProgram.cpp">
@@ -221,5 +224,8 @@
     <ClCompile Include="Source\CmD3D11GpuBufferView.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="Source\CmD3D11TextureView.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 1 - 1
CamelotD3D11RenderSystem/Include/CmD3D11GpuBuffer.h

@@ -42,7 +42,7 @@ namespace CamelotEngine
 	protected:
 		D3D11HardwareBuffer* mBuffer;
 
-		virtual GpuBufferView* createView(UINT32 firstElement, UINT32 elementWidth, UINT32 numElements, bool randomGpuWrite);
+		virtual GpuBufferView* createView(GPU_BUFFER_DESC& desc);
 		virtual void destroyView(GpuBufferView* view);
     };
 }

+ 1 - 1
CamelotD3D11RenderSystem/Include/CmD3D11GpuBufferView.h

@@ -9,7 +9,7 @@ namespace CamelotEngine
 	class CM_D3D11_EXPORT D3D11GpuBufferView : public GpuBufferView
 	{
 	public:
-		D3D11GpuBufferView(ID3D11Buffer* buffer, GpuBufferType type, UINT32 firstElement, UINT32 elementWidth, UINT32 numElements, bool randomGpuWrite, bool useCounter = false);
+		D3D11GpuBufferView(ID3D11Buffer* buffer, GpuBufferType type, GPU_BUFFER_DESC& desc);
 		virtual ~D3D11GpuBufferView();
 
 	private:

+ 1 - 1
CamelotD3D11RenderSystem/Include/CmD3D11HardwareBufferManager.h

@@ -31,7 +31,7 @@ namespace CamelotEngine
 		 *  - APPENDCONSUME buffer type can only be used with randomGpuWrite enabled  
 		 *  - Counter can only be used with STRUCTURED buffer type
 		 */
-		GenericBufferPtr createGenericBuffer(UINT32 elementCount, UINT32 elementSize, 
+		GenericBufferPtr createGpuBuffer(UINT32 elementCount, UINT32 elementSize, 
 			GpuBufferType type, GpuBufferUsage usage, bool randomGpuWrite = false, bool useCounter = false);
 
 	protected:     

+ 4 - 0
CamelotD3D11RenderSystem/Include/CmD3D11Texture.h

@@ -14,6 +14,7 @@ namespace CamelotEngine
 		ID3D11ShaderResourceView* getSRV() const { return mShaderResourceView; }
 		D3D11_SRV_DIMENSION getDimension() const { return mDimension; }
 		DXGI_FORMAT getDXGIFormat() const { return mDXGIFormat; }
+
 	protected:
 		friend class D3D11TextureManager;
 
@@ -81,5 +82,8 @@ namespace CamelotEngine
 		 * @copydoc Texture::freeInternalResourcesImpl
 		 */
 		void freeInternalResourcesImpl();
+
+		TextureView* createView(TEXTURE_VIEW_DESC& _desc);
+		void destroyView(TextureView* view);
 	};
 }

+ 32 - 0
CamelotD3D11RenderSystem/Include/CmD3D11TextureView.h

@@ -0,0 +1,32 @@
+#pragma once
+
+#include "CmD3D11Prerequisites.h"
+#include "CmTextureView.h"
+
+namespace CamelotEngine
+{
+	class CM_D3D11_EXPORT D3D11TextureView : public TextureView
+	{
+	public:
+		D3D11TextureView(Texture* texture, TEXTURE_VIEW_DESC& _desc);
+		virtual ~D3D11TextureView();
+
+	private:
+		ID3D11ShaderResourceView*	mSRV;
+		ID3D11RenderTargetView*		mRTV;
+		ID3D11UnorderedAccessView*	mUAV;
+		ID3D11DepthStencilView*		mDSV;
+
+		ID3D11ShaderResourceView* createSRV(D3D11Texture* texture, 
+			UINT32 mostDetailMip, UINT32 numMips, UINT32 firstArraySlice, UINT32 numArraySlices);
+
+		ID3D11RenderTargetView* createRTV(D3D11Texture* texture, 
+			UINT32 mostDetailMip, UINT32 numMips, UINT32 firstArraySlice, UINT32 numArraySlices);
+
+		ID3D11UnorderedAccessView* createUAV(D3D11Texture* texture, 
+			UINT32 mostDetailMip, UINT32 numMips, UINT32 firstArraySlice, UINT32 numArraySlices);
+
+		ID3D11DepthStencilView* createDSV(D3D11Texture* texture, 
+			UINT32 mostDetailMip, UINT32 numMips, UINT32 firstArraySlice, UINT32 numArraySlices);
+	};
+}

+ 4 - 3
CamelotD3D11RenderSystem/Source/CmD3D11GpuBuffer.cpp

@@ -68,13 +68,14 @@ namespace CamelotEngine
 		mBuffer->copyData(*d3d11SrcBuffer->mBuffer, srcOffset, dstOffset, length, discardWholeBuffer);
 	}
 
-	GpuBufferView* D3D11GpuBuffer::createView(UINT32 firstElement, UINT32 elementWidth, UINT32 numElements, bool randomGpuWrite)
+	GpuBufferView* D3D11GpuBuffer::createView(GPU_BUFFER_DESC& desc)
 	{
-		return new D3D11GpuBufferView(mBuffer->getD3DBuffer(), mType, firstElement, elementWidth, numElements, randomGpuWrite, mUseCounter);
+		return new D3D11GpuBufferView(mBuffer->getD3DBuffer(), mType, desc);
 	}
 
 	void D3D11GpuBuffer::destroyView(GpuBufferView* view)
 	{
-		delete view;
+		if(view != nullptr)
+			delete view;
 	}
 }

+ 10 - 6
CamelotD3D11RenderSystem/Source/CmD3D11GpuBufferView.cpp

@@ -1,18 +1,22 @@
 #include "CmD3D11GpuBufferView.h"
 #include "CmD3D11RenderSystem.h"
 #include "CmD3D11Device.h"
+#include "CmUtil.h"
 #include "CmException.h"
 
 namespace CamelotEngine
 {
-	D3D11GpuBufferView::D3D11GpuBufferView(ID3D11Buffer* buffer, GpuBufferType type, 
-		UINT32 firstElement, UINT32 elementWidth, UINT32 numElements, bool randomGpuWrite, bool useCounter)
-		:GpuBufferView(firstElement, elementWidth, numElements, randomGpuWrite), mSRV(nullptr), mUAV(nullptr)
+	D3D11GpuBufferView::D3D11GpuBufferView(ID3D11Buffer* buffer, GpuBufferType type, GPU_BUFFER_DESC& desc)
+		:GpuBufferView(desc), mSRV(nullptr), mUAV(nullptr)
 	{
-		if(randomGpuWrite)
-			mSRV = createSRV(buffer, type, firstElement, elementWidth, numElements);
+		if((desc.usage & GVU_RANDOMWRITE) != 0)
+			mUAV = createUAV(buffer, type, desc.firstElement, desc.numElements, desc.useCounter);
+		else if((desc.usage & GVU_RENDERTARGET) != 0)
+		{
+			CM_EXCEPT(NotImplementedException, "Cannot create a render target view for buffers yet.");
+		}
 		else
-			mUAV = createUAV(buffer, type, firstElement, numElements, useCounter);
+			mSRV = createSRV(buffer, type, desc.firstElement, desc.elementWidth, desc.numElements);
 	}
 
 	D3D11GpuBufferView::~D3D11GpuBufferView()

+ 1 - 1
CamelotD3D11RenderSystem/Source/CmD3D11HardwareBufferManager.cpp

@@ -49,7 +49,7 @@ namespace CamelotEngine
 		return GpuParamBlockPtr(new D3D11GpuParamBlock(blockDesc));
 	}
 
-	GenericBufferPtr D3D11HardwareBufferManager::createGenericBuffer(UINT32 elementCount, UINT32 elementSize, 
+	GenericBufferPtr D3D11HardwareBufferManager::createGpuBuffer(UINT32 elementCount, UINT32 elementSize, 
 		GpuBufferType type, GpuBufferUsage usage, bool randomGpuWrite, bool useCounter)
 	{
 		return GenericBufferPtr(new D3D11GpuBuffer(elementCount, elementSize, type, usage, randomGpuWrite, useCounter));

+ 12 - 0
CamelotD3D11RenderSystem/Source/CmD3D11Texture.cpp

@@ -2,6 +2,7 @@
 #include "CmD3D11Mappings.h"
 #include "CmD3D11Device.h"
 #include "CmD3D11RenderSystem.h"
+#include "CmD3D11TextureView.h"
 #include "CmException.h"
 #include "CmAsyncOp.h"
 
@@ -588,6 +589,17 @@ namespace CamelotEngine
 			break;
 		}
 	}
+
+	TextureView* D3D11Texture::createView(TEXTURE_VIEW_DESC& _desc)
+	{
+		return new D3D11TextureView(this, _desc);
+	}
+
+	void D3D11Texture::destroyView(TextureView* view)
+	{
+		if(view != nullptr)
+			delete view;
+	}
 }
 
 #undef THROW_IF_NOT_RENDER_THREAD

+ 210 - 0
CamelotD3D11RenderSystem/Source/CmD3D11TextureView.cpp

@@ -0,0 +1,210 @@
+#include "CmD3D11TextureView.h"
+#include "CmD3D11RenderSystem.h"
+#include "CmD3D11Device.h"
+#include "CmD3D11Texture.h"
+#include "CmUtil.h"
+#include "CmException.h"
+
+namespace CamelotEngine
+{
+	D3D11TextureView::D3D11TextureView(Texture* texture, TEXTURE_VIEW_DESC& _desc)
+		:TextureView(texture, _desc),
+		mSRV(nullptr), mUAV(nullptr), mDSV(nullptr), mRTV(nullptr)
+	{
+		D3D11Texture* d3d11Texture = static_cast<D3D11Texture*>(texture);
+
+		if((mDesc.usage & GVU_RANDOMWRITE) != 0)
+			mUAV = createUAV(d3d11Texture, mDesc.mostDetailMip, mDesc.numMips, mDesc.firstArraySlice, mDesc.numArraySlices);
+		else if((mDesc.usage & GVU_RENDERTARGET) != 0)
+			mRTV = createRTV(d3d11Texture, mDesc.mostDetailMip, mDesc.numMips, mDesc.firstArraySlice, mDesc.numArraySlices);
+		else if((mDesc.usage & GVU_DEPTHSTENCIL) != 0)
+			mDSV = createDSV(d3d11Texture, mDesc.mostDetailMip, mDesc.numMips, mDesc.firstArraySlice, mDesc.numArraySlices);
+		else
+			mSRV = createSRV(d3d11Texture, mDesc.mostDetailMip, mDesc.numMips, mDesc.firstArraySlice, mDesc.numArraySlices);
+	}
+
+	D3D11TextureView::~D3D11TextureView()
+	{
+		SAFE_RELEASE(mSRV);
+		SAFE_RELEASE(mUAV);
+		SAFE_RELEASE(mDSV);
+		SAFE_RELEASE(mRTV);
+	}
+
+	ID3D11ShaderResourceView* D3D11TextureView::createSRV(D3D11Texture* texture, 
+		UINT32 mostDetailMip, UINT32 numMips, UINT32 firstArraySlice, UINT32 numArraySlices)
+	{
+		D3D11_SHADER_RESOURCE_VIEW_DESC desc;
+		ZeroMemory(&desc, sizeof(desc));
+
+		switch(texture->getTextureType())
+		{
+		case TEX_TYPE_1D:
+			desc.Texture1D.MipLevels = numMips;
+			desc.Texture1D.MostDetailedMip = mostDetailMip;
+			desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D;
+			break;
+		case TEX_TYPE_2D:
+			desc.Texture2D.MipLevels = numMips;
+			desc.Texture2D.MostDetailedMip = mostDetailMip;
+			if(texture->getFSAA() > 0)
+				desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS;
+			else
+				desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
+			break;
+		case TEX_TYPE_3D:
+			desc.Texture3D.MipLevels = numMips;
+			desc.Texture3D.MostDetailedMip = mostDetailMip;
+			desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
+			break;
+		case TEX_TYPE_CUBE_MAP:
+			desc.TextureCube.MipLevels = numMips;
+			desc.TextureCube.MostDetailedMip = mostDetailMip;
+			desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
+			break;
+		default:
+			CM_EXCEPT(InvalidParametersException, "Invalid texture type for this view type.");
+		}
+
+		desc.Format = texture->getDXGIFormat();
+
+		ID3D11ShaderResourceView* srv = nullptr;
+
+		D3D11RenderSystem* d3d11rs = static_cast<D3D11RenderSystem*>(D3D11RenderSystem::instancePtr());
+		HRESULT hr = d3d11rs->getPrimaryDevice().getD3D11Device()->CreateShaderResourceView(texture->getDX11Resource(), &desc, &srv);
+
+		if (FAILED(hr) || d3d11rs->getPrimaryDevice().hasError())
+		{
+			String msg = d3d11rs->getPrimaryDevice().getErrorDescription();
+			CM_EXCEPT(RenderingAPIException, "Cannot create ShaderResourceView: " + msg);
+		}
+
+		return srv;
+	}
+
+	ID3D11RenderTargetView* D3D11TextureView::createRTV(D3D11Texture* texture, 
+		UINT32 mostDetailMip, UINT32 numMips, UINT32 firstArraySlice, UINT32 numArraySlices)
+	{
+		D3D11_RENDER_TARGET_VIEW_DESC desc;
+		ZeroMemory(&desc, sizeof(desc));
+
+		switch(texture->getTextureType())
+		{
+		case TEX_TYPE_1D:
+			desc.Texture1D.MipSlice = mostDetailMip;
+			desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1D;
+			break;
+		case TEX_TYPE_2D:
+			desc.Texture2D.MipSlice = mostDetailMip;
+			if(texture->getFSAA() > 0)
+				desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS;
+			else
+				desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
+			break;
+		case TEX_TYPE_3D:
+			desc.Texture3D.MipSlice = mostDetailMip;
+			desc.Texture3D.FirstWSlice = firstArraySlice;
+			desc.Texture3D.WSize = numArraySlices;
+			desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
+			break;
+		default:
+			CM_EXCEPT(InvalidParametersException, "Invalid texture type for this view type.");
+		}
+
+		desc.Format = texture->getDXGIFormat();
+
+		ID3D11RenderTargetView* rtv = nullptr;
+
+		D3D11RenderSystem* d3d11rs = static_cast<D3D11RenderSystem*>(D3D11RenderSystem::instancePtr());
+		HRESULT hr = d3d11rs->getPrimaryDevice().getD3D11Device()->CreateRenderTargetView(texture->getDX11Resource(), &desc, &rtv);
+
+		if (FAILED(hr) || d3d11rs->getPrimaryDevice().hasError())
+		{
+			String msg = d3d11rs->getPrimaryDevice().getErrorDescription();
+			CM_EXCEPT(RenderingAPIException, "Cannot create RenderTargetView: " + msg);
+		}
+
+		return rtv;
+	}
+
+	ID3D11UnorderedAccessView* D3D11TextureView::createUAV(D3D11Texture* texture,
+		UINT32 mostDetailMip, UINT32 numMips, UINT32 firstArraySlice, UINT32 numArraySlices)
+	{
+		D3D11_UNORDERED_ACCESS_VIEW_DESC desc;
+		ZeroMemory(&desc, sizeof(desc));
+
+		switch(texture->getTextureType())
+		{
+		case TEX_TYPE_1D:
+			desc.Texture1D.MipSlice = mostDetailMip;
+			desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE1D;
+			break;
+		case TEX_TYPE_2D:
+			desc.Texture2D.MipSlice = mostDetailMip;
+			desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D;
+			break;
+		case TEX_TYPE_3D:
+			desc.Texture3D.MipSlice = mostDetailMip;
+			desc.Texture3D.FirstWSlice = firstArraySlice;
+			desc.Texture3D.WSize = numArraySlices;
+			desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE3D;
+			break;
+		default:
+			CM_EXCEPT(InvalidParametersException, "Invalid texture type for this view type.");
+		}
+
+		desc.Format = texture->getDXGIFormat();
+
+		ID3D11UnorderedAccessView* uav = nullptr;
+
+		D3D11RenderSystem* d3d11rs = static_cast<D3D11RenderSystem*>(D3D11RenderSystem::instancePtr());
+		HRESULT hr = d3d11rs->getPrimaryDevice().getD3D11Device()->CreateUnorderedAccessView(texture->getDX11Resource(), &desc, &uav);
+
+		if (FAILED(hr) || d3d11rs->getPrimaryDevice().hasError())
+		{
+			String msg = d3d11rs->getPrimaryDevice().getErrorDescription();
+			CM_EXCEPT(RenderingAPIException, "Cannot create UnorderedAccessView: " + msg);
+		}
+
+		return uav;
+	}
+
+	ID3D11DepthStencilView* D3D11TextureView::createDSV(D3D11Texture* texture, 
+		UINT32 mostDetailMip, UINT32 numMips, UINT32 firstArraySlice, UINT32 numArraySlices)
+	{
+		D3D11_DEPTH_STENCIL_VIEW_DESC desc;
+		ZeroMemory(&desc, sizeof(desc));
+
+		switch(texture->getTextureType())
+		{
+		case TEX_TYPE_1D:
+			desc.Texture1D.MipSlice = mostDetailMip;
+			desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE1D;
+			break;
+		case TEX_TYPE_2D:
+			desc.Texture2D.MipSlice = mostDetailMip;
+			if(texture->getFSAA() > 0)
+				desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS;
+			else
+				desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
+			break;
+		default:
+			CM_EXCEPT(InvalidParametersException, "Invalid texture type for this view type.");
+		}
+
+		desc.Format = texture->getDXGIFormat();
+
+		ID3D11DepthStencilView* dsv = nullptr;
+
+		D3D11RenderSystem* d3d11rs = static_cast<D3D11RenderSystem*>(D3D11RenderSystem::instancePtr());
+		HRESULT hr = d3d11rs->getPrimaryDevice().getD3D11Device()->CreateDepthStencilView(texture->getDX11Resource(), &desc, &dsv);
+
+		if (FAILED(hr) || d3d11rs->getPrimaryDevice().hasError())
+		{
+			String msg = d3d11rs->getPrimaryDevice().getErrorDescription();
+			CM_EXCEPT(RenderingAPIException, "Cannot create DepthStencilView: " + msg);
+		}
+
+		return dsv;
+	}
+}

+ 1 - 1
CamelotD3D9Renderer/Include/CmD3D9GpuBuffer.h

@@ -39,7 +39,7 @@ namespace CamelotEngine
 			UINT32 dstOffset, UINT32 length, bool discardWholeBuffer = false);
 
 	protected:
-		virtual GpuBufferView* createView(UINT32 firstElement, UINT32 elementWidth, UINT32 numElements, bool randomGpuWrite);
+		virtual GpuBufferView* createView(GPU_BUFFER_DESC& desc);
 		virtual void destroyView(GpuBufferView* view);
 	};
 }

+ 1 - 1
CamelotD3D9Renderer/Include/CmD3D9HardwareBufferManager.h

@@ -64,7 +64,7 @@ namespace CamelotEngine {
 		 *
 		 * DirectX 9 does not support generic buffers so this method will return a dummy instance.
 		 */
-		GenericBufferPtr createGenericBuffer(UINT32 elementCount, UINT32 elementSize, 
+		GenericBufferPtr createGpuBuffer(UINT32 elementCount, UINT32 elementSize, 
 			GpuBufferType type, GpuBufferUsage usage, bool randomGpuWrite = false, bool useCounter = false);
     };
 }

+ 1 - 1
CamelotD3D9Renderer/Source/CmD3D9GpuBuffer.cpp

@@ -36,7 +36,7 @@ namespace CamelotEngine
 	{
 	}
 
-	GpuBufferView* D3D9GpuBuffer::createView(UINT32 firstElement, UINT32 elementWidth, UINT32 numElements, bool randomGpuWrite)
+	GpuBufferView* D3D9GpuBuffer::createView(GPU_BUFFER_DESC& desc)
 	{
 		return nullptr;
 	}

+ 1 - 1
CamelotD3D9Renderer/Source/CmD3D9HardwareBufferManager.cpp

@@ -72,7 +72,7 @@ namespace CamelotEngine {
 		return GpuParamBlockPtr(new GpuParamBlock(paramDesc));
 	}
 	//-----------------------------------------------------------------------
-	GenericBufferPtr D3D9HardwareBufferManager::createGenericBuffer(UINT32 elementCount, UINT32 elementSize, 
+	GenericBufferPtr D3D9HardwareBufferManager::createGpuBuffer(UINT32 elementCount, UINT32 elementSize, 
 		GpuBufferType type, GpuBufferUsage usage, bool randomGpuWrite, bool useCounter)
 	{
 		return GenericBufferPtr(new D3D9GpuBuffer(elementCount, elementSize, type, usage, randomGpuWrite, useCounter));

+ 1 - 1
CamelotGLRenderer/Include/CmGLGpuBuffer.h

@@ -39,7 +39,7 @@ namespace CamelotEngine
 			UINT32 dstOffset, UINT32 length, bool discardWholeBuffer = false);
 
 	protected:
-		virtual GpuBufferView* createView(UINT32 firstElement, UINT32 elementWidth, UINT32 numElements, bool randomGpuWrite);
+		virtual GpuBufferView* createView(GPU_BUFFER_DESC& desc);
 		virtual void destroyView(GpuBufferView* view);
 	};
 }

+ 1 - 1
CamelotGLRenderer/Include/CmGLHardwareBufferManager.h

@@ -70,7 +70,7 @@ namespace CamelotEngine {
 		 *
 		 * OpenGL does not support generic buffers so this method will return a dummy instance.
 		 */
-		GenericBufferPtr createGenericBuffer(UINT32 elementCount, UINT32 elementSize, 
+		GenericBufferPtr createGpuBuffer(UINT32 elementCount, UINT32 elementSize, 
 			GpuBufferType type, GpuBufferUsage usage, bool randomGpuWrite = false, bool useCounter = false);
 
         /// Utility function to get the correct GL usage based on HBU's

+ 1 - 1
CamelotGLRenderer/Source/CmGLGpuBuffer.cpp

@@ -36,7 +36,7 @@ namespace CamelotEngine
 	{
 	}
 
-	GpuBufferView* GLGpuBuffer::createView(UINT32 firstElement, UINT32 elementWidth, UINT32 numElements, bool randomGpuWrite)
+	GpuBufferView* GLGpuBuffer::createView(GPU_BUFFER_DESC& desc)
 	{
 		return nullptr;
 	}

+ 1 - 1
CamelotGLRenderer/Source/CmGLHardwareBufferManager.cpp

@@ -109,7 +109,7 @@ namespace CamelotEngine {
 		return GpuParamBlockPtr(new GLGpuParamBlock(paramDesc));
 	}
 	//---------------------------------------------------------------------
-	GenericBufferPtr GLHardwareBufferManager::createGenericBuffer(UINT32 elementCount, UINT32 elementSize, 
+	GenericBufferPtr GLHardwareBufferManager::createGpuBuffer(UINT32 elementCount, UINT32 elementSize, 
 		GpuBufferType type, GpuBufferUsage usage, bool randomGpuWrite, bool useCounter)
 	{
 		return GenericBufferPtr(new GLGpuBuffer(elementCount, elementSize, type, usage, randomGpuWrite, useCounter));

+ 2 - 0
CamelotRenderer/CamelotRenderer.vcxproj

@@ -204,6 +204,7 @@
     <ClInclude Include="Include\CmIndexBuffer.h" />
     <ClInclude Include="Include\CmOcclusionQuery.h" />
     <ClInclude Include="Include\CmPixelBuffer.h" />
+    <ClInclude Include="Include\CmTextureView.h" />
     <ClInclude Include="Include\CmVertexBuffer.h" />
     <ClInclude Include="Include\CmHighLevelGpuProgram.h" />
     <ClInclude Include="Include\CmHighLevelGpuProgramManager.h" />
@@ -288,6 +289,7 @@
     <ClCompile Include="Source\CmIndexBuffer.cpp" />
     <ClCompile Include="Source\CmOcclusionQuery.cpp" />
     <ClCompile Include="Source\CmPixelBuffer.cpp" />
+    <ClCompile Include="Source\CmTextureView.cpp" />
     <ClCompile Include="Source\CmVertexBuffer.cpp" />
     <ClCompile Include="Source\CmHighLevelGpuProgram.cpp" />
     <ClCompile Include="Source\CmHighLevelGpuProgramManager.cpp" />

+ 6 - 0
CamelotRenderer/CamelotRenderer.vcxproj.filters

@@ -359,6 +359,9 @@
     <ClInclude Include="Include\CmGpuBufferView.h">
       <Filter>Header Files\RenderSystem</Filter>
     </ClInclude>
+    <ClInclude Include="Include\CmTextureView.h">
+      <Filter>Header Files\RenderSystem</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\CamelotRenderer.cpp">
@@ -541,5 +544,8 @@
     <ClCompile Include="Source\CmGpuBuffer.cpp">
       <Filter>Source Files\RenderSystem</Filter>
     </ClCompile>
+    <ClCompile Include="Source\CmTextureView.cpp">
+      <Filter>Source Files\RenderSystem</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 12 - 1
CamelotRenderer/Include/CmCommonEnums.h

@@ -233,7 +233,7 @@ namespace CamelotEngine {
 		/** Indicates the application would like to modify this buffer with the CPU
 		fairly often. 
 		*/
-		GBU_DYNAMIC = 2,
+		GBU_DYNAMIC = 2
 	};
 
 	/**
@@ -247,6 +247,17 @@ namespace CamelotEngine {
 		GBT_APPENDCONSUME
 	};
 
+	/**
+	 * @brief	Combine these to generate a different type of gpu views
+	 */
+	enum GpuViewUsage
+	{
+		GVU_DEFAULT,
+		GVU_RENDERTARGET,
+		GVU_DEPTHSTENCIL,
+		GVU_RANDOMWRITE
+	};
+
 	/** Texture addressing mode for each texture coordinate. */
 	struct UVWAddressingMode
 	{

+ 3 - 3
CamelotRenderer/Include/CmGpuBuffer.h

@@ -21,7 +21,7 @@ namespace CamelotEngine
 		virtual void copyData(GpuBuffer& srcBuffer, UINT32 srcOffset, 
 			UINT32 dstOffset, UINT32 length, bool discardWholeBuffer = false) = 0;
 
-		GpuBufferView* requestView(UINT32 firstElement, UINT32 elementWidth, UINT32 numElements, bool randomGpuWrite);
+		GpuBufferView* requestView(UINT32 firstElement, UINT32 elementWidth, UINT32 numElements, bool useCounter, GpuViewUsage usage);
 		void releaseView(GpuBufferView* view);
 
 	protected:
@@ -32,7 +32,7 @@ namespace CamelotEngine
 		UINT32 mElementCount;
 		UINT32 mElementSize;
 
-		virtual GpuBufferView* createView(UINT32 firstElement, UINT32 elementWidth, UINT32 numElements, bool randomGpuWrite) = 0;
+		virtual GpuBufferView* createView(GPU_BUFFER_DESC& desc) = 0;
 		virtual void destroyView(GpuBufferView* view) = 0;
 		void clearBufferViews();
 
@@ -46,6 +46,6 @@ namespace CamelotEngine
 			UINT32 refCount;
 		};
 
-		std::unordered_map<GpuBufferView::Key, GpuBufferReference*, GpuBufferView::HashFunction, GpuBufferView::EqualFunction> mBufferViews;
+		std::unordered_map<GPU_BUFFER_DESC, GpuBufferReference*, GpuBufferView::HashFunction, GpuBufferView::EqualFunction> mBufferViews;
     };
 }

+ 16 - 28
CamelotRenderer/Include/CmGpuBufferView.h

@@ -1,52 +1,40 @@
 #pragma once
 
 #include "CmPrerequisites.h"
+#include "CmCommonEnums.h"
 
 namespace CamelotEngine
 {
+	struct CM_EXPORT GPU_BUFFER_DESC
+	{
+		UINT32 firstElement;
+		UINT32 elementWidth;
+		UINT32 numElements;
+		bool useCounter;
+		GpuViewUsage usage;
+	};
+
 	class CM_EXPORT GpuBufferView
 	{
 	public:
-		struct Key
-		{
-			Key()
-			{ }
-
-			Key(const GpuBufferView& view)
-				: mFirstElement(view.mFirstElement), mElementWidth(view.mElementWidth)
-				, mNumElements(view.mNumElements), mRandomGpuWrite(view.mRandomGpuWrite)
-			{ }
-
-			Key(UINT32 firstElement, UINT32 elementWidth, UINT32 numElements, bool randomGpuWrite)
-				: mFirstElement(firstElement), mElementWidth(elementWidth)
-				, mNumElements(numElements), mRandomGpuWrite(randomGpuWrite)
-			{ }
-
-			UINT32 mFirstElement;
-			UINT32 mElementWidth;
-			UINT32 mNumElements;
-			bool mRandomGpuWrite;
-		};
-
 		class HashFunction
 		{
 		public:
-			size_t operator()(const Key &key) const;
+			size_t operator()(const GPU_BUFFER_DESC& key) const;
 		};
 
 		class EqualFunction
 		{
 		public:
-			bool operator()(const Key &a, const Key &b) const;
+			bool operator()(const GPU_BUFFER_DESC& a, const GPU_BUFFER_DESC& b) const;
 		};
 
-		GpuBufferView(UINT32 firstElement, UINT32 elementWidth, UINT32 numElements, bool randomGpuWrite);
+		GpuBufferView(GPU_BUFFER_DESC& desc);
 		virtual ~GpuBufferView();
 
+		const GPU_BUFFER_DESC& getDesc() const { return mDesc; }
+
 	private:
-		UINT32 mFirstElement;
-		UINT32 mElementWidth;
-		UINT32 mNumElements;
-		bool mRandomGpuWrite;
+		GPU_BUFFER_DESC mDesc;
 	};
 }

+ 1 - 1
CamelotRenderer/Include/CmHardwareBufferManager.h

@@ -123,7 +123,7 @@ namespace CamelotEngine {
 		 *
 		 * Be aware that some of these settings cannot be used together, and you will receive an assert if in debug mode.
 		 */
-		virtual GenericBufferPtr createGenericBuffer(UINT32 elementCount, UINT32 elementSize, 
+		virtual GenericBufferPtr createGpuBuffer(UINT32 elementCount, UINT32 elementSize, 
 			GpuBufferType type, GpuBufferUsage usage, bool randomGpuWrite = false, bool useCounter = false) = 0;
 
         /** Creates a new vertex declaration. */

+ 26 - 0
CamelotRenderer/Include/CmTexture.h

@@ -32,6 +32,7 @@ THE SOFTWARE.
 #include "CmResource.h"
 #include "CmHardwareBuffer.h"
 #include "CmPixelUtil.h"
+#include "CmTextureView.h"
 
 namespace CamelotEngine {
 
@@ -205,6 +206,31 @@ namespace CamelotEngine {
 			another texture. */
 		void copy(TexturePtr& target);
 
+		/************************************************************************/
+		/* 								TEXTURE VIEW                      		*/
+		/************************************************************************/
+
+		TextureView* requestView(UINT32 mostDetailMip, UINT32 numMips, UINT32 firstArraySlice, UINT32 numArraySlices, GpuViewUsage usage);
+		void releaseView(TextureView* view);
+
+	protected:
+
+		virtual TextureView* createView(TEXTURE_VIEW_DESC& _desc);
+		virtual void destroyView(TextureView* view);
+		void clearBufferViews();
+
+		struct TextureViewReference
+		{
+			TextureViewReference(TextureView* _view)
+				:view(_view), refCount(0)
+			{ }
+
+			TextureView* view;
+			UINT32 refCount;
+		};
+
+		std::unordered_map<TEXTURE_VIEW_DESC, TextureViewReference*, TextureView::HashFunction, TextureView::EqualFunction> mTextureViews;
+
     protected:
 		friend class TextureManager;
 

+ 40 - 0
CamelotRenderer/Include/CmTextureView.h

@@ -0,0 +1,40 @@
+#pragma once
+
+#include "CmPrerequisites.h"
+#include "CmCommonEnums.h"
+
+namespace CamelotEngine
+{
+	struct CM_EXPORT TEXTURE_VIEW_DESC
+	{
+		UINT32 mostDetailMip;
+		UINT32 numMips;
+		UINT32 firstArraySlice;
+		UINT32 numArraySlices;
+		GpuViewUsage usage;
+	};
+
+	class CM_EXPORT TextureView
+	{
+	public:
+		class HashFunction
+		{
+		public:
+			size_t operator()(const TEXTURE_VIEW_DESC &key) const;
+		};
+
+		class EqualFunction
+		{
+		public:
+			bool operator()(const TEXTURE_VIEW_DESC &a, const TEXTURE_VIEW_DESC &b) const;
+		};
+
+		TextureView(Texture* texture, TEXTURE_VIEW_DESC& _desc);
+		virtual ~TextureView();
+
+		const TEXTURE_VIEW_DESC& getDesc() const { return mDesc; }
+
+	protected:
+		TEXTURE_VIEW_DESC mDesc;
+	};
+}

+ 10 - 7
CamelotRenderer/Source/CmGpuBuffer.cpp

@@ -25,14 +25,19 @@ namespace CamelotEngine
 		mBufferViews.clear();
 	}
 
-	GpuBufferView* GpuBuffer::requestView(UINT32 firstElement, UINT32 elementWidth, UINT32 numElements, bool randomGpuWrite)
+	GpuBufferView* GpuBuffer::requestView(UINT32 firstElement, UINT32 elementWidth, UINT32 numElements, bool useCounter, GpuViewUsage usage)
 	{
-		GpuBufferView::Key key(firstElement, elementWidth, numElements, randomGpuWrite);
+		GPU_BUFFER_DESC key;
+		key.firstElement = firstElement;
+		key.elementWidth = elementWidth;
+		key.numElements = numElements;
+		key.numElements = numElements;
+		key.usage = usage;
 
 		auto iterFind = mBufferViews.find(key);
 		if(iterFind == mBufferViews.end())
 		{
-			GpuBufferView* newView = createView(firstElement, elementWidth, numElements, randomGpuWrite);
+			GpuBufferView* newView = createView(key);
 			mBufferViews[key] = new GpuBufferReference(newView);
 
 			iterFind = mBufferViews.find(key);
@@ -44,12 +49,10 @@ namespace CamelotEngine
 
 	void GpuBuffer::releaseView(GpuBufferView* view)
 	{
-		GpuBufferView::Key key(*view);
-
-		auto iterFind = mBufferViews.find(key);
+		auto iterFind = mBufferViews.find(view->getDesc());
 		if(iterFind == mBufferViews.end())
 		{
-			CM_EXCEPT(InternalErrorException, "Trying to release a buffer that doesn't exist!");
+			CM_EXCEPT(InternalErrorException, "Trying to release a buffer view that doesn't exist!");
 		}
 
 		iterFind->second->refCount--;

+ 11 - 10
CamelotRenderer/Source/CmGpuBufferView.cpp

@@ -3,26 +3,27 @@
 
 namespace CamelotEngine
 {
-	size_t GpuBufferView::HashFunction::operator()(const Key &key) const
+	size_t GpuBufferView::HashFunction::operator()(const GPU_BUFFER_DESC& key) const
 	{
 		size_t seed = 0;
-		hash_combine(seed, key.mElementWidth);
-		hash_combine(seed, key.mFirstElement);
-		hash_combine(seed, key.mNumElements);
-		hash_combine(seed, key.mRandomGpuWrite);
+		hash_combine(seed, key.elementWidth);
+		hash_combine(seed, key.firstElement);
+		hash_combine(seed, key.numElements);
+		hash_combine(seed, key.useCounter);
+		hash_combine(seed, key.usage);
 
 		return seed;
 	}
 
 	bool GpuBufferView::EqualFunction::operator()
-		(const Key &a, const Key &b) const
+		(const GPU_BUFFER_DESC& a, const GPU_BUFFER_DESC& b) const
 	{
-		return a.mElementWidth == b.mElementWidth && a.mFirstElement == b.mFirstElement 
-			&& a.mNumElements == b.mNumElements && a.mRandomGpuWrite == b.mRandomGpuWrite;
+		return a.elementWidth == b.elementWidth && a.firstElement == b.firstElement 
+			&& a.numElements == b.numElements && a.useCounter == b.useCounter && a.usage == b.usage;
 	}
 
-	GpuBufferView::GpuBufferView(UINT32 firstElement, UINT32 elementWidth, UINT32 numElements, bool randomGpuWrite)
-		:mFirstElement(firstElement), mElementWidth(elementWidth), mNumElements(numElements), mRandomGpuWrite(randomGpuWrite)
+	GpuBufferView::GpuBufferView(GPU_BUFFER_DESC& desc)
+		:mDesc(desc)
 	{
 
 	}

+ 72 - 0
CamelotRenderer/Source/CmTexture.cpp

@@ -107,6 +107,7 @@ namespace CamelotEngine {
 	void Texture::freeInternalResources(void)
 	{
 		freeInternalResourcesImpl();
+		clearBufferViews();
 	}
 
 	void Texture::setRawPixels(const PixelData& data, UINT32 face, UINT32 mip)
@@ -237,6 +238,77 @@ namespace CamelotEngine {
 			CM_EXCEPT(InternalErrorException, "Calling an internal texture method from a non-render thread!");
 	}
 
+	/************************************************************************/
+	/* 								TEXTURE VIEW                      		*/
+	/************************************************************************/
+
+	TextureView* Texture::createView(TEXTURE_VIEW_DESC& _desc)
+	{
+		return new TextureView(this, _desc);
+	}
+
+	void Texture::destroyView(TextureView* view)
+	{
+		if(view != nullptr)
+			delete view;
+	}
+
+	void Texture::clearBufferViews()
+	{
+		for(auto iter = mTextureViews.begin(); iter != mTextureViews.end(); ++iter)
+		{
+			destroyView(iter->second->view);
+			delete iter->second;
+		}
+
+		mTextureViews.clear();
+	}
+
+	TextureView* Texture::requestView(UINT32 mostDetailMip, UINT32 numMips, UINT32 firstArraySlice, UINT32 numArraySlices, GpuViewUsage usage)
+	{
+		TEXTURE_VIEW_DESC key;
+		key.mostDetailMip = mostDetailMip;
+		key.numMips = numMips;
+		key.firstArraySlice = firstArraySlice;
+		key.numArraySlices = numArraySlices;
+		key.usage = usage;
+
+		auto iterFind = mTextureViews.find(key);
+		if(iterFind == mTextureViews.end())
+		{
+			TextureView* newView = createView(key);
+			mTextureViews[key] = new TextureViewReference(newView);
+
+			iterFind = mTextureViews.find(key);
+		}
+
+		iterFind->second->refCount++;
+		return iterFind->second->view;
+	}
+
+	void Texture::releaseView(TextureView* view)
+	{
+		TextureView key(*view);
+
+		auto iterFind = mTextureViews.find(view->getDesc());
+		if(iterFind == mTextureViews.end())
+		{
+			CM_EXCEPT(InternalErrorException, "Trying to release a texture view that doesn't exist!");
+		}
+
+		iterFind->second->refCount--;
+
+		if(iterFind->second->refCount == 0)
+		{
+			TextureViewReference* toRemove = iterFind->second;
+
+			mTextureViews.erase(iterFind);
+
+			destroyView(toRemove->view);
+			delete toRemove;
+		}
+	}
+
 	/************************************************************************/
 	/* 								SERIALIZATION                      		*/
 	/************************************************************************/

+ 35 - 0
CamelotRenderer/Source/CmTextureView.cpp

@@ -0,0 +1,35 @@
+#include "CmTextureView.h"
+#include "CmUtil.h"
+
+namespace CamelotEngine
+{
+	size_t TextureView::HashFunction::operator()(const TEXTURE_VIEW_DESC &key) const
+	{
+		size_t seed = 0;
+		hash_combine(seed, key.mostDetailMip);
+		hash_combine(seed, key.numMips);
+		hash_combine(seed, key.firstArraySlice);
+		hash_combine(seed, key.numArraySlices);
+		hash_combine(seed, key.usage);
+
+		return seed;
+	}
+
+	bool TextureView::EqualFunction::operator()
+		(const TEXTURE_VIEW_DESC &a, const TEXTURE_VIEW_DESC &b) const
+	{
+		return a.mostDetailMip == b.mostDetailMip && a.numMips == b.numMips 
+			&& a.firstArraySlice == b.firstArraySlice && a.numArraySlices == b.numArraySlices && a.usage == b.usage;
+	}
+
+	TextureView::TextureView(Texture* texture, TEXTURE_VIEW_DESC& _desc)
+		: mDesc(_desc)
+	{
+
+	}
+
+	TextureView::~TextureView()
+	{
+
+	}
+}

+ 1 - 1
CamelotRenderer/TODO.txt

@@ -14,10 +14,10 @@
 
 
 >>>>>>>>>>FINAL SPRINT BEFORE EDITOR WORK
-Port depth stencil buffer for OpenGL
 Make sure that I am able to blit contents from render textures on all render systems
 Get rid of SurfaceDesc in CmRenderTarget. I should probably add a resource view similar as I did with buffers.
  - Also in render and multirender textures whenever get depth stencil surface I always use 0 mip and 0 face, however it should use a surface desc same as color surface
+ - Take care of handling texture UAVs too
 Once I get DX11 running make sure to test if driver complains about missing shader attributes or invalid size ones
  Working generic buffers
  A way to bind buffers to a Pass, while specifying buffer range