Răsfoiți Sursa

Added high-level code to bind specific texture subresource for sampling (not used by low level yet)

BearishSun 9 ani în urmă
părinte
comite
8a02e1877f

+ 3 - 0
Source/BansheeCore/Include/BsCommonTypes.h

@@ -556,6 +556,9 @@ namespace bs
 		UINT32 numMipLevels;
 		UINT32 numMipLevels;
 		UINT32 arraySlice;
 		UINT32 arraySlice;
 		UINT32 numArraySlices;
 		UINT32 numArraySlices;
+
+		/** Surface that covers all texture sub-resources. */
+		static BS_CORE_EXPORT const TextureSurface COMPLETE;
 	};
 	};
 
 
 	/** Meta-data describing a chunk of audio. */
 	/** Meta-data describing a chunk of audio. */

+ 1 - 1
Source/BansheeCore/Include/BsGpuParam.h

@@ -182,7 +182,7 @@ namespace bs
 		TGpuParamTexture(GpuParamObjectDesc* paramDesc, const GpuParamsType& parent);
 		TGpuParamTexture(GpuParamObjectDesc* paramDesc, const GpuParamsType& parent);
 
 
 		/** @copydoc TGpuDataParam::set */
 		/** @copydoc TGpuDataParam::set */
-		void set(const TextureType& texture) const;
+		void set(const TextureType& texture, const TextureSurface& surface = TextureSurface::COMPLETE) const;
 
 
 		/** @copydoc TGpuDataParam::get */
 		/** @copydoc TGpuDataParam::get */
 		TextureType get() const;
 		TextureType get() const;

+ 18 - 10
Source/BansheeCore/Include/BsGpuParams.h

@@ -168,7 +168,10 @@ namespace bs
 		/**	Gets a sampler state bound to the specified set/slot combination. */
 		/**	Gets a sampler state bound to the specified set/slot combination. */
 		SamplerType getSamplerState(UINT32 set, UINT32 slot) const;
 		SamplerType getSamplerState(UINT32 set, UINT32 slot) const;
 
 
-		/** Gets information that determines which texture surfaces to bind as load/store parameters. */
+		/** Gets information that determines which texture surfaces to bind as a sampled texture parameter. */
+		const TextureSurface& getTextureSurface(UINT32 set, UINT32 slot) const;
+
+		/** Gets information that determines which texture surfaces to bind as a load/store parameter. */
 		const TextureSurface& getLoadStoreSurface(UINT32 set, UINT32 slot) const;
 		const TextureSurface& getLoadStoreSurface(UINT32 set, UINT32 slot) const;
 
 
 		/**
 		/**
@@ -196,7 +199,8 @@ namespace bs
 		virtual void setParamBlockBuffer(UINT32 set, UINT32 slot, const ParamsBufferType& paramBlockBuffer);
 		virtual void setParamBlockBuffer(UINT32 set, UINT32 slot, const ParamsBufferType& paramBlockBuffer);
 
 
 		/**	Sets a texture at the specified set/slot combination. */
 		/**	Sets a texture at the specified set/slot combination. */
-		virtual void setTexture(UINT32 set, UINT32 slot, const TextureType& texture);
+		virtual void setTexture(UINT32 set, UINT32 slot, const TextureType& texture, 
+								const TextureSurface& surface = TextureSurface::COMPLETE);
 
 
 		/**	Sets a load/store texture at the specified set/slot combination. */
 		/**	Sets a load/store texture at the specified set/slot combination. */
 		virtual void setLoadStoreTexture(UINT32 set, UINT32 slot, const TextureType& texture, const TextureSurface& surface);
 		virtual void setLoadStoreTexture(UINT32 set, UINT32 slot, const TextureType& texture, const TextureSurface& surface);
@@ -207,16 +211,14 @@ namespace bs
 		/**	Sets a sampler state at the specified set/slot combination. */
 		/**	Sets a sampler state at the specified set/slot combination. */
 		virtual void setSamplerState(UINT32 set, UINT32 slot, const SamplerType& sampler);
 		virtual void setSamplerState(UINT32 set, UINT32 slot, const SamplerType& sampler);
 
 
-		/**	Sets information that determines which texture surfaces to bind	as load/store parameters. */
-		virtual void setLoadStoreSurface(UINT32 set, UINT32 slot, const TextureSurface& surface);
-
 		/**	Assigns a data value to the parameter with the specified name. */
 		/**	Assigns a data value to the parameter with the specified name. */
 		template<class T> void setParam(GpuProgramType type, const String& name, const T& value)
 		template<class T> void setParam(GpuProgramType type, const String& name, const T& value)
 		{ TGpuDataParam<T, Core> param; getParam(type, name, param); param.set(value); }
 		{ TGpuDataParam<T, Core> param; getParam(type, name, param); param.set(value); }
 
 
 		/**	Assigns a texture to the parameter with the specified name. */
 		/**	Assigns a texture to the parameter with the specified name. */
-		void setTexture(GpuProgramType type, const String& name, const TextureType& texture)
-		{ TGpuParamTexture<Core> param; getTextureParam(type, name, param); param.set(texture); }
+		void setTexture(GpuProgramType type, const String& name, const TextureType& texture,
+						const TextureSurface& surface = TextureSurface::COMPLETE)
+		{ TGpuParamTexture<Core> param; getTextureParam(type, name, param); param.set(texture, surface); }
 
 
 		/**	Assigns a load/store texture to the parameter with the specified name. */
 		/**	Assigns a load/store texture to the parameter with the specified name. */
 		void setLoadStoreTexture(GpuProgramType type, const String& name, const TextureType& texture, const TextureSurface& surface)
 		void setLoadStoreTexture(GpuProgramType type, const String& name, const TextureType& texture, const TextureSurface& surface)
@@ -236,10 +238,16 @@ namespace bs
 		/** @copydoc CoreObject::getThisPtr */
 		/** @copydoc CoreObject::getThisPtr */
 		virtual SPtr<GpuParamsType> _getThisPtr() const = 0;
 		virtual SPtr<GpuParamsType> _getThisPtr() const = 0;
 
 
+		/** Data for a single bound texture. */
+		struct TextureData
+		{
+			TextureType texture;
+			TextureSurface surface;
+		};
+
 		ParamsBufferType* mParamBlockBuffers = nullptr;
 		ParamsBufferType* mParamBlockBuffers = nullptr;
-		TextureType* mTextures = nullptr;
-		TextureType* mLoadStoreTextures = nullptr;
-		TextureSurface* mLoadStoreSurfaces = nullptr;
+		TextureData* mSampledTextureData = nullptr;
+		TextureData* mLoadStoreTextureData = nullptr;
 		BufferType* mBuffers = nullptr;
 		BufferType* mBuffers = nullptr;
 		SamplerType* mSamplerStates = nullptr;
 		SamplerType* mSamplerStates = nullptr;
 	};
 	};

+ 4 - 1
Source/BansheeCore/Include/BsMaterial.h

@@ -218,7 +218,10 @@ namespace bs
 		void setStructData(const String& name, void* value, UINT32 size, UINT32 arrayIdx = 0) { return getParamStruct(name).set(value, size, arrayIdx); }
 		void setStructData(const String& name, void* value, UINT32 size, UINT32 arrayIdx = 0) { return getParamStruct(name).set(value, size, arrayIdx); }
 
 
 		/** Assigns a texture to the shader parameter with the specified name. */
 		/** Assigns a texture to the shader parameter with the specified name. */
-		void setTexture(const String& name, const TextureType& value) { return getParamTexture(name).set(value); }
+		void setTexture(const String& name, const TextureType& value, const TextureSurface& surface = TextureSurface::COMPLETE)
+		{
+			return getParamTexture(name).set(value, surface);
+		}
 
 
 		/** Assigns a texture to be used for random load/store operations to the shader parameter with the specified name. */
 		/** Assigns a texture to be used for random load/store operations to the shader parameter with the specified name. */
 		void setLoadStoreTexture(const String& name, const TextureType& value, const TextureSurface& surface)
 		void setLoadStoreTexture(const String& name, const TextureType& value, const TextureSurface& surface)

+ 1 - 1
Source/BansheeCore/Include/BsMaterialParam.h

@@ -108,7 +108,7 @@ namespace bs
 		TMaterialParamTexture() { }
 		TMaterialParamTexture() { }
 
 
 		/** @copydoc GpuParamTexture::set */
 		/** @copydoc GpuParamTexture::set */
-		void set(const TextureType& texture) const;
+		void set(const TextureType& texture, const TextureSurface& surface = TextureSurface::COMPLETE) const;
 
 
 		/** @copydoc GpuParamTexture::get */
 		/** @copydoc GpuParamTexture::get */
 		TextureType get() const;
 		TextureType get() const;

+ 6 - 4
Source/BansheeCore/Include/BsMaterialParams.h

@@ -388,7 +388,7 @@ namespace bs
 		 * @param[in]	name		Name of the shader parameter.
 		 * @param[in]	name		Name of the shader parameter.
 		 * @param[out]	value		Output value of the parameter.
 		 * @param[out]	value		Output value of the parameter.
 		 */
 		 */
-		void getTexture(const String& name, TextureType& value) const;
+		void getTexture(const String& name, TextureType& value, TextureSurface& surface) const;
 
 
 		/**
 		/**
 		 * Sets the value of a shader texture parameter with the specified name. If the parameter name or type is not
 		 * Sets the value of a shader texture parameter with the specified name. If the parameter name or type is not
@@ -397,7 +397,8 @@ namespace bs
 		 * @param[in]	name		Name of the shader parameter.
 		 * @param[in]	name		Name of the shader parameter.
 		 * @param[in]	value		New value of the parameter.
 		 * @param[in]	value		New value of the parameter.
 		 */
 		 */
-		void setTexture(const String& name, const TextureType& value);
+		void setTexture(const String& name, const TextureType& value, 
+						const TextureSurface& surface = TextureSurface::COMPLETE);
 
 
 		/**
 		/**
 		 * Returns the value of a shader load/store texture parameter with the specified name. If the parameter name or
 		 * Returns the value of a shader load/store texture parameter with the specified name. If the parameter name or
@@ -479,13 +480,14 @@ namespace bs
 		 * Equivalent to getTexture(const String&, HTexture&) except it uses the internal parameter reference directly,
 		 * Equivalent to getTexture(const String&, HTexture&) except it uses the internal parameter reference directly,
 		 * avoiding the name lookup. Caller must guarantee the parameter reference is valid and belongs to this object.
 		 * avoiding the name lookup. Caller must guarantee the parameter reference is valid and belongs to this object.
 		 */
 		 */
-		void getTexture(const ParamData& param, TextureType& value) const;
+		void getTexture(const ParamData& param, TextureType& value, TextureSurface& surface) const;
 
 
 		/**
 		/**
 		 * Equivalent to setTexture(const String&, HTexture&) except it uses the internal parameter reference directly,
 		 * Equivalent to setTexture(const String&, HTexture&) except it uses the internal parameter reference directly,
 		 * avoiding the name lookup. Caller must guarantee the parameter reference is valid and belongs to this object.
 		 * avoiding the name lookup. Caller must guarantee the parameter reference is valid and belongs to this object.
 		 */
 		 */
-		void setTexture(const ParamData& param, const TextureType& value);
+		void setTexture(const ParamData& param, const TextureType& value, 
+						const TextureSurface& surface = TextureSurface::COMPLETE);
 
 
 		/**
 		/**
 		 * Equivalent to getBuffer(const String&, SPtr<GpuBuffer>&) except it uses the internal parameter reference
 		 * Equivalent to getBuffer(const String&, SPtr<GpuBuffer>&) except it uses the internal parameter reference

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

@@ -193,12 +193,12 @@ namespace bs
 	{ }
 	{ }
 
 
 	template<bool Core>
 	template<bool Core>
-	void TGpuParamTexture<Core>::set(const TextureType& texture) const
+	void TGpuParamTexture<Core>::set(const TextureType& texture, const TextureSurface& surface) const
 	{
 	{
 		if (mParent == nullptr)
 		if (mParent == nullptr)
 			return;
 			return;
 
 
-		mParent->setTexture(mParamDesc->set, mParamDesc->slot, texture);
+		mParent->setTexture(mParamDesc->set, mParamDesc->slot, texture, surface);
 
 
 		mParent->_markResourcesDirty();
 		mParent->_markResourcesDirty();
 		mParent->_markCoreDirty();
 		mParent->_markCoreDirty();

+ 81 - 61
Source/BansheeCore/Source/BsGpuParams.cpp

@@ -18,6 +18,8 @@
 
 
 namespace bs
 namespace bs
 {
 {
+	const TextureSurface TextureSurface::COMPLETE = TextureSurface(0, 0, 0, 0);
+
 	GpuParamsBase::GpuParamsBase(const SPtr<GpuPipelineParamInfoBase>& paramInfo)
 	GpuParamsBase::GpuParamsBase(const SPtr<GpuPipelineParamInfoBase>& paramInfo)
 		:mParamInfo(paramInfo)
 		:mParamInfo(paramInfo)
 	{ }
 	{ }
@@ -146,46 +148,45 @@ namespace bs
 		UINT32 numSamplers = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::SamplerState);
 		UINT32 numSamplers = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::SamplerState);
 		
 		
 		UINT32 paramBlocksSize = sizeof(ParamsBufferType) * numParamBlocks;
 		UINT32 paramBlocksSize = sizeof(ParamsBufferType) * numParamBlocks;
-		UINT32 texturesSize = sizeof(TextureType) * numTextures;
-		UINT32 loadStoreTexturesSize = sizeof(TextureType) * numStorageTextures;
-		UINT32 loadStoreSurfacesSize = sizeof(TextureSurface) * numStorageTextures;
+		UINT32 texturesSize = (sizeof(TextureType) + sizeof(TextureSurface)) * numTextures;
+		UINT32 loadStoreTexturesSize = (sizeof(TextureType) + sizeof(TextureSurface)) * numStorageTextures;
 		UINT32 buffersSize = sizeof(BufferType) * numBuffers;
 		UINT32 buffersSize = sizeof(BufferType) * numBuffers;
 		UINT32 samplerStatesSize = sizeof(SamplerType) * numSamplers;
 		UINT32 samplerStatesSize = sizeof(SamplerType) * numSamplers;
 
 
-		UINT32 totalSize = paramBlocksSize + texturesSize + loadStoreTexturesSize + loadStoreSurfacesSize +
-			buffersSize + samplerStatesSize;
+		UINT32 totalSize = paramBlocksSize + texturesSize + loadStoreTexturesSize + buffersSize + samplerStatesSize;
 
 
 		UINT8* data = (UINT8*)bs_alloc(totalSize);
 		UINT8* data = (UINT8*)bs_alloc(totalSize);
 		mParamBlockBuffers = (ParamsBufferType*)data;
 		mParamBlockBuffers = (ParamsBufferType*)data;
 		for (UINT32 i = 0; i < numParamBlocks; i++)
 		for (UINT32 i = 0; i < numParamBlocks; i++)
 			new (&mParamBlockBuffers[i]) ParamsBufferType();
 			new (&mParamBlockBuffers[i]) ParamsBufferType();
 
 
-		data += sizeof(ParamsBufferType) * numParamBlocks;
-		mTextures = (TextureType*)data;
+		data += paramBlocksSize;
+		mSampledTextureData = (TextureData*)data;
 		for (UINT32 i = 0; i < numTextures; i++)
 		for (UINT32 i = 0; i < numTextures; i++)
-			new (&mTextures[i]) TextureType();
-
-		data += sizeof(TextureType) * numTextures;
-		mLoadStoreTextures = (TextureType*)data;
-		for (UINT32 i = 0; i < numStorageTextures; i++)
-			new (&mLoadStoreTextures[i]) TextureType();
+		{
+			new (&mSampledTextureData[i].texture) TextureType();
+			new (&mSampledTextureData[i].surface) TextureSurface(0, 0, 0, 0);
+		}
 
 
-		data += sizeof(TextureType) * numStorageTextures;
-		mLoadStoreSurfaces = (TextureSurface*)data;
+		data += texturesSize;
+		mLoadStoreTextureData = (TextureData*)data;
 		for (UINT32 i = 0; i < numStorageTextures; i++)
 		for (UINT32 i = 0; i < numStorageTextures; i++)
-			new (&mLoadStoreSurfaces[i]) TextureSurface();
+		{
+			new (&mLoadStoreTextureData[i].texture) TextureType();
+			new (&mLoadStoreTextureData[i].surface) TextureSurface(0, 0, 0, 0);
+		}
 
 
-		data += sizeof(TextureSurface) * numStorageTextures;
+		data += loadStoreTexturesSize;
 		mBuffers = (BufferType*)data;
 		mBuffers = (BufferType*)data;
 		for (UINT32 i = 0; i < numBuffers; i++)
 		for (UINT32 i = 0; i < numBuffers; i++)
 			new (&mBuffers[i]) BufferType();
 			new (&mBuffers[i]) BufferType();
 
 
-		data += sizeof(BufferType) * numBuffers;
+		data += buffersSize;
 		mSamplerStates = (SamplerType*)data;
 		mSamplerStates = (SamplerType*)data;
 		for (UINT32 i = 0; i < numSamplers; i++)
 		for (UINT32 i = 0; i < numSamplers; i++)
 			new (&mSamplerStates[i]) SamplerType();
 			new (&mSamplerStates[i]) SamplerType();
 
 
-		data += sizeof(SamplerType) * numSamplers;
+		data += samplerStatesSize;
 	}
 	}
 
 
 	template<bool Core>
 	template<bool Core>
@@ -200,13 +201,16 @@ namespace bs
 		for (UINT32 i = 0; i < numParamBlocks; i++)
 		for (UINT32 i = 0; i < numParamBlocks; i++)
 			mParamBlockBuffers[i].~ParamsBufferType();
 			mParamBlockBuffers[i].~ParamsBufferType();
 
 
-		for (UINT32 i = 0; i <  numTextures; i++)
-			mTextures[i].~TextureType();
+		for (UINT32 i = 0; i < numTextures; i++)
+		{
+			mSampledTextureData[i].texture.~TextureType();
+			mSampledTextureData[i].surface.~TextureSurface();
+		}
 
 
 		for (UINT32 i = 0; i <  numStorageTextures; i++)
 		for (UINT32 i = 0; i <  numStorageTextures; i++)
 		{
 		{
-			mLoadStoreTextures[i].~TextureType();
-			mLoadStoreSurfaces[i].~TextureSurface();
+			mLoadStoreTextureData[i].texture.~TextureType();
+			mLoadStoreTextureData[i].surface.~TextureSurface();
 		}
 		}
 
 
 		for (UINT32 i = 0; i < numBuffers; i++)
 		for (UINT32 i = 0; i < numBuffers; i++)
@@ -395,7 +399,7 @@ namespace bs
 		if (globalSlot == (UINT32)-1)
 		if (globalSlot == (UINT32)-1)
 			return TGpuParams<Core>::TextureType();
 			return TGpuParams<Core>::TextureType();
 
 
-		return mTextures[globalSlot];
+		return mSampledTextureData[globalSlot].texture;
 	}
 	}
 
 
 	template<bool Core>
 	template<bool Core>
@@ -405,7 +409,7 @@ namespace bs
 		if (globalSlot == (UINT32)-1)
 		if (globalSlot == (UINT32)-1)
 			return TGpuParams<Core>::TextureType();
 			return TGpuParams<Core>::TextureType();
 
 
-		return mLoadStoreTextures[globalSlot];
+		return mLoadStoreTextureData[globalSlot].texture;
 	}
 	}
 
 
 	template<bool Core>
 	template<bool Core>
@@ -428,6 +432,18 @@ namespace bs
 		return mSamplerStates[globalSlot];
 		return mSamplerStates[globalSlot];
 	}
 	}
 
 
+	template<bool Core>
+	const TextureSurface& TGpuParams<Core>::getTextureSurface(UINT32 set, UINT32 slot) const
+	{
+		static TextureSurface emptySurface;
+
+		UINT32 globalSlot = mParamInfo->getSequentialSlot(GpuPipelineParamInfo::ParamType::Texture, set, slot);
+		if (globalSlot == (UINT32)-1)
+			return emptySurface;
+
+		return mSampledTextureData[globalSlot].surface;
+	}
+
 	template<bool Core>
 	template<bool Core>
 	const TextureSurface& TGpuParams<Core>::getLoadStoreSurface(UINT32 set, UINT32 slot) const
 	const TextureSurface& TGpuParams<Core>::getLoadStoreSurface(UINT32 set, UINT32 slot) const
 	{
 	{
@@ -437,18 +453,19 @@ namespace bs
 		if (globalSlot == (UINT32)-1)
 		if (globalSlot == (UINT32)-1)
 			return emptySurface;
 			return emptySurface;
 
 
-		return mLoadStoreSurfaces[globalSlot];
+		return mLoadStoreTextureData[globalSlot].surface;
 	}
 	}
 
 
 
 
 	template<bool Core>
 	template<bool Core>
-	void TGpuParams<Core>::setTexture(UINT32 set, UINT32 slot, const TextureType& texture)
+	void TGpuParams<Core>::setTexture(UINT32 set, UINT32 slot, const TextureType& texture, const TextureSurface& surface)
 	{
 	{
 		UINT32 globalSlot = mParamInfo->getSequentialSlot(GpuPipelineParamInfo::ParamType::Texture, set, slot);
 		UINT32 globalSlot = mParamInfo->getSequentialSlot(GpuPipelineParamInfo::ParamType::Texture, set, slot);
 		if (globalSlot == (UINT32)-1)
 		if (globalSlot == (UINT32)-1)
 			return;
 			return;
 
 
-		mTextures[globalSlot] = texture;
+		mSampledTextureData[globalSlot].texture = texture;
+		mSampledTextureData[globalSlot].surface = surface;
 
 
 		_markResourcesDirty();
 		_markResourcesDirty();
 		_markCoreDirty();
 		_markCoreDirty();
@@ -461,7 +478,8 @@ namespace bs
 		if (globalSlot == (UINT32)-1)
 		if (globalSlot == (UINT32)-1)
 			return;
 			return;
 
 
-		mLoadStoreTextures[globalSlot] = texture;
+		mLoadStoreTextureData[globalSlot].texture = texture;
+		mLoadStoreTextureData[globalSlot].surface = surface;
 
 
 		_markResourcesDirty();
 		_markResourcesDirty();
 		_markCoreDirty();
 		_markCoreDirty();
@@ -493,16 +511,6 @@ namespace bs
 		_markCoreDirty();
 		_markCoreDirty();
 	}
 	}
 
 
-	template<bool Core>
-	void TGpuParams<Core>::setLoadStoreSurface(UINT32 set, UINT32 slot, const TextureSurface& surface)
-	{
-		UINT32 globalSlot = mParamInfo->getSequentialSlot(GpuPipelineParamInfo::ParamType::LoadStoreTexture, set, slot);
-		if (globalSlot == (UINT32)-1)
-			return;
-
-		mLoadStoreSurfaces[globalSlot] = surface;
-	}
-
 	template class TGpuParams < false > ;
 	template class TGpuParams < false > ;
 	template class TGpuParams < true > ;
 	template class TGpuParams < true > ;
 
 
@@ -602,6 +610,7 @@ namespace bs
 		UINT32 numBuffers = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::Buffer);
 		UINT32 numBuffers = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::Buffer);
 		UINT32 numSamplers = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::SamplerState);
 		UINT32 numSamplers = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::SamplerState);
 
 
+		UINT32 sampledSurfacesSize = numTextures * sizeof(TextureSurface);
 		UINT32 loadStoreSurfacesSize = numStorageTextures * sizeof(TextureSurface);
 		UINT32 loadStoreSurfacesSize = numStorageTextures * sizeof(TextureSurface);
 		UINT32 paramBufferSize = numParamBlocks * sizeof(SPtr<ct::GpuParamBlockBuffer>);
 		UINT32 paramBufferSize = numParamBlocks * sizeof(SPtr<ct::GpuParamBlockBuffer>);
 		UINT32 textureArraySize = numTextures * sizeof(SPtr<ct::Texture>);
 		UINT32 textureArraySize = numTextures * sizeof(SPtr<ct::Texture>);
@@ -609,11 +618,12 @@ namespace bs
 		UINT32 bufferArraySize = numBuffers * sizeof(SPtr<ct::GpuBuffer>);
 		UINT32 bufferArraySize = numBuffers * sizeof(SPtr<ct::GpuBuffer>);
 		UINT32 samplerArraySize = numSamplers * sizeof(SPtr<ct::SamplerState>);
 		UINT32 samplerArraySize = numSamplers * sizeof(SPtr<ct::SamplerState>);
 
 
-		UINT32 totalSize = loadStoreSurfacesSize + paramBufferSize + textureArraySize + loadStoreTextureArraySize 
-			+ bufferArraySize + samplerArraySize;
+		UINT32 totalSize = sampledSurfacesSize + loadStoreSurfacesSize + paramBufferSize + textureArraySize 
+			+ loadStoreTextureArraySize + bufferArraySize + samplerArraySize;
 
 
-		UINT32 textureInfoOffset = 0;
-		UINT32 paramBufferOffset = textureInfoOffset + loadStoreSurfacesSize;
+		UINT32 sampledSurfaceOffset = 0;
+		UINT32 loadStoreSurfaceOffset = sampledSurfaceOffset + sampledSurfacesSize;
+		UINT32 paramBufferOffset = loadStoreSurfaceOffset + loadStoreSurfacesSize;
 		UINT32 textureArrayOffset = paramBufferOffset + paramBufferSize;
 		UINT32 textureArrayOffset = paramBufferOffset + paramBufferSize;
 		UINT32 loadStoreTextureArrayOffset = textureArrayOffset + textureArraySize;
 		UINT32 loadStoreTextureArrayOffset = textureArrayOffset + textureArraySize;
 		UINT32 bufferArrayOffset = loadStoreTextureArrayOffset + loadStoreTextureArraySize;
 		UINT32 bufferArrayOffset = loadStoreTextureArrayOffset + loadStoreTextureArraySize;
@@ -621,7 +631,8 @@ namespace bs
 
 
 		UINT8* data = allocator->alloc(totalSize);
 		UINT8* data = allocator->alloc(totalSize);
 
 
-		TextureSurface* loadStoreSurfaces = (TextureSurface*)(data + textureInfoOffset);
+		TextureSurface* sampledSurfaces = (TextureSurface*)(data + sampledSurfaceOffset);
+		TextureSurface* loadStoreSurfaces = (TextureSurface*)(data + loadStoreSurfaceOffset);
 		SPtr<ct::GpuParamBlockBuffer>* paramBuffers = (SPtr<ct::GpuParamBlockBuffer>*)(data + paramBufferOffset);
 		SPtr<ct::GpuParamBlockBuffer>* paramBuffers = (SPtr<ct::GpuParamBlockBuffer>*)(data + paramBufferOffset);
 		SPtr<ct::Texture>* textures = (SPtr<ct::Texture>*)(data + textureArrayOffset);
 		SPtr<ct::Texture>* textures = (SPtr<ct::Texture>*)(data + textureArrayOffset);
 		SPtr<ct::Texture>* loadStoreTextures = (SPtr<ct::Texture>*)(data + loadStoreTextureArrayOffset);
 		SPtr<ct::Texture>* loadStoreTextures = (SPtr<ct::Texture>*)(data + loadStoreTextureArrayOffset);
@@ -639,10 +650,13 @@ namespace bs
 
 
 		for (UINT32 i = 0; i < numTextures; i++)
 		for (UINT32 i = 0; i < numTextures; i++)
 		{
 		{
+			new (&sampledSurfaces[i]) TextureSurface();
+			sampledSurfaces[i] = mSampledTextureData[i].surface;
+
 			new (&textures[i]) SPtr<ct::Texture>();
 			new (&textures[i]) SPtr<ct::Texture>();
 
 
-			if (mTextures[i].isLoaded())
-				textures[i] = mTextures[i]->getCore();
+			if (mSampledTextureData[i].texture.isLoaded())
+				textures[i] = mSampledTextureData[i].texture->getCore();
 			else
 			else
 				textures[i] = nullptr;
 				textures[i] = nullptr;
 		}
 		}
@@ -650,12 +664,12 @@ namespace bs
 		for (UINT32 i = 0; i < numStorageTextures; i++)
 		for (UINT32 i = 0; i < numStorageTextures; i++)
 		{
 		{
 			new (&loadStoreSurfaces[i]) TextureSurface();
 			new (&loadStoreSurfaces[i]) TextureSurface();
-			loadStoreSurfaces[i] = mLoadStoreSurfaces[i];
+			loadStoreSurfaces[i] = mLoadStoreTextureData[i].surface;
 
 
 			new (&loadStoreTextures[i]) SPtr<ct::Texture>();
 			new (&loadStoreTextures[i]) SPtr<ct::Texture>();
 
 
-			if (mLoadStoreTextures[i].isLoaded())
-				loadStoreTextures[i] = mLoadStoreTextures[i]->getCore();
+			if (mLoadStoreTextureData[i].texture.isLoaded())
+				loadStoreTextures[i] = mLoadStoreTextureData[i].texture->getCore();
 			else
 			else
 				loadStoreTextures[i] = nullptr;
 				loadStoreTextures[i] = nullptr;
 		}
 		}
@@ -690,14 +704,14 @@ namespace bs
 
 
 		for (UINT32 i = 0; i < numTextures; i++)
 		for (UINT32 i = 0; i < numTextures; i++)
 		{
 		{
-			if (mTextures[i] != nullptr)
-				resources.push_back(mTextures[i]);
+			if (mSampledTextureData[i].texture != nullptr)
+				resources.push_back(mSampledTextureData[i].texture);
 		}
 		}
 
 
 		for (UINT32 i = 0; i < numStorageTextures; i++)
 		for (UINT32 i = 0; i < numStorageTextures; i++)
 		{
 		{
-			if (mLoadStoreTextures[i] != nullptr)
-				resources.push_back(mLoadStoreTextures[i]);
+			if (mLoadStoreTextureData[i].texture != nullptr)
+				resources.push_back(mLoadStoreTextureData[i].texture);
 		}
 		}
 	}
 	}
 
 
@@ -722,6 +736,7 @@ namespace bs
 		UINT32 numBuffers = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::Buffer);
 		UINT32 numBuffers = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::Buffer);
 		UINT32 numSamplers = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::SamplerState);
 		UINT32 numSamplers = mParamInfo->getNumElements(GpuPipelineParamInfo::ParamType::SamplerState);
 
 
+		UINT32 sampledSurfacesSize = numTextures * sizeof(TextureSurface);
 		UINT32 loadStoreSurfacesSize = numStorageTextures * sizeof(TextureSurface);
 		UINT32 loadStoreSurfacesSize = numStorageTextures * sizeof(TextureSurface);
 		UINT32 paramBufferSize = numParamBlocks * sizeof(SPtr<GpuParamBlockBuffer>);
 		UINT32 paramBufferSize = numParamBlocks * sizeof(SPtr<GpuParamBlockBuffer>);
 		UINT32 textureArraySize = numTextures * sizeof(SPtr<Texture>);
 		UINT32 textureArraySize = numTextures * sizeof(SPtr<Texture>);
@@ -729,11 +744,12 @@ namespace bs
 		UINT32 bufferArraySize = numBuffers * sizeof(SPtr<GpuBuffer>);
 		UINT32 bufferArraySize = numBuffers * sizeof(SPtr<GpuBuffer>);
 		UINT32 samplerArraySize = numSamplers * sizeof(SPtr<SamplerState>);
 		UINT32 samplerArraySize = numSamplers * sizeof(SPtr<SamplerState>);
 
 
-		UINT32 totalSize = loadStoreSurfacesSize + paramBufferSize + textureArraySize + loadStoreTextureArraySize
-			+ bufferArraySize + samplerArraySize;
+		UINT32 totalSize = sampledSurfacesSize + loadStoreSurfacesSize + paramBufferSize + textureArraySize 
+			+ loadStoreTextureArraySize + bufferArraySize + samplerArraySize;
 
 
-		UINT32 textureInfoOffset = 0;
-		UINT32 paramBufferOffset = textureInfoOffset + loadStoreSurfacesSize;
+		UINT32 sampledSurfacesOffset = 0;
+		UINT32 loadStoreSurfaceOffset = sampledSurfacesOffset + sampledSurfacesSize;
+		UINT32 paramBufferOffset = loadStoreSurfaceOffset + loadStoreSurfacesSize;
 		UINT32 textureArrayOffset = paramBufferOffset + paramBufferSize;
 		UINT32 textureArrayOffset = paramBufferOffset + paramBufferSize;
 		UINT32 loadStoreTextureArrayOffset = textureArrayOffset + textureArraySize;
 		UINT32 loadStoreTextureArrayOffset = textureArrayOffset + textureArraySize;
 		UINT32 bufferArrayOffset = loadStoreTextureArrayOffset + loadStoreTextureArraySize;
 		UINT32 bufferArrayOffset = loadStoreTextureArrayOffset + loadStoreTextureArraySize;
@@ -743,7 +759,8 @@ namespace bs
 
 
 		UINT8* dataPtr = data.getBuffer();
 		UINT8* dataPtr = data.getBuffer();
 
 
-		TextureSurface* loadStoreSurfaces = (TextureSurface*)(dataPtr + textureInfoOffset);
+		TextureSurface* sampledSurfaces = (TextureSurface*)(dataPtr + sampledSurfacesOffset);
+		TextureSurface* loadStoreSurfaces = (TextureSurface*)(dataPtr + loadStoreSurfaceOffset);
 		SPtr<GpuParamBlockBuffer>* paramBuffers = (SPtr<GpuParamBlockBuffer>*)(dataPtr + paramBufferOffset);
 		SPtr<GpuParamBlockBuffer>* paramBuffers = (SPtr<GpuParamBlockBuffer>*)(dataPtr + paramBufferOffset);
 		SPtr<Texture>* textures = (SPtr<Texture>*)(dataPtr + textureArrayOffset);
 		SPtr<Texture>* textures = (SPtr<Texture>*)(dataPtr + textureArrayOffset);
 		SPtr<Texture>* loadStoreTextures = (SPtr<Texture>*)(dataPtr + loadStoreTextureArrayOffset);
 		SPtr<Texture>* loadStoreTextures = (SPtr<Texture>*)(dataPtr + loadStoreTextureArrayOffset);
@@ -759,16 +776,19 @@ namespace bs
 
 
 		for (UINT32 i = 0; i < numTextures; i++)
 		for (UINT32 i = 0; i < numTextures; i++)
 		{
 		{
-			mTextures[i] = textures[i];
+			mSampledTextureData[i].surface = sampledSurfaces[i];
+			loadStoreSurfaces[i].~TextureSurface();
+
+			mSampledTextureData[i].texture = textures[i];
 			textures[i].~SPtr<Texture>();
 			textures[i].~SPtr<Texture>();
 		}
 		}
 
 
 		for (UINT32 i = 0; i < numStorageTextures; i++)
 		for (UINT32 i = 0; i < numStorageTextures; i++)
 		{
 		{
-			mLoadStoreSurfaces[i] = loadStoreSurfaces[i];
+			mLoadStoreTextureData[i].surface = loadStoreSurfaces[i];
 			loadStoreSurfaces[i].~TextureSurface();
 			loadStoreSurfaces[i].~TextureSurface();
 
 
-			mLoadStoreTextures[i] = loadStoreTextures[i];
+			mLoadStoreTextureData[i].texture = loadStoreTextures[i];
 			loadStoreTextures[i].~SPtr<Texture>();
 			loadStoreTextures[i].~SPtr<Texture>();
 		}
 		}
 
 

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

@@ -999,10 +999,11 @@ namespace bs
 					if (materialParamInfo->version <= mParamVersion && !updateAll)
 					if (materialParamInfo->version <= mParamVersion && !updateAll)
 						continue;
 						continue;
 
 
+					TextureSurface surface;
 					TextureType texture;
 					TextureType texture;
-					params->getTexture(*materialParamInfo, texture);
+					params->getTexture(*materialParamInfo, texture, surface);
 
 
-					paramPtr->setTexture(paramInfo.setIdx, paramInfo.slotIdx, texture);
+					paramPtr->setTexture(paramInfo.setIdx, paramInfo.slotIdx, texture, surface);
 				}
 				}
 
 
 				for (UINT32 k = 0; k < stageInfo.numLoadStoreTextures; k++)
 				for (UINT32 k = 0; k < stageInfo.numLoadStoreTextures; k++)

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

@@ -649,7 +649,8 @@ namespace bs
 				TMaterialParamTexture<false> curParam = getParamTexture(param.first);
 				TMaterialParamTexture<false> curParam = getParamTexture(param.first);
 
 
 				HTexture texture;
 				HTexture texture;
-				params->getTexture(*paramData, texture);
+				TextureSurface surface;
+				params->getTexture(*paramData, texture, surface);
 				curParam.set(texture);
 				curParam.set(texture);
 			}
 			}
 			else
 			else

+ 6 - 3
Source/BansheeCore/Source/BsMaterialParam.cpp

@@ -157,7 +157,7 @@ namespace bs
 	}
 	}
 
 
 	template<bool Core>
 	template<bool Core>
-	void TMaterialParamTexture<Core>::set(const TextureType& texture) const
+	void TMaterialParamTexture<Core>::set(const TextureType& texture, const TextureSurface& surface) const
 	{
 	{
 		if (mMaterial == nullptr)
 		if (mMaterial == nullptr)
 			return;
 			return;
@@ -170,7 +170,7 @@ namespace bs
 		if (newValue == nullptr)
 		if (newValue == nullptr)
 			params->getDefaultTexture(*data, newValue);
 			params->getDefaultTexture(*data, newValue);
 
 
-		params->setTexture(*data, newValue);
+		params->setTexture(*data, newValue, surface);
 		mMaterial->_markCoreDirty();
 		mMaterial->_markCoreDirty();
 	}
 	}
 
 
@@ -181,10 +181,12 @@ namespace bs
 		if (mMaterial == nullptr)
 		if (mMaterial == nullptr)
 			return texture;
 			return texture;
 
 
+		TextureSurface surface;
+
 		SPtr<MaterialParamsType> params = mMaterial->_getInternalParams();
 		SPtr<MaterialParamsType> params = mMaterial->_getInternalParams();
 		const MaterialParams::ParamData* data = params->getParamData(mParamIndex);
 		const MaterialParams::ParamData* data = params->getParamData(mParamIndex);
 
 
-		params->getTexture(*data, texture);
+		params->getTexture(*data, texture, surface);
 		return texture;
 		return texture;
 	}
 	}
 	
 	
@@ -234,6 +236,7 @@ namespace bs
 
 
 		SPtr<MaterialParamsType> params = mMaterial->_getInternalParams();
 		SPtr<MaterialParamsType> params = mMaterial->_getInternalParams();
 		const MaterialParams::ParamData* data = params->getParamData(mParamIndex);
 		const MaterialParams::ParamData* data = params->getParamData(mParamIndex);
+
 		params->getLoadStoreTexture(*data, texture, surface);
 		params->getLoadStoreTexture(*data, texture, surface);
 
 
 		return texture;
 		return texture;

+ 8 - 6
Source/BansheeCore/Source/BsMaterialParams.cpp

@@ -315,7 +315,7 @@ namespace bs
 	}
 	}
 
 
 	template<bool Core>
 	template<bool Core>
-	void TMaterialParams<Core>::getTexture(const String& name, TextureType& value) const
+	void TMaterialParams<Core>::getTexture(const String& name, TextureType& value, TextureSurface& surface) const
 	{
 	{
 		const ParamData* param = nullptr;
 		const ParamData* param = nullptr;
 		GetParamResult result = getParamData(name, ParamType::Texture, GPDT_UNKNOWN, 0, &param);
 		GetParamResult result = getParamData(name, ParamType::Texture, GPDT_UNKNOWN, 0, &param);
@@ -325,11 +325,11 @@ namespace bs
 			return;
 			return;
 		}
 		}
 
 
-		getTexture(*param, value);
+		getTexture(*param, value, surface);
 	}
 	}
 
 
 	template<bool Core>
 	template<bool Core>
-	void TMaterialParams<Core>::setTexture(const String& name, const TextureType& value)
+	void TMaterialParams<Core>::setTexture(const String& name, const TextureType& value, const TextureSurface& surface)
 	{
 	{
 		const ParamData* param = nullptr;
 		const ParamData* param = nullptr;
 		GetParamResult result = getParamData(name, ParamType::Texture, GPDT_UNKNOWN, 0, &param);
 		GetParamResult result = getParamData(name, ParamType::Texture, GPDT_UNKNOWN, 0, &param);
@@ -339,7 +339,7 @@ namespace bs
 			return;
 			return;
 		}
 		}
 
 
-		setTexture(*param, value);
+		setTexture(*param, value, surface);
 	}
 	}
 
 
 	template<bool Core>
 	template<bool Core>
@@ -463,18 +463,20 @@ namespace bs
 	}
 	}
 
 
 	template<bool Core>
 	template<bool Core>
-	void TMaterialParams<Core>::getTexture(const ParamData& param, TextureType& value) const
+	void TMaterialParams<Core>::getTexture(const ParamData& param, TextureType& value, TextureSurface& surface) const
 	{
 	{
 		ParamTextureDataType& textureParam = mTextureParams[param.index];
 		ParamTextureDataType& textureParam = mTextureParams[param.index];
 		value = textureParam.value;
 		value = textureParam.value;
+		surface = textureParam.surface;
 	}
 	}
 	
 	
 	template<bool Core>
 	template<bool Core>
-	void TMaterialParams<Core>::setTexture(const ParamData& param, const TextureType& value)
+	void TMaterialParams<Core>::setTexture(const ParamData& param, const TextureType& value, const TextureSurface& surface)
 	{
 	{
 		ParamTextureDataType& textureParam = mTextureParams[param.index];
 		ParamTextureDataType& textureParam = mTextureParams[param.index];
 		textureParam.value = value;
 		textureParam.value = value;
 		textureParam.isLoadStore = false;
 		textureParam.isLoadStore = false;
+		textureParam.surface = surface;
 
 
 		param.version = ++mParamVersion;
 		param.version = ++mParamVersion;
 	}
 	}

+ 2 - 4
Source/BansheeVulkanRenderAPI/Include/BsVulkanGpuParams.h

@@ -22,7 +22,8 @@ namespace bs { namespace ct
 		void setParamBlockBuffer(UINT32 set, UINT32 slot, const SPtr<GpuParamBlockBuffer>& paramBlockBuffer) override;
 		void setParamBlockBuffer(UINT32 set, UINT32 slot, const SPtr<GpuParamBlockBuffer>& paramBlockBuffer) override;
 
 
 		/** @copydoc GpuParams::setTexture */
 		/** @copydoc GpuParams::setTexture */
-		void setTexture(UINT32 set, UINT32 slot, const SPtr<Texture>& texture) override;
+		void setTexture(UINT32 set, UINT32 slot, const SPtr<Texture>& texture, 
+						const TextureSurface& surface = TextureSurface::COMPLETE) override;
 
 
 		/** @copydoc GpuParams::setLoadStoreTexture */
 		/** @copydoc GpuParams::setLoadStoreTexture */
 		void setLoadStoreTexture(UINT32 set, UINT32 slot, const SPtr<Texture>& texture,
 		void setLoadStoreTexture(UINT32 set, UINT32 slot, const SPtr<Texture>& texture,
@@ -34,9 +35,6 @@ namespace bs { namespace ct
 		/** @copydoc GpuParams::setSamplerState */
 		/** @copydoc GpuParams::setSamplerState */
 		void setSamplerState(UINT32 set, UINT32 slot, const SPtr<SamplerState>& sampler) override;
 		void setSamplerState(UINT32 set, UINT32 slot, const SPtr<SamplerState>& sampler) override;
 
 
-		/** @copydoc GpuParams::setLoadStoreSurface */
-		void setLoadStoreSurface(UINT32 set, UINT32 slot, const TextureSurface& surface) override;
-
 		/** Returns the total number of descriptor sets used by this object. */
 		/** Returns the total number of descriptor sets used by this object. */
 		UINT32 getNumSets() const;
 		UINT32 getNumSets() const;
 
 

+ 11 - 44
Source/BansheeVulkanRenderAPI/Source/BsVulkanGpuParams.cpp

@@ -263,9 +263,9 @@ namespace bs { namespace ct
 		mSetsDirty[set] = true;
 		mSetsDirty[set] = true;
 	}
 	}
 
 
-	void VulkanGpuParams::setTexture(UINT32 set, UINT32 slot, const SPtr<Texture>& texture)
+	void VulkanGpuParams::setTexture(UINT32 set, UINT32 slot, const SPtr<Texture>& texture, const TextureSurface& surface)
 	{
 	{
-		GpuParams::setTexture(set, slot, texture);
+		GpuParams::setTexture(set, slot, texture, surface);
 
 
 		VulkanGpuPipelineParamInfo& vkParamInfo = static_cast<VulkanGpuPipelineParamInfo&>(*mParamInfo);
 		VulkanGpuPipelineParamInfo& vkParamInfo = static_cast<VulkanGpuPipelineParamInfo&>(*mParamInfo);
 		UINT32 bindingIdx = vkParamInfo.getBindingIdx(set, slot);
 		UINT32 bindingIdx = vkParamInfo.getBindingIdx(set, slot);
@@ -295,7 +295,7 @@ namespace bs { namespace ct
 			PerSetData& perSetData = mPerDeviceData[i].perSetData[set];
 			PerSetData& perSetData = mPerDeviceData[i].perSetData[set];
 			if (imageRes != nullptr)
 			if (imageRes != nullptr)
 			{
 			{
-				perSetData.writeInfos[bindingIdx].image.imageView = imageRes->getView(false);
+				perSetData.writeInfos[bindingIdx].image.imageView = imageRes->getView(surface, false);
 				mPerDeviceData[i].sampledImages[sequentialIdx] = imageRes->getHandle();
 				mPerDeviceData[i].sampledImages[sequentialIdx] = imageRes->getHandle();
 			}
 			}
 			else
 			else
@@ -472,41 +472,6 @@ namespace bs { namespace ct
 		mSetsDirty[set] = true;
 		mSetsDirty[set] = true;
 	}
 	}
 
 
-	void VulkanGpuParams::setLoadStoreSurface(UINT32 set, UINT32 slot, const TextureSurface& surface)
-	{
-		GpuParams::setLoadStoreSurface(set, slot, surface);
-
-		VulkanGpuPipelineParamInfo& vkParamInfo = static_cast<VulkanGpuPipelineParamInfo&>(*mParamInfo);
-		UINT32 bindingIdx = vkParamInfo.getBindingIdx(set, slot);
-		if (bindingIdx == -1)
-		{
-			LOGERR("Provided set/slot combination is not used by the GPU program: " + toString(set) + "," +
-				   toString(slot) + ".");
-			return;
-		}
-
-		SPtr<Texture> texture = getLoadStoreTexture(set, slot);
-		if (texture == nullptr)
-			return;
-
-		Lock(mMutex);
-
-		VulkanTexture* vulkanTexture = static_cast<VulkanTexture*>(texture.get());
-		for (UINT32 i = 0; i < BS_MAX_DEVICES; i++)
-		{
-			if (mPerDeviceData[i].perSetData == nullptr)
-				continue;
-
-			VulkanImage* imageRes = vulkanTexture->getResource(i);
-
-			PerSetData& perSetData = mPerDeviceData[i].perSetData[set];
-			if (imageRes != nullptr)
-				perSetData.writeInfos[bindingIdx].image.imageView = imageRes->getView(surface, false);
-		}
-
-		mSetsDirty[set] = true;
-	}
-
 	UINT32 VulkanGpuParams::getNumSets() const
 	UINT32 VulkanGpuParams::getNumSets() const
 	{
 	{
 		return mParamInfo->getNumSets();
 		return mParamInfo->getNumSets();
@@ -642,10 +607,10 @@ namespace bs { namespace ct
 
 
 		for (UINT32 i = 0; i < numStorageTextures; i++)
 		for (UINT32 i = 0; i < numStorageTextures; i++)
 		{
 		{
-			if (mLoadStoreTextures[i] == nullptr)
+			if (mLoadStoreTextureData[i].texture == nullptr)
 				continue;
 				continue;
 
 
-			VulkanTexture* element = static_cast<VulkanTexture*>(mLoadStoreTextures[i].get());
+			VulkanTexture* element = static_cast<VulkanTexture*>(mLoadStoreTextureData[i].texture.get());
 			VulkanImage* resource = element->getResource(deviceIdx);
 			VulkanImage* resource = element->getResource(deviceIdx);
 			if (resource == nullptr)
 			if (resource == nullptr)
 				continue;
 				continue;
@@ -667,7 +632,7 @@ namespace bs { namespace ct
 
 
 				UINT32 bindingIdx = vkParamInfo.getBindingIdx(set, slot);
 				UINT32 bindingIdx = vkParamInfo.getBindingIdx(set, slot);
 
 
-				const TextureSurface& surface = mLoadStoreSurfaces[i];
+				const TextureSurface& surface = mLoadStoreTextureData[i].surface;
 				perDeviceData.perSetData[set].writeInfos[bindingIdx].image.imageView = resource->getView(surface, false);;
 				perDeviceData.perSetData[set].writeInfos[bindingIdx].image.imageView = resource->getView(surface, false);;
 
 
 				mSetsDirty[set] = true;
 				mSetsDirty[set] = true;
@@ -676,10 +641,10 @@ namespace bs { namespace ct
 
 
 		for (UINT32 i = 0; i < numTextures; i++)
 		for (UINT32 i = 0; i < numTextures; i++)
 		{
 		{
-			if (mTextures[i] == nullptr)
+			if (mSampledTextureData[i].texture == nullptr)
 				continue;
 				continue;
 
 
-			VulkanTexture* element = static_cast<VulkanTexture*>(mTextures[i].get());
+			VulkanTexture* element = static_cast<VulkanTexture*>(mSampledTextureData[i].texture.get());
 			VulkanImage* resource = element->getResource(deviceIdx);
 			VulkanImage* resource = element->getResource(deviceIdx);
 			if (resource == nullptr)
 			if (resource == nullptr)
 				continue;
 				continue;
@@ -709,7 +674,9 @@ namespace bs { namespace ct
 				mParamInfo->getSetSlot(GpuPipelineParamInfo::ParamType::Texture, i, set, slot);
 				mParamInfo->getSetSlot(GpuPipelineParamInfo::ParamType::Texture, i, set, slot);
 
 
 				UINT32 bindingIdx = vkParamInfo.getBindingIdx(set, slot);
 				UINT32 bindingIdx = vkParamInfo.getBindingIdx(set, slot);
-				perDeviceData.perSetData[set].writeInfos[bindingIdx].image.imageView = resource->getView(false);
+
+				const TextureSurface& surface = mSampledTextureData[i].surface;
+				perDeviceData.perSetData[set].writeInfos[bindingIdx].image.imageView = resource->getView(surface, false);
 
 
 				mSetsDirty[set] = true;
 				mSetsDirty[set] = true;
 			}
 			}

+ 2 - 2
Source/BansheeVulkanRenderAPI/Source/BsVulkanTexture.cpp

@@ -210,9 +210,9 @@ namespace bs { namespace ct
 
 
 		mImageViewCI.subresourceRange.aspectMask = aspectMask;
 		mImageViewCI.subresourceRange.aspectMask = aspectMask;
 		mImageViewCI.subresourceRange.baseMipLevel = surface.mipLevel;
 		mImageViewCI.subresourceRange.baseMipLevel = surface.mipLevel;
-		mImageViewCI.subresourceRange.levelCount = surface.numMipLevels;
+		mImageViewCI.subresourceRange.levelCount = surface.numMipLevels == 0 ? VK_REMAINING_MIP_LEVELS : surface.numMipLevels;
 		mImageViewCI.subresourceRange.baseArrayLayer = surface.arraySlice;
 		mImageViewCI.subresourceRange.baseArrayLayer = surface.arraySlice;
-		mImageViewCI.subresourceRange.layerCount = surface.numArraySlices;
+		mImageViewCI.subresourceRange.layerCount = surface.numArraySlices == 0 ? VK_REMAINING_ARRAY_LAYERS : surface.numArraySlices;
 
 
 		VkImageView view;
 		VkImageView view;
 		VkResult result = vkCreateImageView(mOwner->getDevice().getLogical(), &mImageViewCI, gVulkanAllocator, &view);
 		VkResult result = vkCreateImageView(mOwner->getDevice().getLogical(), &mImageViewCI, gVulkanAllocator, &view);