浏览代码

[REFACTOR] Bind texture for sampling uses texture views

Panagiotis Christopoulos Charitos 8 年之前
父节点
当前提交
4694f7fd12

+ 2 - 8
src/anki/gr/CommandBuffer.h

@@ -226,16 +226,10 @@ public:
 	/// Bind texture and sample.
 	/// Bind texture and sample.
 	/// @param set The set to bind to.
 	/// @param set The set to bind to.
 	/// @param binding The binding to bind to.
 	/// @param binding The binding to bind to.
-	/// @param tex The texture to bind.
+	/// @param texView The texture view to bind.
 	/// @param sampler The sampler to override the default sampler of the tex.
 	/// @param sampler The sampler to override the default sampler of the tex.
 	/// @param usage The state the tex is in.
 	/// @param usage The state the tex is in.
-	/// @param aspect The depth stencil aspect.
-	void bindTextureAndSampler(U32 set,
-		U32 binding,
-		TexturePtr tex,
-		SamplerPtr sampler,
-		TextureUsageBit usage,
-		DepthStencilAspectBit aspect = DepthStencilAspectBit::NONE);
+	void bindTextureAndSampler(U32 set, U32 binding, TextureViewPtr texView, SamplerPtr sampler, TextureUsageBit usage);
 
 
 	/// Bind uniform buffer.
 	/// Bind uniform buffer.
 	/// @param set The set to bind to.
 	/// @param set The set to bind to.

+ 8 - 4
src/anki/gr/RenderGraph.h

@@ -9,6 +9,7 @@
 #include <anki/gr/Enums.h>
 #include <anki/gr/Enums.h>
 #include <anki/gr/TextureView.h>
 #include <anki/gr/TextureView.h>
 #include <anki/gr/Buffer.h>
 #include <anki/gr/Buffer.h>
+#include <anki/gr/GrManager.h>
 #include <anki/gr/Framebuffer.h>
 #include <anki/gr/Framebuffer.h>
 #include <anki/gr/CommandBuffer.h>
 #include <anki/gr/CommandBuffer.h>
 #include <anki/util/HashMap.h>
 #include <anki/util/HashMap.h>
@@ -139,17 +140,20 @@ public:
 		TexturePtr tex;
 		TexturePtr tex;
 		TextureUsageBit usage;
 		TextureUsageBit usage;
 		getRenderTargetState(handle, subresource, tex, usage);
 		getRenderTargetState(handle, subresource, tex, usage);
-		m_commandBuffer->bindTextureAndSampler(set, binding, tex, sampler, usage, subresource.m_depthStencilAspect);
+		TextureViewInitInfo viewInit(tex, subresource, "TmpRenderGraph");
+		TextureViewPtr view = m_commandBuffer->getManager().newTextureView(viewInit);
+		m_commandBuffer->bindTextureAndSampler(set, binding, view, sampler, usage);
 	}
 	}
 
 
 	/// Convenience method to bind the whole texture as color.
 	/// Convenience method to bind the whole texture as color.
 	void bindColorTextureAndSampler(U32 set, U32 binding, RenderTargetHandle handle, SamplerPtr sampler)
 	void bindColorTextureAndSampler(U32 set, U32 binding, RenderTargetHandle handle, SamplerPtr sampler)
 	{
 	{
 		TexturePtr tex = getTexture(handle);
 		TexturePtr tex = getTexture(handle);
-		TextureViewInitInfo subresource(tex); // Use the whole texture
+		TextureViewInitInfo viewInit(tex); // Use the whole texture
 		TextureUsageBit usage;
 		TextureUsageBit usage;
-		getRenderTargetState(handle, subresource, tex, usage);
-		m_commandBuffer->bindTextureAndSampler(set, binding, tex, sampler, usage, DepthStencilAspectBit::NONE);
+		getRenderTargetState(handle, viewInit, tex, usage);
+		TextureViewPtr view = m_commandBuffer->getManager().newTextureView(viewInit);
+		m_commandBuffer->bindTextureAndSampler(set, binding, view, sampler, usage);
 	}
 	}
 
 
 	/// Convenience method.
 	/// Convenience method.

+ 2 - 2
src/anki/gr/vulkan/CommandBuffer.cpp

@@ -174,10 +174,10 @@ void CommandBuffer::setBlendOperation(U32 attachment, BlendOperation funcRgb, Bl
 }
 }
 
 
 void CommandBuffer::bindTextureAndSampler(
 void CommandBuffer::bindTextureAndSampler(
-	U32 set, U32 binding, TexturePtr tex, SamplerPtr sampler, TextureUsageBit usage, DepthStencilAspectBit aspect)
+	U32 set, U32 binding, TextureViewPtr texView, SamplerPtr sampler, TextureUsageBit usage)
 {
 {
 	ANKI_VK_SELF(CommandBufferImpl);
 	ANKI_VK_SELF(CommandBufferImpl);
-	self.bindTextureAndSampler(set, binding, tex, sampler, usage, aspect);
+	self.bindTextureAndSamplerInternal(set, binding, texView, sampler, usage);
 }
 }
 
 
 void CommandBuffer::bindUniformBuffer(U32 set, U32 binding, BufferPtr buff, PtrSize offset, PtrSize range)
 void CommandBuffer::bindUniformBuffer(U32 set, U32 binding, BufferPtr buff, PtrSize offset, PtrSize range)

+ 10 - 8
src/anki/gr/vulkan/CommandBufferImpl.h

@@ -219,17 +219,19 @@ public:
 		m_state.setBlendOperation(attachment, funcRgb, funcA);
 		m_state.setBlendOperation(attachment, funcRgb, funcA);
 	}
 	}
 
 
-	void bindTextureAndSampler(
-		U32 set, U32 binding, TexturePtr& tex_, SamplerPtr sampler, TextureUsageBit usage, DepthStencilAspectBit aspect)
+	void bindTextureAndSamplerInternal(
+		U32 set, U32 binding, TextureViewPtr& texView, SamplerPtr sampler, TextureUsageBit usage)
 	{
 	{
 		commandCommon();
 		commandCommon();
 		const U realBinding = binding;
 		const U realBinding = binding;
-		const Texture& tex = *tex_;
-		const TextureImpl& teximpl = static_cast<const TextureImpl&>(tex);
-		ANKI_ASSERT((!teximpl.getDepthStencilAspect() || !!aspect) && "Need to set aspect for DS textures");
-		const VkImageLayout lay = teximpl.computeLayout(usage, 0);
-		m_dsetState[set].bindTextureAndSampler(realBinding, &tex, sampler.get(), aspect, lay);
-		m_microCmdb->pushObjectRef(tex_);
+		const TextureViewImpl& view = static_cast<const TextureViewImpl&>(*texView);
+		const TextureImpl& tex = static_cast<const TextureImpl&>(*view.m_tex);
+		ANKI_ASSERT(tex.isSubresourceGoodForSampling(view.m_subresource));
+		const VkImageLayout lay = tex.computeLayout(usage, 0);
+
+		m_dsetState[set].bindTextureAndSampler(realBinding, &view, sampler.get(), lay);
+
+		m_microCmdb->pushObjectRef(texView);
 		m_microCmdb->pushObjectRef(sampler);
 		m_microCmdb->pushObjectRef(sampler);
 	}
 	}
 
 

+ 1 - 2
src/anki/gr/vulkan/DescriptorSet.cpp

@@ -286,7 +286,7 @@ void DSThreadAllocator::writeSet(const Array<AnyBinding, MAX_BINDINGS_PER_DESCRI
 			{
 			{
 			case DescriptorType::TEXTURE:
 			case DescriptorType::TEXTURE:
 				tex[texCount].sampler = b.m_tex.m_sampler->getHandle();
 				tex[texCount].sampler = b.m_tex.m_sampler->getHandle();
-				tex[texCount].imageView = b.m_tex.m_tex->getOrCreateResourceGroupView(b.m_tex.m_aspect);
+				tex[texCount].imageView = b.m_tex.m_texView->m_handle;
 				tex[texCount].imageLayout = b.m_tex.m_layout;
 				tex[texCount].imageLayout = b.m_tex.m_layout;
 
 
 				w.pImageInfo = &tex[texCount];
 				w.pImageInfo = &tex[texCount];
@@ -506,7 +506,6 @@ void DescriptorSetState::flush(Bool& stateDirty,
 			{
 			{
 			case DescriptorType::TEXTURE:
 			case DescriptorType::TEXTURE:
 				toHash[toHashCount++] = m_bindings[i].m_uuids[1];
 				toHash[toHashCount++] = m_bindings[i].m_uuids[1];
-				toHash[toHashCount++] = U64(m_bindings[i].m_tex.m_aspect);
 				toHash[toHashCount++] = U64(m_bindings[i].m_tex.m_layout);
 				toHash[toHashCount++] = U64(m_bindings[i].m_tex.m_layout);
 				break;
 				break;
 			case DescriptorType::UNIFORM_BUFFER:
 			case DescriptorType::UNIFORM_BUFFER:

+ 7 - 8
src/anki/gr/vulkan/DescriptorSet.h

@@ -64,9 +64,8 @@ private:
 class TextureBinding
 class TextureBinding
 {
 {
 public:
 public:
-	const TextureImpl* m_tex = nullptr;
+	const TextureViewImpl* m_texView = nullptr;
 	const MicroSampler* m_sampler = nullptr;
 	const MicroSampler* m_sampler = nullptr;
-	DepthStencilAspectBit m_aspect = DepthStencilAspectBit::NONE;
 	VkImageLayout m_layout = VK_IMAGE_LAYOUT_MAX_ENUM;
 	VkImageLayout m_layout = VK_IMAGE_LAYOUT_MAX_ENUM;
 };
 };
 
 
@@ -107,19 +106,19 @@ public:
 		m_layoutDirty = true;
 		m_layoutDirty = true;
 	}
 	}
 
 
-	void bindTextureAndSampler(
-		U binding, const Texture* tex, const Sampler* sampler, DepthStencilAspectBit aspect, VkImageLayout layout)
+	void bindTextureAndSampler(U binding, const TextureView* texView, const Sampler* sampler, VkImageLayout layout)
 	{
 	{
-		ANKI_ASSERT(static_cast<const TextureImpl&>(*tex).aspectValid(aspect));
+		const TextureViewImpl& viewImpl = static_cast<const TextureViewImpl&>(*texView);
+		ANKI_ASSERT(viewImpl.m_tex->isSubresourceGoodForSampling(viewImpl.m_subresource));
+
 		AnyBinding& b = m_bindings[binding];
 		AnyBinding& b = m_bindings[binding];
 		b = {};
 		b = {};
 		b.m_type = DescriptorType::TEXTURE;
 		b.m_type = DescriptorType::TEXTURE;
-		b.m_uuids[0] = tex->getUuid();
+		b.m_uuids[0] = viewImpl.m_hash;
 		b.m_uuids[1] = sampler->getUuid();
 		b.m_uuids[1] = sampler->getUuid();
 
 
-		b.m_tex.m_tex = static_cast<const TextureImpl*>(tex);
+		b.m_tex.m_texView = &viewImpl;
 		b.m_tex.m_sampler = static_cast<const SamplerImpl*>(sampler)->m_sampler.get();
 		b.m_tex.m_sampler = static_cast<const SamplerImpl*>(sampler)->m_sampler.get();
-		b.m_tex.m_aspect = aspect;
 		b.m_tex.m_layout = layout;
 		b.m_tex.m_layout = layout;
 
 
 		m_anyBindingDirty = true;
 		m_anyBindingDirty = true;

+ 1 - 1
src/anki/renderer/Bloom.cpp

@@ -170,7 +170,7 @@ void Bloom::runUpscaleAndSslf(RenderPassWorkContext& rgraphCtx)
 	cmdb->setBlendFactors(0, BlendFactor::ONE, BlendFactor::ONE);
 	cmdb->setBlendFactors(0, BlendFactor::ONE, BlendFactor::ONE);
 	cmdb->bindTextureAndSampler(0,
 	cmdb->bindTextureAndSampler(0,
 		1,
 		1,
-		m_sslf.m_lensDirtTex->getGrTexture(),
+		m_sslf.m_lensDirtTex->getGrTextureView(),
 		m_sslf.m_lensDirtTex->getSampler(),
 		m_sslf.m_lensDirtTex->getSampler(),
 		TextureUsageBit::SAMPLED_FRAGMENT);
 		TextureUsageBit::SAMPLED_FRAGMENT);
 	drawQuad(cmdb);
 	drawQuad(cmdb);

+ 2 - 2
src/anki/renderer/FinalComposite.cpp

@@ -116,9 +116,9 @@ void FinalComposite::run(const RenderingContext& ctx, RenderPassWorkContext& rgr
 
 
 	rgraphCtx.bindColorTextureAndSampler(0, 1, m_r->getBloom().getRt(), m_r->getLinearSampler());
 	rgraphCtx.bindColorTextureAndSampler(0, 1, m_r->getBloom().getRt(), m_r->getLinearSampler());
 	cmdb->bindTextureAndSampler(
 	cmdb->bindTextureAndSampler(
-		0, 2, m_lut->getGrTexture(), m_r->getLinearSampler(), TextureUsageBit::SAMPLED_FRAGMENT);
+		0, 2, m_lut->getGrTextureView(), m_r->getLinearSampler(), TextureUsageBit::SAMPLED_FRAGMENT);
 	cmdb->bindTextureAndSampler(
 	cmdb->bindTextureAndSampler(
-		0, 3, m_blueNoise->getGrTexture(), m_blueNoise->getSampler(), TextureUsageBit::SAMPLED_FRAGMENT);
+		0, 3, m_blueNoise->getGrTextureView(), m_blueNoise->getSampler(), TextureUsageBit::SAMPLED_FRAGMENT);
 	if(dbgEnabled)
 	if(dbgEnabled)
 	{
 	{
 		rgraphCtx.bindColorTextureAndSampler(0, 5, m_r->getDbg().getRt(), m_r->getLinearSampler());
 		rgraphCtx.bindColorTextureAndSampler(0, 5, m_r->getDbg().getRt(), m_r->getLinearSampler());

+ 6 - 3
src/anki/renderer/ForwardShading.cpp

@@ -114,8 +114,11 @@ void ForwardShading::drawVolumetric(RenderingContext& ctx, RenderPassWorkContext
 		0, 0, m_r->getDepthDownscale().getHalfDepthColorRt(), m_r->getNearestSampler());
 		0, 0, m_r->getDepthDownscale().getHalfDepthColorRt(), m_r->getNearestSampler());
 	rgraphCtx.bindColorTextureAndSampler(0, 1, m_r->getDepthDownscale().getQuarterColorRt(), m_r->getNearestSampler());
 	rgraphCtx.bindColorTextureAndSampler(0, 1, m_r->getDepthDownscale().getQuarterColorRt(), m_r->getNearestSampler());
 	rgraphCtx.bindColorTextureAndSampler(0, 2, m_r->getVolumetric().getRt(), m_r->getLinearSampler());
 	rgraphCtx.bindColorTextureAndSampler(0, 2, m_r->getVolumetric().getRt(), m_r->getLinearSampler());
-	cmdb->bindTextureAndSampler(
-		0, 3, m_vol.m_noiseTex->getGrTexture(), m_r->getTrilinearRepeatSampler(), TextureUsageBit::SAMPLED_FRAGMENT);
+	cmdb->bindTextureAndSampler(0,
+		3,
+		m_vol.m_noiseTex->getGrTextureView(),
+		m_r->getTrilinearRepeatSampler(),
+		TextureUsageBit::SAMPLED_FRAGMENT);
 
 
 	drawQuad(cmdb);
 	drawQuad(cmdb);
 
 
@@ -144,7 +147,7 @@ void ForwardShading::drawUpscale(const RenderingContext& ctx, RenderPassWorkCont
 	rgraphCtx.bindColorTextureAndSampler(0, 2, m_runCtx.m_rt, m_r->getLinearSampler());
 	rgraphCtx.bindColorTextureAndSampler(0, 2, m_runCtx.m_rt, m_r->getLinearSampler());
 	cmdb->bindTextureAndSampler(0,
 	cmdb->bindTextureAndSampler(0,
 		3,
 		3,
-		m_upscale.m_noiseTex->getGrTexture(),
+		m_upscale.m_noiseTex->getGrTextureView(),
 		m_r->getTrilinearRepeatSampler(),
 		m_r->getTrilinearRepeatSampler(),
 		TextureUsageBit::SAMPLED_FRAGMENT);
 		TextureUsageBit::SAMPLED_FRAGMENT);
 
 

+ 2 - 2
src/anki/renderer/Indirect.h

@@ -36,9 +36,9 @@ anki_internal:
 		return m_lightShading.m_mipCount;
 		return m_lightShading.m_mipCount;
 	}
 	}
 
 
-	TexturePtr getIntegrationLut() const
+	TextureViewPtr getIntegrationLut() const
 	{
 	{
-		return m_integrationLut->getGrTexture();
+		return m_integrationLut->getGrTextureView();
 	}
 	}
 
 
 	SamplerPtr getIntegrationLutSampler() const
 	SamplerPtr getIntegrationLutSampler() const

+ 6 - 3
src/anki/renderer/LensFlare.cpp

@@ -196,9 +196,12 @@ void LensFlare::runDrawFlares(const RenderingContext& ctx, CommandBufferPtr& cmd
 		++c;
 		++c;
 
 
 		// Render
 		// Render
-		ANKI_ASSERT(flareEl.m_texture);
-		cmdb->bindTextureAndSampler(
-			0, 0, TexturePtr(flareEl.m_texture), m_r->getTrilinearRepeatSampler(), TextureUsageBit::SAMPLED_FRAGMENT);
+		ANKI_ASSERT(flareEl.m_textureView);
+		cmdb->bindTextureAndSampler(0,
+			0,
+			TextureViewPtr(const_cast<TextureView*>(flareEl.m_textureView)),
+			m_r->getTrilinearRepeatSampler(),
+			TextureUsageBit::SAMPLED_FRAGMENT);
 
 
 		cmdb->drawArraysIndirect(
 		cmdb->drawArraysIndirect(
 			PrimitiveTopology::TRIANGLE_STRIP, 1, i * sizeof(DrawArraysIndirectInfo), m_indirectBuff);
 			PrimitiveTopology::TRIANGLE_STRIP, 1, i * sizeof(DrawArraysIndirectInfo), m_indirectBuff);

+ 6 - 6
src/anki/renderer/LightBin.cpp

@@ -318,9 +318,9 @@ public:
 	Atomic<U32> m_count = {0};
 	Atomic<U32> m_count = {0};
 	Atomic<U32> m_count2 = {0};
 	Atomic<U32> m_count2 = {0};
 
 
-	TexturePtr m_diffDecalTexAtlas;
+	TextureViewPtr m_diffDecalTexAtlas;
 	SpinLock m_diffDecalTexAtlasMtx;
 	SpinLock m_diffDecalTexAtlasMtx;
-	TexturePtr m_normalRoughnessDecalTexAtlas;
+	TextureViewPtr m_normalRoughnessDecalTexAtlas;
 	SpinLock m_normalRoughnessDecalTexAtlasMtx;
 	SpinLock m_normalRoughnessDecalTexAtlasMtx;
 
 
 	LightBin* m_bin = nullptr;
 	LightBin* m_bin = nullptr;
@@ -490,8 +490,8 @@ Error LightBin::bin(const Mat4& viewMat,
 	// Sync
 	// Sync
 	ANKI_CHECK(m_threadPool->waitForAllThreadsToFinish());
 	ANKI_CHECK(m_threadPool->waitForAllThreadsToFinish());
 
 
-	out.m_diffDecalTex = ctx.m_diffDecalTexAtlas;
-	out.m_normRoughnessDecalTex = ctx.m_normalRoughnessDecalTexAtlas;
+	out.m_diffDecalTexView = ctx.m_diffDecalTexAtlas;
+	out.m_normRoughnessDecalTexView = ctx.m_normalRoughnessDecalTexAtlas;
 
 
 	return Error::NONE;
 	return Error::NONE;
 }
 }
@@ -792,7 +792,7 @@ void LightBin::writeAndBinDecal(const DecalQueueElement& decalEl, LightBinContex
 	I idx = ctx.m_decalCount.fetchAdd(1);
 	I idx = ctx.m_decalCount.fetchAdd(1);
 	ShaderDecal& decal = ctx.m_decals[idx];
 	ShaderDecal& decal = ctx.m_decals[idx];
 
 
-	TexturePtr atlas(decalEl.m_diffuseAtlas);
+	TextureViewPtr atlas(const_cast<TextureView*>(decalEl.m_diffuseAtlas));
 	Vec4 uv = decalEl.m_diffuseAtlasUv;
 	Vec4 uv = decalEl.m_diffuseAtlasUv;
 	decal.m_diffUv = Vec4(uv.x(), uv.y(), uv.z() - uv.x(), uv.w() - uv.y());
 	decal.m_diffUv = Vec4(uv.x(), uv.y(), uv.z() - uv.x(), uv.w() - uv.y());
 	decal.m_blendFactors[0] = decalEl.m_diffuseAtlasBlendFactor;
 	decal.m_blendFactors[0] = decalEl.m_diffuseAtlasBlendFactor;
@@ -807,7 +807,7 @@ void LightBin::writeAndBinDecal(const DecalQueueElement& decalEl, LightBinContex
 		ctx.m_diffDecalTexAtlas = atlas;
 		ctx.m_diffDecalTexAtlas = atlas;
 	}
 	}
 
 
-	atlas.reset(decalEl.m_normalRoughnessAtlas);
+	atlas.reset(const_cast<TextureView*>(decalEl.m_normalRoughnessAtlas));
 	uv = decalEl.m_normalRoughnessAtlasUv;
 	uv = decalEl.m_normalRoughnessAtlasUv;
 	decal.m_normRoughnessUv = Vec4(uv.x(), uv.y(), uv.z() - uv.x(), uv.w() - uv.y());
 	decal.m_normRoughnessUv = Vec4(uv.x(), uv.y(), uv.z() - uv.x(), uv.w() - uv.y());
 	decal.m_blendFactors[1] = decalEl.m_normalRoughnessAtlasBlendFactor;
 	decal.m_blendFactors[1] = decalEl.m_normalRoughnessAtlasBlendFactor;

+ 2 - 2
src/anki/renderer/LightBin.h

@@ -27,8 +27,8 @@ public:
 	StagingGpuMemoryToken m_clustersToken;
 	StagingGpuMemoryToken m_clustersToken;
 	StagingGpuMemoryToken m_lightIndicesToken;
 	StagingGpuMemoryToken m_lightIndicesToken;
 
 
-	TexturePtr m_diffDecalTex;
-	TexturePtr m_normRoughnessDecalTex;
+	TextureViewPtr m_diffDecalTexView;
+	TextureViewPtr m_normRoughnessDecalTexView;
 };
 };
 
 
 /// Bins lights and probes to clusters.
 /// Bins lights and probes to clusters.

+ 2 - 2
src/anki/renderer/LightShading.cpp

@@ -150,12 +150,12 @@ void LightShading::run(const RenderingContext& ctx, RenderPassWorkContext& rgrap
 		TextureUsageBit::SAMPLED_FRAGMENT);
 		TextureUsageBit::SAMPLED_FRAGMENT);
 	cmdb->bindTextureAndSampler(0,
 	cmdb->bindTextureAndSampler(0,
 		4,
 		4,
-		(rsrc.m_diffDecalTex) ? rsrc.m_diffDecalTex : m_r->getDummyTexture(),
+		(rsrc.m_diffDecalTexView) ? rsrc.m_diffDecalTexView : m_r->getDummyTextureView(),
 		m_r->getTrilinearRepeatSampler(),
 		m_r->getTrilinearRepeatSampler(),
 		TextureUsageBit::SAMPLED_FRAGMENT);
 		TextureUsageBit::SAMPLED_FRAGMENT);
 	cmdb->bindTextureAndSampler(0,
 	cmdb->bindTextureAndSampler(0,
 		5,
 		5,
-		(rsrc.m_normRoughnessDecalTex) ? rsrc.m_normRoughnessDecalTex : m_r->getDummyTexture(),
+		(rsrc.m_normRoughnessDecalTexView) ? rsrc.m_normRoughnessDecalTexView : m_r->getDummyTextureView(),
 		m_r->getTrilinearRepeatSampler(),
 		m_r->getTrilinearRepeatSampler(),
 		TextureUsageBit::SAMPLED_FRAGMENT);
 		TextureUsageBit::SAMPLED_FRAGMENT);
 
 

+ 5 - 3
src/anki/renderer/RenderQueue.h

@@ -128,7 +128,8 @@ public:
 	Vec3 m_worldPosition;
 	Vec3 m_worldPosition;
 	Vec2 m_firstFlareSize;
 	Vec2 m_firstFlareSize;
 	Vec4 m_colorMultiplier;
 	Vec4 m_colorMultiplier;
-	Texture* m_texture; ///< Totaly unsafe but we can't have a smart ptr in here since there will be no deletion.
+	/// Totaly unsafe but we can't have a smart ptr in here since there will be no deletion.
+	const TextureView* m_textureView;
 	const void* m_userData;
 	const void* m_userData;
 	RenderQueueDrawCallback m_drawCallback;
 	RenderQueueDrawCallback m_drawCallback;
 };
 };
@@ -141,9 +142,10 @@ class DecalQueueElement final
 public:
 public:
 	const void* m_userData;
 	const void* m_userData;
 	RenderQueueDrawCallback m_drawCallback;
 	RenderQueueDrawCallback m_drawCallback;
-	Texture* m_diffuseAtlas; ///< Totaly unsafe but we can't have a smart ptr in here since there will be no deletion.
 	/// Totaly unsafe but we can't have a smart ptr in here since there will be no deletion.
 	/// Totaly unsafe but we can't have a smart ptr in here since there will be no deletion.
-	Texture* m_normalRoughnessAtlas;
+	const TextureView* m_diffuseAtlas;
+	/// Totaly unsafe but we can't have a smart ptr in here since there will be no deletion.
+	const TextureView* m_normalRoughnessAtlas;
 	Vec4 m_diffuseAtlasUv;
 	Vec4 m_diffuseAtlasUv;
 	Vec4 m_normalRoughnessAtlasUv;
 	Vec4 m_normalRoughnessAtlasUv;
 	F32 m_diffuseAtlasBlendFactor;
 	F32 m_diffuseAtlasBlendFactor;

+ 4 - 1
src/anki/renderer/Renderer.cpp

@@ -93,7 +93,10 @@ Error Renderer::initInternal(const ConfigSet& config)
 		texinit.m_usage = TextureUsageBit::SAMPLED_FRAGMENT;
 		texinit.m_usage = TextureUsageBit::SAMPLED_FRAGMENT;
 		texinit.m_format = PixelFormat(ComponentFormat::R8G8B8A8, TransformFormat::UNORM);
 		texinit.m_format = PixelFormat(ComponentFormat::R8G8B8A8, TransformFormat::UNORM);
 		texinit.m_initialUsage = TextureUsageBit::SAMPLED_FRAGMENT;
 		texinit.m_initialUsage = TextureUsageBit::SAMPLED_FRAGMENT;
-		m_dummyTex = getGrManager().newTexture(texinit);
+		TexturePtr tex = getGrManager().newTexture(texinit);
+
+		TextureViewInitInfo viewinit(tex);
+		m_dummyTexView = getGrManager().newTextureView(viewinit);
 	}
 	}
 
 
 	m_dummyBuff = getGrManager().newBuffer(BufferInitInfo(getDummyBufferSize(),
 	m_dummyBuff = getGrManager().newBuffer(BufferInitInfo(getDummyBufferSize(),

+ 3 - 3
src/anki/renderer/Renderer.h

@@ -285,9 +285,9 @@ anki_internal:
 		return m_willDrawToDefaultFbo;
 		return m_willDrawToDefaultFbo;
 	}
 	}
 
 
-	TexturePtr getDummyTexture() const
+	TextureViewPtr getDummyTextureView() const
 	{
 	{
-		return m_dummyTex;
+		return m_dummyTexView;
 	}
 	}
 
 
 	BufferPtr getDummyBuffer() const
 	BufferPtr getDummyBuffer() const
@@ -365,7 +365,7 @@ private:
 	Array<Mat4, 16> m_jitteredMats16x;
 	Array<Mat4, 16> m_jitteredMats16x;
 	Array<Mat4, 8> m_jitteredMats8x;
 	Array<Mat4, 8> m_jitteredMats8x;
 
 
-	TexturePtr m_dummyTex;
+	TextureViewPtr m_dummyTexView;
 	BufferPtr m_dummyBuff;
 	BufferPtr m_dummyBuff;
 
 
 	SamplerPtr m_nearestSampler;
 	SamplerPtr m_nearestSampler;

+ 5 - 2
src/anki/renderer/Ssao.cpp

@@ -133,8 +133,11 @@ void Ssao::runMain(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx
 
 
 	rgraphCtx.bindColorTextureAndSampler(0, 0, m_r->getDepthDownscale().getQuarterColorRt(), m_r->getLinearSampler());
 	rgraphCtx.bindColorTextureAndSampler(0, 0, m_r->getDepthDownscale().getQuarterColorRt(), m_r->getLinearSampler());
 	rgraphCtx.bindColorTextureAndSampler(0, 1, m_r->getGBuffer().getColorRt(2), m_r->getLinearSampler());
 	rgraphCtx.bindColorTextureAndSampler(0, 1, m_r->getGBuffer().getColorRt(2), m_r->getLinearSampler());
-	cmdb->bindTextureAndSampler(
-		0, 2, m_main.m_noiseTex->getGrTexture(), m_r->getTrilinearRepeatSampler(), TextureUsageBit::SAMPLED_FRAGMENT);
+	cmdb->bindTextureAndSampler(0,
+		2,
+		m_main.m_noiseTex->getGrTextureView(),
+		m_r->getTrilinearRepeatSampler(),
+		TextureUsageBit::SAMPLED_FRAGMENT);
 	rgraphCtx.bindColorTextureAndSampler(0, 3, m_runCtx.m_rts[(m_r->getFrameCount() + 1) & 1], m_r->getLinearSampler());
 	rgraphCtx.bindColorTextureAndSampler(0, 3, m_runCtx.m_rts[(m_r->getFrameCount() + 1) & 1], m_r->getLinearSampler());
 
 
 	struct Unis
 	struct Unis

+ 5 - 2
src/anki/renderer/Volumetric.cpp

@@ -125,8 +125,11 @@ void Volumetric::runMain(const RenderingContext& ctx, RenderPassWorkContext& rgr
 	cmdb->setViewport(0, 0, m_width, m_height);
 	cmdb->setViewport(0, 0, m_width, m_height);
 
 
 	rgraphCtx.bindColorTextureAndSampler(0, 0, m_r->getDepthDownscale().getQuarterColorRt(), m_r->getLinearSampler());
 	rgraphCtx.bindColorTextureAndSampler(0, 0, m_r->getDepthDownscale().getQuarterColorRt(), m_r->getLinearSampler());
-	cmdb->bindTextureAndSampler(
-		0, 1, m_main.m_noiseTex->getGrTexture(), m_r->getTrilinearRepeatSampler(), TextureUsageBit::SAMPLED_FRAGMENT);
+	cmdb->bindTextureAndSampler(0,
+		1,
+		m_main.m_noiseTex->getGrTextureView(),
+		m_r->getTrilinearRepeatSampler(),
+		TextureUsageBit::SAMPLED_FRAGMENT);
 	rgraphCtx.bindColorTextureAndSampler(0, 2, m_runCtx.m_rts[(m_r->getFrameCount() + 1) & 1], m_r->getLinearSampler());
 	rgraphCtx.bindColorTextureAndSampler(0, 2, m_runCtx.m_rts[(m_r->getFrameCount() + 1) & 1], m_r->getLinearSampler());
 	rgraphCtx.bindColorTextureAndSampler(0, 3, m_r->getShadowMapping().getShadowmapRt(), m_r->getLinearSampler());
 	rgraphCtx.bindColorTextureAndSampler(0, 3, m_r->getShadowMapping().getShadowmapRt(), m_r->getLinearSampler());
 
 

+ 6 - 1
src/anki/resource/TextureAtlas.h

@@ -42,11 +42,16 @@ public:
 	/// Load a texture atlas.
 	/// Load a texture atlas.
 	ANKI_USE_RESULT Error load(const ResourceFilename& filename, Bool async);
 	ANKI_USE_RESULT Error load(const ResourceFilename& filename, Bool async);
 
 
-	TexturePtr getGrTexture() const
+	const TexturePtr& getGrTexture() const
 	{
 	{
 		return m_tex->getGrTexture();
 		return m_tex->getGrTexture();
 	}
 	}
 
 
+	const TextureViewPtr& getGrTextureView() const
+	{
+		return m_tex->getGrTextureView();
+	}
+
 	U getWidth() const
 	U getWidth() const
 	{
 	{
 		return m_size[0];
 		return m_size[0];

+ 5 - 0
src/anki/resource/TextureResource.cpp

@@ -194,6 +194,11 @@ Error TextureResource::load(const ResourceFilename& filename, Bool async)
 
 
 	m_size = UVec3(init.m_width, init.m_height, init.m_depth);
 	m_size = UVec3(init.m_width, init.m_height, init.m_depth);
 	m_layerCount = init.m_layerCount;
 	m_layerCount = init.m_layerCount;
+
+	// Create the texture view
+	TextureViewInitInfo viewInit(m_tex, "Rsrc");
+	m_texView = getManager().getGrManager().newTextureView(viewInit);
+
 	return Error::NONE;
 	return Error::NONE;
 }
 }
 
 

+ 8 - 7
src/anki/resource/TextureResource.h

@@ -31,22 +31,22 @@ public:
 	/// Load a texture
 	/// Load a texture
 	ANKI_USE_RESULT Error load(const ResourceFilename& filename, Bool async);
 	ANKI_USE_RESULT Error load(const ResourceFilename& filename, Bool async);
 
 
-	/// Get the texture
+	/// Get the texture.
 	const TexturePtr& getGrTexture() const
 	const TexturePtr& getGrTexture() const
 	{
 	{
 		return m_tex;
 		return m_tex;
 	}
 	}
 
 
-	/// Get the sampler.
-	const SamplerPtr& getSampler() const
+	/// Get the texture view.
+	const TextureViewPtr& getGrTextureView() const
 	{
 	{
-		return m_sampler;
+		return m_texView;
 	}
 	}
 
 
-	/// Get the texture
-	TexturePtr& getGrTexture()
+	/// Get the sampler.
+	const SamplerPtr& getSampler() const
 	{
 	{
-		return m_tex;
+		return m_sampler;
 	}
 	}
 
 
 	U getWidth() const
 	U getWidth() const
@@ -80,6 +80,7 @@ private:
 	class LoadingContext;
 	class LoadingContext;
 
 
 	TexturePtr m_tex;
 	TexturePtr m_tex;
+	TextureViewPtr m_texView;
 	SamplerPtr m_sampler;
 	SamplerPtr m_sampler;
 	UVec3 m_size = UVec3(0u);
 	UVec3 m_size = UVec3(0u);
 	U32 m_layerCount = 0;
 	U32 m_layerCount = 0;

+ 2 - 2
src/anki/scene/DecalComponent.h

@@ -121,10 +121,10 @@ public:
 	void setupDecalQueueElement(DecalQueueElement& el) const
 	void setupDecalQueueElement(DecalQueueElement& el) const
 	{
 	{
 		el.m_diffuseAtlas = (m_layers[LayerType::DIFFUSE].m_atlas)
 		el.m_diffuseAtlas = (m_layers[LayerType::DIFFUSE].m_atlas)
-			? m_layers[LayerType::DIFFUSE].m_atlas->getGrTexture().get()
+			? m_layers[LayerType::DIFFUSE].m_atlas->getGrTextureView().get()
 			: nullptr;
 			: nullptr;
 		el.m_normalRoughnessAtlas = (m_layers[LayerType::NORMAL_ROUGHNESS].m_atlas)
 		el.m_normalRoughnessAtlas = (m_layers[LayerType::NORMAL_ROUGHNESS].m_atlas)
-			? m_layers[LayerType::NORMAL_ROUGHNESS].m_atlas->getGrTexture().get()
+			? m_layers[LayerType::NORMAL_ROUGHNESS].m_atlas->getGrTextureView().get()
 			: nullptr;
 			: nullptr;
 		el.m_diffuseAtlasUv = m_layers[LayerType::DIFFUSE].m_uv;
 		el.m_diffuseAtlasUv = m_layers[LayerType::DIFFUSE].m_uv;
 		el.m_normalRoughnessAtlasUv = m_layers[LayerType::NORMAL_ROUGHNESS].m_uv;
 		el.m_normalRoughnessAtlasUv = m_layers[LayerType::NORMAL_ROUGHNESS].m_uv;

+ 1 - 1
src/anki/scene/LensFlareComponent.h

@@ -85,7 +85,7 @@ public:
 		el.m_worldPosition = m_worldPosition.xyz();
 		el.m_worldPosition = m_worldPosition.xyz();
 		el.m_firstFlareSize = m_firstFlareSize;
 		el.m_firstFlareSize = m_firstFlareSize;
 		el.m_colorMultiplier = m_colorMul;
 		el.m_colorMultiplier = m_colorMul;
-		el.m_texture = m_tex->getGrTexture().get();
+		el.m_textureView = m_tex->getGrTextureView().get();
 		el.m_userData = this;
 		el.m_userData = this;
 		el.m_drawCallback = debugDrawCallback;
 		el.m_drawCallback = debugDrawCallback;
 	}
 	}

+ 1 - 1
src/anki/scene/RenderComponent.cpp

@@ -187,7 +187,7 @@ void RenderComponent::allocateAndSetupUniforms(
 		{
 		{
 			ctx.m_commandBuffer->bindTextureAndSampler(set,
 			ctx.m_commandBuffer->bindTextureAndSampler(set,
 				progVariant.getTextureUnit(progvar),
 				progVariant.getTextureUnit(progvar),
-				mvar.getValue<TextureResourcePtr>()->getGrTexture(),
+				mvar.getValue<TextureResourcePtr>()->getGrTextureView(),
 				mvar.getValue<TextureResourcePtr>()->getSampler(),
 				mvar.getValue<TextureResourcePtr>()->getSampler(),
 				TextureUsageBit::SAMPLED_FRAGMENT);
 				TextureUsageBit::SAMPLED_FRAGMENT);
 			break;
 			break;

+ 2 - 2
src/anki/ui/Canvas.cpp

@@ -233,8 +233,8 @@ void Canvas::appendToCommandBuffer(CommandBufferPtr cmdb)
 		{
 		{
 			progToBind = m_grProgs[RGBA_TEX];
 			progToBind = m_grProgs[RGBA_TEX];
 
 
-			Texture* t = numberToPtr<Texture*>(ptrToNumber(cmd->texture.ptr) & ~FONT_TEXTURE_MASK);
-			cmdb->bindTextureAndSampler(0, 0, TexturePtr(t), m_sampler, TextureUsageBit::SAMPLED_FRAGMENT);
+			TextureView* t = numberToPtr<TextureView*>(ptrToNumber(cmd->texture.ptr) & ~FONT_TEXTURE_MASK);
+			cmdb->bindTextureAndSampler(0, 0, TextureViewPtr(t), m_sampler, TextureUsageBit::SAMPLED_FRAGMENT);
 		}
 		}
 		else
 		else
 		{
 		{

+ 1 - 1
src/anki/ui/Font.cpp

@@ -56,7 +56,7 @@ Error Font::init(const CString& filename, const std::initializer_list<U32>& font
 
 
 	// End building
 	// End building
 	nk_handle texHandle;
 	nk_handle texHandle;
-	texHandle.ptr = numberToPtr<void*>(ptrToNumber(m_tex.get()) | FONT_TEXTURE_MASK);
+	texHandle.ptr = numberToPtr<void*>(ptrToNumber(m_texView.get()) | FONT_TEXTURE_MASK);
 	nk_font_atlas_end(&m_atlas, texHandle, nullptr);
 	nk_font_atlas_end(&m_atlas, texHandle, nullptr);
 
 
 	nk_font_atlas_cleanup(&m_atlas);
 	nk_font_atlas_cleanup(&m_atlas);

+ 19 - 7
tests/gr/Gr.cpp

@@ -583,6 +583,9 @@ ANKI_TEST(Gr, ViewportAndScissorOffscreen)
 	init.m_type = TextureType::_2D;
 	init.m_type = TextureType::_2D;
 	TexturePtr rt = gr->newTexture(init);
 	TexturePtr rt = gr->newTexture(init);
 
 
+	TextureViewInitInfo viewInit(rt);
+	TextureViewPtr texView = gr->newTextureView(viewInit);
+
 	Array<FramebufferPtr, 4> fb;
 	Array<FramebufferPtr, 4> fb;
 	for(FramebufferPtr& f : fb)
 	for(FramebufferPtr& f : fb)
 	{
 	{
@@ -671,7 +674,7 @@ ANKI_TEST(Gr, ViewportAndScissorOffscreen)
 			TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE,
 			TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE,
 			TextureUsageBit::SAMPLED_FRAGMENT,
 			TextureUsageBit::SAMPLED_FRAGMENT,
 			TextureSurfaceInfo(0, 0, 0, 0));
 			TextureSurfaceInfo(0, 0, 0, 0));
-		cmdb->bindTextureAndSampler(0, 0, rt, sampler, TextureUsageBit::SAMPLED_FRAGMENT);
+		cmdb->bindTextureAndSampler(0, 0, texView, sampler, TextureUsageBit::SAMPLED_FRAGMENT);
 		cmdb->beginRenderPass(defaultFb, {}, {});
 		cmdb->beginRenderPass(defaultFb, {}, {});
 		cmdb->drawArrays(PrimitiveTopology::TRIANGLES, 6);
 		cmdb->drawArrays(PrimitiveTopology::TRIANGLES, 6);
 		cmdb->endRenderPass();
 		cmdb->endRenderPass();
@@ -925,6 +928,8 @@ ANKI_TEST(Gr, DrawWithTexture)
 
 
 	TexturePtr a = gr->newTexture(init);
 	TexturePtr a = gr->newTexture(init);
 
 
+	TextureViewPtr aView = gr->newTextureView(TextureViewInitInfo(a));
+
 	//
 	//
 	// Create texture B
 	// Create texture B
 	//
 	//
@@ -937,6 +942,8 @@ ANKI_TEST(Gr, DrawWithTexture)
 
 
 	TexturePtr b = gr->newTexture(init);
 	TexturePtr b = gr->newTexture(init);
 
 
+	TextureViewPtr bView = gr->newTextureView(TextureViewInitInfo(b));
+
 	//
 	//
 	// Upload all textures
 	// Upload all textures
 	//
 	//
@@ -1069,8 +1076,8 @@ ANKI_TEST(Gr, DrawWithTexture)
 		cmdb->bindShaderProgram(prog);
 		cmdb->bindShaderProgram(prog);
 		cmdb->beginRenderPass(fb, {}, {});
 		cmdb->beginRenderPass(fb, {}, {});
 
 
-		cmdb->bindTextureAndSampler(0, 0, a, sampler, TextureUsageBit::SAMPLED_FRAGMENT);
-		cmdb->bindTextureAndSampler(0, 1, b, sampler, TextureUsageBit::SAMPLED_FRAGMENT);
+		cmdb->bindTextureAndSampler(0, 0, aView, sampler, TextureUsageBit::SAMPLED_FRAGMENT);
+		cmdb->bindTextureAndSampler(0, 1, bView, sampler, TextureUsageBit::SAMPLED_FRAGMENT);
 		cmdb->drawArrays(PrimitiveTopology::TRIANGLES, 6);
 		cmdb->drawArrays(PrimitiveTopology::TRIANGLES, 6);
 		cmdb->endRenderPass();
 		cmdb->endRenderPass();
 		cmdb->flush();
 		cmdb->flush();
@@ -1155,6 +1162,9 @@ static void drawOffscreen(GrManager& gr, Bool useSecondLevel)
 	TexturePtr col0 = gr.newTexture(init);
 	TexturePtr col0 = gr.newTexture(init);
 	TexturePtr col1 = gr.newTexture(init);
 	TexturePtr col1 = gr.newTexture(init);
 
 
+	TextureViewPtr col0View = gr.newTextureView(TextureViewInitInfo(col0));
+	TextureViewPtr col1View = gr.newTextureView(TextureViewInitInfo(col1));
+
 	init.m_format = DS_FORMAT;
 	init.m_format = DS_FORMAT;
 	TexturePtr dp = gr.newTexture(init);
 	TexturePtr dp = gr.newTexture(init);
 
 
@@ -1257,8 +1267,8 @@ static void drawOffscreen(GrManager& gr, Bool useSecondLevel)
 		cmdb->beginRenderPass(dfb, {}, {});
 		cmdb->beginRenderPass(dfb, {}, {});
 		cmdb->bindShaderProgram(resolveProg);
 		cmdb->bindShaderProgram(resolveProg);
 		cmdb->setViewport(0, 0, WIDTH, HEIGHT);
 		cmdb->setViewport(0, 0, WIDTH, HEIGHT);
-		cmdb->bindTextureAndSampler(0, 0, col0, sampler, TextureUsageBit::SAMPLED_FRAGMENT);
-		cmdb->bindTextureAndSampler(0, 1, col1, sampler, TextureUsageBit::SAMPLED_FRAGMENT);
+		cmdb->bindTextureAndSampler(0, 0, col0View, sampler, TextureUsageBit::SAMPLED_FRAGMENT);
+		cmdb->bindTextureAndSampler(0, 1, col1View, sampler, TextureUsageBit::SAMPLED_FRAGMENT);
 		cmdb->drawArrays(PrimitiveTopology::TRIANGLES, 6);
 		cmdb->drawArrays(PrimitiveTopology::TRIANGLES, 6);
 		cmdb->endRenderPass();
 		cmdb->endRenderPass();
 
 
@@ -1386,7 +1396,8 @@ ANKI_TEST(Gr, ImageLoadStore)
 
 
 		cmdb->bindShaderProgram(prog);
 		cmdb->bindShaderProgram(prog);
 		cmdb->beginRenderPass(dfb, {}, {});
 		cmdb->beginRenderPass(dfb, {}, {});
-		cmdb->bindTextureAndSampler(0, 0, tex, sampler, TextureUsageBit::SAMPLED_FRAGMENT);
+		cmdb->bindTextureAndSampler(
+			0, 0, gr->newTextureView(TextureViewInitInfo(tex)), sampler, TextureUsageBit::SAMPLED_FRAGMENT);
 		cmdb->drawArrays(PrimitiveTopology::TRIANGLES, 6);
 		cmdb->drawArrays(PrimitiveTopology::TRIANGLES, 6);
 		cmdb->endRenderPass();
 		cmdb->endRenderPass();
 
 
@@ -1537,7 +1548,8 @@ ANKI_TEST(Gr, 3DTextures)
 		U idx = (F32(ITERATION_COUNT - iterations - 1) / ITERATION_COUNT) * TEX_COORDS_LOD.getSize();
 		U idx = (F32(ITERATION_COUNT - iterations - 1) / ITERATION_COUNT) * TEX_COORDS_LOD.getSize();
 		*uv = TEX_COORDS_LOD[idx];
 		*uv = TEX_COORDS_LOD[idx];
 
 
-		cmdb->bindTextureAndSampler(0, 0, a, sampler, TextureUsageBit::SAMPLED_FRAGMENT);
+		cmdb->bindTextureAndSampler(
+			0, 0, gr->newTextureView(TextureViewInitInfo(a)), sampler, TextureUsageBit::SAMPLED_FRAGMENT);
 		cmdb->drawArrays(PrimitiveTopology::TRIANGLES, 6);
 		cmdb->drawArrays(PrimitiveTopology::TRIANGLES, 6);
 
 
 		cmdb->endRenderPass();
 		cmdb->endRenderPass();