Forráskód Böngészése

Specific mip & level can now be specified when binding sampled textures

BearishSun 9 éve
szülő
commit
319c6c756f

+ 2 - 23
Source/BansheeCore/Include/BsTexture.h

@@ -416,13 +416,6 @@ namespace bs
 		SPtr<TextureView> requestView(UINT32 mostDetailMip, UINT32 numMips, UINT32 firstArraySlice, UINT32 numArraySlices, 
 									  GpuViewUsage usage);
 
-		/**
-		 * Releases the view. View won't actually get destroyed until all references to it are released.
-		 *
-		 * @note	Core thread only.
-		 */
-		void releaseView(const SPtr<TextureView>& view);
-
 		/** Returns a plain white texture. */
 		static SPtr<Texture> WHITE;
 
@@ -458,24 +451,10 @@ namespace bs
 		/**	Creates a view of a specific subresource in a texture. */
 		virtual SPtr<TextureView> createView(const TEXTURE_VIEW_DESC& desc);
 
-		/**
-		 * Releases all internal texture view references. Views won't get destroyed if there are external references still 
-		 * held.
-		 */
+		/** Releases all internal texture view references. */
 		void clearBufferViews();
 
-		/** Holds a single texture view with a usage reference count. */
-		struct TextureViewReference
-		{
-			TextureViewReference(SPtr<TextureView> _view)
-				:view(_view), refCount(0)
-			{ }
-
-			SPtr<TextureView> view;
-			UINT32 refCount;
-		};
-
-		UnorderedMap<TEXTURE_VIEW_DESC, TextureViewReference*, TextureView::HashFunction, TextureView::EqualFunction> mTextureViews;
+		UnorderedMap<TEXTURE_VIEW_DESC, SPtr<TextureView>, TextureView::HashFunction, TextureView::EqualFunction> mTextureViews;
 		TextureProperties mProperties;
 		SPtr<PixelData> mInitData;
 	};

+ 3 - 2
Source/BansheeCore/Source/BsPixelUtil.cpp

@@ -1149,13 +1149,14 @@ namespace bs
 		UINT32 count = 0;
         if((width > 0) && (height > 0))
         {
-            do {
+			while (!(width == 1 && height == 1 && depth == 1))
+            { 
                 if(width>1)		width = width/2;
                 if(height>1)	height = height/2;
                 if(depth>1)		depth = depth/2;
                     
                 count ++;
-            } while(!(width == 1 && height == 1 && depth == 1));
+            } 
         }
 
 		return count;

+ 1 - 10
Source/BansheeCore/Source/BsRenderTexture.cpp

@@ -138,16 +138,7 @@ namespace bs
 	{ }
 
 	RenderTexture::~RenderTexture()
-	{ 
-		for (UINT32 i = 0; i < BS_MAX_MULTIPLE_RENDER_TARGETS; i++)
-		{
-			if (mColorSurfaces[i] != nullptr)
-				mDesc.colorSurfaces[i].texture->releaseView(mColorSurfaces[i]);
-		}
-
-		if (mDepthStencilSurface != nullptr)
-			mDesc.depthStencilSurface.texture->releaseView(mDepthStencilSurface);
-	}
+	{ }
 
 	void RenderTexture::initialize()
 	{

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

@@ -490,53 +490,25 @@ namespace bs
 	{
 		THROW_IF_NOT_CORE_THREAD;
 
+		const TextureProperties& texProps = getProperties();
+
 		TEXTURE_VIEW_DESC key;
 		key.mostDetailMip = mostDetailMip;
-		key.numMips = numMips;
+		key.numMips = numMips == 0 ? (texProps.getNumMipmaps() + 1) : numMips;
 		key.firstArraySlice = firstArraySlice;
+		key.numArraySlices = numArraySlices == 0 ? texProps.getNumFaces() : numArraySlices;
 		key.usage = usage;
 
-		const TextureProperties& texProps = getProperties();
-		if(numArraySlices == 0) // Automatically determine slice count
-			key.numArraySlices = texProps.getNumFaces();
-		else
-			key.numArraySlices = numArraySlices;
-
 		auto iterFind = mTextureViews.find(key);
 		if (iterFind == mTextureViews.end())
 		{
-			SPtr<TextureView> newView = createView(key);
-			mTextureViews[key] = new (bs_alloc<TextureViewReference>()) TextureViewReference(newView);
+			SPtr<TextureView> newView = 
+			mTextureViews[key] = createView(key);
 
 			iterFind = mTextureViews.find(key);
 		}
 
-		iterFind->second->refCount++;
-		return iterFind->second->view;
-	}
-
-	void Texture::releaseView(const SPtr<TextureView>& view)
-	{
-		THROW_IF_NOT_CORE_THREAD;
-
-		assert(view != nullptr);
-
-		auto iterFind = mTextureViews.find(view->getDesc());
-		if (iterFind == mTextureViews.end())
-		{
-			LOGERR("Trying to release a texture view that doesn't exist!");
-			return;
-		}
-
-		iterFind->second->refCount--;
-
-		if (iterFind->second->refCount == 0)
-		{
-			TextureViewReference* toRemove = iterFind->second;
-
-			mTextureViews.erase(iterFind);
-			bs_delete(toRemove);
-		}
+		return iterFind->second;
 	}
 
 	/************************************************************************/

+ 0 - 1
Source/BansheeD3D11RenderAPI/Include/BsD3D11RenderAPI.h

@@ -210,7 +210,6 @@ namespace bs { namespace ct
 		D3D11HLSLProgramFactory* mHLSLFactory;
 		D3D11InputLayoutManager* mIAManager;
 
-		std::pair<SPtr<Texture>, SPtr<TextureView>> mBoundUAVs[D3D11_PS_CS_UAV_REGISTER_COUNT];
 		bool mPSUAVsBound;
 		bool mCSUAVsBound;
 

+ 7 - 22
Source/BansheeD3D11RenderAPI/Source/BsD3D11RenderAPI.cpp

@@ -142,15 +142,6 @@ namespace bs { namespace ct
 	{
 		THROW_IF_NOT_CORE_THREAD;
 
-		for (auto& boundUAV : mBoundUAVs)
-		{
-			if (boundUAV.second != nullptr)
-				boundUAV.first->releaseView(boundUAV.second);
-
-			boundUAV.second = nullptr;
-			boundUAV.first = nullptr;
-		}
-
 		// Ensure that all GPU commands finish executing before shutting down the device. If we don't do this a crash
 		// on shutdown may occurr as the driver is still executing the commands, and we unload this library.
 		mDevice->getImmediateContext()->Flush();
@@ -348,7 +339,7 @@ namespace bs { namespace ct
 
 			ID3D11DeviceContext* context = mDevice->getImmediateContext();
 
-			// Clear any previously bound UAVs (otherwise shaders attempting to read resources viewed by those view will
+			// Clear any previously bound UAVs (otherwise shaders attempting to read resources viewed by those views will
 			// be unable to)
 			if (mPSUAVsBound || mCSUAVsBound)
 			{
@@ -393,15 +384,19 @@ namespace bs { namespace ct
 					for (auto iter = paramDesc->textures.begin(); iter != paramDesc->textures.end(); ++iter)
 					{
 						UINT32 slot = iter->second.slot;
+
 						SPtr<Texture> texture = gpuParams->getTexture(iter->second.set, slot);
+						const TextureSurface& surface = gpuParams->getTextureSurface(iter->second.set, slot);
 
 						while (slot >= (UINT32)srvs.size())
 							srvs.push_back(nullptr);
 
 						if (texture != nullptr)
 						{
-							D3D11Texture* d3d11Texture = static_cast<D3D11Texture*>(texture.get());
-							srvs[slot] = d3d11Texture->getSRV();
+							SPtr<TextureView> texView = texture->requestView(surface.mipLevel, 1, surface.arraySlice, surface.numArraySlices, GVU_DEFAULT);
+
+							D3D11TextureView* d3d11texView = static_cast<D3D11TextureView*>(texView.get());
+							srvs[slot] = d3d11texView->getSRV();
 						}
 					}
 
@@ -454,20 +449,10 @@ namespace bs { namespace ct
 
 							D3D11TextureView* d3d11texView = static_cast<D3D11TextureView*>(texView.get());
 							uavs[slot] = d3d11texView->getUAV();
-
-							if (mBoundUAVs[slot].second != nullptr)
-								mBoundUAVs[slot].first->releaseView(mBoundUAVs[slot].second);
-
-							mBoundUAVs[slot] = std::make_pair(texture, texView);
 						}
 						else
 						{
 							uavs[slot] = nullptr;
-
-							if (mBoundUAVs[slot].second != nullptr)
-								mBoundUAVs[slot].first->releaseView(mBoundUAVs[slot].second);
-
-							mBoundUAVs[slot] = std::pair<SPtr<Texture>, SPtr<TextureView>>();
 						}
 					}
 

+ 1 - 8
Source/BansheeD3D11RenderAPI/Source/BsD3D11RenderWindow.cpp

@@ -104,9 +104,6 @@ namespace bs
 			mWindow = nullptr;
 		}
 
-		if (mDepthStencilView != nullptr)
-			mDepthStencilBuffer->releaseView(mDepthStencilView);
-
 		destroySizeDependedD3DResources();
 	}
 
@@ -693,11 +690,7 @@ namespace bs
 			BS_EXCEPT(RenderingAPIException, "Unable to create rendertagert view\nError Description:" + errorDescription);
 		}
 
-		if (mDepthStencilView != nullptr)
-		{
-			mDepthStencilBuffer->releaseView(mDepthStencilView);
-			mDepthStencilView = nullptr;
-		}
+		mDepthStencilView = nullptr;
 
 		if (mDesc.depthBuffer)
 		{

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

@@ -25,6 +25,8 @@ namespace bs { namespace ct
 
 	D3D11Texture::~D3D11Texture()
 	{ 
+		clearBufferViews();
+
 		SAFE_RELEASE(mTex);
 		SAFE_RELEASE(m1DTex);
 		SAFE_RELEASE(m2DTex);

+ 21 - 9
Source/BansheeD3D11RenderAPI/Source/BsD3D11TextureView.cpp

@@ -100,20 +100,32 @@ namespace bs { namespace ct
 			desc.Texture3D.MostDetailedMip = mostDetailMip;
 			break;
 		case TEX_TYPE_CUBE_MAP:
-			if (numFaces <= 6)
+			if(numFaces % 6 == 0)
 			{
-				desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
-				desc.TextureCube.MipLevels = numMips;
-				desc.TextureCube.MostDetailedMip = mostDetailMip;
+				if (numFaces == 6)
+				{
+					desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
+					desc.TextureCube.MipLevels = numMips;
+					desc.TextureCube.MostDetailedMip = mostDetailMip;
+				}
+				else
+				{
+					desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBEARRAY;
+					desc.TextureCubeArray.MipLevels = numMips;
+					desc.TextureCubeArray.MostDetailedMip = mostDetailMip;
+					desc.TextureCubeArray.First2DArrayFace = firstArraySlice;
+					desc.TextureCubeArray.NumCubes = numArraySlices / 6;
+				}
 			}
 			else
 			{
-				desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBEARRAY;
-				desc.TextureCubeArray.MipLevels = numMips;
-				desc.TextureCubeArray.MostDetailedMip = mostDetailMip;
-				desc.TextureCubeArray.First2DArrayFace = firstArraySlice;
-				desc.TextureCubeArray.NumCubes = numArraySlices / 6;
+				desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
+				desc.Texture2DArray.MipLevels = numMips;
+				desc.Texture2DArray.MostDetailedMip = mostDetailMip;
+				desc.Texture2DArray.FirstArraySlice = firstArraySlice;
+				desc.Texture2DArray.ArraySize = numArraySlices;
 			}
+
 			break;
 		default:
 			BS_EXCEPT(InvalidParametersException, "Invalid texture type for this view type.");

+ 2 - 0
Source/BansheeGLRenderAPI/CMakeSources.cmake

@@ -32,6 +32,7 @@ set(BS_BANSHEEGLRENDERAPI_INC_NOFILTER
 	"Include/BsGLBuffer.h"
 	"Include/BsGLCommandBuffer.h"
 	"Include/BsGLCommandBufferManager.h"
+	"Include/BsGLTextureView.h"
 )
 
 set(BS_BANSHEEGLRENDERAPI_SRC_WIN32
@@ -68,6 +69,7 @@ set(BS_BANSHEEGLRENDERAPI_SRC_NOFILTER
 	"Source/BsGLBuffer.cpp"
 	"Source/BsGLCommandBuffer.cpp"
 	"Source/BsGLCommandBufferManager.cpp"
+	"Source/BsGLTextureView.cpp"
 )
 
 set(BS_BANSHEEGLRENDERAPI_INC_GLSL

+ 1 - 0
Source/BansheeGLRenderAPI/Include/BsGLPrerequisites.h

@@ -85,6 +85,7 @@ namespace bs { namespace ct
 	class GLVertexArrayObject;
 	struct GLSLProgramPipeline;
 	class GLSLProgramPipelineManager;
+	class GLTextureView;
 
 	/** @addtogroup GL
 	 *  @{

+ 3 - 0
Source/BansheeGLRenderAPI/Include/BsGLTexture.h

@@ -69,6 +69,9 @@ namespace bs { namespace ct
 		/** Creates pixel buffers for each face and mip level. Texture must have been created previously. */
 		void createSurfaceList();
 
+		/**	Creates an empty and uninitialized texture view object. */
+		SPtr<TextureView> createView(const TEXTURE_VIEW_DESC& desc) override;
+
     private:
         GLuint mTextureID;
 		GLenum mGLFormat;

+ 32 - 0
Source/BansheeGLRenderAPI/Include/BsGLTextureView.h

@@ -0,0 +1,32 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsGLPrerequisites.h"
+#include "BsTextureView.h"
+
+namespace bs { namespace ct
+{
+	/** @addtogroup GL
+	 *  @{
+	 */
+
+	/**	OpenGL implementation of a texture resource view. */
+	class GLTextureView : public TextureView
+	{
+	public:
+		~GLTextureView();
+
+		/**	Returns internal OpenGL texture view handle. */
+		GLuint getGLID() const { return mViewID; }
+
+	protected:
+		friend class GLTexture;
+
+		GLTextureView(const GLTexture* texture, const TEXTURE_VIEW_DESC& desc);
+	private:
+		GLuint mViewID;
+	};
+
+	/** @} */
+}}

+ 7 - 1
Source/BansheeGLRenderAPI/Source/BsGLRenderAPI.cpp

@@ -27,6 +27,7 @@
 #include "BsGLGpuBuffer.h"
 #include "BsGLCommandBuffer.h"
 #include "BsGLCommandBufferManager.h"
+#include "BsGLTextureView.h"
 
 namespace bs { namespace ct
 {
@@ -421,6 +422,7 @@ namespace bs { namespace ct
 					{
 						UINT32 binding = entry.second.slot;
 						SPtr<Texture> texture = gpuParams->getTexture(entry.second.set, binding);
+						const TextureSurface& surface = gpuParams->getTextureSurface(entry.second.set, binding);
 
 						UINT32 unit = getTexUnit(binding);
 						if (!activateGLTextureUnit(unit))
@@ -435,7 +437,11 @@ namespace bs { namespace ct
 							if (mTextureInfos[unit].type != newTextureType)
 								glBindTexture(mTextureInfos[unit].type, 0);
 
-							glBindTexture(newTextureType, glTex->getGLID());
+							SPtr<TextureView> texView = glTex->requestView(surface.mipLevel, surface.numMipLevels, 
+																surface.arraySlice, surface.numArraySlices, GVU_DEFAULT);
+
+							GLTextureView* glTexView = static_cast<GLTextureView*>(texView.get());
+							glBindTexture(newTextureType, glTexView->getGLID());
 							mTextureInfos[unit].type = newTextureType;
 
 							SPtr<GLSLGpuProgram> activeProgram = getActiveProgram(type);

+ 42 - 68
Source/BansheeGLRenderAPI/Source/BsGLTexture.cpp

@@ -9,6 +9,7 @@
 #include "BsCoreThread.h"
 #include "BsTextureManager.h"
 #include "BsGLRenderTexture.h"
+#include "BsGLTextureView.h"
 #include "BsRenderStats.h"
 
 namespace bs { namespace ct
@@ -67,6 +68,9 @@ namespace bs { namespace ct
 			}
 		}
 
+		// Include the base mip level
+		numMips += 1;
+
 		// Generate texture handle
 		glGenTextures(1, &mTextureID);
 
@@ -74,7 +78,7 @@ namespace bs { namespace ct
 		glBindTexture(getGLTextureTarget(), mTextureID);
 
 		// This needs to be set otherwise the texture doesn't get rendered
-		glTexParameteri(getGLTextureTarget(), GL_TEXTURE_MAX_LEVEL, numMips);
+		glTexParameteri(getGLTextureTarget(), GL_TEXTURE_MAX_LEVEL, numMips - 1);
 
 		// Allocate internal buffer so that glTexSubImageXD can be used
 		mGLFormat = GLPixelUtil::getGLInternalFormat(mInternalFormat, mProperties.isHardwareGammaEnabled());
@@ -83,83 +87,48 @@ namespace bs { namespace ct
 		if((usage & (TU_RENDERTARGET | TU_DEPTHSTENCIL)) != 0 && mProperties.getTextureType() == TEX_TYPE_2D && sampleCount > 1)
 		{
 			if (numFaces <= 1)
-				glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, sampleCount, mGLFormat, width, height, GL_FALSE);
+				glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, sampleCount, mGLFormat, width, height, GL_FALSE);
 			else
-				glTexImage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, sampleCount, mGLFormat, width, height, numFaces, GL_FALSE);
+				glTexStorage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, sampleCount, mGLFormat, width, height, numFaces, GL_FALSE);
 		}
 		else if((usage & TU_DEPTHSTENCIL) != 0 && mProperties.getTextureType() == TEX_TYPE_2D)
 		{
-			GLenum depthStencilType = GLPixelUtil::getDepthStencilTypeFromPF(mInternalFormat);
-			GLenum depthStencilFormat = GLPixelUtil::getDepthStencilFormatFromPF(mInternalFormat);
-
 			if (numFaces <= 1)
-			{
-				glTexImage2D(GL_TEXTURE_2D, 0, mGLFormat, width, height, 0,
-							 depthStencilFormat, depthStencilType, nullptr);
-			}
+				glTexStorage2D(GL_TEXTURE_2D, numMips, mGLFormat, width, height);
 			else
-			{
-				glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, mGLFormat, width, height, numFaces, 0,
-							 depthStencilFormat, depthStencilType, nullptr);
-			}
+				glTexStorage3D(GL_TEXTURE_2D_ARRAY, numMips, mGLFormat, width, height, numFaces);
 		}
 		else
 		{
-			GLenum baseFormat = GLPixelUtil::getGLOriginFormat(mInternalFormat);
-			GLenum baseDataType = GLPixelUtil::getGLOriginDataType(mInternalFormat);
-
-			// Run through this process to pre-generate mipmap pyramid
-			for (UINT32 mip = 0; mip <= numMips; mip++)
+			switch (texType)
 			{
-				switch (texType)
-				{
-				case TEX_TYPE_1D:
-				{
-					if (numFaces <= 1)
-						glTexImage1D(GL_TEXTURE_1D, mip, mGLFormat, width, 0, baseFormat, baseDataType, nullptr);
-					else
-						glTexImage2D(GL_TEXTURE_1D_ARRAY, mip, mGLFormat, width, numFaces, 0, baseFormat, baseDataType, nullptr);
-				}
-					break;
-				case TEX_TYPE_2D:
-				{
-					if (numFaces <= 1)
-						glTexImage2D(GL_TEXTURE_2D, mip, mGLFormat, width, height, 0, baseFormat, baseDataType, nullptr);
-					else
-						glTexImage3D(GL_TEXTURE_2D_ARRAY, mip, mGLFormat, width, height, numFaces, 0, baseFormat, baseDataType, nullptr);
-				}
-					break;
-				case TEX_TYPE_3D:
-					glTexImage3D(GL_TEXTURE_3D, mip, mGLFormat, width, height,
-						depth, 0, baseFormat, baseDataType, nullptr);
-					break;
-				case TEX_TYPE_CUBE_MAP:
-				{
-					if (numFaces <= 6)
-					{
-						for (UINT32 face = 0; face < 6; face++)
-						{
-							glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mip, mGLFormat,
-								width, height, 0, baseFormat, baseDataType, nullptr);
-						}
-					}
-					else
-					{
-						glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, mGLFormat,
-							width, height, numFaces, 0, baseFormat, baseDataType, nullptr);
-					}
-				}
-					break;
-				}
-
-				if(width > 1)
-					width = width/2;
-
-				if(height > 1)
-					height = height/2;
-
-				if(depth > 1)	
-					depth = depth/2;
+			case TEX_TYPE_1D:
+			{
+				if (numFaces <= 1)
+					glTexStorage1D(GL_TEXTURE_1D, numMips, mGLFormat, width);
+				else
+					glTexStorage2D(GL_TEXTURE_1D_ARRAY, numMips, mGLFormat, width, numFaces);
+			}
+				break;
+			case TEX_TYPE_2D:
+			{
+				if (numFaces <= 1)
+					glTexStorage2D(GL_TEXTURE_2D, numMips, mGLFormat, width, height);
+				else
+					glTexStorage3D(GL_TEXTURE_2D_ARRAY, numMips, mGLFormat, width, height, numFaces);
+			}
+				break;
+			case TEX_TYPE_3D:
+				glTexStorage3D(GL_TEXTURE_3D, numMips, mGLFormat, width, height, depth);
+				break;
+			case TEX_TYPE_CUBE_MAP:
+			{
+				if (numFaces <= 6)
+					glTexStorage2D(GL_TEXTURE_CUBE_MAP, numMips, mGLFormat, width, height);
+				else
+					glTexStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, numMips, mGLFormat, width, height, numFaces);
+			}
+				break;
 			}
 		}
 
@@ -333,4 +302,9 @@ namespace bs { namespace ct
 		assert(idx < mSurfaceList.size());
 		return mSurfaceList[idx];
 	}
+
+	SPtr<TextureView> GLTexture::createView(const TEXTURE_VIEW_DESC& desc)
+	{
+		return bs_shared_ptr<GLTextureView>(new (bs_alloc<GLTextureView>()) GLTextureView(this, desc));
+	}
 }}

+ 76 - 0
Source/BansheeGLRenderAPI/Source/BsGLTextureView.cpp

@@ -0,0 +1,76 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#include "BsGLTextureView.h"
+#include "BsGLTexture.h"
+
+namespace bs { namespace ct {
+	GLTextureView::GLTextureView(const GLTexture* texture, const TEXTURE_VIEW_DESC& desc)
+		:TextureView(desc), mViewID(0)
+	{
+		const TextureProperties& props = texture->getProperties();
+		GLuint originalTexture = texture->getGLID();
+
+		GLenum target;
+
+		switch (props.getTextureType())
+		{
+		case TEX_TYPE_1D:
+		{
+			if (desc.numArraySlices <= 1)
+				target = GL_TEXTURE_1D;
+			else
+				target = GL_TEXTURE_1D_ARRAY;
+		}
+		break;
+		default:
+		case TEX_TYPE_2D:
+		{
+			if(props.getNumSamples() <= 1)
+			{
+				if (desc.numArraySlices <= 1)
+					target = GL_TEXTURE_2D;
+				else
+					target = GL_TEXTURE_2D_ARRAY;
+			}
+			else
+			{
+				if (desc.numArraySlices <= 1)
+					target = GL_TEXTURE_2D_MULTISAMPLE;
+				else
+					target = GL_TEXTURE_2D_MULTISAMPLE_ARRAY;
+			}
+		}
+		break;
+		case TEX_TYPE_3D:
+			target = GL_TEXTURE_3D;
+			break;
+		case TEX_TYPE_CUBE_MAP:
+		{
+			if(desc.numArraySlices % 6 == 0)
+			{
+				if (desc.numArraySlices == 6)
+					target = GL_TEXTURE_CUBE_MAP;
+				else
+					target = GL_TEXTURE_CUBE_MAP_ARRAY;
+			}
+			else
+			{
+				if(desc.numArraySlices == 1)
+					target = GL_TEXTURE_2D;
+				else
+					target = GL_TEXTURE_2D_ARRAY;
+			}
+		}
+		break;
+		}
+
+		glGenTextures(1, &mViewID);
+		glTextureView(mViewID, target, originalTexture, texture->getGLFormat(), desc.mostDetailMip, desc.numMips,
+					  desc.firstArraySlice, desc.numArraySlices);
+	}
+
+	GLTextureView::~GLTextureView()
+	{
+		glDeleteTextures(1, &mViewID);
+	}
+}}