Browse Source

Switch to KHR_dynamic_rendering

Panagiotis Christopoulos Charitos 1 year ago
parent
commit
210af1c027
67 changed files with 680 additions and 1666 deletions
  1. 0 1
      AnKi/Gr.h
  2. 0 1
      AnKi/Gr/CMakeLists.txt
  3. 28 4
      AnKi/Gr/CommandBuffer.h
  4. 4 6
      AnKi/Gr/Common.h
  5. 1 3
      AnKi/Gr/Common/InstantiationMacros.def.h
  6. 0 137
      AnKi/Gr/Framebuffer.h
  7. 86 242
      AnKi/Gr/RenderGraph.cpp
  8. 30 46
      AnKi/Gr/RenderGraph.h
  9. 25 50
      AnKi/Gr/RenderGraph.inl.h
  10. 1 1
      AnKi/Gr/Vulkan/VkBuffer.cpp
  11. 137 65
      AnKi/Gr/Vulkan/VkCommandBuffer.cpp
  12. 4 12
      AnKi/Gr/Vulkan/VkCommandBuffer.h
  13. 7 7
      AnKi/Gr/Vulkan/VkCommon.cpp
  14. 10 2
      AnKi/Gr/Vulkan/VkCommon.h
  15. 0 390
      AnKi/Gr/Vulkan/VkFramebuffer.cpp
  16. 0 158
      AnKi/Gr/Vulkan/VkFramebuffer.h
  17. 45 30
      AnKi/Gr/Vulkan/VkGrManager.cpp
  18. 47 33
      AnKi/Gr/Vulkan/VkPipeline.cpp
  19. 37 18
      AnKi/Gr/Vulkan/VkPipeline.h
  20. 0 2
      AnKi/Gr/Vulkan/VkTextureView.h
  21. 2 4
      AnKi/Renderer/Bloom.cpp
  22. 0 2
      AnKi/Renderer/Bloom.h
  23. 5 9
      AnKi/Renderer/Dbg.cpp
  24. 0 1
      AnKi/Renderer/Dbg.h
  25. 4 13
      AnKi/Renderer/DepthDownscale.cpp
  26. 2 4
      AnKi/Renderer/DepthDownscale.h
  27. 5 13
      AnKi/Renderer/DownscaleBlur.cpp
  28. 0 2
      AnKi/Renderer/DownscaleBlur.h
  29. 1 4
      AnKi/Renderer/FinalComposite.cpp
  30. 0 2
      AnKi/Renderer/FinalComposite.h
  31. 18 46
      AnKi/Renderer/GBuffer.cpp
  32. 0 1
      AnKi/Renderer/GBuffer.h
  33. 5 7
      AnKi/Renderer/GBufferPost.cpp
  34. 0 2
      AnKi/Renderer/GBufferPost.h
  35. 25 32
      AnKi/Renderer/IndirectDiffuseProbes.cpp
  36. 0 1
      AnKi/Renderer/IndirectDiffuseProbes.h
  37. 8 34
      AnKi/Renderer/LightShading.cpp
  38. 0 1
      AnKi/Renderer/LightShading.h
  39. 1 5
      AnKi/Renderer/MainRenderer.cpp
  40. 0 1
      AnKi/Renderer/MainRenderer.h
  41. 1 4
      AnKi/Renderer/MotionVectors.cpp
  42. 0 1
      AnKi/Renderer/MotionVectors.h
  43. 29 34
      AnKi/Renderer/ProbeReflections.cpp
  44. 0 1
      AnKi/Renderer/ProbeReflections.h
  45. 22 23
      AnKi/Renderer/Renderer.cpp
  46. 3 6
      AnKi/Renderer/Scale.cpp
  47. 0 1
      AnKi/Renderer/Scale.h
  48. 5 10
      AnKi/Renderer/ShadowMapping.cpp
  49. 0 3
      AnKi/Renderer/ShadowMapping.h
  50. 4 7
      AnKi/Renderer/ShadowmapsResolve.cpp
  51. 0 1
      AnKi/Renderer/ShadowmapsResolve.h
  52. 3 6
      AnKi/Renderer/Ssao.cpp
  53. 0 1
      AnKi/Renderer/Ssao.h
  54. 2 4
      AnKi/Renderer/Ssr.cpp
  55. 0 1
      AnKi/Renderer/Ssr.h
  56. 1 4
      AnKi/Renderer/TemporalAA.cpp
  57. 0 1
      AnKi/Renderer/TemporalAA.h
  58. 5 6
      AnKi/Renderer/Utils/HzbGenerator.cpp
  59. 0 2
      AnKi/Renderer/Utils/HzbGenerator.h
  60. 1 1
      AnKi/Renderer/VrsSriGeneration.cpp
  61. 2 2
      AnKi/Renderer/VrsSriGeneration.h
  62. 3 3
      AnKi/Resource/ImageResource.cpp
  63. 1 0
      AnKi/Scene/Components/GlobalIlluminationProbeComponent.cpp
  64. 1 1
      AnKi/Ui/Font.cpp
  65. 46 130
      Tests/Gr/Gr.cpp
  66. 4 7
      Tests/Gr/GrMeshShaders.cpp
  67. 9 14
      Tests/Ui/Ui.cpp

+ 0 - 1
AnKi/Gr.h

@@ -11,7 +11,6 @@
 #include <AnKi/Gr/Sampler.h>
 #include <AnKi/Gr/Sampler.h>
 #include <AnKi/Gr/Shader.h>
 #include <AnKi/Gr/Shader.h>
 #include <AnKi/Gr/ShaderProgram.h>
 #include <AnKi/Gr/ShaderProgram.h>
-#include <AnKi/Gr/Framebuffer.h>
 #include <AnKi/Gr/CommandBuffer.h>
 #include <AnKi/Gr/CommandBuffer.h>
 #include <AnKi/Gr/OcclusionQuery.h>
 #include <AnKi/Gr/OcclusionQuery.h>
 #include <AnKi/Gr/TimestampQuery.h>
 #include <AnKi/Gr/TimestampQuery.h>

+ 0 - 1
AnKi/Gr/CMakeLists.txt

@@ -15,7 +15,6 @@ set(backend_headers
 	CommandBuffer.h
 	CommandBuffer.h
 	Common.h
 	Common.h
 	Fence.h
 	Fence.h
-	Framebuffer.h
 	GrManager.h
 	GrManager.h
 	GrObject.h
 	GrObject.h
 	OcclusionQuery.h
 	OcclusionQuery.h

+ 28 - 4
AnKi/Gr/CommandBuffer.h

@@ -6,7 +6,6 @@
 #pragma once
 #pragma once
 
 
 #include <AnKi/Gr/GrObject.h>
 #include <AnKi/Gr/GrObject.h>
-#include <AnKi/Gr/Framebuffer.h>
 #include <AnKi/Util/Functions.h>
 #include <AnKi/Util/Functions.h>
 #include <AnKi/Util/WeakArray.h>
 #include <AnKi/Util/WeakArray.h>
 #include <AnKi/Math.h>
 #include <AnKi/Math.h>
@@ -51,6 +50,23 @@ public:
 	PtrSize m_range = 0;
 	PtrSize m_range = 0;
 };
 };
 
 
+class RenderTarget
+{
+public:
+	TextureView* m_view = nullptr;
+
+	RenderTargetLoadOperation m_loadOperation = RenderTargetLoadOperation::kClear;
+	RenderTargetStoreOperation m_storeOperation = RenderTargetStoreOperation::kStore;
+
+	RenderTargetLoadOperation m_stencilLoadOperation = RenderTargetLoadOperation::kClear;
+	RenderTargetStoreOperation m_stencilStoreOperation = RenderTargetStoreOperation::kStore;
+
+	ClearValue m_clearValue;
+
+	TextureUsageBit m_usage = TextureUsageBit::kFramebufferWrite;
+	DepthStencilAspectBit m_aspect = DepthStencilAspectBit::kNone;
+};
+
 /// Command buffer initialization flags.
 /// Command buffer initialization flags.
 enum class CommandBufferFlag : U8
 enum class CommandBufferFlag : U8
 {
 {
@@ -268,11 +284,19 @@ public:
 	/// Bind a program.
 	/// Bind a program.
 	void bindShaderProgram(ShaderProgram* prog);
 	void bindShaderProgram(ShaderProgram* prog);
 
 
-	/// Begin renderpass.
+	/// Begin a renderpass.
 	/// The minx, miny, width, height control the area that the load and store operations will happen. If the scissor is bigger than the render area
 	/// The minx, miny, width, height control the area that the load and store operations will happen. If the scissor is bigger than the render area
 	/// the results are undefined.
 	/// the results are undefined.
-	void beginRenderPass(Framebuffer* fb, const Array<TextureUsageBit, kMaxColorRenderTargets>& colorAttachmentUsages,
-						 TextureUsageBit depthStencilAttachmentUsage, U32 minx = 0, U32 miny = 0, U32 width = kMaxU32, U32 height = kMaxU32);
+	void beginRenderPass(ConstWeakArray<RenderTarget> colorRts, RenderTarget* depthStencilRt, U32 minx = 0, U32 miny = 0, U32 width = kMaxU32,
+						 U32 height = kMaxU32, TextureView* vrsRt = nullptr, U8 vrsRtTexelSizeX = 0, U8 vrsRtTexelSizeY = 0);
+
+	/// See beginRenderPass.
+	void beginRenderPass(std::initializer_list<RenderTarget> colorRts, RenderTarget* depthStencilRt = nullptr, U32 minx = 0, U32 miny = 0,
+						 U32 width = kMaxU32, U32 height = kMaxU32, TextureView* vrsRt = nullptr, U8 vrsRtTexelSizeX = 0, U8 vrsRtTexelSizeY = 0)
+	{
+		beginRenderPass(ConstWeakArray(colorRts.begin(), U32(colorRts.size())), depthStencilRt, minx, miny, width, height, vrsRt, vrsRtTexelSizeX,
+						vrsRtTexelSizeY);
+	}
 
 
 	/// End renderpass.
 	/// End renderpass.
 	void endRenderPass();
 	void endRenderPass();

+ 4 - 6
AnKi/Gr/Common.h

@@ -675,7 +675,7 @@ enum class PipelineQueryType : U8
 };
 };
 
 
 /// Attachment load operation.
 /// Attachment load operation.
-enum class AttachmentLoadOperation : U8
+enum class RenderTargetLoadOperation : U8
 {
 {
 	kLoad,
 	kLoad,
 	kClear,
 	kClear,
@@ -683,7 +683,7 @@ enum class AttachmentLoadOperation : U8
 };
 };
 
 
 /// Attachment store operation.
 /// Attachment store operation.
-enum class AttachmentStoreOperation : U8
+enum class RenderTargetStoreOperation : U8
 {
 {
 	kStore,
 	kStore,
 	kDontCare
 	kDontCare
@@ -956,7 +956,6 @@ class TextureSurfaceInfo
 {
 {
 public:
 public:
 	U32 m_level = 0;
 	U32 m_level = 0;
-	U32 m_depth = 0;
 	U32 m_face = 0;
 	U32 m_face = 0;
 	U32 m_layer = 0;
 	U32 m_layer = 0;
 
 
@@ -964,9 +963,8 @@ public:
 
 
 	constexpr TextureSurfaceInfo(const TextureSurfaceInfo&) = default;
 	constexpr TextureSurfaceInfo(const TextureSurfaceInfo&) = default;
 
 
-	constexpr TextureSurfaceInfo(U32 level, U32 depth, U32 face, U32 layer)
+	constexpr TextureSurfaceInfo(U32 level, U32 face, U32 layer)
 		: m_level(level)
 		: m_level(level)
-		, m_depth(depth)
 		, m_face(face)
 		, m_face(face)
 		, m_layer(layer)
 		, m_layer(layer)
 	{
 	{
@@ -976,7 +974,7 @@ public:
 
 
 	Bool operator==(const TextureSurfaceInfo& b) const
 	Bool operator==(const TextureSurfaceInfo& b) const
 	{
 	{
-		return m_level == b.m_level && m_depth == b.m_depth && m_face == b.m_face && m_layer == b.m_layer;
+		return m_level == b.m_level && m_face == b.m_face && m_layer == b.m_layer;
 	}
 	}
 
 
 	Bool operator!=(const TextureSurfaceInfo& b) const
 	Bool operator!=(const TextureSurfaceInfo& b) const

+ 1 - 3
AnKi/Gr/Common/InstantiationMacros.def.h

@@ -11,8 +11,6 @@ ANKI_INSTANTIATE_GR_OBJECT(CommandBuffer)
 ANKI_INSTANTIATE_GR_OBJECT_DELIMITER()
 ANKI_INSTANTIATE_GR_OBJECT_DELIMITER()
 ANKI_INSTANTIATE_GR_OBJECT(Fence)
 ANKI_INSTANTIATE_GR_OBJECT(Fence)
 ANKI_INSTANTIATE_GR_OBJECT_DELIMITER()
 ANKI_INSTANTIATE_GR_OBJECT_DELIMITER()
-ANKI_INSTANTIATE_GR_OBJECT(Framebuffer)
-ANKI_INSTANTIATE_GR_OBJECT_DELIMITER()
 ANKI_INSTANTIATE_GR_OBJECT(OcclusionQuery)
 ANKI_INSTANTIATE_GR_OBJECT(OcclusionQuery)
 ANKI_INSTANTIATE_GR_OBJECT_DELIMITER()
 ANKI_INSTANTIATE_GR_OBJECT_DELIMITER()
 ANKI_INSTANTIATE_GR_OBJECT(TimestampQuery)
 ANKI_INSTANTIATE_GR_OBJECT(TimestampQuery)
@@ -29,4 +27,4 @@ ANKI_INSTANTIATE_GR_OBJECT(TextureView)
 ANKI_INSTANTIATE_GR_OBJECT_DELIMITER()
 ANKI_INSTANTIATE_GR_OBJECT_DELIMITER()
 ANKI_INSTANTIATE_GR_OBJECT(AccelerationStructure)
 ANKI_INSTANTIATE_GR_OBJECT(AccelerationStructure)
 ANKI_INSTANTIATE_GR_OBJECT_DELIMITER()
 ANKI_INSTANTIATE_GR_OBJECT_DELIMITER()
-ANKI_INSTANTIATE_GR_OBJECT(GrUpscaler)
+ANKI_INSTANTIATE_GR_OBJECT(GrUpscaler)

+ 0 - 137
AnKi/Gr/Framebuffer.h

@@ -1,137 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#pragma once
-
-#include <AnKi/Gr/GrObject.h>
-#include <AnKi/Gr/TextureView.h>
-
-namespace anki {
-
-/// @addtogroup graphics
-/// @{
-
-/// Framebuffer attachment info.
-class FramebufferAttachmentInfo
-{
-public:
-	TextureViewPtr m_textureView;
-
-	AttachmentLoadOperation m_loadOperation = AttachmentLoadOperation::kClear;
-	AttachmentStoreOperation m_storeOperation = AttachmentStoreOperation::kStore;
-
-	AttachmentLoadOperation m_stencilLoadOperation = AttachmentLoadOperation::kClear;
-	AttachmentStoreOperation m_stencilStoreOperation = AttachmentStoreOperation::kStore;
-
-	ClearValue m_clearValue;
-};
-
-/// Framebuffer initializer.
-class FramebufferInitInfo : public GrBaseInitInfo
-{
-public:
-	Array<FramebufferAttachmentInfo, kMaxColorRenderTargets> m_colorAttachments;
-	U32 m_colorAttachmentCount = 0;
-	FramebufferAttachmentInfo m_depthStencilAttachment;
-
-	class
-	{
-	public:
-		TextureViewPtr m_textureView;
-		U32 m_texelWidth = 0;
-		U32 m_texelHeight = 0;
-	} m_shadingRateImage;
-
-	FramebufferInitInfo()
-		: GrBaseInitInfo()
-	{
-	}
-
-	FramebufferInitInfo(CString name)
-		: GrBaseInitInfo(name)
-	{
-	}
-
-	FramebufferInitInfo(const FramebufferInitInfo& b)
-		: GrBaseInitInfo(b)
-	{
-		operator=(b);
-	}
-
-	~FramebufferInitInfo() = default;
-
-	FramebufferInitInfo& operator=(const FramebufferInitInfo& b)
-	{
-		GrBaseInitInfo::operator=(b);
-
-		for(U i = 0; i < b.m_colorAttachmentCount; i++)
-		{
-			m_colorAttachments[i] = b.m_colorAttachments[i];
-		}
-
-		m_colorAttachmentCount = b.m_colorAttachmentCount;
-		m_depthStencilAttachment = b.m_depthStencilAttachment;
-		m_shadingRateImage = b.m_shadingRateImage;
-		return *this;
-	}
-
-	Bool isValid() const
-	{
-		for(U i = 0; i < m_colorAttachmentCount; ++i)
-		{
-			if(!m_colorAttachments[i].m_textureView.isCreated())
-			{
-				return false;
-			}
-		}
-
-		if(m_colorAttachmentCount == 0 && !m_depthStencilAttachment.m_textureView.isCreated())
-		{
-			return false;
-		}
-
-		if(m_shadingRateImage.m_textureView)
-		{
-			if(m_shadingRateImage.m_texelHeight == 0 || m_shadingRateImage.m_texelWidth == 0)
-			{
-				return false;
-			}
-
-			if(!isPowerOfTwo(m_shadingRateImage.m_texelHeight) || !isPowerOfTwo(m_shadingRateImage.m_texelWidth))
-			{
-				return false;
-			}
-		}
-
-		return true;
-	}
-};
-
-/// GPU framebuffer.
-class Framebuffer : public GrObject
-{
-	ANKI_GR_OBJECT
-
-public:
-	static constexpr GrObjectType kClassType = GrObjectType::kFramebuffer;
-
-protected:
-	/// Construct.
-	Framebuffer(CString name)
-		: GrObject(kClassType, name)
-	{
-	}
-
-	/// Destroy.
-	~Framebuffer()
-	{
-	}
-
-private:
-	[[nodiscard]] static Framebuffer* newInstance(const FramebufferInitInfo& init);
-};
-/// @}
-
-} // end namespace anki

+ 86 - 242
AnKi/Gr/RenderGraph.cpp

@@ -7,7 +7,6 @@
 #include <AnKi/Gr/GrManager.h>
 #include <AnKi/Gr/GrManager.h>
 #include <AnKi/Gr/Texture.h>
 #include <AnKi/Gr/Texture.h>
 #include <AnKi/Gr/Sampler.h>
 #include <AnKi/Gr/Sampler.h>
-#include <AnKi/Gr/Framebuffer.h>
 #include <AnKi/Gr/CommandBuffer.h>
 #include <AnKi/Gr/CommandBuffer.h>
 #include <AnKi/Util/Tracer.h>
 #include <AnKi/Util/Tracer.h>
 #include <AnKi/Util/BitSet.h>
 #include <AnKi/Util/BitSet.h>
@@ -121,11 +120,24 @@ public:
 
 
 	Function<void(RenderPassWorkContext&), MemoryPoolPtrWrapper<StackMemoryPool>> m_callback;
 	Function<void(RenderPassWorkContext&), MemoryPoolPtrWrapper<StackMemoryPool>> m_callback;
 
 
-	Array<U32, 4> m_fbRenderArea;
-	Array<TextureUsageBit, kMaxColorRenderTargets> m_colorUsages = {}; ///< For beginRender pass
-	TextureUsageBit m_dsUsage = TextureUsageBit::kNone; ///< For beginRender pass
-
-	FramebufferPtr m_framebuffer;
+	class
+	{
+	public:
+		Array<RenderTarget, kMaxColorRenderTargets> m_colorRts;
+		RenderTarget m_dsRt;
+		TextureView* m_vrsRt = nullptr;
+		Array<U32, 4> m_renderArea = {};
+		U8 m_colorRtCount = 0;
+		U8 m_vrsTexelSizeX = 0;
+		U8 m_vrsTexelSizeY = 0;
+
+		Array<TextureViewPtr, kMaxColorRenderTargets + 2> m_refs;
+
+		Bool hasRenderpass() const
+		{
+			return m_renderArea[3] != 0;
+		}
+	} m_beginRenderpassInfo;
 
 
 	BaseString<MemoryPoolPtrWrapper<StackMemoryPool>> m_name;
 	BaseString<MemoryPoolPtrWrapper<StackMemoryPool>> m_name;
 
 
@@ -149,7 +161,6 @@ public:
 	DynamicArray<TextureBarrier, MemoryPoolPtrWrapper<StackMemoryPool>> m_textureBarriersBefore;
 	DynamicArray<TextureBarrier, MemoryPoolPtrWrapper<StackMemoryPool>> m_textureBarriersBefore;
 	DynamicArray<BufferBarrier, MemoryPoolPtrWrapper<StackMemoryPool>> m_bufferBarriersBefore;
 	DynamicArray<BufferBarrier, MemoryPoolPtrWrapper<StackMemoryPool>> m_bufferBarriersBefore;
 	DynamicArray<ASBarrier, MemoryPoolPtrWrapper<StackMemoryPool>> m_asBarriersBefore;
 	DynamicArray<ASBarrier, MemoryPoolPtrWrapper<StackMemoryPool>> m_asBarriersBefore;
-	Bool m_drawsToPresentImage = false;
 
 
 	Batch(StackMemoryPool* pool)
 	Batch(StackMemoryPool* pool)
 		: m_passIndices(pool)
 		: m_passIndices(pool)
@@ -170,7 +181,6 @@ public:
 		m_textureBarriersBefore = std::move(b.m_textureBarriersBefore);
 		m_textureBarriersBefore = std::move(b.m_textureBarriersBefore);
 		m_bufferBarriersBefore = std::move(b.m_bufferBarriersBefore);
 		m_bufferBarriersBefore = std::move(b.m_bufferBarriersBefore);
 		m_asBarriersBefore = std::move(b.m_asBarriersBefore);
 		m_asBarriersBefore = std::move(b.m_asBarriersBefore);
-		m_drawsToPresentImage = b.m_drawsToPresentImage;
 
 
 		return *this;
 		return *this;
 	}
 	}
@@ -199,95 +209,6 @@ public:
 	}
 	}
 };
 };
 
 
-void FramebufferDescription::bake()
-{
-	m_hash = 0;
-	ANKI_ASSERT(m_colorAttachmentCount > 0 || !!m_depthStencilAttachment.m_aspect);
-
-	// First the depth attachments
-	if(m_colorAttachmentCount)
-	{
-		ANKI_BEGIN_PACKED_STRUCT
-		struct ColorAttachment
-		{
-			TextureSurfaceInfo m_surf;
-			U32 m_loadOp;
-			U32 m_storeOp;
-			Array<U32, 4> m_clearColor;
-		};
-		ANKI_END_PACKED_STRUCT
-		static_assert(sizeof(ColorAttachment) == 4 * (4 + 1 + 1 + 4), "Wrong size");
-
-		Array<ColorAttachment, kMaxColorRenderTargets> colorAttachments;
-		for(U i = 0; i < m_colorAttachmentCount; ++i)
-		{
-			const FramebufferDescriptionAttachment& inAtt = m_colorAttachments[i];
-			colorAttachments[i].m_surf = inAtt.m_surface;
-			colorAttachments[i].m_loadOp = static_cast<U32>(inAtt.m_loadOperation);
-			colorAttachments[i].m_storeOp = static_cast<U32>(inAtt.m_storeOperation);
-			memcpy(&colorAttachments[i].m_clearColor[0], &inAtt.m_clearValue.m_coloru[0], sizeof(U32) * 4);
-		}
-
-		m_hash = computeHash(&colorAttachments[0], sizeof(ColorAttachment) * m_colorAttachmentCount);
-	}
-
-	// DS attachment
-	if(!!m_depthStencilAttachment.m_aspect)
-	{
-		ANKI_BEGIN_PACKED_STRUCT
-		class DSAttachment
-		{
-		public:
-			TextureSurfaceInfo m_surf;
-			U32 m_loadOp;
-			U32 m_storeOp;
-			U32 m_stencilLoadOp;
-			U32 m_stencilStoreOp;
-			U32 m_aspect;
-			F32 m_depthClear;
-			I32 m_stencilClear;
-		} outAtt;
-		ANKI_END_PACKED_STRUCT
-
-		const FramebufferDescriptionAttachment& inAtt = m_depthStencilAttachment;
-		const Bool hasDepth = !!(inAtt.m_aspect & DepthStencilAspectBit::kDepth);
-		const Bool hasStencil = !!(inAtt.m_aspect & DepthStencilAspectBit::kStencil);
-
-		outAtt.m_surf = inAtt.m_surface;
-		outAtt.m_loadOp = (hasDepth) ? static_cast<U32>(inAtt.m_loadOperation) : 0;
-		outAtt.m_storeOp = (hasDepth) ? static_cast<U32>(inAtt.m_storeOperation) : 0;
-		outAtt.m_stencilLoadOp = (hasStencil) ? static_cast<U32>(inAtt.m_stencilLoadOperation) : 0;
-		outAtt.m_stencilStoreOp = (hasStencil) ? static_cast<U32>(inAtt.m_stencilStoreOperation) : 0;
-		outAtt.m_aspect = static_cast<U32>(inAtt.m_aspect);
-		outAtt.m_depthClear = (hasDepth) ? inAtt.m_clearValue.m_depthStencil.m_depth : 0.0f;
-		outAtt.m_stencilClear = (hasStencil) ? inAtt.m_clearValue.m_depthStencil.m_stencil : 0;
-
-		m_hash = (m_hash != 0) ? appendHash(&outAtt, sizeof(outAtt), m_hash) : computeHash(&outAtt, sizeof(outAtt));
-	}
-
-	// SRI
-	if(m_shadingRateAttachmentTexelWidth > 0 && m_shadingRateAttachmentTexelHeight > 0)
-	{
-		ANKI_BEGIN_PACKED_STRUCT
-		class SriToHash
-		{
-		public:
-			U32 m_sriTexelWidth;
-			U32 m_sriTexelHeight;
-			TextureSurfaceInfo m_surface;
-		} sriToHash;
-		ANKI_END_PACKED_STRUCT
-
-		sriToHash.m_sriTexelWidth = m_shadingRateAttachmentTexelWidth;
-		sriToHash.m_sriTexelHeight = m_shadingRateAttachmentTexelHeight;
-		sriToHash.m_surface = m_shadingRateAttachmentSurface;
-
-		m_hash = (m_hash != 0) ? appendHash(&sriToHash, sizeof(sriToHash), m_hash) : computeHash(&sriToHash, sizeof(sriToHash));
-	}
-
-	ANKI_ASSERT(m_hash != 0 && m_hash != 1);
-}
-
 RenderGraph::RenderGraph(CString name)
 RenderGraph::RenderGraph(CString name)
 	: GrObject(kClassType, name)
 	: GrObject(kClassType, name)
 {
 {
@@ -370,7 +291,7 @@ void RenderGraph::reset()
 
 
 	for(Pass& p : m_ctx->m_passes)
 	for(Pass& p : m_ctx->m_passes)
 	{
 	{
-		p.m_framebuffer.reset(nullptr);
+		p.m_beginRenderpassInfo.m_refs.fill(TextureViewPtr(nullptr));
 		p.m_callback.destroy();
 		p.m_callback.destroy();
 		p.m_name.destroy();
 		p.m_name.destroy();
 	}
 	}
@@ -423,106 +344,6 @@ TexturePtr RenderGraph::getOrCreateRenderTarget(const TextureInitInfo& initInf,
 	return tex;
 	return tex;
 }
 }
 
 
-FramebufferPtr RenderGraph::getOrCreateFramebuffer(const FramebufferDescription& fbDescr, const RenderTargetHandle* rtHandles,
-												   Bool& drawsToPresentable)
-{
-	ANKI_ASSERT(rtHandles);
-	U64 hash = fbDescr.m_hash;
-	ANKI_ASSERT(hash > 0);
-
-	drawsToPresentable = false;
-
-	// Create a hash that includes the render targets
-	Array<U64, kMaxColorRenderTargets + 2> uuids;
-	U count = 0;
-	for(U i = 0; i < fbDescr.m_colorAttachmentCount; ++i)
-	{
-		uuids[count++] = m_ctx->m_rts[rtHandles[i].m_idx].m_texture->getUuid();
-
-		if(!!(m_ctx->m_rts[rtHandles[i].m_idx].m_texture->getTextureUsage() & TextureUsageBit::kPresent))
-		{
-			drawsToPresentable = true;
-		}
-	}
-
-	if(!!fbDescr.m_depthStencilAttachment.m_aspect)
-	{
-		uuids[count++] = m_ctx->m_rts[rtHandles[kMaxColorRenderTargets].m_idx].m_texture->getUuid();
-	}
-
-	if(fbDescr.m_shadingRateAttachmentTexelWidth > 0)
-	{
-		uuids[count++] = m_ctx->m_rts[rtHandles[kMaxColorRenderTargets + 1].m_idx].m_texture->getUuid();
-	}
-
-	hash = appendHash(&uuids[0], sizeof(U64) * count, hash);
-
-	FramebufferPtr fb;
-	auto it = m_fbCache.find(hash);
-	if(it != m_fbCache.getEnd())
-	{
-		fb = *it;
-	}
-	else
-	{
-		// Create a complete fb init info
-		FramebufferInitInfo fbInit("RenderGraph FB");
-		fbInit.m_colorAttachmentCount = fbDescr.m_colorAttachmentCount;
-		for(U i = 0; i < fbInit.m_colorAttachmentCount; ++i)
-		{
-			FramebufferAttachmentInfo& outAtt = fbInit.m_colorAttachments[i];
-			const FramebufferDescriptionAttachment& inAtt = fbDescr.m_colorAttachments[i];
-
-			outAtt.m_clearValue = inAtt.m_clearValue;
-			outAtt.m_loadOperation = inAtt.m_loadOperation;
-			outAtt.m_storeOperation = inAtt.m_storeOperation;
-
-			// Create texture view
-			const TextureViewInitInfo viewInit(m_ctx->m_rts[rtHandles[i].m_idx].m_texture.get(), TextureSubresourceInfo(inAtt.m_surface),
-											   "RenderGraph");
-			TextureViewPtr view = GrManager::getSingleton().newTextureView(viewInit);
-
-			outAtt.m_textureView = std::move(view);
-		}
-
-		if(!!fbDescr.m_depthStencilAttachment.m_aspect)
-		{
-			FramebufferAttachmentInfo& outAtt = fbInit.m_depthStencilAttachment;
-			const FramebufferDescriptionAttachment& inAtt = fbDescr.m_depthStencilAttachment;
-
-			outAtt.m_clearValue = inAtt.m_clearValue;
-			outAtt.m_loadOperation = inAtt.m_loadOperation;
-			outAtt.m_storeOperation = inAtt.m_storeOperation;
-			outAtt.m_stencilLoadOperation = inAtt.m_stencilLoadOperation;
-			outAtt.m_stencilStoreOperation = inAtt.m_stencilStoreOperation;
-
-			// Create texture view
-			const TextureViewInitInfo viewInit(m_ctx->m_rts[rtHandles[kMaxColorRenderTargets].m_idx].m_texture.get(),
-											   TextureSubresourceInfo(inAtt.m_surface, inAtt.m_aspect), "RenderGraph");
-			TextureViewPtr view = GrManager::getSingleton().newTextureView(viewInit);
-
-			outAtt.m_textureView = std::move(view);
-		}
-
-		if(fbDescr.m_shadingRateAttachmentTexelWidth > 0)
-		{
-			const TextureViewInitInfo viewInit(m_ctx->m_rts[rtHandles[kMaxColorRenderTargets + 1].m_idx].m_texture.get(),
-											   fbDescr.m_shadingRateAttachmentSurface, "RenderGraph SRI");
-			TextureViewPtr view = GrManager::getSingleton().newTextureView(viewInit);
-
-			fbInit.m_shadingRateImage.m_texelWidth = fbDescr.m_shadingRateAttachmentTexelWidth;
-			fbInit.m_shadingRateImage.m_texelHeight = fbDescr.m_shadingRateAttachmentTexelHeight;
-			fbInit.m_shadingRateImage.m_textureView = std::move(view);
-		}
-
-		// Create
-		fb = GrManager::getSingleton().newFramebuffer(fbInit);
-		m_fbCache.emplace(hash, fb);
-	}
-
-	return fb;
-}
-
 Bool RenderGraph::overlappingTextureSubresource(const TextureSubresourceInfo& suba, const TextureSubresourceInfo& subb)
 Bool RenderGraph::overlappingTextureSubresource(const TextureSubresourceInfo& suba, const TextureSubresourceInfo& subb)
 {
 {
 #define ANKI_OVERLAPPING(first, count) ((suba.first < subb.first + subb.count) && (subb.first < suba.first + suba.count))
 #define ANKI_OVERLAPPING(first, count) ((suba.first < subb.first + subb.count) && (subb.first < suba.first + suba.count))
@@ -807,21 +628,6 @@ void RenderGraph::initRenderPassesAndSetDeps(const RenderGraphDescription& descr
 			memcpy(&inf, &inDep.m_texture, sizeof(inf));
 			memcpy(&inf, &inDep.m_texture, sizeof(inf));
 		}
 		}
 
 
-		// Create command buffers and framebuffer
-		if(inPass.m_type == RenderPassDescriptionBase::Type::kGraphics)
-		{
-			const GraphicsRenderPassDescription& graphicsPass = static_cast<const GraphicsRenderPassDescription&>(inPass);
-
-			if(graphicsPass.hasFramebuffer())
-			{
-				Bool drawsToPresentable;
-				outPass.m_framebuffer = getOrCreateFramebuffer(graphicsPass.m_fbDescr, &graphicsPass.m_rtHandles[0], drawsToPresentable);
-
-				outPass.m_fbRenderArea = graphicsPass.m_fbRenderArea;
-				outPass.m_drawsToPresentable = drawsToPresentable;
-			}
-		}
-
 		// Set dependencies by checking all previous subpasses.
 		// Set dependencies by checking all previous subpasses.
 		U32 prevPassIdx = passIdx;
 		U32 prevPassIdx = passIdx;
 		while(prevPassIdx--)
 		while(prevPassIdx--)
@@ -846,7 +652,6 @@ void RenderGraph::initBatches()
 	while(passesAssignedToBatchCount < passCount)
 	while(passesAssignedToBatchCount < passCount)
 	{
 	{
 		Batch batch(m_ctx->m_as.getMemoryPool().m_pool);
 		Batch batch(m_ctx->m_as.getMemoryPool().m_pool);
-		batch.m_drawsToPresentImage = false;
 
 
 		for(U32 i = 0; i < passCount; ++i)
 		for(U32 i = 0; i < passCount; ++i)
 		{
 		{
@@ -855,9 +660,6 @@ void RenderGraph::initBatches()
 				// Add to the batch
 				// Add to the batch
 				++passesAssignedToBatchCount;
 				++passesAssignedToBatchCount;
 				batch.m_passIndices.emplaceBack(i);
 				batch.m_passIndices.emplaceBack(i);
-
-				// Will batch draw to the swapchain?
-				batch.m_drawsToPresentImage = batch.m_drawsToPresentImage || m_ctx->m_passes[i].m_drawsToPresentable;
 			}
 			}
 		}
 		}
 
 
@@ -880,34 +682,72 @@ void RenderGraph::initGraphicsPasses(const RenderGraphDescription& descr)
 
 
 	for(U32 passIdx = 0; passIdx < passCount; ++passIdx)
 	for(U32 passIdx = 0; passIdx < passCount; ++passIdx)
 	{
 	{
-		const RenderPassDescriptionBase& inPass = *descr.m_passes[passIdx];
+		const RenderPassDescriptionBase& baseInPass = *descr.m_passes[passIdx];
 		Pass& outPass = ctx.m_passes[passIdx];
 		Pass& outPass = ctx.m_passes[passIdx];
 
 
 		// Create command buffers and framebuffer
 		// Create command buffers and framebuffer
-		if(inPass.m_type == RenderPassDescriptionBase::Type::kGraphics)
+		if(baseInPass.m_type == RenderPassDescriptionBase::Type::kGraphics)
 		{
 		{
-			const GraphicsRenderPassDescription& graphicsPass = static_cast<const GraphicsRenderPassDescription&>(inPass);
+			const GraphicsRenderPassDescription& inPass = static_cast<const GraphicsRenderPassDescription&>(baseInPass);
 
 
-			if(graphicsPass.hasFramebuffer())
+			if(inPass.hasRenderpass())
 			{
 			{
+				outPass.m_beginRenderpassInfo.m_renderArea = inPass.m_rpassRenderArea;
+				outPass.m_beginRenderpassInfo.m_colorRtCount = inPass.m_colorRtCount;
+
 				// Init the usage bits
 				// Init the usage bits
-				TextureUsageBit usage;
-				for(U i = 0; i < graphicsPass.m_fbDescr.m_colorAttachmentCount; ++i)
+				for(U32 i = 0; i < inPass.m_colorRtCount; ++i)
 				{
 				{
-					getCrntUsage(graphicsPass.m_rtHandles[i], outPass.m_batchIdx,
-								 TextureSubresourceInfo(graphicsPass.m_fbDescr.m_colorAttachments[i].m_surface), usage);
+					const RenderTargetInfo& inAttachment = inPass.m_rts[i];
+					RenderTarget& outAttachment = outPass.m_beginRenderpassInfo.m_colorRts[i];
+
+					getCrntUsage(inAttachment.m_handle, outPass.m_batchIdx, TextureSubresourceInfo(inAttachment.m_surface), outAttachment.m_usage);
 
 
-					outPass.m_colorUsages[i] = usage;
+					const TextureViewInitInfo viewInit(m_ctx->m_rts[inAttachment.m_handle.m_idx].m_texture.get(),
+													   TextureSubresourceInfo(inAttachment.m_surface), "RenderGraph");
+					TextureViewPtr view = GrManager::getSingleton().newTextureView(viewInit);
+					outAttachment.m_view = view.get();
+					outPass.m_beginRenderpassInfo.m_refs[i] = view;
+
+					outAttachment.m_loadOperation = inAttachment.m_loadOperation;
+					outAttachment.m_storeOperation = inAttachment.m_storeOperation;
+					outAttachment.m_clearValue = inAttachment.m_clearValue;
+				}
+
+				if(!!inPass.m_rts[kMaxColorRenderTargets].m_aspect)
+				{
+					const RenderTargetInfo& inAttachment = inPass.m_rts[kMaxColorRenderTargets];
+					RenderTarget& outAttachment = outPass.m_beginRenderpassInfo.m_dsRt;
+
+					const TextureSubresourceInfo subresource = TextureSubresourceInfo(inAttachment.m_surface, inAttachment.m_aspect);
+					getCrntUsage(inAttachment.m_handle, outPass.m_batchIdx, subresource, outAttachment.m_usage);
+
+					const TextureViewInitInfo viewInit(m_ctx->m_rts[inAttachment.m_handle.m_idx].m_texture.get(),
+													   TextureSubresourceInfo(inAttachment.m_surface, inAttachment.m_aspect), "RenderGraph");
+					TextureViewPtr view = GrManager::getSingleton().newTextureView(viewInit);
+					outAttachment.m_view = view.get();
+					outPass.m_beginRenderpassInfo.m_refs[kMaxColorRenderTargets] = view;
+
+					outAttachment.m_loadOperation = inAttachment.m_loadOperation;
+					outAttachment.m_storeOperation = inAttachment.m_storeOperation;
+					outAttachment.m_stencilLoadOperation = inAttachment.m_stencilLoadOperation;
+					outAttachment.m_stencilStoreOperation = inAttachment.m_stencilStoreOperation;
+					outAttachment.m_clearValue = inAttachment.m_clearValue;
+					outAttachment.m_aspect = inAttachment.m_aspect;
 				}
 				}
 
 
-				if(!!graphicsPass.m_fbDescr.m_depthStencilAttachment.m_aspect)
+				if(inPass.m_vrsRtTexelSizeX > 0)
 				{
 				{
-					TextureSubresourceInfo subresource = TextureSubresourceInfo(graphicsPass.m_fbDescr.m_depthStencilAttachment.m_surface,
-																				graphicsPass.m_fbDescr.m_depthStencilAttachment.m_aspect);
+					const RenderTargetInfo& inAttachment = inPass.m_rts[kMaxColorRenderTargets + 1];
 
 
-					getCrntUsage(graphicsPass.m_rtHandles[kMaxColorRenderTargets], outPass.m_batchIdx, subresource, usage);
+					const TextureViewInitInfo viewInit(m_ctx->m_rts[inAttachment.m_handle.m_idx].m_texture.get(), inAttachment.m_surface,
+													   "RenderGraph SRI");
+					TextureViewPtr view = GrManager::getSingleton().newTextureView(viewInit);
+					outPass.m_beginRenderpassInfo.m_vrsRt = view.get();
+					outPass.m_beginRenderpassInfo.m_refs[kMaxColorRenderTargets + 1] = view;
 
 
-					outPass.m_dsUsage = usage;
+					outPass.m_beginRenderpassInfo.m_vrsTexelSizeX = inPass.m_vrsRtTexelSizeX;
+					outPass.m_beginRenderpassInfo.m_vrsTexelSizeY = inPass.m_vrsRtTexelSizeY;
 				}
 				}
 			}
 			}
 		}
 		}
@@ -926,7 +766,7 @@ void RenderGraph::iterateSurfsOrVolumes(const Texture& tex, const TextureSubreso
 				// Compute surf or vol idx
 				// Compute surf or vol idx
 				const U32 faceCount = textureTypeIsCube(tex.getTextureType()) ? 6 : 1;
 				const U32 faceCount = textureTypeIsCube(tex.getTextureType()) ? 6 : 1;
 				const U32 idx = (faceCount * tex.getLayerCount()) * mip + faceCount * layer + face;
 				const U32 idx = (faceCount * tex.getLayerCount()) * mip + faceCount * layer + face;
-				const TextureSurfaceInfo surf(mip, 0, face, layer);
+				const TextureSurfaceInfo surf(mip, face, layer);
 
 
 				if(!func(idx, surf))
 				if(!func(idx, surf))
 				{
 				{
@@ -1156,8 +996,8 @@ void RenderGraph::minimizeSubchannelSwitches()
 		U32 computePasses = 0;
 		U32 computePasses = 0;
 
 
 		std::sort(batch.m_passIndices.getBegin(), batch.m_passIndices.getEnd(), [&](U32 a, U32 b) {
 		std::sort(batch.m_passIndices.getBegin(), batch.m_passIndices.getEnd(), [&](U32 a, U32 b) {
-			const Bool aIsCompute = !ctx.m_passes[a].m_framebuffer.isCreated();
-			const Bool bIsCompute = !ctx.m_passes[b].m_framebuffer.isCreated();
+			const Bool aIsCompute = !ctx.m_passes[a].m_beginRenderpassInfo.hasRenderpass();
+			const Bool bIsCompute = !ctx.m_passes[b].m_beginRenderpassInfo.hasRenderpass();
 
 
 			graphicsPasses += !aIsCompute + !bIsCompute;
 			graphicsPasses += !aIsCompute + !bIsCompute;
 			computePasses += aIsCompute + bIsCompute;
 			computePasses += aIsCompute + bIsCompute;
@@ -1197,8 +1037,8 @@ void RenderGraph::sortBatchPasses()
 	for(Batch& batch : ctx.m_batches)
 	for(Batch& batch : ctx.m_batches)
 	{
 	{
 		std::sort(batch.m_passIndices.getBegin(), batch.m_passIndices.getEnd(), [&](U32 a, U32 b) {
 		std::sort(batch.m_passIndices.getBegin(), batch.m_passIndices.getEnd(), [&](U32 a, U32 b) {
-			const Bool aIsCompute = !ctx.m_passes[a].m_framebuffer.isCreated();
-			const Bool bIsCompute = !ctx.m_passes[b].m_framebuffer.isCreated();
+			const Bool aIsCompute = !ctx.m_passes[a].m_beginRenderpassInfo.hasRenderpass();
+			const Bool bIsCompute = !ctx.m_passes[b].m_beginRenderpassInfo.hasRenderpass();
 
 
 			return aIsCompute < bIsCompute;
 			return aIsCompute < bIsCompute;
 		});
 		});
@@ -1375,15 +1215,19 @@ void RenderGraph::recordAndSubmitCommandBuffers(FencePtr* optionalFence)
 					// Call the passes
 					// Call the passes
 					for(U32 passIdx : batch.m_passIndices)
 					for(U32 passIdx : batch.m_passIndices)
 					{
 					{
-						const Pass& pass = m_ctx->m_passes[passIdx];
+						Pass& pass = m_ctx->m_passes[passIdx];
 
 
-						const Vec3 passColor = (pass.m_framebuffer) ? Vec3(0.0f, 1.0f, 0.0f) : Vec3(1.0f, 1.0f, 0.0f);
+						const Vec3 passColor = (pass.m_beginRenderpassInfo.hasRenderpass()) ? Vec3(0.0f, 1.0f, 0.0f) : Vec3(1.0f, 1.0f, 0.0f);
 						cmdb->pushDebugMarker(pass.m_name, passColor);
 						cmdb->pushDebugMarker(pass.m_name, passColor);
 
 
-						if(pass.m_framebuffer)
+						if(pass.m_beginRenderpassInfo.hasRenderpass())
 						{
 						{
-							cmdb->beginRenderPass(pass.m_framebuffer.get(), pass.m_colorUsages, pass.m_dsUsage, pass.m_fbRenderArea[0],
-												  pass.m_fbRenderArea[1], pass.m_fbRenderArea[2], pass.m_fbRenderArea[3]);
+							cmdb->beginRenderPass({pass.m_beginRenderpassInfo.m_colorRts.getBegin(), U32(pass.m_beginRenderpassInfo.m_colorRtCount)},
+												  pass.m_beginRenderpassInfo.m_dsRt.m_view ? &pass.m_beginRenderpassInfo.m_dsRt : nullptr,
+												  pass.m_beginRenderpassInfo.m_renderArea[0], pass.m_beginRenderpassInfo.m_renderArea[1],
+												  pass.m_beginRenderpassInfo.m_renderArea[2], pass.m_beginRenderpassInfo.m_renderArea[3],
+												  pass.m_beginRenderpassInfo.m_vrsRt, pass.m_beginRenderpassInfo.m_vrsTexelSizeX,
+												  pass.m_beginRenderpassInfo.m_vrsTexelSizeY);
 						}
 						}
 
 
 						{
 						{
@@ -1392,7 +1236,7 @@ void RenderGraph::recordAndSubmitCommandBuffers(FencePtr* optionalFence)
 							pass.m_callback(ctx);
 							pass.m_callback(ctx);
 						}
 						}
 
 
-						if(pass.m_framebuffer)
+						if(pass.m_beginRenderpassInfo.hasRenderpass())
 						{
 						{
 							cmdb->endRenderPass();
 							cmdb->endRenderPass();
 						}
 						}

+ 30 - 46
AnKi/Gr/RenderGraph.h

@@ -9,7 +9,6 @@
 #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/GrManager.h>
-#include <AnKi/Gr/Framebuffer.h>
 #include <AnKi/Gr/TimestampQuery.h>
 #include <AnKi/Gr/TimestampQuery.h>
 #include <AnKi/Gr/CommandBuffer.h>
 #include <AnKi/Gr/CommandBuffer.h>
 #include <AnKi/Gr/AccelerationStructure.h>
 #include <AnKi/Gr/AccelerationStructure.h>
@@ -375,46 +374,29 @@ protected:
 	void newDependency(const RenderPassDependency& dep);
 	void newDependency(const RenderPassDependency& dep);
 };
 };
 
 
-/// Framebuffer attachment info.
-class FramebufferDescriptionAttachment
+/// Renderpass attachment info. Used in GraphicsRenderPassDescription::setRenderpassInfo. It mirrors the RenderPass.
+/// @memberof GraphicsRenderPassDescription
+class RenderTargetInfo
 {
 {
 public:
 public:
+	RenderTargetHandle m_handle;
 	TextureSurfaceInfo m_surface;
 	TextureSurfaceInfo m_surface;
-	AttachmentLoadOperation m_loadOperation = AttachmentLoadOperation::kDontCare;
-	AttachmentStoreOperation m_storeOperation = AttachmentStoreOperation::kStore;
-	ClearValue m_clearValue;
-
-	AttachmentLoadOperation m_stencilLoadOperation = AttachmentLoadOperation::kDontCare;
-	AttachmentStoreOperation m_stencilStoreOperation = AttachmentStoreOperation::kStore;
-
 	DepthStencilAspectBit m_aspect = DepthStencilAspectBit::kNone; ///< Relevant only for depth stencil textures.
 	DepthStencilAspectBit m_aspect = DepthStencilAspectBit::kNone; ///< Relevant only for depth stencil textures.
-};
 
 
-/// Describes a framebuffer.
-/// @memberof RenderGraphDescription
-class FramebufferDescription
-{
-	friend class GraphicsRenderPassDescription;
-	friend class RenderGraph;
+	RenderTargetLoadOperation m_loadOperation = RenderTargetLoadOperation::kDontCare;
+	RenderTargetStoreOperation m_storeOperation = RenderTargetStoreOperation::kStore;
 
 
-public:
-	Array<FramebufferDescriptionAttachment, kMaxColorRenderTargets> m_colorAttachments;
-	U32 m_colorAttachmentCount = 0;
-	FramebufferDescriptionAttachment m_depthStencilAttachment;
-	U32 m_shadingRateAttachmentTexelWidth = 0;
-	U32 m_shadingRateAttachmentTexelHeight = 0;
-	TextureSurfaceInfo m_shadingRateAttachmentSurface;
+	RenderTargetLoadOperation m_stencilLoadOperation = RenderTargetLoadOperation::kDontCare;
+	RenderTargetStoreOperation m_stencilStoreOperation = RenderTargetStoreOperation::kStore;
 
 
-	/// Calculate the hash for the framebuffer.
-	void bake();
+	ClearValue m_clearValue;
+
+	RenderTargetInfo() = default;
 
 
-	Bool isBacked() const
+	RenderTargetInfo(RenderTargetHandle handle)
+		: m_handle(handle)
 	{
 	{
-		return m_hash != 0;
 	}
 	}
-
-private:
-	U64 m_hash = 0;
 };
 };
 
 
 /// A graphics render pass for RenderGraph.
 /// A graphics render pass for RenderGraph.
@@ -428,25 +410,30 @@ public:
 	GraphicsRenderPassDescription(RenderGraphDescription* descr, StackMemoryPool* pool)
 	GraphicsRenderPassDescription(RenderGraphDescription* descr, StackMemoryPool* pool)
 		: RenderPassDescriptionBase(Type::kGraphics, descr, pool)
 		: RenderPassDescriptionBase(Type::kGraphics, descr, pool)
 	{
 	{
-		memset(&m_rtHandles[0], 0xFF, sizeof(m_rtHandles));
 	}
 	}
 
 
-	void setFramebufferInfo(const FramebufferDescription& fbInfo, ConstWeakArray<RenderTargetHandle> colorRenderTargetHandles,
-							RenderTargetHandle depthStencilRenderTargetHandle = {}, RenderTargetHandle shadingRateRenderTargetHandle = {},
-							U32 minx = 0, U32 miny = 0, U32 maxx = kMaxU32, U32 maxy = kMaxU32);
+	void setRenderpassInfo(ConstWeakArray<RenderTargetInfo> colorRts, const RenderTargetInfo* depthStencilRt = nullptr, U32 minx = 0, U32 miny = 0,
+						   U32 width = kMaxU32, U32 height = kMaxU32, const RenderTargetHandle* vrsRt = nullptr, U8 vrsRtTexelSizeX = 0,
+						   U8 vrsRtTexelSizeY = 0);
 
 
-	void setFramebufferInfo(const FramebufferDescription& fbInfo, std::initializer_list<RenderTargetHandle> colorRenderTargetHandles,
-							RenderTargetHandle depthStencilRenderTargetHandle = {}, RenderTargetHandle shadingRateRenderTargetHandle = {},
-							U32 minx = 0, U32 miny = 0, U32 maxx = kMaxU32, U32 maxy = kMaxU32);
+	void setRenderpassInfo(std::initializer_list<RenderTargetInfo> colorRts, const RenderTargetInfo* depthStencilRt = nullptr, U32 minx = 0,
+						   U32 miny = 0, U32 width = kMaxU32, U32 height = kMaxU32, const RenderTargetHandle* vrsRt = nullptr, U8 vrsRtTexelSizeX = 0,
+						   U8 vrsRtTexelSizeY = 0)
+	{
+		ConstWeakArray<RenderTargetInfo> colorRtsArr(colorRts.begin(), U32(colorRts.size()));
+		setRenderpassInfo(colorRtsArr, depthStencilRt, minx, miny, width, height, vrsRt, vrsRtTexelSizeX, vrsRtTexelSizeY);
+	}
 
 
 private:
 private:
-	Array<RenderTargetHandle, kMaxColorRenderTargets + 2> m_rtHandles;
-	FramebufferDescription m_fbDescr;
-	Array<U32, 4> m_fbRenderArea = {};
+	Array<RenderTargetInfo, kMaxColorRenderTargets + 2> m_rts;
+	Array<U32, 4> m_rpassRenderArea = {};
+	U8 m_colorRtCount = 0;
+	U8 m_vrsRtTexelSizeX = 0;
+	U8 m_vrsRtTexelSizeY = 0;
 
 
-	Bool hasFramebuffer() const
+	Bool hasRenderpass() const
 	{
 	{
-		return m_fbDescr.m_hash != 0;
+		return m_rpassRenderArea[3] != 0;
 	}
 	}
 };
 };
 
 
@@ -593,7 +580,6 @@ public:
 /// The idea for the RenderGraph is to automate:
 /// The idea for the RenderGraph is to automate:
 /// - Synchronization (barriers, events etc) between passes.
 /// - Synchronization (barriers, events etc) between passes.
 /// - Command buffer creation .
 /// - Command buffer creation .
-/// - Framebuffer creation.
 /// - Render target creation (optional since textures can be imported as well).
 /// - Render target creation (optional since textures can be imported as well).
 ///
 ///
 /// It accepts a description of the frame's render passes (compute and graphics), compiles that description to calculate
 /// It accepts a description of the frame's render passes (compute and graphics), compiles that description to calculate
@@ -649,7 +635,6 @@ private:
 	};
 	};
 
 
 	GrHashMap<U64, RenderTargetCacheEntry> m_renderTargetCache; ///< Non-imported render targets.
 	GrHashMap<U64, RenderTargetCacheEntry> m_renderTargetCache; ///< Non-imported render targets.
-	GrHashMap<U64, FramebufferPtr> m_fbCache; ///< Framebuffer cache.
 	GrHashMap<U64, ImportedRenderTargetInfo> m_importedRenderTargets;
 	GrHashMap<U64, ImportedRenderTargetInfo> m_importedRenderTargets;
 
 
 	BakeContext* m_ctx = nullptr;
 	BakeContext* m_ctx = nullptr;
@@ -680,7 +665,6 @@ private:
 	void sortBatchPasses();
 	void sortBatchPasses();
 
 
 	TexturePtr getOrCreateRenderTarget(const TextureInitInfo& initInf, U64 hash);
 	TexturePtr getOrCreateRenderTarget(const TextureInitInfo& initInf, U64 hash);
-	FramebufferPtr getOrCreateFramebuffer(const FramebufferDescription& fbDescr, const RenderTargetHandle* rtHandles, Bool& drawsToPresentableTex);
 
 
 	/// Every N number of frames clean unused cached items.
 	/// Every N number of frames clean unused cached items.
 	void periodicCleanup();
 	void periodicCleanup();

+ 25 - 50
AnKi/Gr/RenderGraph.inl.h

@@ -186,66 +186,41 @@ inline void RenderPassDescriptionBase::newDependency(const RenderPassDependency&
 	}
 	}
 }
 }
 
 
-inline void GraphicsRenderPassDescription::setFramebufferInfo(const FramebufferDescription& fbInfo,
-															  std::initializer_list<RenderTargetHandle> colorRenderTargetHandles,
-															  RenderTargetHandle depthStencilRenderTargetHandle,
-															  RenderTargetHandle shadingRateRenderTargetHandle, U32 minx, U32 miny, U32 maxx,
-															  U32 maxy)
+inline void GraphicsRenderPassDescription::setRenderpassInfo(ConstWeakArray<RenderTargetInfo> colorRts, const RenderTargetInfo* depthStencilRt,
+															 U32 minx, U32 miny, U32 width, U32 height, const RenderTargetHandle* vrsRt,
+															 U8 vrsRtTexelSizeX, U8 vrsRtTexelSizeY)
 {
 {
-	Array<RenderTargetHandle, kMaxColorRenderTargets> rts;
-	U32 count = 0;
-	for(const RenderTargetHandle& h : colorRenderTargetHandles)
+	m_colorRtCount = U8(colorRts.getSize());
+	for(U32 i = 0; i < m_colorRtCount; ++i)
 	{
 	{
-		rts[count++] = h;
-	}
-	setFramebufferInfo(fbInfo, ConstWeakArray<RenderTargetHandle>(&rts[0], count), depthStencilRenderTargetHandle, shadingRateRenderTargetHandle,
-					   minx, miny, maxx, maxy);
-}
-
-inline void GraphicsRenderPassDescription::setFramebufferInfo(const FramebufferDescription& fbInfo,
-															  ConstWeakArray<RenderTargetHandle> colorRenderTargetHandles,
-															  RenderTargetHandle depthStencilRenderTargetHandle,
-															  RenderTargetHandle shadingRateRenderTargetHandle, U32 minx, U32 miny, U32 maxx,
-															  U32 maxy)
-{
-#if ANKI_ASSERTIONS_ENABLED
-	ANKI_ASSERT(fbInfo.isBacked() && "Forgot call GraphicsRenderPassFramebufferInfo::bake");
-	for(U32 i = 0; i < colorRenderTargetHandles.getSize(); ++i)
-	{
-		if(i >= fbInfo.m_colorAttachmentCount)
-		{
-			ANKI_ASSERT(!colorRenderTargetHandles[i].isValid());
-		}
-		else
-		{
-			ANKI_ASSERT(colorRenderTargetHandles[i].isValid());
-		}
+		m_rts[i].m_handle = colorRts[i].m_handle;
+		m_rts[i].m_surface = colorRts[i].m_surface;
+		m_rts[i].m_loadOperation = colorRts[i].m_loadOperation;
+		m_rts[i].m_storeOperation = colorRts[i].m_storeOperation;
+		m_rts[i].m_clearValue = colorRts[i].m_clearValue;
 	}
 	}
 
 
-	if(!fbInfo.m_depthStencilAttachment.m_aspect)
-	{
-		ANKI_ASSERT(!depthStencilRenderTargetHandle.isValid());
-	}
-	else
+	if(depthStencilRt)
 	{
 	{
-		ANKI_ASSERT(depthStencilRenderTargetHandle.isValid());
+		m_rts[kMaxColorRenderTargets].m_handle = depthStencilRt->m_handle;
+		m_rts[kMaxColorRenderTargets].m_surface = depthStencilRt->m_surface;
+		ANKI_ASSERT(!!depthStencilRt->m_aspect);
+		m_rts[kMaxColorRenderTargets].m_aspect = depthStencilRt->m_aspect;
+		m_rts[kMaxColorRenderTargets].m_loadOperation = depthStencilRt->m_loadOperation;
+		m_rts[kMaxColorRenderTargets].m_storeOperation = depthStencilRt->m_storeOperation;
+		m_rts[kMaxColorRenderTargets].m_stencilLoadOperation = depthStencilRt->m_stencilLoadOperation;
+		m_rts[kMaxColorRenderTargets].m_stencilStoreOperation = depthStencilRt->m_stencilStoreOperation;
+		m_rts[kMaxColorRenderTargets].m_clearValue = depthStencilRt->m_clearValue;
 	}
 	}
 
 
-	if(fbInfo.m_shadingRateAttachmentTexelWidth > 0 && fbInfo.m_shadingRateAttachmentTexelHeight > 0)
+	if(vrsRt)
 	{
 	{
-		ANKI_ASSERT(shadingRateRenderTargetHandle.isValid());
+		m_rts[kMaxColorRenderTargets + 1].m_handle = *vrsRt;
+		m_vrsRtTexelSizeX = vrsRtTexelSizeX;
+		m_vrsRtTexelSizeY = vrsRtTexelSizeY;
 	}
 	}
-	else
-	{
-		ANKI_ASSERT(!shadingRateRenderTargetHandle.isValid());
-	}
-#endif
 
 
-	m_fbDescr = fbInfo;
-	memcpy(m_rtHandles.getBegin(), colorRenderTargetHandles.getBegin(), colorRenderTargetHandles.getSizeInBytes());
-	m_rtHandles[kMaxColorRenderTargets] = depthStencilRenderTargetHandle;
-	m_rtHandles[kMaxColorRenderTargets + 1] = shadingRateRenderTargetHandle;
-	m_fbRenderArea = {minx, miny, maxx, maxy};
+	m_rpassRenderArea = {minx, miny, width, height};
 }
 }
 
 
 inline RenderGraphDescription::~RenderGraphDescription()
 inline RenderGraphDescription::~RenderGraphDescription()

+ 1 - 1
AnKi/Gr/Vulkan/VkBuffer.cpp

@@ -48,12 +48,12 @@ void* Buffer::map(PtrSize offset, PtrSize range, [[maybe_unused]] BufferMapAcces
 
 
 void Buffer::unmap()
 void Buffer::unmap()
 {
 {
+#if ANKI_ASSERTIONS_ENABLED
 	ANKI_VK_SELF(BufferImpl);
 	ANKI_VK_SELF(BufferImpl);
 
 
 	ANKI_ASSERT(self.isCreated());
 	ANKI_ASSERT(self.isCreated());
 	ANKI_ASSERT(self.m_mapped);
 	ANKI_ASSERT(self.m_mapped);
 
 
-#if ANKI_ASSERTIONS_ENABLED
 	self.m_mapped = false;
 	self.m_mapped = false;
 #endif
 #endif
 }
 }

+ 137 - 65
AnKi/Gr/Vulkan/VkCommandBuffer.cpp

@@ -383,97 +383,177 @@ void CommandBuffer::bindShaderProgram(ShaderProgram* prog)
 #endif
 #endif
 }
 }
 
 
-void CommandBuffer::beginRenderPass(Framebuffer* fb, const Array<TextureUsageBit, kMaxColorRenderTargets>& colorAttachmentUsages,
-									TextureUsageBit depthStencilAttachmentUsage, U32 minx, U32 miny, U32 width, U32 height)
+void CommandBuffer::beginRenderPass(ConstWeakArray<RenderTarget> colorRts, RenderTarget* depthStencilRt, U32 minx, U32 miny, U32 width, U32 height,
+									TextureView* vrsRt, U8 vrsRtTexelSizeX, U8 vrsRtTexelSizeY)
 {
 {
 	ANKI_VK_SELF(CommandBufferImpl);
 	ANKI_VK_SELF(CommandBufferImpl);
+
+	ANKI_ASSERT(!self.m_insideRenderpass);
+#if ANKI_ASSERTIONS_ENABLED
+	self.m_insideRenderpass = true;
+#endif
+
 	self.commandCommon();
 	self.commandCommon();
-	ANKI_ASSERT(!self.insideRenderPass());
 
 
-	FramebufferImpl& impl = static_cast<FramebufferImpl&>(*fb);
-	self.m_activeFb = fb;
+	Array<VkRenderingAttachmentInfo, kMaxColorRenderTargets> vkColorAttachments;
+	VkRenderingAttachmentInfo vkDepthAttachment;
+	VkRenderingAttachmentInfo vkStencilAttachment;
+	VkRenderingFragmentShadingRateAttachmentInfoKHR vkVrsAttachment;
+	VkRenderingInfo info = {};
+	Bool drawsToSwapchain = false;
+	U32 fbWidth = 0;
+	U32 fbHeight = 0;
+
+	Array<Format, kMaxColorRenderTargets> colorFormats = {};
+	Format dsFormat = Format::kNone;
+
+	// Do color targets
+	for(U32 i = 0; i < colorRts.getSize(); ++i)
+	{
+		ANKI_ASSERT(!colorRts[i].m_aspect);
+		const TextureViewImpl& view = static_cast<const TextureViewImpl&>(*colorRts[i].m_view);
+
+		vkColorAttachments[i] = {};
+		vkColorAttachments[i].sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR;
+		vkColorAttachments[i].imageView = view.getHandle();
+		vkColorAttachments[i].imageLayout = view.getTextureImpl().computeLayout(colorRts[i].m_usage, 0);
+		vkColorAttachments[i].loadOp = convertLoadOp(colorRts[i].m_loadOperation);
+		vkColorAttachments[i].storeOp = convertStoreOp(colorRts[i].m_storeOperation);
+		vkColorAttachments[i].clearValue.color.float32[0] = colorRts[i].m_clearValue.m_colorf[0];
+		vkColorAttachments[i].clearValue.color.float32[1] = colorRts[i].m_clearValue.m_colorf[1];
+		vkColorAttachments[i].clearValue.color.float32[2] = colorRts[i].m_clearValue.m_colorf[2];
+		vkColorAttachments[i].clearValue.color.float32[3] = colorRts[i].m_clearValue.m_colorf[3];
+
+		if(!!(view.getTextureImpl().getTextureUsage() & TextureUsageBit::kPresent))
+		{
+			drawsToSwapchain = true;
+		}
 
 
-	self.m_state.beginRenderPass(&impl);
+		ANKI_ASSERT(fbWidth == 0 || (fbWidth == view.getTextureImpl().getWidth() >> view.getSubresource().m_firstMipmap));
+		ANKI_ASSERT(fbHeight == 0 || (fbHeight == view.getTextureImpl().getHeight() >> view.getSubresource().m_firstMipmap));
+		fbWidth = view.getTextureImpl().getWidth() >> view.getSubresource().m_firstMipmap;
+		fbHeight = view.getTextureImpl().getHeight() >> view.getSubresource().m_firstMipmap;
 
 
-	VkRenderPassBeginInfo bi = {};
-	bi.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
-	bi.clearValueCount = impl.getAttachmentCount();
-	bi.pClearValues = impl.getClearValues();
-	bi.framebuffer = impl.getFramebufferHandle();
+		colorFormats[i] = view.getTextureImpl().getFormat();
+	}
 
 
-	// Calc the layouts
-	Array<VkImageLayout, kMaxColorRenderTargets> colAttLayouts;
-	for(U i = 0; i < impl.getColorAttachmentCount(); ++i)
+	if(colorRts.getSize())
 	{
 	{
-		const TextureViewImpl& view = static_cast<const TextureViewImpl&>(*impl.getColorAttachment(i));
-		colAttLayouts[i] = view.getTextureImpl().computeLayout(colorAttachmentUsages[i], 0);
+		info.colorAttachmentCount = colorRts.getSize();
+		info.pColorAttachments = vkColorAttachments.getBegin();
+
+		ANKI_ASSERT((!drawsToSwapchain || colorRts.getSize() == 1) && "Can't handle that");
 	}
 	}
 
 
-	VkImageLayout dsAttLayout = VK_IMAGE_LAYOUT_MAX_ENUM;
-	if(impl.hasDepthStencil())
+	// DS
+	if(depthStencilRt)
 	{
 	{
-		const TextureViewImpl& view = static_cast<const TextureViewImpl&>(*impl.getDepthStencilAttachment());
-		dsAttLayout = view.getTextureImpl().computeLayout(depthStencilAttachmentUsage, 0);
+		ANKI_ASSERT(!!depthStencilRt->m_aspect);
+		const TextureViewImpl& view = static_cast<const TextureViewImpl&>(*depthStencilRt->m_view);
+
+		if(!!(depthStencilRt->m_aspect & DepthStencilAspectBit::kDepth))
+		{
+			vkDepthAttachment = {};
+			vkDepthAttachment.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR;
+			vkDepthAttachment.imageView = view.getHandle();
+			vkDepthAttachment.imageLayout = view.getTextureImpl().computeLayout(depthStencilRt->m_usage, 0);
+			vkDepthAttachment.loadOp = convertLoadOp(depthStencilRt->m_loadOperation);
+			vkDepthAttachment.storeOp = convertStoreOp(depthStencilRt->m_storeOperation);
+			vkDepthAttachment.clearValue.depthStencil.depth = depthStencilRt->m_clearValue.m_depthStencil.m_depth;
+			vkDepthAttachment.clearValue.depthStencil.stencil = depthStencilRt->m_clearValue.m_depthStencil.m_stencil;
+
+			info.pDepthAttachment = &vkDepthAttachment;
+		}
+
+		if(!!(depthStencilRt->m_aspect & DepthStencilAspectBit::kStencil) && getFormatInfo(view.getTextureImpl().getFormat()).isStencil())
+		{
+			vkStencilAttachment = {};
+			vkStencilAttachment.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR;
+			vkStencilAttachment.imageView = view.getHandle();
+			vkStencilAttachment.imageLayout = view.getTextureImpl().computeLayout(depthStencilRt->m_usage, 0);
+			vkStencilAttachment.loadOp = convertLoadOp(depthStencilRt->m_stencilLoadOperation);
+			vkStencilAttachment.storeOp = convertStoreOp(depthStencilRt->m_stencilStoreOperation);
+			vkStencilAttachment.clearValue.depthStencil.depth = depthStencilRt->m_clearValue.m_depthStencil.m_depth;
+			vkStencilAttachment.clearValue.depthStencil.stencil = depthStencilRt->m_clearValue.m_depthStencil.m_stencil;
+
+			info.pStencilAttachment = &vkStencilAttachment;
+		}
+
+		ANKI_ASSERT(fbWidth == 0 || (fbWidth == view.getTextureImpl().getWidth() >> view.getSubresource().m_firstMipmap));
+		ANKI_ASSERT(fbHeight == 0 || (fbHeight == view.getTextureImpl().getHeight() >> view.getSubresource().m_firstMipmap));
+		fbWidth = view.getTextureImpl().getWidth() >> view.getSubresource().m_firstMipmap;
+		fbHeight = view.getTextureImpl().getHeight() >> view.getSubresource().m_firstMipmap;
+
+		dsFormat = view.getTextureImpl().getFormat();
 	}
 	}
 
 
-	VkImageLayout sriAttachmentLayout = VK_IMAGE_LAYOUT_MAX_ENUM;
-	if(impl.hasSri())
+	if(vrsRt)
 	{
 	{
+		vkVrsAttachment = {};
+		vkVrsAttachment.sType = VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR;
+		vkVrsAttachment.imageView = static_cast<const TextureViewImpl&>(*vrsRt).getHandle();
 		// Technically it's possible for SRI to be in other layout. Don't bother though
 		// Technically it's possible for SRI to be in other layout. Don't bother though
-		sriAttachmentLayout = VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR;
+		vkVrsAttachment.imageLayout = VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR;
+		vkVrsAttachment.shadingRateAttachmentTexelSize.width = vrsRtTexelSizeX;
+		vkVrsAttachment.shadingRateAttachmentTexelSize.height = vrsRtTexelSizeY;
+
+		appendPNextList(info, &vkVrsAttachment);
 	}
 	}
 
 
-	bi.renderPass = impl.getRenderPassHandle(colAttLayouts, dsAttLayout, sriAttachmentLayout);
+	info.sType = VK_STRUCTURE_TYPE_RENDERING_INFO;
+	info.layerCount = 1;
 
 
 	// Set the render area
 	// Set the render area
-	U32 fbWidth, fbHeight;
-	impl.getAttachmentsSize(fbWidth, fbHeight);
-
 	ANKI_ASSERT(minx < fbWidth && miny < fbHeight);
 	ANKI_ASSERT(minx < fbWidth && miny < fbHeight);
 
 
+	const Bool flipViewport = drawsToSwapchain;
 	const U32 maxx = min<U32>(minx + width, fbWidth);
 	const U32 maxx = min<U32>(minx + width, fbWidth);
 	const U32 maxy = min<U32>(miny + height, fbHeight);
 	const U32 maxy = min<U32>(miny + height, fbHeight);
 	width = maxx - minx;
 	width = maxx - minx;
 	height = maxy - miny;
 	height = maxy - miny;
 	ANKI_ASSERT(minx + width <= fbWidth && miny + height <= fbHeight);
 	ANKI_ASSERT(minx + width <= fbWidth && miny + height <= fbHeight);
 
 
-	const Bool flipvp = self.flipViewport();
-	bi.renderArea.offset.x = minx;
-	if(flipvp)
+	info.renderArea.offset.x = minx;
+	if(flipViewport)
 	{
 	{
 		ANKI_ASSERT(height <= fbHeight);
 		ANKI_ASSERT(height <= fbHeight);
 	}
 	}
-	bi.renderArea.offset.y = (flipvp) ? fbHeight - (miny + height) : miny;
-	bi.renderArea.extent.width = width;
-	bi.renderArea.extent.height = height;
+	info.renderArea.offset.y = (flipViewport) ? fbHeight - (miny + height) : miny;
+	info.renderArea.extent.width = width;
+	info.renderArea.extent.height = height;
 
 
-	VkSubpassBeginInfo subpassBeginInfo = {};
-	subpassBeginInfo.sType = VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO;
-	subpassBeginInfo.contents = VK_SUBPASS_CONTENTS_INLINE;
-
-	vkCmdBeginRenderPass2KHR(self.m_handle, &bi, &subpassBeginInfo);
+	// State bookkeeping
+	self.m_state.beginRenderPass({colorFormats.getBegin(), colorRts.getSize()}, dsFormat, flipViewport);
 
 
 	// Re-set the viewport and scissor because sometimes they are set clamped
 	// Re-set the viewport and scissor because sometimes they are set clamped
 	self.m_viewportDirty = true;
 	self.m_viewportDirty = true;
 	self.m_scissorDirty = true;
 	self.m_scissorDirty = true;
 
 
-	self.m_renderedToDefaultFb = self.m_renderedToDefaultFb || impl.hasPresentableTexture();
-	self.m_microCmdb->pushObjectRef(fb);
+	self.m_renderpassDrawsToDefaultFb = drawsToSwapchain;
+	if(drawsToSwapchain)
+	{
+		self.m_renderedToDefaultFb = true;
+	}
+
+	self.m_renderpassWidth = fbWidth;
+	self.m_renderpassHeight = fbHeight;
+
+	// Finaly
+	vkCmdBeginRenderingKHR(self.m_handle, &info);
 }
 }
 
 
 void CommandBuffer::endRenderPass()
 void CommandBuffer::endRenderPass()
 {
 {
 	ANKI_VK_SELF(CommandBufferImpl);
 	ANKI_VK_SELF(CommandBufferImpl);
-	self.commandCommon();
-	ANKI_ASSERT(self.insideRenderPass());
-
-	VkSubpassEndInfo subpassEndInfo = {};
-	subpassEndInfo.sType = VK_STRUCTURE_TYPE_SUBPASS_END_INFO;
 
 
-	vkCmdEndRenderPass2KHR(self.m_handle, &subpassEndInfo);
+	ANKI_ASSERT(self.m_insideRenderpass);
+#if ANKI_ASSERTIONS_ENABLED
+	self.m_insideRenderpass = false;
+#endif
 
 
-	self.m_activeFb = nullptr;
+	self.commandCommon();
 	self.m_state.endRenderPass();
 	self.m_state.endRenderPass();
+	vkCmdEndRenderingKHR(self.m_handle);
 }
 }
 
 
 void CommandBuffer::setVrsRate(VrsRate rate)
 void CommandBuffer::setVrsRate(VrsRate rate)
@@ -705,7 +785,7 @@ void CommandBuffer::generateMipmaps2d(TextureView* texView)
 		if(i > 0)
 		if(i > 0)
 		{
 		{
 			VkImageSubresourceRange range;
 			VkImageSubresourceRange range;
-			tex.computeVkImageSubresourceRange(TextureSubresourceInfo(TextureSurfaceInfo(i, 0, face, layer), aspect), range);
+			tex.computeVkImageSubresourceRange(TextureSubresourceInfo(TextureSurfaceInfo(i, face, layer), aspect), range);
 
 
 			self.setImageBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
 			self.setImageBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
 								 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, tex.m_imageHandle,
 								 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, tex.m_imageHandle,
@@ -715,7 +795,7 @@ void CommandBuffer::generateMipmaps2d(TextureView* texView)
 		// Transition destination
 		// Transition destination
 		{
 		{
 			VkImageSubresourceRange range;
 			VkImageSubresourceRange range;
-			tex.computeVkImageSubresourceRange(TextureSubresourceInfo(TextureSurfaceInfo(i + 1, 0, face, layer), aspect), range);
+			tex.computeVkImageSubresourceRange(TextureSubresourceInfo(TextureSurfaceInfo(i + 1, face, layer), aspect), range);
 
 
 			self.setImageBarrier(VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, VK_IMAGE_LAYOUT_UNDEFINED, VK_PIPELINE_STAGE_TRANSFER_BIT,
 			self.setImageBarrier(VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, VK_IMAGE_LAYOUT_UNDEFINED, VK_PIPELINE_STAGE_TRANSFER_BIT,
 								 VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, tex.m_imageHandle, range);
 								 VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, tex.m_imageHandle, range);
@@ -813,7 +893,7 @@ void CommandBuffer::copyBufferToTextureView(Buffer* buff, PtrSize offset, [[mayb
 	const Bool is3D = tex.getTextureType() == TextureType::k3D;
 	const Bool is3D = tex.getTextureType() == TextureType::k3D;
 	const VkImageAspectFlags aspect = convertImageAspect(view.getSubresource().m_depthStencilAspect);
 	const VkImageAspectFlags aspect = convertImageAspect(view.getSubresource().m_depthStencilAspect);
 
 
-	const TextureSurfaceInfo surf(view.getSubresource().m_firstMipmap, view.getSubresource().m_firstFace, 0, view.getSubresource().m_firstLayer);
+	const TextureSurfaceInfo surf(view.getSubresource().m_firstMipmap, view.getSubresource().m_firstFace, view.getSubresource().m_firstLayer);
 	const TextureVolumeInfo vol(view.getSubresource().m_firstMipmap);
 	const TextureVolumeInfo vol(view.getSubresource().m_firstMipmap);
 
 
 	// Compute the sizes of the mip
 	// Compute the sizes of the mip
@@ -852,7 +932,7 @@ void CommandBuffer::fillBuffer(Buffer* buff, PtrSize offset, PtrSize size, U32 v
 {
 {
 	ANKI_VK_SELF(CommandBufferImpl);
 	ANKI_VK_SELF(CommandBufferImpl);
 	self.commandCommon();
 	self.commandCommon();
-	ANKI_ASSERT(!self.insideRenderPass());
+	ANKI_ASSERT(!self.m_insideRenderpass);
 	const BufferImpl& impl = static_cast<const BufferImpl&>(*buff);
 	const BufferImpl& impl = static_cast<const BufferImpl&>(*buff);
 	ANKI_ASSERT(impl.usageValid(BufferUsageBit::kTransferDestination));
 	ANKI_ASSERT(impl.usageValid(BufferUsageBit::kTransferDestination));
 
 
@@ -872,7 +952,7 @@ void CommandBuffer::writeOcclusionQueriesResultToBuffer(ConstWeakArray<Occlusion
 	ANKI_VK_SELF(CommandBufferImpl);
 	ANKI_VK_SELF(CommandBufferImpl);
 	ANKI_ASSERT(queries.getSize() > 0);
 	ANKI_ASSERT(queries.getSize() > 0);
 	self.commandCommon();
 	self.commandCommon();
-	ANKI_ASSERT(!self.insideRenderPass());
+	ANKI_ASSERT(!self.m_insideRenderpass);
 
 
 	const BufferImpl& impl = static_cast<const BufferImpl&>(*buff);
 	const BufferImpl& impl = static_cast<const BufferImpl&>(*buff);
 	ANKI_ASSERT(impl.usageValid(BufferUsageBit::kTransferDestination));
 	ANKI_ASSERT(impl.usageValid(BufferUsageBit::kTransferDestination));
@@ -1459,7 +1539,7 @@ void CommandBufferImpl::drawcallCommon()
 	// Preconditions
 	// Preconditions
 	commandCommon();
 	commandCommon();
 	ANKI_ASSERT(m_graphicsProg);
 	ANKI_ASSERT(m_graphicsProg);
-	ANKI_ASSERT(insideRenderPass());
+	ANKI_ASSERT(m_insideRenderpass);
 	ANKI_ASSERT(m_graphicsProg->getReflectionInfo().m_pushConstantsSize == m_setPushConstantsSize && "Forgot to set pushConstants");
 	ANKI_ASSERT(m_graphicsProg->getReflectionInfo().m_pushConstantsSize == m_setPushConstantsSize && "Forgot to set pushConstants");
 
 
 	// Get or create ppline
 	// Get or create ppline
@@ -1489,12 +1569,8 @@ void CommandBufferImpl::drawcallCommon()
 	// Flush viewport
 	// Flush viewport
 	if(m_viewportDirty) [[unlikely]]
 	if(m_viewportDirty) [[unlikely]]
 	{
 	{
-		const Bool flipvp = flipViewport();
-
-		U32 fbWidth, fbHeight;
-		static_cast<const FramebufferImpl&>(*m_activeFb).getAttachmentsSize(fbWidth, fbHeight);
-
-		VkViewport vp = computeViewport(&m_viewport[0], fbWidth, fbHeight, flipvp);
+		const Bool flipvp = m_renderpassDrawsToDefaultFb;
+		VkViewport vp = computeViewport(&m_viewport[0], m_renderpassWidth, m_renderpassHeight, flipvp);
 
 
 		// Additional optimization
 		// Additional optimization
 		if(memcmp(&vp, &m_lastViewport, sizeof(vp)) != 0)
 		if(memcmp(&vp, &m_lastViewport, sizeof(vp)) != 0)
@@ -1509,12 +1585,8 @@ void CommandBufferImpl::drawcallCommon()
 	// Flush scissor
 	// Flush scissor
 	if(m_scissorDirty) [[unlikely]]
 	if(m_scissorDirty) [[unlikely]]
 	{
 	{
-		const Bool flipvp = flipViewport();
-
-		U32 fbWidth, fbHeight;
-		static_cast<const FramebufferImpl&>(*m_activeFb).getAttachmentsSize(fbWidth, fbHeight);
-
-		VkRect2D scissor = computeScissor(&m_scissor[0], fbWidth, fbHeight, flipvp);
+		const Bool flipvp = m_renderpassDrawsToDefaultFb;
+		VkRect2D scissor = computeScissor(&m_scissor[0], m_renderpassWidth, m_renderpassHeight, flipvp);
 
 
 		// Additional optimization
 		// Additional optimization
 		if(memcmp(&scissor, &m_lastScissor, sizeof(scissor)) != 0)
 		if(memcmp(&scissor, &m_lastScissor, sizeof(scissor)) != 0)

+ 4 - 12
AnKi/Gr/Vulkan/VkCommandBuffer.h

@@ -104,15 +104,17 @@ private:
 	Bool m_empty : 1 = true;
 	Bool m_empty : 1 = true;
 	Bool m_beganRecording : 1 = false;
 	Bool m_beganRecording : 1 = false;
 	Bool m_debugMarkers : 1 = false;
 	Bool m_debugMarkers : 1 = false;
+	Bool m_renderpassDrawsToDefaultFb : 1 = false;
+	U32 m_renderpassWidth = 0;
+	U32 m_renderpassHeight = 0;
 #if ANKI_ASSERTIONS_ENABLED
 #if ANKI_ASSERTIONS_ENABLED
 	U32 m_commandCount = 0;
 	U32 m_commandCount = 0;
 	U32 m_setPushConstantsSize = 0;
 	U32 m_setPushConstantsSize = 0;
 	U32 m_debugMarkersPushed = 0;
 	U32 m_debugMarkersPushed = 0;
 	Bool m_submitted = false;
 	Bool m_submitted = false;
+	Bool m_insideRenderpass = false;
 #endif
 #endif
 
 
-	Framebuffer* m_activeFb = nullptr;
-
 	PipelineStateTracker m_state;
 	PipelineStateTracker m_state;
 
 
 	Array<DSStateTracker, kMaxDescriptorSets> m_dsetState;
 	Array<DSStateTracker, kMaxDescriptorSets> m_dsetState;
@@ -162,21 +164,11 @@ private:
 
 
 	void dispatchCommon();
 	void dispatchCommon();
 
 
-	Bool insideRenderPass() const
-	{
-		return m_activeFb != nullptr;
-	}
-
 	void setImageBarrier(VkPipelineStageFlags srcStage, VkAccessFlags srcAccess, VkImageLayout prevLayout, VkPipelineStageFlags dstStage,
 	void setImageBarrier(VkPipelineStageFlags srcStage, VkAccessFlags srcAccess, VkImageLayout prevLayout, VkPipelineStageFlags dstStage,
 						 VkAccessFlags dstAccess, VkImageLayout newLayout, VkImage img, const VkImageSubresourceRange& range);
 						 VkAccessFlags dstAccess, VkImageLayout newLayout, VkImage img, const VkImageSubresourceRange& range);
 
 
 	void beginRecording();
 	void beginRecording();
 
 
-	Bool flipViewport() const
-	{
-		return static_cast<const FramebufferImpl&>(*m_activeFb).hasPresentableTexture();
-	}
-
 	static VkViewport computeViewport(U32* viewport, U32 fbWidth, U32 fbHeight, Bool flipvp)
 	static VkViewport computeViewport(U32* viewport, U32 fbWidth, U32 fbHeight, Bool flipvp)
 	{
 	{
 		const U32 minx = viewport[0];
 		const U32 minx = viewport[0];

+ 7 - 7
AnKi/Gr/Vulkan/VkCommon.cpp

@@ -229,19 +229,19 @@ VkBlendOp convertBlendOperation(BlendOperation ak)
 	return out;
 	return out;
 }
 }
 
 
-VkAttachmentLoadOp convertLoadOp(AttachmentLoadOperation ak)
+VkAttachmentLoadOp convertLoadOp(RenderTargetLoadOperation ak)
 {
 {
 	VkAttachmentLoadOp out = VK_ATTACHMENT_LOAD_OP_MAX_ENUM;
 	VkAttachmentLoadOp out = VK_ATTACHMENT_LOAD_OP_MAX_ENUM;
 
 
 	switch(ak)
 	switch(ak)
 	{
 	{
-	case AttachmentLoadOperation::kLoad:
+	case RenderTargetLoadOperation::kLoad:
 		out = VK_ATTACHMENT_LOAD_OP_LOAD;
 		out = VK_ATTACHMENT_LOAD_OP_LOAD;
 		break;
 		break;
-	case AttachmentLoadOperation::kClear:
+	case RenderTargetLoadOperation::kClear:
 		out = VK_ATTACHMENT_LOAD_OP_CLEAR;
 		out = VK_ATTACHMENT_LOAD_OP_CLEAR;
 		break;
 		break;
-	case AttachmentLoadOperation::kDontCare:
+	case RenderTargetLoadOperation::kDontCare:
 		out = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
 		out = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
 		break;
 		break;
 	default:
 	default:
@@ -251,16 +251,16 @@ VkAttachmentLoadOp convertLoadOp(AttachmentLoadOperation ak)
 	return out;
 	return out;
 }
 }
 
 
-VkAttachmentStoreOp convertStoreOp(AttachmentStoreOperation ak)
+VkAttachmentStoreOp convertStoreOp(RenderTargetStoreOperation ak)
 {
 {
 	VkAttachmentStoreOp out = VK_ATTACHMENT_STORE_OP_MAX_ENUM;
 	VkAttachmentStoreOp out = VK_ATTACHMENT_STORE_OP_MAX_ENUM;
 
 
 	switch(ak)
 	switch(ak)
 	{
 	{
-	case AttachmentStoreOperation::kStore:
+	case RenderTargetStoreOperation::kStore:
 		out = VK_ATTACHMENT_STORE_OP_STORE;
 		out = VK_ATTACHMENT_STORE_OP_STORE;
 		break;
 		break;
-	case AttachmentStoreOperation::kDontCare:
+	case RenderTargetStoreOperation::kDontCare:
 		out = VK_ATTACHMENT_STORE_OP_DONT_CARE;
 		out = VK_ATTACHMENT_STORE_OP_DONT_CARE;
 		break;
 		break;
 	default:
 	default:

+ 10 - 2
AnKi/Gr/Vulkan/VkCommon.h

@@ -83,6 +83,7 @@ enum class VulkanExtensions : U64
 	kEXT_mesh_shader = 1u << 31u,
 	kEXT_mesh_shader = 1u << 31u,
 	kEXT_host_query_reset = 1_U64 << 32_U64,
 	kEXT_host_query_reset = 1_U64 << 32_U64,
 	kKHR_fragment_shader_barycentric = 1_U64 << 33_U64,
 	kKHR_fragment_shader_barycentric = 1_U64 << 33_U64,
+	kKHR_dynamic_rendering = 1_U64 << 34_U64,
 };
 };
 ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(VulkanExtensions)
 ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(VulkanExtensions)
 
 
@@ -205,10 +206,10 @@ static_assert(!(BufferUsageBit::kAll & PrivateBufferUsageBit::kAllPrivate), "Upd
 }
 }
 
 
 /// Convert load op.
 /// Convert load op.
-[[nodiscard]] VkAttachmentLoadOp convertLoadOp(AttachmentLoadOperation ak);
+[[nodiscard]] VkAttachmentLoadOp convertLoadOp(RenderTargetLoadOperation ak);
 
 
 /// Convert store op.
 /// Convert store op.
-[[nodiscard]] VkAttachmentStoreOp convertStoreOp(AttachmentStoreOperation ak);
+[[nodiscard]] VkAttachmentStoreOp convertStoreOp(RenderTargetStoreOperation ak);
 
 
 /// Convert buffer usage bitmask.
 /// Convert buffer usage bitmask.
 [[nodiscard]] VkBufferUsageFlags convertBufferUsageBit(BufferUsageBit usageMask);
 [[nodiscard]] VkBufferUsageFlags convertBufferUsageBit(BufferUsageBit usageMask);
@@ -369,6 +370,13 @@ static_assert(!(BufferUsageBit::kAll & PrivateBufferUsageBit::kAllPrivate), "Upd
 
 
 	return out;
 	return out;
 }
 }
+
+template<typename TMain, typename TPnext>
+void appendPNextList(TMain& struc, TPnext* pNext)
+{
+	pNext->pNext = const_cast<void*>(struc.pNext);
+	struc.pNext = pNext;
+}
 /// @}
 /// @}
 
 
 } // end namespace anki
 } // end namespace anki

+ 0 - 390
AnKi/Gr/Vulkan/VkFramebuffer.cpp

@@ -1,390 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#include <AnKi/Gr/Vulkan/VkFramebuffer.h>
-#include <AnKi/Gr/Vulkan/VkGrManager.h>
-
-namespace anki {
-
-Framebuffer* Framebuffer::newInstance(const FramebufferInitInfo& init)
-{
-	FramebufferImpl* impl = anki::newInstance<FramebufferImpl>(GrMemoryPool::getSingleton(), init.getName());
-	const Error err = impl->init(init);
-	if(err)
-	{
-		deleteInstance(GrMemoryPool::getSingleton(), impl);
-		impl = nullptr;
-	}
-	return impl;
-}
-
-FramebufferImpl::~FramebufferImpl()
-{
-	if(m_fbHandle)
-	{
-		vkDestroyFramebuffer(getVkDevice(), m_fbHandle, nullptr);
-	}
-
-	for(auto it : m_renderpassHandles)
-	{
-		VkRenderPass rpass = it;
-		ANKI_ASSERT(rpass);
-		vkDestroyRenderPass(getVkDevice(), rpass, nullptr);
-	}
-
-	if(m_compatibleRenderpassHandle)
-	{
-		vkDestroyRenderPass(getVkDevice(), m_compatibleRenderpassHandle, nullptr);
-	}
-}
-
-Error FramebufferImpl::init(const FramebufferInitInfo& init)
-{
-	ANKI_ASSERT(init.isValid());
-
-	// Init common
-	for(U32 i = 0; i < init.m_colorAttachmentCount; ++i)
-	{
-		m_colorAttachmentMask.set(i);
-		m_colorAttCount = U8(i + 1);
-	}
-
-	if(init.m_depthStencilAttachment.m_textureView)
-	{
-		m_aspect = init.m_depthStencilAttachment.m_textureView->getSubresource().m_depthStencilAspect;
-	}
-
-	m_hasSri = init.m_shadingRateImage.m_textureView.isCreated();
-
-	initClearValues(init);
-
-	// Create a renderpass.
-	initRpassCreateInfo(init);
-	ANKI_VK_CHECK(vkCreateRenderPass2KHR(getVkDevice(), &m_rpassCi, nullptr, &m_compatibleRenderpassHandle));
-	getGrManagerImpl().trySetVulkanHandleName(init.getName(), VK_OBJECT_TYPE_RENDER_PASS, m_compatibleRenderpassHandle);
-
-	// Create the FB
-	ANKI_CHECK(initFbs(init));
-
-	return Error::kNone;
-}
-
-void FramebufferImpl::initClearValues(const FramebufferInitInfo& init)
-{
-	for(U i = 0; i < m_colorAttCount; ++i)
-	{
-		if(init.m_colorAttachments[i].m_loadOperation == AttachmentLoadOperation::kClear)
-		{
-			F32* col = &m_clearVals[i].color.float32[0];
-			col[0] = init.m_colorAttachments[i].m_clearValue.m_colorf[0];
-			col[1] = init.m_colorAttachments[i].m_clearValue.m_colorf[1];
-			col[2] = init.m_colorAttachments[i].m_clearValue.m_colorf[2];
-			col[3] = init.m_colorAttachments[i].m_clearValue.m_colorf[3];
-		}
-		else
-		{
-			m_clearVals[i] = {};
-		}
-	}
-
-	if(hasDepthStencil())
-	{
-		if(init.m_depthStencilAttachment.m_loadOperation == AttachmentLoadOperation::kClear
-		   || init.m_depthStencilAttachment.m_stencilLoadOperation == AttachmentLoadOperation::kClear)
-		{
-			m_clearVals[m_colorAttCount].depthStencil.depth = init.m_depthStencilAttachment.m_clearValue.m_depthStencil.m_depth;
-
-			m_clearVals[m_colorAttCount].depthStencil.stencil = init.m_depthStencilAttachment.m_clearValue.m_depthStencil.m_stencil;
-		}
-		else
-		{
-			m_clearVals[m_colorAttCount] = {};
-		}
-	}
-
-	// Put something for SRI. Value doesn't matter
-	if(hasSri())
-	{
-		m_clearVals[m_colorAttCount + hasDepthStencil()] = {};
-	}
-}
-
-Error FramebufferImpl::initFbs(const FramebufferInitInfo& init)
-{
-	VkFramebufferCreateInfo ci = {};
-	ci.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
-	ci.renderPass = m_compatibleRenderpassHandle;
-	ci.attachmentCount = getTotalAttachmentCount();
-	ci.layers = 1;
-
-	Array<VkImageView, kMaxAttachments> imgViews;
-	U count = 0;
-
-	for(U i = 0; i < init.m_colorAttachmentCount; ++i)
-	{
-		const FramebufferAttachmentInfo& att = init.m_colorAttachments[i];
-		const TextureViewImpl& view = static_cast<const TextureViewImpl&>(*att.m_textureView);
-		const TextureImpl& tex = view.getTextureImpl();
-		ANKI_ASSERT(tex.isSubresourceGoodForFramebufferAttachment(view.getSubresource()));
-
-		imgViews[count] = view.getHandle();
-
-		if(m_width == 0)
-		{
-			m_width = tex.getWidth() >> view.getSubresource().m_firstMipmap;
-			m_height = tex.getHeight() >> view.getSubresource().m_firstMipmap;
-		}
-
-		m_viewRefs.m_color[i] = att.m_textureView;
-
-		if(!!(tex.getTextureUsage() & TextureUsageBit::kPresent))
-		{
-			m_presentableTex = true;
-		}
-
-		++count;
-	}
-
-	if(hasDepthStencil())
-	{
-		const FramebufferAttachmentInfo& att = init.m_depthStencilAttachment;
-		const TextureViewImpl& view = static_cast<const TextureViewImpl&>(*att.m_textureView);
-		const TextureImpl& tex = view.getTextureImpl();
-		ANKI_ASSERT(tex.isSubresourceGoodForFramebufferAttachment(view.getSubresource()));
-
-		imgViews[count] = view.getHandle();
-
-		if(m_width == 0)
-		{
-			m_width = tex.getWidth() >> view.getSubresource().m_firstMipmap;
-			m_height = tex.getHeight() >> view.getSubresource().m_firstMipmap;
-		}
-
-		m_viewRefs.m_depthStencil = att.m_textureView;
-		++count;
-	}
-
-	if(hasSri())
-	{
-		const TextureViewImpl& view = static_cast<const TextureViewImpl&>(*init.m_shadingRateImage.m_textureView);
-		ANKI_ASSERT(view.getTextureImpl().usageValid(TextureUsageBit::kFramebufferShadingRate));
-		imgViews[count] = view.getHandle();
-		m_viewRefs.m_sri = init.m_shadingRateImage.m_textureView;
-		++count;
-	}
-
-	ci.width = m_width;
-	ci.height = m_height;
-
-	ci.pAttachments = &imgViews[0];
-	ANKI_ASSERT(count == ci.attachmentCount);
-
-	ANKI_VK_CHECK(vkCreateFramebuffer(getVkDevice(), &ci, nullptr, &m_fbHandle));
-	getGrManagerImpl().trySetVulkanHandleName(init.getName(), VK_OBJECT_TYPE_FRAMEBUFFER, m_fbHandle);
-
-	return Error::kNone;
-}
-
-void FramebufferImpl::setupAttachmentDescriptor(const FramebufferAttachmentInfo& att, VkAttachmentDescription2& desc, VkImageLayout layout) const
-{
-	desc = {};
-	desc.sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2;
-	desc.format = convertFormat(static_cast<const TextureViewImpl&>(*att.m_textureView).getTextureImpl().getFormat());
-	desc.samples = VK_SAMPLE_COUNT_1_BIT;
-	desc.loadOp = convertLoadOp(att.m_loadOperation);
-	desc.storeOp = convertStoreOp(att.m_storeOperation);
-	desc.stencilLoadOp = convertLoadOp(att.m_stencilLoadOperation);
-	desc.stencilStoreOp = convertStoreOp(att.m_stencilStoreOperation);
-	desc.initialLayout = layout;
-	desc.finalLayout = layout;
-}
-
-void FramebufferImpl::initRpassCreateInfo(const FramebufferInitInfo& init)
-{
-	// Setup attachments and references
-	for(U32 i = 0; i < init.m_colorAttachmentCount; ++i)
-	{
-		setupAttachmentDescriptor(init.m_colorAttachments[i], m_attachmentDescriptions[i], VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
-
-		VkAttachmentReference2& ref = m_references[i];
-		ref.sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2;
-		ref.attachment = i;
-		ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
-	}
-
-	if(hasDepthStencil())
-	{
-		setupAttachmentDescriptor(init.m_depthStencilAttachment, m_attachmentDescriptions[init.m_colorAttachmentCount],
-								  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
-
-		VkAttachmentReference2& ref = m_references[init.m_colorAttachmentCount];
-		ref.sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2;
-		ref.attachment = init.m_colorAttachmentCount;
-		ref.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
-	}
-
-	U32 sriAttachmentIdx = kMaxU32;
-	if(init.m_shadingRateImage.m_textureView)
-	{
-		ANKI_ASSERT(getGrManagerImpl().getDeviceCapabilities().m_vrs && "This requires VRS to be enabled");
-
-		sriAttachmentIdx = init.m_colorAttachmentCount + hasDepthStencil();
-
-		VkAttachmentDescription2& desc = m_attachmentDescriptions[sriAttachmentIdx];
-		desc = {};
-		desc.sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2;
-		desc.format = convertFormat(static_cast<const TextureViewImpl&>(*init.m_shadingRateImage.m_textureView).getTextureImpl().getFormat());
-		desc.samples = VK_SAMPLE_COUNT_1_BIT;
-		desc.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
-		desc.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
-		desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
-		desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
-		desc.initialLayout = VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR;
-		desc.finalLayout = VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR;
-
-		VkAttachmentReference2& ref = m_references[sriAttachmentIdx];
-		ref.sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2;
-		ref.attachment = sriAttachmentIdx;
-		ref.layout = VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR;
-	}
-
-	// Subpass
-	m_subpassDescr.sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2;
-	m_subpassDescr.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
-	m_subpassDescr.colorAttachmentCount = init.m_colorAttachmentCount;
-	m_subpassDescr.pColorAttachments = (init.m_colorAttachmentCount) ? &m_references[0] : nullptr;
-	m_subpassDescr.pDepthStencilAttachment = (hasDepthStencil()) ? &m_references[init.m_colorAttachmentCount] : nullptr;
-
-	if(init.m_shadingRateImage.m_textureView)
-	{
-		m_sriAttachmentInfo.sType = VK_STRUCTURE_TYPE_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR;
-		m_sriAttachmentInfo.shadingRateAttachmentTexelSize.width = init.m_shadingRateImage.m_texelWidth;
-		m_sriAttachmentInfo.shadingRateAttachmentTexelSize.height = init.m_shadingRateImage.m_texelHeight;
-		m_sriAttachmentInfo.pFragmentShadingRateAttachment = &m_references[sriAttachmentIdx];
-
-		m_subpassDescr.pNext = &m_sriAttachmentInfo;
-	}
-
-	// Setup the render pass
-	m_rpassCi.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2;
-	m_rpassCi.pAttachments = &m_attachmentDescriptions[0];
-	m_rpassCi.attachmentCount = getTotalAttachmentCount();
-	m_rpassCi.subpassCount = 1;
-	m_rpassCi.pSubpasses = &m_subpassDescr;
-}
-
-VkRenderPass FramebufferImpl::getRenderPassHandle(const Array<VkImageLayout, kMaxColorRenderTargets>& colorLayouts, VkImageLayout dsLayout,
-												  VkImageLayout shadingRateImageLayout)
-{
-	VkRenderPass out = VK_NULL_HANDLE;
-
-	// Create hash
-	Array<VkImageLayout, kMaxAttachments> allLayouts;
-	U allLayoutCount = 0;
-	for(U i = 0; i < m_colorAttCount; ++i)
-	{
-		ANKI_ASSERT(colorLayouts[i] != VK_IMAGE_LAYOUT_UNDEFINED);
-		allLayouts[allLayoutCount++] = colorLayouts[i];
-	}
-
-	if(hasDepthStencil())
-	{
-		ANKI_ASSERT(dsLayout != VK_IMAGE_LAYOUT_UNDEFINED);
-		allLayouts[allLayoutCount++] = dsLayout;
-	}
-
-	if(hasSri())
-	{
-		ANKI_ASSERT(shadingRateImageLayout != VK_IMAGE_LAYOUT_UNDEFINED);
-		allLayouts[allLayoutCount++] = shadingRateImageLayout;
-	}
-
-	const U64 hash = computeHash(&allLayouts[0], allLayoutCount * sizeof(allLayouts[0]));
-
-	// Try get it
-	{
-		RLockGuard<RWMutex> lock(m_renderpassHandlesMtx);
-		auto it = m_renderpassHandles.find(hash);
-		if(it != m_renderpassHandles.getEnd())
-		{
-			out = *it;
-		}
-	}
-
-	if(out == VK_NULL_HANDLE)
-	{
-		// Create it
-
-		WLockGuard<RWMutex> lock(m_renderpassHandlesMtx);
-
-		// Check again
-		auto it = m_renderpassHandles.find(hash);
-		if(it != m_renderpassHandles.getEnd())
-		{
-			out = *it;
-		}
-		else
-		{
-			VkRenderPassCreateInfo2 ci = m_rpassCi;
-			Array<VkAttachmentDescription2, kMaxAttachments> attachmentDescriptions = m_attachmentDescriptions;
-			Array<VkAttachmentReference2, kMaxAttachments> references = m_references;
-			VkSubpassDescription2 subpassDescr = m_subpassDescr;
-			VkFragmentShadingRateAttachmentInfoKHR sriAttachmentInfo = m_sriAttachmentInfo;
-
-			// Fix pointers
-			subpassDescr.pColorAttachments = &references[0];
-			ci.pAttachments = &attachmentDescriptions[0];
-			ci.pSubpasses = &subpassDescr;
-
-			for(U i = 0; i < subpassDescr.colorAttachmentCount; ++i)
-			{
-				const VkImageLayout lay = colorLayouts[i];
-				ANKI_ASSERT(lay != VK_IMAGE_LAYOUT_UNDEFINED);
-
-				attachmentDescriptions[i].initialLayout = lay;
-				attachmentDescriptions[i].finalLayout = lay;
-
-				references[i].layout = lay;
-			}
-
-			if(hasDepthStencil())
-			{
-				const U i = subpassDescr.colorAttachmentCount;
-				const VkImageLayout lay = dsLayout;
-				ANKI_ASSERT(lay != VK_IMAGE_LAYOUT_UNDEFINED);
-
-				attachmentDescriptions[i].initialLayout = lay;
-				attachmentDescriptions[i].finalLayout = lay;
-
-				references[i].layout = lay;
-				subpassDescr.pDepthStencilAttachment = &references[i];
-			}
-
-			if(hasSri())
-			{
-				const U i = subpassDescr.colorAttachmentCount + hasDepthStencil();
-				const VkImageLayout lay = shadingRateImageLayout;
-
-				attachmentDescriptions[i].initialLayout = lay;
-				attachmentDescriptions[i].finalLayout = lay;
-
-				references[i].layout = lay;
-
-				sriAttachmentInfo.pFragmentShadingRateAttachment = &references[i];
-				subpassDescr.pNext = &sriAttachmentInfo;
-			}
-
-			ANKI_VK_CHECKF(vkCreateRenderPass2KHR(getVkDevice(), &ci, nullptr, &out));
-			getGrManagerImpl().trySetVulkanHandleName(getName(), VK_OBJECT_TYPE_RENDER_PASS, out);
-
-			m_renderpassHandles.emplace(hash, out);
-		}
-	}
-
-	ANKI_ASSERT(out);
-	return out;
-}
-
-} // end namespace anki

+ 0 - 158
AnKi/Gr/Vulkan/VkFramebuffer.h

@@ -1,158 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#pragma once
-
-#include <AnKi/Gr/Framebuffer.h>
-#include <AnKi/Gr/Vulkan/VkSwapchainFactory.h>
-#include <AnKi/Util/HashMap.h>
-#include <AnKi/Util/BitSet.h>
-
-namespace anki {
-
-// Forward
-class FramebufferAttachmentInfo;
-
-/// @addtogroup vulkan
-/// @{
-
-/// Framebuffer implementation.
-class FramebufferImpl final : public Framebuffer
-{
-public:
-	FramebufferImpl(CString name)
-		: Framebuffer(name)
-	{
-	}
-
-	~FramebufferImpl();
-
-	Error init(const FramebufferInitInfo& init);
-
-	/// Good for pipeline creation.
-	VkRenderPass getCompatibleRenderPass() const
-	{
-		ANKI_ASSERT(m_compatibleRenderpassHandle);
-		return m_compatibleRenderpassHandle;
-	}
-
-	/// Use it for binding. It's thread-safe
-	VkRenderPass getRenderPassHandle(const Array<VkImageLayout, kMaxColorRenderTargets>& colorLayouts, VkImageLayout dsLayout,
-									 VkImageLayout shadingRateImageLayout);
-
-	VkFramebuffer getFramebufferHandle() const
-	{
-		ANKI_ASSERT(m_fbHandle);
-		return m_fbHandle;
-	}
-
-	void getAttachmentInfo(BitSet<kMaxColorRenderTargets, U8>& colorAttachments, Bool& depth, Bool& stencil) const
-	{
-		colorAttachments = m_colorAttachmentMask;
-		depth = !!(m_aspect & DepthStencilAspectBit::kDepth);
-		stencil = !!(m_aspect & DepthStencilAspectBit::kStencil);
-	}
-
-	U32 getColorAttachmentCount() const
-	{
-		return m_colorAttCount;
-	}
-
-	Bool hasDepthStencil() const
-	{
-		return !!m_aspect;
-	}
-
-	U32 getAttachmentCount() const
-	{
-		return getTotalAttachmentCount();
-	}
-
-	const TextureViewPtr& getColorAttachment(U att) const
-	{
-		return m_viewRefs.m_color[att];
-	}
-
-	const TextureViewPtr& getDepthStencilAttachment() const
-	{
-		return m_viewRefs.m_depthStencil;
-	}
-
-	const TextureViewPtr& getSriAttachment() const
-	{
-		return m_viewRefs.m_sri;
-	}
-
-	const VkClearValue* getClearValues() const
-	{
-		return &m_clearVals[0];
-	}
-
-	void getAttachmentsSize(U32& width, U32& height) const
-	{
-		ANKI_ASSERT(m_width != 0 && m_height != 0);
-		width = m_width;
-		height = m_height;
-	}
-
-	Bool hasPresentableTexture() const
-	{
-		return m_presentableTex;
-	}
-
-	Bool hasSri() const
-	{
-		return m_hasSri;
-	}
-
-private:
-	static constexpr U32 kMaxAttachments = kMaxColorRenderTargets + 2; ///< Color + depth/stencil + SRI
-
-	BitSet<kMaxColorRenderTargets, U8> m_colorAttachmentMask = {false};
-	DepthStencilAspectBit m_aspect = DepthStencilAspectBit::kNone;
-
-	U8 m_colorAttCount = 0;
-	Array<VkClearValue, kMaxAttachments> m_clearVals;
-
-	U32 m_width = 0;
-	U32 m_height = 0;
-	Bool m_presentableTex = false;
-	Bool m_hasSri = false;
-
-	class
-	{
-	public:
-		Array<TextureViewPtr, kMaxColorRenderTargets> m_color;
-		TextureViewPtr m_depthStencil;
-		TextureViewPtr m_sri;
-	} m_viewRefs;
-
-	// VK objects
-	VkRenderPass m_compatibleRenderpassHandle = VK_NULL_HANDLE; ///< Compatible renderpass. Good for pipeline creation.
-	GrHashMap<U64, VkRenderPass> m_renderpassHandles;
-	RWMutex m_renderpassHandlesMtx;
-	VkFramebuffer m_fbHandle = VK_NULL_HANDLE;
-
-	// RenderPass create info
-	VkRenderPassCreateInfo2 m_rpassCi = {};
-	Array<VkAttachmentDescription2, kMaxAttachments> m_attachmentDescriptions = {};
-	Array<VkAttachmentReference2, kMaxAttachments> m_references = {};
-	VkSubpassDescription2 m_subpassDescr = {};
-	VkFragmentShadingRateAttachmentInfoKHR m_sriAttachmentInfo = {};
-
-	// Methods
-	Error initFbs(const FramebufferInitInfo& init);
-	void initRpassCreateInfo(const FramebufferInitInfo& init);
-	void initClearValues(const FramebufferInitInfo& init);
-	void setupAttachmentDescriptor(const FramebufferAttachmentInfo& att, VkAttachmentDescription2& desc, VkImageLayout layout) const;
-
-	U32 getTotalAttachmentCount() const
-	{
-		return m_colorAttCount + hasDepthStencil() + hasSri();
-	}
-};
-/// @}
-
-} // end namespace anki

+ 45 - 30
AnKi/Gr/Vulkan/VkGrManager.cpp

@@ -14,7 +14,6 @@
 #include <AnKi/Gr/Vulkan/VkShader.h>
 #include <AnKi/Gr/Vulkan/VkShader.h>
 #include <AnKi/Gr/Vulkan/VkShaderProgram.h>
 #include <AnKi/Gr/Vulkan/VkShaderProgram.h>
 #include <AnKi/Gr/Vulkan/VkCommandBuffer.h>
 #include <AnKi/Gr/Vulkan/VkCommandBuffer.h>
-#include <AnKi/Gr/Vulkan/VkFramebuffer.h>
 #include <AnKi/Gr/Vulkan/VkOcclusionQuery.h>
 #include <AnKi/Gr/Vulkan/VkOcclusionQuery.h>
 #include <AnKi/Gr/Vulkan/VkTimestampQuery.h>
 #include <AnKi/Gr/Vulkan/VkTimestampQuery.h>
 #include <AnKi/Gr/Vulkan/VkPipelineQuery.h>
 #include <AnKi/Gr/Vulkan/VkPipelineQuery.h>
@@ -145,7 +144,6 @@ ANKI_NEW_GR_OBJECT(Sampler)
 ANKI_NEW_GR_OBJECT(Shader)
 ANKI_NEW_GR_OBJECT(Shader)
 ANKI_NEW_GR_OBJECT(ShaderProgram)
 ANKI_NEW_GR_OBJECT(ShaderProgram)
 ANKI_NEW_GR_OBJECT(CommandBuffer)
 ANKI_NEW_GR_OBJECT(CommandBuffer)
-ANKI_NEW_GR_OBJECT(Framebuffer)
 ANKI_NEW_GR_OBJECT_NO_INIT_INFO(OcclusionQuery)
 ANKI_NEW_GR_OBJECT_NO_INIT_INFO(OcclusionQuery)
 ANKI_NEW_GR_OBJECT_NO_INIT_INFO(TimestampQuery)
 ANKI_NEW_GR_OBJECT_NO_INIT_INFO(TimestampQuery)
 ANKI_NEW_GR_OBJECT(PipelineQuery)
 ANKI_NEW_GR_OBJECT(PipelineQuery)
@@ -995,6 +993,16 @@ Error GrManagerImpl::initDevice()
 				m_extensions |= VulkanExtensions::kKHR_fragment_shader_barycentric;
 				m_extensions |= VulkanExtensions::kKHR_fragment_shader_barycentric;
 				extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
 				extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
 			}
 			}
+			else if(extensionName == VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME)
+			{
+				m_extensions |= VulkanExtensions::kKHR_dynamic_rendering;
+				extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
+			}
+			else if(extensionName == VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME)
+			{
+				// Want it because of dynamic_rendering
+				extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
+			}
 		}
 		}
 
 
 		ANKI_VK_LOGI("Will enable the following device extensions:");
 		ANKI_VK_LOGI("Will enable the following device extensions:");
@@ -1082,8 +1090,7 @@ Error GrManagerImpl::initDevice()
 			return Error::kFunctionFailed;
 			return Error::kFunctionFailed;
 		}
 		}
 
 
-		descriptorIndexingFeatures.pNext = const_cast<void*>(ci.pNext);
-		ci.pNext = &descriptorIndexingFeatures;
+		appendPNextList(ci, &descriptorIndexingFeatures);
 	}
 	}
 
 
 	// Buffer address
 	// Buffer address
@@ -1100,8 +1107,7 @@ Error GrManagerImpl::initDevice()
 		deviceBufferFeatures.bufferDeviceAddressCaptureReplay = deviceBufferFeatures.bufferDeviceAddressCaptureReplay && g_debugMarkersCVar.get();
 		deviceBufferFeatures.bufferDeviceAddressCaptureReplay = deviceBufferFeatures.bufferDeviceAddressCaptureReplay && g_debugMarkersCVar.get();
 		deviceBufferFeatures.bufferDeviceAddressMultiDevice = false;
 		deviceBufferFeatures.bufferDeviceAddressMultiDevice = false;
 
 
-		deviceBufferFeatures.pNext = const_cast<void*>(ci.pNext);
-		ci.pNext = &deviceBufferFeatures;
+		appendPNextList(ci, &deviceBufferFeatures);
 	}
 	}
 
 
 	// Scalar block layout
 	// Scalar block layout
@@ -1122,8 +1128,7 @@ Error GrManagerImpl::initDevice()
 			return Error::kFunctionFailed;
 			return Error::kFunctionFailed;
 		}
 		}
 
 
-		scalarBlockLayoutFeatures.pNext = const_cast<void*>(ci.pNext);
-		ci.pNext = &scalarBlockLayoutFeatures;
+		appendPNextList(ci, &scalarBlockLayoutFeatures);
 	}
 	}
 
 
 	// Timeline semaphore
 	// Timeline semaphore
@@ -1144,8 +1149,7 @@ Error GrManagerImpl::initDevice()
 			return Error::kFunctionFailed;
 			return Error::kFunctionFailed;
 		}
 		}
 
 
-		timelineSemaphoreFeatures.pNext = const_cast<void*>(ci.pNext);
-		ci.pNext = &timelineSemaphoreFeatures;
+		appendPNextList(ci, &timelineSemaphoreFeatures);
 	}
 	}
 
 
 	// Set RT features
 	// Set RT features
@@ -1180,8 +1184,7 @@ Error GrManagerImpl::initDevice()
 		accelerationStructureFeatures.descriptorBindingAccelerationStructureUpdateAfterBind = false;
 		accelerationStructureFeatures.descriptorBindingAccelerationStructureUpdateAfterBind = false;
 
 
 		ANKI_ASSERT(accelerationStructureFeatures.pNext == nullptr);
 		ANKI_ASSERT(accelerationStructureFeatures.pNext == nullptr);
-		accelerationStructureFeatures.pNext = const_cast<void*>(ci.pNext);
-		ci.pNext = &rtPipelineFeatures;
+		appendPNextList(ci, &accelerationStructureFeatures);
 
 
 		// Get some more stuff
 		// Get some more stuff
 		VkPhysicalDeviceAccelerationStructurePropertiesKHR props = {};
 		VkPhysicalDeviceAccelerationStructurePropertiesKHR props = {};
@@ -1197,8 +1200,7 @@ Error GrManagerImpl::initDevice()
 		pplineExecutablePropertiesFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR;
 		pplineExecutablePropertiesFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR;
 		pplineExecutablePropertiesFeatures.pipelineExecutableInfo = true;
 		pplineExecutablePropertiesFeatures.pipelineExecutableInfo = true;
 
 
-		pplineExecutablePropertiesFeatures.pNext = const_cast<void*>(ci.pNext);
-		ci.pNext = &pplineExecutablePropertiesFeatures;
+		appendPNextList(ci, &pplineExecutablePropertiesFeatures);
 	}
 	}
 
 
 	// F16 I8
 	// F16 I8
@@ -1213,8 +1215,7 @@ Error GrManagerImpl::initDevice()
 		float16Int8Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR;
 		float16Int8Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR;
 		getPhysicalDevicaFeatures2(float16Int8Features);
 		getPhysicalDevicaFeatures2(float16Int8Features);
 
 
-		float16Int8Features.pNext = const_cast<void*>(ci.pNext);
-		ci.pNext = &float16Int8Features;
+		appendPNextList(ci, &float16Int8Features);
 	}
 	}
 
 
 	// 64bit atomics
 	// 64bit atomics
@@ -1231,8 +1232,7 @@ Error GrManagerImpl::initDevice()
 		atomicInt64Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR;
 		atomicInt64Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR;
 		getPhysicalDevicaFeatures2(atomicInt64Features);
 		getPhysicalDevicaFeatures2(atomicInt64Features);
 
 
-		atomicInt64Features.pNext = const_cast<void*>(ci.pNext);
-		ci.pNext = &atomicInt64Features;
+		appendPNextList(ci, &atomicInt64Features);
 	}
 	}
 
 
 	// VRS
 	// VRS
@@ -1285,8 +1285,7 @@ Error GrManagerImpl::initDevice()
 
 
 		if(m_capabilities.m_vrs)
 		if(m_capabilities.m_vrs)
 		{
 		{
-			fragmentShadingRateFeatures.pNext = const_cast<void*>(ci.pNext);
-			ci.pNext = &fragmentShadingRateFeatures;
+			appendPNextList(ci, &fragmentShadingRateFeatures);
 		}
 		}
 	}
 	}
 
 
@@ -1307,8 +1306,7 @@ Error GrManagerImpl::initDevice()
 
 
 		meshShadersFeatures.multiviewMeshShader = false;
 		meshShadersFeatures.multiviewMeshShader = false;
 		meshShadersFeatures.primitiveFragmentShadingRateMeshShader = false;
 		meshShadersFeatures.primitiveFragmentShadingRateMeshShader = false;
-		meshShadersFeatures.pNext = const_cast<void*>(ci.pNext);
-		ci.pNext = &meshShadersFeatures;
+		appendPNextList(ci, &meshShadersFeatures);
 
 
 		ANKI_VK_LOGI(VK_EXT_MESH_SHADER_EXTENSION_NAME " is supported and enabled");
 		ANKI_VK_LOGI(VK_EXT_MESH_SHADER_EXTENSION_NAME " is supported and enabled");
 	}
 	}
@@ -1330,8 +1328,7 @@ Error GrManagerImpl::initDevice()
 			return Error::kFunctionFailed;
 			return Error::kFunctionFailed;
 		}
 		}
 
 
-		hostQueryResetFeatures.pNext = const_cast<void*>(ci.pNext);
-		ci.pNext = &hostQueryResetFeatures;
+		appendPNextList(ci, &hostQueryResetFeatures);
 	}
 	}
 	else
 	else
 	{
 	{
@@ -1352,8 +1349,7 @@ Error GrManagerImpl::initDevice()
 			return Error::kFunctionFailed;
 			return Error::kFunctionFailed;
 		}
 		}
 
 
-		baryFeatures.pNext = const_cast<void*>(ci.pNext);
-		ci.pNext = &baryFeatures;
+		appendPNextList(ci, &baryFeatures);
 
 
 		m_capabilities.m_barycentrics = true;
 		m_capabilities.m_barycentrics = true;
 	}
 	}
@@ -1363,8 +1359,7 @@ Error GrManagerImpl::initDevice()
 	{
 	{
 		maintenance4Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES_KHR;
 		maintenance4Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES_KHR;
 		maintenance4Features.maintenance4 = true;
 		maintenance4Features.maintenance4 = true;
-		maintenance4Features.pNext = const_cast<void*>(ci.pNext);
-		ci.pNext = &maintenance4Features;
+		appendPNextList(ci, &maintenance4Features);
 	}
 	}
 
 
 	if(!(m_extensions & VulkanExtensions::kKHR_draw_indirect_count) || m_capabilities.m_maxDrawIndirectCount < kMaxU32)
 	if(!(m_extensions & VulkanExtensions::kKHR_draw_indirect_count) || m_capabilities.m_maxDrawIndirectCount < kMaxU32)
@@ -1373,8 +1368,6 @@ Error GrManagerImpl::initDevice()
 		return Error::kFunctionFailed;
 		return Error::kFunctionFailed;
 	}
 	}
 
 
-	ANKI_VK_CHECK(vkCreateDevice(m_physicalDevice, &ci, nullptr, &m_device));
-
 	if(!(m_extensions & VulkanExtensions::kKHR_spirv_1_4))
 	if(!(m_extensions & VulkanExtensions::kKHR_spirv_1_4))
 	{
 	{
 		ANKI_VK_LOGE(VK_KHR_SPIRV_1_4_EXTENSION_NAME " is not supported");
 		ANKI_VK_LOGE(VK_KHR_SPIRV_1_4_EXTENSION_NAME " is not supported");
@@ -1387,6 +1380,28 @@ Error GrManagerImpl::initDevice()
 		return Error::kFunctionFailed;
 		return Error::kFunctionFailed;
 	}
 	}
 
 
+	VkPhysicalDeviceDynamicRenderingFeatures dynRenderingFeatures = {};
+	if(!(m_extensions & VulkanExtensions::kKHR_dynamic_rendering))
+	{
+		ANKI_VK_LOGE(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME " is not supported");
+		return Error::kFunctionFailed;
+	}
+	else
+	{
+		dynRenderingFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES_KHR;
+		getPhysicalDevicaFeatures2(dynRenderingFeatures);
+
+		if(!dynRenderingFeatures.dynamicRendering)
+		{
+			ANKI_VK_LOGE("VkPhysicalDeviceDynamicRenderingFeatures::dynamicRendering is false");
+			return Error::kFunctionFailed;
+		}
+
+		appendPNextList(ci, &dynRenderingFeatures);
+	}
+
+	ANKI_VK_CHECK(vkCreateDevice(m_physicalDevice, &ci, nullptr, &m_device));
+
 	return Error::kNone;
 	return Error::kNone;
 }
 }
 
 

+ 47 - 33
AnKi/Gr/Vulkan/VkPipeline.cpp

@@ -20,8 +20,8 @@ void PipelineStateTracker::reset()
 	m_shaderColorAttachmentWritemask.unsetAll();
 	m_shaderColorAttachmentWritemask.unsetAll();
 	m_fbDepth = false;
 	m_fbDepth = false;
 	m_fbStencil = false;
 	m_fbStencil = false;
-	m_defaultFb = false;
-	m_fbColorAttachmentMask.unsetAll();
+	m_rendersToSwapchain = false;
+	m_fbColorAttachmentCount = 0;
 }
 }
 
 
 Bool PipelineStateTracker::updateHashes()
 Bool PipelineStateTracker::updateHashes()
@@ -36,14 +36,6 @@ Bool PipelineStateTracker::updateHashes()
 		m_hashes.m_prog = m_state.m_prog->getUuid();
 		m_hashes.m_prog = m_state.m_prog->getUuid();
 	}
 	}
 
 
-	// Rpass
-	if(m_dirty.m_rpass)
-	{
-		m_dirty.m_rpass = false;
-		stateDirty = true;
-		m_hashes.m_rpass = ptrToNumber(m_state.m_rpass);
-	}
-
 	// Vertex
 	// Vertex
 	if(m_dirty.m_attribs.getAnySet() || m_dirty.m_vertBindings.getAnySet())
 	if(m_dirty.m_attribs.getAnySet() || m_dirty.m_vertBindings.getAnySet())
 	{
 	{
@@ -114,9 +106,9 @@ Bool PipelineStateTracker::updateHashes()
 	}
 	}
 
 
 	// Color
 	// Color
-	if(!!m_fbColorAttachmentMask)
+	if(m_fbColorAttachmentCount)
 	{
 	{
-		ANKI_ASSERT((m_fbColorAttachmentMask == m_shaderColorAttachmentWritemask || !m_shaderColorAttachmentWritemask)
+		ANKI_ASSERT((m_fbColorAttachmentCount == m_shaderColorAttachmentWritemask.getSetBitCount() || !m_shaderColorAttachmentWritemask)
 					&& "Shader and FB should have same attachment mask or shader mask should be zero");
 					&& "Shader and FB should have same attachment mask or shader mask should be zero");
 
 
 		if(m_dirty.m_color)
 		if(m_dirty.m_color)
@@ -126,20 +118,25 @@ Bool PipelineStateTracker::updateHashes()
 			stateDirty = true;
 			stateDirty = true;
 		}
 		}
 
 
-		if(!!(m_dirty.m_colAttachments & m_fbColorAttachmentMask))
+		for(U32 i = 0; i < m_fbColorAttachmentCount; ++i)
 		{
 		{
-			for(U i = 0; i < kMaxColorRenderTargets; ++i)
+			if(m_dirty.m_colAttachments.get(i))
 			{
 			{
-				if(m_fbColorAttachmentMask.get(i) && m_dirty.m_colAttachments.get(i))
-				{
-					m_dirty.m_colAttachments.unset(i);
-					m_hashes.m_colAttachments[i] = computeHash(&m_state.m_color.m_attachments[i], sizeof(m_state.m_color.m_attachments[i]));
-					stateDirty = true;
-				}
+				m_dirty.m_colAttachments.unset(i);
+				m_hashes.m_colAttachments[i] = computeHash(&m_state.m_color.m_attachments[i], sizeof(m_state.m_color.m_attachments[i]));
+				stateDirty = true;
 			}
 			}
 		}
 		}
 	}
 	}
 
 
+	// Rpass
+	if(m_dirty.m_rpass)
+	{
+		m_dirty.m_rpass = false;
+		stateDirty = true;
+		m_hashes.m_rpass = computeHash(m_state.m_attachmentFormats.getBegin(), m_state.m_attachmentFormats.getSizeInBytes());
+	}
+
 	return stateDirty;
 	return stateDirty;
 }
 }
 
 
@@ -185,16 +182,13 @@ void PipelineStateTracker::updateSuperHash()
 	}
 	}
 
 
 	// Color
 	// Color
-	if(!!m_fbColorAttachmentMask)
+	if(m_fbColorAttachmentCount)
 	{
 	{
 		buff[count++] = m_hashes.m_color;
 		buff[count++] = m_hashes.m_color;
 
 
-		for(U i = 0; i < kMaxColorRenderTargets; ++i)
+		for(U i = 0; i < m_fbColorAttachmentCount; ++i)
 		{
 		{
-			if(m_fbColorAttachmentMask.get(i))
-			{
-				buff[count++] = m_hashes.m_colAttachments[i];
-			}
+			buff[count++] = m_hashes.m_colAttachments[i];
 		}
 		}
 	}
 	}
 
 
@@ -274,7 +268,7 @@ const VkGraphicsPipelineCreateInfo& PipelineStateTracker::updatePipelineCreateIn
 	rastCi.rasterizerDiscardEnable = false;
 	rastCi.rasterizerDiscardEnable = false;
 	rastCi.polygonMode = convertFillMode(m_state.m_rasterizer.m_fillMode);
 	rastCi.polygonMode = convertFillMode(m_state.m_rasterizer.m_fillMode);
 	rastCi.cullMode = convertCullMode(m_state.m_rasterizer.m_cullMode);
 	rastCi.cullMode = convertCullMode(m_state.m_rasterizer.m_cullMode);
-	rastCi.frontFace = (!m_defaultFb) ? VK_FRONT_FACE_CLOCKWISE : VK_FRONT_FACE_COUNTER_CLOCKWISE; // For viewport flip
+	rastCi.frontFace = (!m_rendersToSwapchain) ? VK_FRONT_FACE_CLOCKWISE : VK_FRONT_FACE_COUNTER_CLOCKWISE; // For viewport flip
 	rastCi.depthBiasEnable = m_state.m_rasterizer.m_depthBiasEnabled;
 	rastCi.depthBiasEnable = m_state.m_rasterizer.m_depthBiasEnabled;
 	rastCi.lineWidth = 1.0;
 	rastCi.lineWidth = 1.0;
 	ci.pRasterizationState = &rastCi;
 	ci.pRasterizationState = &rastCi;
@@ -286,8 +280,7 @@ const VkGraphicsPipelineCreateInfo& PipelineStateTracker::updatePipelineCreateIn
 		rastOrderCi.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_RASTERIZATION_ORDER_AMD;
 		rastOrderCi.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_RASTERIZATION_ORDER_AMD;
 		rastOrderCi.rasterizationOrder = convertRasterizationOrder(m_state.m_rasterizer.m_rasterizationOrder);
 		rastOrderCi.rasterizationOrder = convertRasterizationOrder(m_state.m_rasterizer.m_rasterizationOrder);
 
 
-		ANKI_ASSERT(rastCi.pNext == nullptr);
-		rastCi.pNext = &rastOrderCi;
+		appendPNextList(rastCi, &rastOrderCi);
 	}
 	}
 
 
 	// MS
 	// MS
@@ -335,17 +328,16 @@ const VkGraphicsPipelineCreateInfo& PipelineStateTracker::updatePipelineCreateIn
 	}
 	}
 
 
 	// Color/blend
 	// Color/blend
-	if(!!m_fbColorAttachmentMask)
+	if(m_fbColorAttachmentCount)
 	{
 	{
 		VkPipelineColorBlendStateCreateInfo& colCi = m_ci.m_color;
 		VkPipelineColorBlendStateCreateInfo& colCi = m_ci.m_color;
 		colCi = {};
 		colCi = {};
 		colCi.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
 		colCi.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
-		colCi.attachmentCount = m_fbColorAttachmentMask.getSetBitCount();
+		colCi.attachmentCount = m_fbColorAttachmentCount;
 		colCi.pAttachments = &m_ci.m_colAttachments[0];
 		colCi.pAttachments = &m_ci.m_colAttachments[0];
 
 
 		for(U i = 0; i < colCi.attachmentCount; ++i)
 		for(U i = 0; i < colCi.attachmentCount; ++i)
 		{
 		{
-			ANKI_ASSERT(m_fbColorAttachmentMask.get(i) && "No gaps are allowed");
 			VkPipelineColorBlendAttachmentState& out = m_ci.m_colAttachments[i];
 			VkPipelineColorBlendAttachmentState& out = m_ci.m_colAttachments[i];
 			const ColorAttachmentState& in = m_state.m_color.m_attachments[i];
 			const ColorAttachmentState& in = m_state.m_color.m_attachments[i];
 
 
@@ -369,6 +361,29 @@ const VkGraphicsPipelineCreateInfo& PipelineStateTracker::updatePipelineCreateIn
 	dynCi = {};
 	dynCi = {};
 	dynCi.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
 	dynCi.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
 
 
+	// Renderpass related (Dynamic rendering)
+	VkPipelineRenderingCreateInfoKHR& dynRendering = m_ci.m_dynamicRendering;
+	dynRendering = {};
+	dynRendering.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR;
+	dynRendering.colorAttachmentCount = m_fbColorAttachmentCount;
+	dynRendering.pColorAttachmentFormats = m_ci.m_dynamicRenderingAttachmentFormats.getBegin();
+	for(U i = 0; i < m_fbColorAttachmentCount; ++i)
+	{
+		m_ci.m_dynamicRenderingAttachmentFormats[i] = convertFormat(m_state.m_attachmentFormats[i]);
+	}
+
+	if(m_fbDepth)
+	{
+		dynRendering.depthAttachmentFormat = convertFormat(m_state.m_attachmentFormats[kMaxColorRenderTargets]);
+	}
+
+	if(m_fbStencil)
+	{
+		dynRendering.stencilAttachmentFormat = convertFormat(m_state.m_attachmentFormats[kMaxColorRenderTargets]);
+	}
+
+	appendPNextList(ci, &m_ci.m_dynamicRendering);
+
 	// Almost all state is dynamic. Depth bias is static
 	// Almost all state is dynamic. Depth bias is static
 	static constexpr Array<VkDynamicState, 10> kDyn = {
 	static constexpr Array<VkDynamicState, 10> kDyn = {
 		{VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR, VK_DYNAMIC_STATE_BLEND_CONSTANTS, VK_DYNAMIC_STATE_DEPTH_BOUNDS,
 		{VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR, VK_DYNAMIC_STATE_BLEND_CONSTANTS, VK_DYNAMIC_STATE_DEPTH_BOUNDS,
@@ -381,7 +396,6 @@ const VkGraphicsPipelineCreateInfo& PipelineStateTracker::updatePipelineCreateIn
 
 
 	// The rest
 	// The rest
 	ci.layout = static_cast<const ShaderProgramImpl&>(*m_state.m_prog).getPipelineLayout().getHandle();
 	ci.layout = static_cast<const ShaderProgramImpl&>(*m_state.m_prog).getPipelineLayout().getHandle();
-	ci.renderPass = m_state.m_rpass;
 	ci.subpass = 0;
 	ci.subpass = 0;
 
 
 	return ci;
 	return ci;

+ 37 - 18
AnKi/Gr/Vulkan/VkPipeline.h

@@ -8,8 +8,6 @@
 #include <AnKi/Gr/Vulkan/VkDescriptorSet.h>
 #include <AnKi/Gr/Vulkan/VkDescriptorSet.h>
 #include <AnKi/Gr/ShaderProgram.h>
 #include <AnKi/Gr/ShaderProgram.h>
 #include <AnKi/Gr/Vulkan/VkShaderProgram.h>
 #include <AnKi/Gr/Vulkan/VkShaderProgram.h>
-#include <AnKi/Gr/Framebuffer.h>
-#include <AnKi/Gr/Vulkan/VkFramebuffer.h>
 #include <AnKi/Util/HashMap.h>
 #include <AnKi/Util/HashMap.h>
 
 
 namespace anki {
 namespace anki {
@@ -133,7 +131,7 @@ class AllPipelineState
 {
 {
 public:
 public:
 	const ShaderProgramImpl* m_prog = nullptr;
 	const ShaderProgramImpl* m_prog = nullptr;
-	VkRenderPass m_rpass = VK_NULL_HANDLE;
+	Array<Format, kMaxColorRenderTargets + 1> m_attachmentFormats = {};
 
 
 	VertexPipelineState m_vertex;
 	VertexPipelineState m_vertex;
 	InputAssemblerPipelineState m_inputAssembler;
 	InputAssemblerPipelineState m_inputAssembler;
@@ -354,23 +352,37 @@ public:
 		}
 		}
 	}
 	}
 
 
-	void beginRenderPass(const FramebufferImpl* fb)
+	void beginRenderPass(ConstWeakArray<Format> colorFormats, Format depthStencilFormat, Bool rendersToSwapchain)
 	{
 	{
-		ANKI_ASSERT(m_state.m_rpass == VK_NULL_HANDLE);
-		Bool d, s;
-		fb->getAttachmentInfo(m_fbColorAttachmentMask, d, s);
-		m_fbDepth = d;
-		m_fbStencil = s;
-		m_defaultFb = fb->hasPresentableTexture();
+		zeroMemory(m_state.m_attachmentFormats);
+		m_fbColorAttachmentCount = U8(colorFormats.getSize());
 
 
-		m_state.m_rpass = fb->getCompatibleRenderPass();
+		for(U32 i = 0; i < colorFormats.getSize(); ++i)
+		{
+			m_state.m_attachmentFormats[i] = colorFormats[i];
+		}
+
+		m_state.m_attachmentFormats[kMaxColorRenderTargets] = depthStencilFormat;
+
+		if(depthStencilFormat != Format::kNone)
+		{
+			const FormatInfo& inf = getFormatInfo(depthStencilFormat);
+			ANKI_ASSERT(!!inf.m_depthStencil);
+			m_fbDepth = !!(inf.m_depthStencil & DepthStencilAspectBit::kDepth);
+			m_fbStencil = !!(inf.m_depthStencil & DepthStencilAspectBit::kStencil);
+		}
+		else
+		{
+			m_fbDepth = false;
+			m_fbStencil = false;
+		}
+
+		m_rendersToSwapchain = rendersToSwapchain;
 		m_dirty.m_rpass = true;
 		m_dirty.m_rpass = true;
 	}
 	}
 
 
 	void endRenderPass()
 	void endRenderPass()
 	{
 	{
-		ANKI_ASSERT(m_state.m_rpass);
-		m_state.m_rpass = VK_NULL_HANDLE;
 	}
 	}
 
 
 	void setPrimitiveTopology(PrimitiveTopology topology)
 	void setPrimitiveTopology(PrimitiveTopology topology)
@@ -466,8 +478,11 @@ private:
 	// Renderpass info
 	// Renderpass info
 	Bool m_fbDepth : 1 = false;
 	Bool m_fbDepth : 1 = false;
 	Bool m_fbStencil : 1 = false;
 	Bool m_fbStencil : 1 = false;
-	Bool m_defaultFb : 1 = false;
-	BitSet<kMaxColorRenderTargets, U8> m_fbColorAttachmentMask = {false};
+	Bool m_rendersToSwapchain : 1 = false;
+	U8 m_fbColorAttachmentCount : 4 = 0;
+
+	Bool m_pipelineStatisticsEnabled : 1 = false;
+	Bool m_vrsCapable : 1 = false;
 
 
 	class Hashes
 	class Hashes
 	{
 	{
@@ -509,10 +524,14 @@ private:
 		VkPipelineDynamicStateCreateInfo m_dyn;
 		VkPipelineDynamicStateCreateInfo m_dyn;
 		VkGraphicsPipelineCreateInfo m_ppline;
 		VkGraphicsPipelineCreateInfo m_ppline;
 		VkPipelineRasterizationStateRasterizationOrderAMD m_rasterOrder;
 		VkPipelineRasterizationStateRasterizationOrderAMD m_rasterOrder;
-	} m_ci;
+		VkPipelineRenderingCreateInfoKHR m_dynamicRendering;
+		Array<VkFormat, kMaxColorRenderTargets> m_dynamicRenderingAttachmentFormats; ///< Because we can have them living on the stack.
 
 
-	Bool m_pipelineStatisticsEnabled : 1 = false;
-	Bool m_vrsCapable : 1 = false;
+		CreateInfo()
+		{
+			// Do nothing
+		}
+	} m_ci;
 
 
 	Bool updateHashes();
 	Bool updateHashes();
 	void updateSuperHash();
 	void updateSuperHash();

+ 0 - 2
AnKi/Gr/Vulkan/VkTextureView.h

@@ -52,8 +52,6 @@ public:
 		return static_cast<const TextureImpl&>(*m_tex);
 		return static_cast<const TextureImpl&>(*m_tex);
 	}
 	}
 
 
-	U32 getOrCreateBindlessIndex();
-
 private:
 private:
 	VkImageView m_handle = {}; ///< Cache the handle.
 	VkImageView m_handle = {}; ///< Cache the handle.
 	U32 m_bindlessIndex = kMaxU32; ///< Cache it.
 	U32 m_bindlessIndex = kMaxU32; ///< Cache it.

+ 2 - 4
AnKi/Renderer/Bloom.cpp

@@ -31,8 +31,6 @@ Error Bloom::initInternal()
 
 
 	ANKI_CHECK(initExposure());
 	ANKI_CHECK(initExposure());
 	ANKI_CHECK(initUpscale());
 	ANKI_CHECK(initUpscale());
-	m_fbDescr.m_colorAttachmentCount = 1;
-	m_fbDescr.bake();
 	return Error::kNone;
 	return Error::kNone;
 }
 }
 
 
@@ -98,7 +96,7 @@ void Bloom::populateRenderGraph(RenderingContext& ctx)
 		else
 		else
 		{
 		{
 			GraphicsRenderPassDescription& rpass = rgraph.newGraphicsRenderPass("Bloom Main");
 			GraphicsRenderPassDescription& rpass = rgraph.newGraphicsRenderPass("Bloom Main");
-			rpass.setFramebufferInfo(m_fbDescr, {m_runCtx.m_exposureRt});
+			rpass.setRenderpassInfo({RenderTargetInfo(m_runCtx.m_exposureRt)});
 
 
 			rpass.newTextureDependency(getRenderer().getDownscaleBlur().getRt(), TextureUsageBit::kSampledFragment, inputTexSubresource);
 			rpass.newTextureDependency(getRenderer().getDownscaleBlur().getRt(), TextureUsageBit::kSampledFragment, inputTexSubresource);
 			rpass.newTextureDependency(m_runCtx.m_exposureRt, TextureUsageBit::kFramebufferWrite);
 			rpass.newTextureDependency(m_runCtx.m_exposureRt, TextureUsageBit::kFramebufferWrite);
@@ -156,7 +154,7 @@ void Bloom::populateRenderGraph(RenderingContext& ctx)
 		else
 		else
 		{
 		{
 			GraphicsRenderPassDescription& rpass = rgraph.newGraphicsRenderPass("Bloom Upscale");
 			GraphicsRenderPassDescription& rpass = rgraph.newGraphicsRenderPass("Bloom Upscale");
-			rpass.setFramebufferInfo(m_fbDescr, {m_runCtx.m_upscaleRt});
+			rpass.setRenderpassInfo({RenderTargetInfo(m_runCtx.m_upscaleRt)});
 
 
 			rpass.newTextureDependency(m_runCtx.m_exposureRt, TextureUsageBit::kSampledFragment);
 			rpass.newTextureDependency(m_runCtx.m_exposureRt, TextureUsageBit::kSampledFragment);
 			rpass.newTextureDependency(m_runCtx.m_upscaleRt, TextureUsageBit::kFramebufferWrite);
 			rpass.newTextureDependency(m_runCtx.m_upscaleRt, TextureUsageBit::kFramebufferWrite);

+ 0 - 2
AnKi/Renderer/Bloom.h

@@ -46,8 +46,6 @@ public:
 private:
 private:
 	static constexpr Format kRtPixelFormat = Format::kA2B10G10R10_Unorm_Pack32;
 	static constexpr Format kRtPixelFormat = Format::kA2B10G10R10_Unorm_Pack32;
 
 
-	FramebufferDescription m_fbDescr;
-
 	class
 	class
 	{
 	{
 	public:
 	public:

+ 5 - 9
AnKi/Renderer/Dbg.cpp

@@ -41,14 +41,6 @@ Error Dbg::init()
 															  Format::kR8G8B8A8_Unorm, "Dbg");
 															  Format::kR8G8B8A8_Unorm, "Dbg");
 	m_rtDescr.bake();
 	m_rtDescr.bake();
 
 
-	// Create FB descr
-	m_fbDescr.m_colorAttachmentCount = 1;
-	m_fbDescr.m_colorAttachments[0].m_loadOperation = AttachmentLoadOperation::kClear;
-	m_fbDescr.m_depthStencilAttachment.m_loadOperation = AttachmentLoadOperation::kLoad;
-	m_fbDescr.m_depthStencilAttachment.m_stencilLoadOperation = AttachmentLoadOperation::kDontCare;
-	m_fbDescr.m_depthStencilAttachment.m_aspect = DepthStencilAspectBit::kDepth;
-	m_fbDescr.bake();
-
 	ResourceManager& rsrcManager = ResourceManager::getSingleton();
 	ResourceManager& rsrcManager = ResourceManager::getSingleton();
 	ANKI_CHECK(rsrcManager.loadResource("EngineAssets/GiProbe.ankitex", m_giProbeImage));
 	ANKI_CHECK(rsrcManager.loadResource("EngineAssets/GiProbe.ankitex", m_giProbeImage));
 	ANKI_CHECK(rsrcManager.loadResource("EngineAssets/LightBulb.ankitex", m_pointLightImage));
 	ANKI_CHECK(rsrcManager.loadResource("EngineAssets/LightBulb.ankitex", m_pointLightImage));
@@ -256,7 +248,11 @@ void Dbg::populateRenderGraph(RenderingContext& ctx)
 		run(rgraphCtx, ctx);
 		run(rgraphCtx, ctx);
 	});
 	});
 
 
-	pass.setFramebufferInfo(m_fbDescr, {m_runCtx.m_rt}, getRenderer().getGBuffer().getDepthRt());
+	RenderTargetInfo colorRti(m_runCtx.m_rt);
+	colorRti.m_loadOperation = RenderTargetLoadOperation::kClear;
+	RenderTargetInfo depthRti(getRenderer().getGBuffer().getDepthRt());
+	depthRti.m_loadOperation = RenderTargetLoadOperation::kLoad;
+	pass.setRenderpassInfo({colorRti}, &depthRti);
 
 
 	pass.newTextureDependency(m_runCtx.m_rt, TextureUsageBit::kFramebufferWrite);
 	pass.newTextureDependency(m_runCtx.m_rt, TextureUsageBit::kFramebufferWrite);
 	pass.newTextureDependency(getRenderer().getGBuffer().getDepthRt(), TextureUsageBit::kSampledFragment | TextureUsageBit::kFramebufferRead);
 	pass.newTextureDependency(getRenderer().getGBuffer().getDepthRt(), TextureUsageBit::kSampledFragment | TextureUsageBit::kFramebufferRead);

+ 0 - 1
AnKi/Renderer/Dbg.h

@@ -67,7 +67,6 @@ public:
 
 
 private:
 private:
 	RenderTargetDescription m_rtDescr;
 	RenderTargetDescription m_rtDescr;
-	FramebufferDescription m_fbDescr;
 
 
 	ImageResourcePtr m_giProbeImage;
 	ImageResourcePtr m_giProbeImage;
 	ImageResourcePtr m_pointLightImage;
 	ImageResourcePtr m_pointLightImage;

+ 4 - 13
AnKi/Renderer/DepthDownscale.cpp

@@ -77,18 +77,6 @@ Error DepthDownscale::initInternal()
 		fence->clientWait(6.0_sec);
 		fence->clientWait(6.0_sec);
 	}
 	}
 
 
-	if(!preferCompute)
-	{
-		m_fbDescrs.resize(m_mipCount);
-		for(U32 mip = 0; mip < m_mipCount; ++mip)
-		{
-			FramebufferDescription& fbDescr = m_fbDescrs[mip];
-			fbDescr.m_colorAttachmentCount = 1;
-			fbDescr.m_colorAttachments[0].m_surface.m_level = mip;
-			fbDescr.bake();
-		}
-	}
-
 	return Error::kNone;
 	return Error::kNone;
 }
 }
 
 
@@ -175,7 +163,10 @@ void DepthDownscale::populateRenderGraph(RenderingContext& ctx)
 		{
 		{
 			static constexpr Array<CString, 4> passNames = {"Depth downscale #1", "Depth downscale #2", "Depth downscale #3", "Depth downscale #4"};
 			static constexpr Array<CString, 4> passNames = {"Depth downscale #1", "Depth downscale #2", "Depth downscale #3", "Depth downscale #4"};
 			GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass(passNames[mip]);
 			GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass(passNames[mip]);
-			pass.setFramebufferInfo(m_fbDescrs[mip], {m_runCtx.m_rt});
+
+			RenderTargetInfo rti(m_runCtx.m_rt);
+			rti.m_surface.m_level = mip;
+			pass.setRenderpassInfo({rti});
 
 
 			if(mip == 0)
 			if(mip == 0)
 			{
 			{

+ 2 - 4
AnKi/Renderer/DepthDownscale.h

@@ -18,8 +18,8 @@ namespace anki {
 class DepthDownscale : public RendererObject
 class DepthDownscale : public RendererObject
 {
 {
 public:
 public:
-	static constexpr TextureSubresourceInfo kQuarterInternalResolution = TextureSurfaceInfo(0, 0, 0, 0);
-	static constexpr TextureSubresourceInfo kEighthInternalResolution = TextureSurfaceInfo(1, 0, 0, 0);
+	static constexpr TextureSubresourceInfo kQuarterInternalResolution = TextureSurfaceInfo(0, 0, 0);
+	static constexpr TextureSubresourceInfo kEighthInternalResolution = TextureSurfaceInfo(1, 0, 0);
 
 
 	DepthDownscale() = default;
 	DepthDownscale() = default;
 
 
@@ -49,8 +49,6 @@ private:
 
 
 	BufferPtr m_counterBuffer;
 	BufferPtr m_counterBuffer;
 
 
-	RendererDynamicArray<FramebufferDescription> m_fbDescrs;
-
 	U32 m_mipCount = 0;
 	U32 m_mipCount = 0;
 
 
 	class
 	class

+ 5 - 13
AnKi/Renderer/DownscaleBlur.cpp

@@ -47,18 +47,6 @@ Error DownscaleBlur::initInternal()
 	texinit.m_mipmapCount = U8(m_passCount);
 	texinit.m_mipmapCount = U8(m_passCount);
 	m_rtTex = getRenderer().createAndClearRenderTarget(texinit, TextureUsageBit::kSampledCompute);
 	m_rtTex = getRenderer().createAndClearRenderTarget(texinit, TextureUsageBit::kSampledCompute);
 
 
-	// FB descr
-	if(!preferCompute)
-	{
-		m_fbDescrs.resize(m_passCount);
-		for(U32 pass = 0; pass < m_passCount; ++pass)
-		{
-			m_fbDescrs[pass].m_colorAttachmentCount = 1;
-			m_fbDescrs[pass].m_colorAttachments[0].m_surface.m_level = pass;
-			m_fbDescrs[pass].bake();
-		}
-	}
-
 	// Shader programs
 	// Shader programs
 	ANKI_CHECK(loadShaderProgram("ShaderBinaries/DownscaleBlur.ankiprogbin", m_prog, m_grProg));
 	ANKI_CHECK(loadShaderProgram("ShaderBinaries/DownscaleBlur.ankiprogbin", m_prog, m_grProg));
 
 
@@ -91,7 +79,11 @@ void DownscaleBlur::populateRenderGraph(RenderingContext& ctx)
 		else
 		else
 		{
 		{
 			GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass(passNames[i]);
 			GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass(passNames[i]);
-			pass.setFramebufferInfo(m_fbDescrs[i], {m_runCtx.m_rt});
+
+			RenderTargetInfo rtInf(m_runCtx.m_rt);
+			rtInf.m_surface.m_level = i;
+			pass.setRenderpassInfo({rtInf});
+
 			ppass = &pass;
 			ppass = &pass;
 		}
 		}
 
 

+ 0 - 2
AnKi/Renderer/DownscaleBlur.h

@@ -53,8 +53,6 @@ private:
 
 
 	TexturePtr m_rtTex;
 	TexturePtr m_rtTex;
 
 
-	RendererDynamicArray<FramebufferDescription> m_fbDescrs;
-
 	ShaderProgramResourcePtr m_prog;
 	ShaderProgramResourcePtr m_prog;
 	ShaderProgramPtr m_grProg;
 	ShaderProgramPtr m_grProg;
 
 

+ 1 - 4
AnKi/Renderer/FinalComposite.cpp

@@ -29,9 +29,6 @@ Error FinalComposite::initInternal()
 
 
 	ANKI_CHECK(loadColorGradingTextureImage("EngineAssets/DefaultLut.ankitex"));
 	ANKI_CHECK(loadColorGradingTextureImage("EngineAssets/DefaultLut.ankitex"));
 
 
-	m_fbDescr.m_colorAttachmentCount = 1;
-	m_fbDescr.bake();
-
 	// Progs
 	// Progs
 	for(MutatorValue dbg = 0; dbg < 2; ++dbg)
 	for(MutatorValue dbg = 0; dbg < 2; ++dbg)
 	{
 	{
@@ -79,7 +76,7 @@ void FinalComposite::populateRenderGraph(RenderingContext& ctx)
 	pass.setWork([this](RenderPassWorkContext& rgraphCtx) {
 	pass.setWork([this](RenderPassWorkContext& rgraphCtx) {
 		run(rgraphCtx);
 		run(rgraphCtx);
 	});
 	});
-	pass.setFramebufferInfo(m_fbDescr, {ctx.m_outRenderTarget});
+	pass.setRenderpassInfo({RenderTargetInfo(ctx.m_outRenderTarget)});
 
 
 	pass.newTextureDependency(ctx.m_outRenderTarget, TextureUsageBit::kFramebufferWrite);
 	pass.newTextureDependency(ctx.m_outRenderTarget, TextureUsageBit::kFramebufferWrite);
 
 

+ 0 - 2
AnKi/Renderer/FinalComposite.h

@@ -30,8 +30,6 @@ public:
 	Error loadColorGradingTextureImage(CString filename);
 	Error loadColorGradingTextureImage(CString filename);
 
 
 private:
 private:
-	FramebufferDescription m_fbDescr;
-
 	ShaderProgramResourcePtr m_prog;
 	ShaderProgramResourcePtr m_prog;
 	Array<ShaderProgramPtr, 2> m_grProgs; ///< [Debug on or off]
 	Array<ShaderProgramPtr, 2> m_grProgs; ///< [Debug on or off]
 
 

+ 18 - 46
AnKi/Renderer/GBuffer.cpp

@@ -70,31 +70,6 @@ Error GBuffer::initInternal()
 		m_hzbRt = getRenderer().createAndClearRenderTarget(texinit, TextureUsageBit::kSampledCompute, clear);
 		m_hzbRt = getRenderer().createAndClearRenderTarget(texinit, TextureUsageBit::kSampledCompute, clear);
 	}
 	}
 
 
-	// FB descr
-	const AttachmentLoadOperation loadop = AttachmentLoadOperation::kClear;
-
-	m_fbDescr.m_colorAttachmentCount = kGBufferColorRenderTargetCount;
-	for(U i = 0; i < kGBufferColorRenderTargetCount; ++i)
-	{
-		m_fbDescr.m_colorAttachments[i].m_loadOperation = loadop;
-		m_fbDescr.m_colorAttachments[i].m_clearValue.m_colorf = {0.0f, 0.0f, 0.0f, 0.0f};
-	}
-
-	m_fbDescr.m_colorAttachments[3].m_loadOperation = AttachmentLoadOperation::kClear;
-	m_fbDescr.m_colorAttachments[3].m_clearValue.m_colorf = {1.0f, 1.0f, 1.0f, 1.0f};
-
-	m_fbDescr.m_depthStencilAttachment.m_loadOperation = AttachmentLoadOperation::kClear;
-	m_fbDescr.m_depthStencilAttachment.m_clearValue.m_depthStencil.m_depth = 1.0f;
-	m_fbDescr.m_depthStencilAttachment.m_aspect = DepthStencilAspectBit::kDepth;
-
-	if(GrManager::getSingleton().getDeviceCapabilities().m_vrs && g_vrsCVar.get())
-	{
-		m_fbDescr.m_shadingRateAttachmentTexelWidth = getRenderer().getVrsSriGeneration().getSriTexelDimension();
-		m_fbDescr.m_shadingRateAttachmentTexelHeight = getRenderer().getVrsSriGeneration().getSriTexelDimension();
-	}
-
-	m_fbDescr.bake();
-
 	ANKI_CHECK(loadShaderProgram("ShaderBinaries/VisualizeGBufferNormal.ankiprogbin", m_visNormalProg, m_visNormalGrProg));
 	ANKI_CHECK(loadShaderProgram("ShaderBinaries/VisualizeGBufferNormal.ankiprogbin", m_visNormalProg, m_visNormalGrProg));
 
 
 	return Error::kNone;
 	return Error::kNone;
@@ -168,25 +143,6 @@ void GBuffer::populateRenderGraph(RenderingContext& ctx)
 	}
 	}
 
 
 	const Bool enableVrs = GrManager::getSingleton().getDeviceCapabilities().m_vrs && g_vrsCVar.get() && g_gbufferVrsCVar.get();
 	const Bool enableVrs = GrManager::getSingleton().getDeviceCapabilities().m_vrs && g_vrsCVar.get() && g_gbufferVrsCVar.get();
-	const Bool fbDescrHasVrs = m_fbDescr.m_shadingRateAttachmentTexelWidth > 0;
-
-	if(enableVrs != fbDescrHasVrs)
-	{
-		// Re-bake the FB descriptor if the VRS state has changed
-
-		if(enableVrs)
-		{
-			m_fbDescr.m_shadingRateAttachmentTexelWidth = getRenderer().getVrsSriGeneration().getSriTexelDimension();
-			m_fbDescr.m_shadingRateAttachmentTexelHeight = getRenderer().getVrsSriGeneration().getSriTexelDimension();
-		}
-		else
-		{
-			m_fbDescr.m_shadingRateAttachmentTexelWidth = 0;
-			m_fbDescr.m_shadingRateAttachmentTexelHeight = 0;
-		}
-
-		m_fbDescr.bake();
-	}
 
 
 	// Create RTs
 	// Create RTs
 	Array<RenderTargetHandle, kMaxColorRenderTargets> rts;
 	Array<RenderTargetHandle, kMaxColorRenderTargets> rts;
@@ -205,8 +161,24 @@ void GBuffer::populateRenderGraph(RenderingContext& ctx)
 	// Create pass
 	// Create pass
 	GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("GBuffer");
 	GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("GBuffer");
 
 
-	pass.setFramebufferInfo(m_fbDescr, ConstWeakArray<RenderTargetHandle>(&rts[0], kGBufferColorRenderTargetCount), m_runCtx.m_crntFrameDepthRt,
-							sriRt);
+	Array<RenderTargetInfo, kGBufferColorRenderTargetCount> colorRti;
+	colorRti[0].m_handle = rts[0];
+	colorRti[0].m_loadOperation = RenderTargetLoadOperation::kClear;
+	colorRti[1].m_handle = rts[1];
+	colorRti[1].m_loadOperation = RenderTargetLoadOperation::kClear;
+	colorRti[2].m_handle = rts[2];
+	colorRti[2].m_loadOperation = RenderTargetLoadOperation::kClear;
+	colorRti[3].m_handle = rts[3];
+	colorRti[3].m_loadOperation = RenderTargetLoadOperation::kClear;
+	colorRti[3].m_clearValue.m_colorf = {1.0f, 1.0f, 1.0f, 1.0f};
+	RenderTargetInfo depthRti(m_runCtx.m_crntFrameDepthRt);
+	depthRti.m_loadOperation = RenderTargetLoadOperation::kClear;
+	depthRti.m_clearValue.m_depthStencil.m_depth = 1.0f;
+	depthRti.m_aspect = DepthStencilAspectBit::kDepth;
+
+	pass.setRenderpassInfo(WeakArray{colorRti}, &depthRti, 0, 0, kMaxU32, kMaxU32, (enableVrs) ? &sriRt : nullptr,
+						   (enableVrs) ? getRenderer().getVrsSriGeneration().getSriTexelDimension() : 0,
+						   (enableVrs) ? getRenderer().getVrsSriGeneration().getSriTexelDimension() : 0);
 	pass.setWork([this, &ctx, visOut, meshletVisOut](RenderPassWorkContext& rgraphCtx) {
 	pass.setWork([this, &ctx, visOut, meshletVisOut](RenderPassWorkContext& rgraphCtx) {
 		ANKI_TRACE_SCOPED_EVENT(GBuffer);
 		ANKI_TRACE_SCOPED_EVENT(GBuffer);
 
 

+ 0 - 1
AnKi/Renderer/GBuffer.h

@@ -71,7 +71,6 @@ private:
 	Array<RenderTargetDescription, kGBufferColorRenderTargetCount> m_colorRtDescrs;
 	Array<RenderTargetDescription, kGBufferColorRenderTargetCount> m_colorRtDescrs;
 	Array<TexturePtr, 2> m_depthRts;
 	Array<TexturePtr, 2> m_depthRts;
 	TexturePtr m_hzbRt;
 	TexturePtr m_hzbRt;
-	FramebufferDescription m_fbDescr;
 
 
 	ShaderProgramResourcePtr m_visNormalProg;
 	ShaderProgramResourcePtr m_visNormalProg;
 	ShaderProgramPtr m_visNormalGrProg;
 	ShaderProgramPtr m_visNormalGrProg;

+ 5 - 7
AnKi/Renderer/GBufferPost.cpp

@@ -28,12 +28,6 @@ Error GBufferPost::initInternal()
 	// Load shaders
 	// Load shaders
 	ANKI_CHECK(loadShaderProgram("ShaderBinaries/GBufferPost.ankiprogbin", m_prog, m_grProg));
 	ANKI_CHECK(loadShaderProgram("ShaderBinaries/GBufferPost.ankiprogbin", m_prog, m_grProg));
 
 
-	// Create FB descr
-	m_fbDescr.m_colorAttachmentCount = 2;
-	m_fbDescr.m_colorAttachments[0].m_loadOperation = AttachmentLoadOperation::kLoad;
-	m_fbDescr.m_colorAttachments[1].m_loadOperation = AttachmentLoadOperation::kLoad;
-	m_fbDescr.bake();
-
 	return Error::kNone;
 	return Error::kNone;
 }
 }
 
 
@@ -82,7 +76,11 @@ void GBufferPost::populateRenderGraph(RenderingContext& ctx)
 		cmdb.setBlendFactors(1, BlendFactor::kOne, BlendFactor::kZero);
 		cmdb.setBlendFactors(1, BlendFactor::kOne, BlendFactor::kZero);
 	});
 	});
 
 
-	rpass.setFramebufferInfo(m_fbDescr, {getRenderer().getGBuffer().getColorRt(0), getRenderer().getGBuffer().getColorRt(1)});
+	RenderTargetInfo rt0(getRenderer().getGBuffer().getColorRt(0));
+	rt0.m_loadOperation = RenderTargetLoadOperation::kLoad;
+	RenderTargetInfo rt1(getRenderer().getGBuffer().getColorRt(1));
+	rt1.m_loadOperation = RenderTargetLoadOperation::kLoad;
+	rpass.setRenderpassInfo({rt0, rt1});
 
 
 	rpass.newTextureDependency(getRenderer().getGBuffer().getColorRt(0), TextureUsageBit::kAllFramebuffer);
 	rpass.newTextureDependency(getRenderer().getGBuffer().getColorRt(0), TextureUsageBit::kAllFramebuffer);
 	rpass.newTextureDependency(getRenderer().getGBuffer().getColorRt(1), TextureUsageBit::kAllFramebuffer);
 	rpass.newTextureDependency(getRenderer().getGBuffer().getColorRt(1), TextureUsageBit::kAllFramebuffer);

+ 0 - 2
AnKi/Renderer/GBufferPost.h

@@ -25,8 +25,6 @@ private:
 	ShaderProgramResourcePtr m_prog;
 	ShaderProgramResourcePtr m_prog;
 	ShaderProgramPtr m_grProg;
 	ShaderProgramPtr m_grProg;
 
 
-	FramebufferDescription m_fbDescr;
-
 	Error initInternal();
 	Error initInternal();
 };
 };
 /// @}
 /// @}

+ 25 - 32
AnKi/Renderer/IndirectDiffuseProbes.cpp

@@ -102,13 +102,6 @@ Error IndirectDiffuseProbes::initShadowMapping()
 		getRenderer().create2DRenderTargetDescription(resolution, resolution, getRenderer().getDepthNoStencilFormat(), "GI SM");
 		getRenderer().create2DRenderTargetDescription(resolution, resolution, getRenderer().getDepthNoStencilFormat(), "GI SM");
 	m_shadowMapping.m_rtDescr.bake();
 	m_shadowMapping.m_rtDescr.bake();
 
 
-	// Create the FB descr
-	m_shadowMapping.m_fbDescr.m_colorAttachmentCount = 0;
-	m_shadowMapping.m_fbDescr.m_depthStencilAttachment.m_aspect = DepthStencilAspectBit::kDepth;
-	m_shadowMapping.m_fbDescr.m_depthStencilAttachment.m_clearValue.m_depthStencil.m_depth = 1.0f;
-	m_shadowMapping.m_fbDescr.m_depthStencilAttachment.m_loadOperation = AttachmentLoadOperation::kClear;
-	m_shadowMapping.m_fbDescr.bake();
-
 	return Error::kNone;
 	return Error::kNone;
 }
 }
 
 
@@ -241,26 +234,25 @@ void IndirectDiffuseProbes::populateRenderGraph(RenderingContext& rctx)
 
 
 			// GBuffer
 			// GBuffer
 			{
 			{
-				// Create the FB descriptor
-				FramebufferDescription fbDescr;
-				fbDescr.m_colorAttachmentCount = kGBufferColorRenderTargetCount;
+				GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass(generateTempPassName("GI: GBuffer", cellIdx, "face", f));
+
+				Array<RenderTargetInfo, kGBufferColorRenderTargetCount> colorRtis;
 				for(U j = 0; j < kGBufferColorRenderTargetCount; ++j)
 				for(U j = 0; j < kGBufferColorRenderTargetCount; ++j)
 				{
 				{
-					fbDescr.m_colorAttachments[j].m_loadOperation = AttachmentLoadOperation::kClear;
-					fbDescr.m_colorAttachments[j].m_surface.m_face = f;
+					colorRtis[j].m_loadOperation = RenderTargetLoadOperation::kClear;
+					colorRtis[j].m_surface.m_face = f;
+					colorRtis[j].m_handle = gbufferColorRts[j];
 				}
 				}
-				fbDescr.m_depthStencilAttachment.m_aspect = DepthStencilAspectBit::kDepth;
-				fbDescr.m_depthStencilAttachment.m_loadOperation = AttachmentLoadOperation::kClear;
-				fbDescr.m_depthStencilAttachment.m_clearValue.m_depthStencil.m_depth = 1.0f;
-				fbDescr.bake();
+				RenderTargetInfo depthRti(gbufferDepthRt);
+				depthRti.m_aspect = DepthStencilAspectBit::kDepth;
+				depthRti.m_loadOperation = RenderTargetLoadOperation::kClear;
+				depthRti.m_clearValue.m_depthStencil.m_depth = 1.0f;
 
 
-				// Create the pass
-				GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass(generateTempPassName("GI: GBuffer", cellIdx, "face", f));
-				pass.setFramebufferInfo(fbDescr, gbufferColorRts, gbufferDepthRt);
+				pass.setRenderpassInfo(colorRtis, &depthRti);
 
 
 				for(U i = 0; i < kGBufferColorRenderTargetCount; ++i)
 				for(U i = 0; i < kGBufferColorRenderTargetCount; ++i)
 				{
 				{
-					pass.newTextureDependency(gbufferColorRts[i], TextureUsageBit::kFramebufferWrite, TextureSurfaceInfo(0, 0, f, 0));
+					pass.newTextureDependency(gbufferColorRts[i], TextureUsageBit::kFramebufferWrite, TextureSurfaceInfo(0, f, 0));
 				}
 				}
 				pass.newTextureDependency(gbufferDepthRt, TextureUsageBit::kAllFramebuffer, TextureSubresourceInfo(DepthStencilAspectBit::kDepth));
 				pass.newTextureDependency(gbufferDepthRt, TextureUsageBit::kAllFramebuffer, TextureSubresourceInfo(DepthStencilAspectBit::kDepth));
 
 
@@ -342,7 +334,12 @@ void IndirectDiffuseProbes::populateRenderGraph(RenderingContext& rctx)
 			{
 			{
 				// Create the pass
 				// Create the pass
 				GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass(generateTempPassName("GI: Shadows", cellIdx, "face", f));
 				GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass(generateTempPassName("GI: Shadows", cellIdx, "face", f));
-				pass.setFramebufferInfo(m_shadowMapping.m_fbDescr, {}, shadowsRt);
+
+				RenderTargetInfo depthRti(shadowsRt);
+				depthRti.m_loadOperation = RenderTargetLoadOperation::kClear;
+				depthRti.m_aspect = DepthStencilAspectBit::kDepth;
+				depthRti.m_clearValue.m_depthStencil.m_depth = 1.0f;
+				pass.setRenderpassInfo({}, &depthRti);
 
 
 				pass.newTextureDependency(shadowsRt, TextureUsageBit::kAllFramebuffer, TextureSubresourceInfo(DepthStencilAspectBit::kDepth));
 				pass.newTextureDependency(shadowsRt, TextureUsageBit::kAllFramebuffer, TextureSubresourceInfo(DepthStencilAspectBit::kDepth));
 				pass.newBufferDependency((shadowMeshletVisOut.isFilled()) ? shadowMeshletVisOut.m_dependency : shadowVisOut.m_dependency,
 				pass.newBufferDependency((shadowMeshletVisOut.isFilled()) ? shadowMeshletVisOut.m_dependency : shadowVisOut.m_dependency,
@@ -391,24 +388,20 @@ void IndirectDiffuseProbes::populateRenderGraph(RenderingContext& rctx)
 
 
 			// Light shading pass
 			// Light shading pass
 			{
 			{
-				// Create FB descr
-				FramebufferDescription fbDescr;
-				fbDescr.m_colorAttachmentCount = 1;
-				fbDescr.m_colorAttachments[0].m_loadOperation = AttachmentLoadOperation::kClear;
-				fbDescr.m_colorAttachments[0].m_surface.m_face = f;
-				fbDescr.bake();
-
-				// Create the pass
 				GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass(generateTempPassName("GI: Light shading", cellIdx, "face", f));
 				GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass(generateTempPassName("GI: Light shading", cellIdx, "face", f));
-				pass.setFramebufferInfo(fbDescr, {lightShadingRt});
+
+				RenderTargetInfo colorRti(lightShadingRt);
+				colorRti.m_loadOperation = RenderTargetLoadOperation::kClear;
+				colorRti.m_surface.m_face = f;
+				pass.setRenderpassInfo({colorRti});
 
 
 				pass.newBufferDependency(lightVis.m_visiblesBufferHandle, BufferUsageBit::kStorageFragmentRead);
 				pass.newBufferDependency(lightVis.m_visiblesBufferHandle, BufferUsageBit::kStorageFragmentRead);
 
 
-				pass.newTextureDependency(lightShadingRt, TextureUsageBit::kFramebufferWrite, TextureSurfaceInfo(0, 0, f, 0));
+				pass.newTextureDependency(lightShadingRt, TextureUsageBit::kFramebufferWrite, TextureSurfaceInfo(0, f, 0));
 
 
 				for(U i = 0; i < kGBufferColorRenderTargetCount; ++i)
 				for(U i = 0; i < kGBufferColorRenderTargetCount; ++i)
 				{
 				{
-					pass.newTextureDependency(gbufferColorRts[i], TextureUsageBit::kSampledFragment, TextureSurfaceInfo(0, 0, f, 0));
+					pass.newTextureDependency(gbufferColorRts[i], TextureUsageBit::kSampledFragment, TextureSurfaceInfo(0, f, 0));
 				}
 				}
 				pass.newTextureDependency(gbufferDepthRt, TextureUsageBit::kSampledFragment, TextureSubresourceInfo(DepthStencilAspectBit::kDepth));
 				pass.newTextureDependency(gbufferDepthRt, TextureUsageBit::kSampledFragment, TextureSubresourceInfo(DepthStencilAspectBit::kDepth));
 
 

+ 0 - 1
AnKi/Renderer/IndirectDiffuseProbes.h

@@ -48,7 +48,6 @@ private:
 	{
 	{
 	public:
 	public:
 		RenderTargetDescription m_rtDescr;
 		RenderTargetDescription m_rtDescr;
-		FramebufferDescription m_fbDescr;
 	} m_shadowMapping;
 	} m_shadowMapping;
 
 
 	class LS
 	class LS

+ 8 - 34
AnKi/Renderer/LightShading.cpp

@@ -60,20 +60,6 @@ Error LightShading::initLightShading()
 		getRenderer().create2DRenderTargetDescription(internalResolution.x(), internalResolution.y(), getRenderer().getHdrFormat(), "Light Shading");
 		getRenderer().create2DRenderTargetDescription(internalResolution.x(), internalResolution.y(), getRenderer().getHdrFormat(), "Light Shading");
 	m_lightShading.m_rtDescr.bake();
 	m_lightShading.m_rtDescr.bake();
 
 
-	// Create FB descr
-	m_lightShading.m_fbDescr.m_colorAttachmentCount = 1;
-	m_lightShading.m_fbDescr.m_depthStencilAttachment.m_loadOperation = AttachmentLoadOperation::kLoad;
-	m_lightShading.m_fbDescr.m_depthStencilAttachment.m_stencilLoadOperation = AttachmentLoadOperation::kDontCare;
-	m_lightShading.m_fbDescr.m_depthStencilAttachment.m_aspect = DepthStencilAspectBit::kDepth;
-
-	if(GrManager::getSingleton().getDeviceCapabilities().m_vrs && g_vrsCVar.get())
-	{
-		m_lightShading.m_fbDescr.m_shadingRateAttachmentTexelWidth = getRenderer().getVrsSriGeneration().getSriTexelDimension();
-		m_lightShading.m_fbDescr.m_shadingRateAttachmentTexelHeight = getRenderer().getVrsSriGeneration().getSriTexelDimension();
-	}
-
-	m_lightShading.m_fbDescr.bake();
-
 	// Debug visualization
 	// Debug visualization
 	ANKI_CHECK(loadShaderProgram("ShaderBinaries/VisualizeHdrRenderTarget.ankiprogbin", m_visualizeRtProg, m_visualizeRtGrProg));
 	ANKI_CHECK(loadShaderProgram("ShaderBinaries/VisualizeHdrRenderTarget.ankiprogbin", m_visualizeRtProg, m_visualizeRtGrProg));
 
 
@@ -266,25 +252,6 @@ void LightShading::populateRenderGraph(RenderingContext& ctx)
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
 
 
 	const Bool enableVrs = GrManager::getSingleton().getDeviceCapabilities().m_vrs && g_vrsCVar.get();
 	const Bool enableVrs = GrManager::getSingleton().getDeviceCapabilities().m_vrs && g_vrsCVar.get();
-	const Bool fbDescrHasVrs = m_lightShading.m_fbDescr.m_shadingRateAttachmentTexelWidth > 0;
-
-	if(enableVrs != fbDescrHasVrs)
-	{
-		// Re-bake the FB descriptor if the VRS state has changed
-
-		if(enableVrs)
-		{
-			m_lightShading.m_fbDescr.m_shadingRateAttachmentTexelWidth = getRenderer().getVrsSriGeneration().getSriTexelDimension();
-			m_lightShading.m_fbDescr.m_shadingRateAttachmentTexelHeight = getRenderer().getVrsSriGeneration().getSriTexelDimension();
-		}
-		else
-		{
-			m_lightShading.m_fbDescr.m_shadingRateAttachmentTexelWidth = 0;
-			m_lightShading.m_fbDescr.m_shadingRateAttachmentTexelHeight = 0;
-		}
-
-		m_lightShading.m_fbDescr.bake();
-	}
 
 
 	// Create RT
 	// Create RT
 	m_runCtx.m_rt = rgraph.newRenderTarget(m_lightShading.m_rtDescr);
 	m_runCtx.m_rt = rgraph.newRenderTarget(m_lightShading.m_rtDescr);
@@ -301,7 +268,14 @@ void LightShading::populateRenderGraph(RenderingContext& ctx)
 	pass.setWork([this, &ctx](RenderPassWorkContext& rgraphCtx) {
 	pass.setWork([this, &ctx](RenderPassWorkContext& rgraphCtx) {
 		run(ctx, rgraphCtx);
 		run(ctx, rgraphCtx);
 	});
 	});
-	pass.setFramebufferInfo(m_lightShading.m_fbDescr, {m_runCtx.m_rt}, getRenderer().getGBuffer().getDepthRt(), sriRt);
+
+	RenderTargetInfo colorRt(m_runCtx.m_rt);
+	RenderTargetInfo depthRt(getRenderer().getGBuffer().getDepthRt());
+	depthRt.m_loadOperation = RenderTargetLoadOperation::kLoad;
+	depthRt.m_aspect = DepthStencilAspectBit::kDepth;
+	pass.setRenderpassInfo({colorRt}, &depthRt, 0, 0, kMaxU32, kMaxU32, (enableVrs) ? &sriRt : nullptr,
+						   (enableVrs) ? getRenderer().getVrsSriGeneration().getSriTexelDimension() : 0,
+						   (enableVrs) ? getRenderer().getVrsSriGeneration().getSriTexelDimension() : 0);
 
 
 	const TextureUsageBit readUsage = TextureUsageBit::kSampledFragment;
 	const TextureUsageBit readUsage = TextureUsageBit::kSampledFragment;
 
 

+ 0 - 1
AnKi/Renderer/LightShading.h

@@ -36,7 +36,6 @@ private:
 	{
 	{
 	public:
 	public:
 		RenderTargetDescription m_rtDescr;
 		RenderTargetDescription m_rtDescr;
-		FramebufferDescription m_fbDescr;
 
 
 		// Light shaders
 		// Light shaders
 		ShaderProgramResourcePtr m_prog;
 		ShaderProgramResourcePtr m_prog;

+ 1 - 5
AnKi/Renderer/MainRenderer.cpp

@@ -69,10 +69,6 @@ Error MainRenderer::init(const MainRendererInitInfo& inf)
 			"Final Composite");
 			"Final Composite");
 		m_tmpRtDesc.bake();
 		m_tmpRtDesc.bake();
 
 
-		// FB descr
-		m_fbDescr.m_colorAttachmentCount = 1;
-		m_fbDescr.bake();
-
 		ANKI_R_LOGI("There will be a blit pass to the swapchain because render scaling is not 1.0");
 		ANKI_R_LOGI("There will be a blit pass to the swapchain because render scaling is not 1.0");
 	}
 	}
 
 
@@ -116,7 +112,7 @@ Error MainRenderer::render(Texture* presentTex)
 	{
 	{
 		GraphicsRenderPassDescription& pass = ctx.m_renderGraphDescr.newGraphicsRenderPass("Final Blit");
 		GraphicsRenderPassDescription& pass = ctx.m_renderGraphDescr.newGraphicsRenderPass("Final Blit");
 
 
-		pass.setFramebufferInfo(m_fbDescr, {presentRt});
+		pass.setRenderpassInfo({RenderTargetInfo(presentRt)});
 		pass.setWork([this](RenderPassWorkContext& rgraphCtx) {
 		pass.setWork([this](RenderPassWorkContext& rgraphCtx) {
 			CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
 			CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
 			cmdb.setViewport(0, 0, m_swapchainResolution.x(), m_swapchainResolution.y());
 			cmdb.setViewport(0, 0, m_swapchainResolution.x(), m_swapchainResolution.y());

+ 0 - 1
AnKi/Renderer/MainRenderer.h

@@ -61,7 +61,6 @@ private:
 
 
 	RenderGraphPtr m_rgraph;
 	RenderGraphPtr m_rgraph;
 	RenderTargetDescription m_tmpRtDesc;
 	RenderTargetDescription m_tmpRtDesc;
-	FramebufferDescription m_fbDescr;
 
 
 	class
 	class
 	{
 	{

+ 1 - 4
AnKi/Renderer/MotionVectors.cpp

@@ -34,9 +34,6 @@ Error MotionVectors::initInternal()
 		getRenderer().getInternalResolution().x(), getRenderer().getInternalResolution().y(), Format::kR16G16_Sfloat, "MotionVectors");
 		getRenderer().getInternalResolution().x(), getRenderer().getInternalResolution().y(), Format::kR16G16_Sfloat, "MotionVectors");
 	m_motionVectorsRtDescr.bake();
 	m_motionVectorsRtDescr.bake();
 
 
-	m_fbDescr.m_colorAttachmentCount = 1;
-	m_fbDescr.bake();
-
 	return Error::kNone;
 	return Error::kNone;
 }
 }
 
 
@@ -61,7 +58,7 @@ void MotionVectors::populateRenderGraph(RenderingContext& ctx)
 	else
 	else
 	{
 	{
 		GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("MotionVectors");
 		GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("MotionVectors");
-		pass.setFramebufferInfo(m_fbDescr, {m_runCtx.m_motionVectorsRtHandle});
+		pass.setRenderpassInfo({RenderTargetInfo(m_runCtx.m_motionVectorsRtHandle)});
 
 
 		readUsage = TextureUsageBit::kSampledFragment;
 		readUsage = TextureUsageBit::kSampledFragment;
 		writeUsage = TextureUsageBit::kFramebufferWrite;
 		writeUsage = TextureUsageBit::kFramebufferWrite;

+ 0 - 1
AnKi/Renderer/MotionVectors.h

@@ -44,7 +44,6 @@ private:
 	ShaderProgramResourcePtr m_prog;
 	ShaderProgramResourcePtr m_prog;
 	ShaderProgramPtr m_grProg;
 	ShaderProgramPtr m_grProg;
 	RenderTargetDescription m_motionVectorsRtDescr;
 	RenderTargetDescription m_motionVectorsRtDescr;
-	FramebufferDescription m_fbDescr;
 
 
 	class
 	class
 	{
 	{

+ 29 - 34
AnKi/Renderer/ProbeReflections.cpp

@@ -143,13 +143,6 @@ Error ProbeReflections::initShadowMapping()
 		getRenderer().create2DRenderTargetDescription(resolution, resolution, getRenderer().getDepthNoStencilFormat(), "CubeRefl SM");
 		getRenderer().create2DRenderTargetDescription(resolution, resolution, getRenderer().getDepthNoStencilFormat(), "CubeRefl SM");
 	m_shadowMapping.m_rtDescr.bake();
 	m_shadowMapping.m_rtDescr.bake();
 
 
-	// FB descr
-	m_shadowMapping.m_fbDescr.m_colorAttachmentCount = 0;
-	m_shadowMapping.m_fbDescr.m_depthStencilAttachment.m_aspect = DepthStencilAspectBit::kDepth;
-	m_shadowMapping.m_fbDescr.m_depthStencilAttachment.m_clearValue.m_depthStencil.m_depth = 1.0f;
-	m_shadowMapping.m_fbDescr.m_depthStencilAttachment.m_loadOperation = AttachmentLoadOperation::kClear;
-	m_shadowMapping.m_fbDescr.bake();
-
 	return Error::kNone;
 	return Error::kNone;
 }
 }
 
 
@@ -240,26 +233,26 @@ void ProbeReflections::populateRenderGraph(RenderingContext& rctx)
 
 
 		// GBuffer pass
 		// GBuffer pass
 		{
 		{
-			// Create the FB descr
-			FramebufferDescription fbDescr;
-			fbDescr.m_colorAttachmentCount = kGBufferColorRenderTargetCount;
+			// Create pass
+			GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass(generateTempPassName("Cube refl: GBuffer", f));
+
+			Array<RenderTargetInfo, kGBufferColorRenderTargetCount> colorRtis;
 			for(U j = 0; j < kGBufferColorRenderTargetCount; ++j)
 			for(U j = 0; j < kGBufferColorRenderTargetCount; ++j)
 			{
 			{
-				fbDescr.m_colorAttachments[j].m_loadOperation = AttachmentLoadOperation::kClear;
-				fbDescr.m_colorAttachments[j].m_surface.m_face = f;
+				colorRtis[j].m_loadOperation = RenderTargetLoadOperation::kClear;
+				colorRtis[j].m_surface.m_face = f;
+				colorRtis[j].m_handle = gbufferColorRts[j];
 			}
 			}
-			fbDescr.m_depthStencilAttachment.m_aspect = DepthStencilAspectBit::kDepth;
-			fbDescr.m_depthStencilAttachment.m_loadOperation = AttachmentLoadOperation::kClear;
-			fbDescr.m_depthStencilAttachment.m_clearValue.m_depthStencil.m_depth = 1.0f;
-			fbDescr.bake();
+			RenderTargetInfo depthRti(gbufferDepthRt);
+			depthRti.m_aspect = DepthStencilAspectBit::kDepth;
+			depthRti.m_loadOperation = RenderTargetLoadOperation::kClear;
+			depthRti.m_clearValue.m_depthStencil.m_depth = 1.0f;
 
 
-			// Create pass
-			GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass(generateTempPassName("Cube refl: GBuffer", f));
-			pass.setFramebufferInfo(fbDescr, gbufferColorRts, gbufferDepthRt);
+			pass.setRenderpassInfo(colorRtis, &depthRti);
 
 
 			for(U i = 0; i < kGBufferColorRenderTargetCount; ++i)
 			for(U i = 0; i < kGBufferColorRenderTargetCount; ++i)
 			{
 			{
-				pass.newTextureDependency(gbufferColorRts[i], TextureUsageBit::kFramebufferWrite, TextureSurfaceInfo(0, 0, f, 0));
+				pass.newTextureDependency(gbufferColorRts[i], TextureUsageBit::kFramebufferWrite, TextureSurfaceInfo(0, f, 0));
 			}
 			}
 
 
 			pass.newTextureDependency(gbufferDepthRt, TextureUsageBit::kAllFramebuffer, TextureSubresourceInfo(DepthStencilAspectBit::kDepth));
 			pass.newTextureDependency(gbufferDepthRt, TextureUsageBit::kAllFramebuffer, TextureSubresourceInfo(DepthStencilAspectBit::kDepth));
@@ -338,7 +331,13 @@ void ProbeReflections::populateRenderGraph(RenderingContext& rctx)
 		{
 		{
 			// Pass
 			// Pass
 			GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass(generateTempPassName("Cube refl: Shadows", f));
 			GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass(generateTempPassName("Cube refl: Shadows", f));
-			pass.setFramebufferInfo(m_shadowMapping.m_fbDescr, {}, shadowMapRt);
+
+			RenderTargetInfo depthRti(shadowMapRt);
+			depthRti.m_loadOperation = RenderTargetLoadOperation::kClear;
+			depthRti.m_clearValue.m_depthStencil.m_depth = 1.0f;
+			depthRti.m_aspect = DepthStencilAspectBit::kDepth;
+
+			pass.setRenderpassInfo({}, &depthRti);
 
 
 			pass.newTextureDependency(shadowMapRt, TextureUsageBit::kAllFramebuffer, TextureSubresourceInfo(DepthStencilAspectBit::kDepth));
 			pass.newTextureDependency(shadowMapRt, TextureUsageBit::kAllFramebuffer, TextureSubresourceInfo(DepthStencilAspectBit::kDepth));
 			pass.newBufferDependency((shadowMeshletVisOut.isFilled()) ? shadowMeshletVisOut.m_dependency : shadowVisOut.m_dependency,
 			pass.newBufferDependency((shadowMeshletVisOut.isFilled()) ? shadowMeshletVisOut.m_dependency : shadowVisOut.m_dependency,
@@ -385,23 +384,19 @@ void ProbeReflections::populateRenderGraph(RenderingContext& rctx)
 
 
 		// Light shading pass
 		// Light shading pass
 		{
 		{
-			// FB descr
-			FramebufferDescription fbDescr;
-			fbDescr.m_colorAttachmentCount = 1;
-			fbDescr.m_colorAttachments[0].m_surface.m_face = f;
-			fbDescr.m_colorAttachments[0].m_loadOperation = AttachmentLoadOperation::kClear;
-			fbDescr.bake();
-
-			// Pass
 			GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass(generateTempPassName("Cube refl: light shading", f));
 			GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass(generateTempPassName("Cube refl: light shading", f));
-			pass.setFramebufferInfo(fbDescr, {probeTexture});
+
+			RenderTargetInfo colorRti(probeTexture);
+			colorRti.m_surface.m_face = f;
+			colorRti.m_loadOperation = RenderTargetLoadOperation::kClear;
+			pass.setRenderpassInfo({colorRti});
 
 
 			pass.newBufferDependency(lightVis.m_visiblesBufferHandle, BufferUsageBit::kStorageFragmentRead);
 			pass.newBufferDependency(lightVis.m_visiblesBufferHandle, BufferUsageBit::kStorageFragmentRead);
-			pass.newTextureDependency(probeTexture, TextureUsageBit::kFramebufferWrite, TextureSubresourceInfo(TextureSurfaceInfo(0, 0, f, 0)));
+			pass.newTextureDependency(probeTexture, TextureUsageBit::kFramebufferWrite, TextureSubresourceInfo(TextureSurfaceInfo(0, f, 0)));
 
 
 			for(U i = 0; i < kGBufferColorRenderTargetCount; ++i)
 			for(U i = 0; i < kGBufferColorRenderTargetCount; ++i)
 			{
 			{
-				pass.newTextureDependency(gbufferColorRts[i], TextureUsageBit::kSampledFragment, TextureSurfaceInfo(0, 0, f, 0));
+				pass.newTextureDependency(gbufferColorRts[i], TextureUsageBit::kSampledFragment, TextureSurfaceInfo(0, f, 0));
 			}
 			}
 			pass.newTextureDependency(gbufferDepthRt, TextureUsageBit::kSampledFragment, TextureSubresourceInfo(DepthStencilAspectBit::kDepth));
 			pass.newTextureDependency(gbufferDepthRt, TextureUsageBit::kSampledFragment, TextureSubresourceInfo(DepthStencilAspectBit::kDepth));
 
 
@@ -524,14 +519,14 @@ void ProbeReflections::populateRenderGraph(RenderingContext& rctx)
 		{
 		{
 			GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass(generateTempPassName("Cube refl: Gen mips", faceIdx));
 			GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass(generateTempPassName("Cube refl: Gen mips", faceIdx));
 
 
-			TextureSubresourceInfo subresource(TextureSurfaceInfo(0, 0, faceIdx, 0));
+			TextureSubresourceInfo subresource(TextureSurfaceInfo(0, faceIdx, 0));
 			subresource.m_mipmapCount = m_lightShading.m_mipCount;
 			subresource.m_mipmapCount = m_lightShading.m_mipCount;
 			pass.newTextureDependency(probeTexture, TextureUsageBit::kGenerateMipmaps, subresource);
 			pass.newTextureDependency(probeTexture, TextureUsageBit::kGenerateMipmaps, subresource);
 
 
 			pass.setWork([this, faceIdx, probeTexture](RenderPassWorkContext& rgraphCtx) {
 			pass.setWork([this, faceIdx, probeTexture](RenderPassWorkContext& rgraphCtx) {
 				ANKI_TRACE_SCOPED_EVENT(ProbeReflections);
 				ANKI_TRACE_SCOPED_EVENT(ProbeReflections);
 
 
-				TextureSubresourceInfo subresource(TextureSurfaceInfo(0, 0, faceIdx, 0));
+				TextureSubresourceInfo subresource(TextureSurfaceInfo(0, faceIdx, 0));
 				subresource.m_mipmapCount = m_lightShading.m_mipCount;
 				subresource.m_mipmapCount = m_lightShading.m_mipCount;
 
 
 				Texture* texToBind;
 				Texture* texToBind;

+ 0 - 1
AnKi/Renderer/ProbeReflections.h

@@ -91,7 +91,6 @@ private:
 	{
 	{
 	public:
 	public:
 		RenderTargetDescription m_rtDescr;
 		RenderTargetDescription m_rtDescr;
-		FramebufferDescription m_fbDescr;
 	} m_shadowMapping;
 	} m_shadowMapping;
 
 
 	class
 	class

+ 22 - 23
AnKi/Renderer/Renderer.cpp

@@ -482,13 +482,14 @@ TexturePtr Renderer::createAndClearRenderTarget(const TextureInitInfo& inf, Text
 		{
 		{
 			for(U32 layer = 0; layer < inf.m_layerCount; ++layer)
 			for(U32 layer = 0; layer < inf.m_layerCount; ++layer)
 			{
 			{
-				TextureSurfaceInfo surf(mip, 0, face, layer);
+				TextureSurfaceInfo surf(mip, face, layer);
 
 
 				if(!useCompute)
 				if(!useCompute)
 				{
 				{
-					FramebufferInitInfo fbInit("RendererClearRT");
-					Array<TextureUsageBit, kMaxColorRenderTargets> colUsage = {};
-					TextureUsageBit dsUsage = TextureUsageBit::kNone;
+					RenderTarget rt;
+					rt.m_clearValue = clearVal;
+
+					TextureViewPtr view;
 
 
 					if(getFormatInfo(inf.m_format).isDepthStencil())
 					if(getFormatInfo(inf.m_format).isDepthStencil())
 					{
 					{
@@ -503,33 +504,28 @@ TexturePtr Renderer::createAndClearRenderTarget(const TextureInitInfo& inf, Text
 							aspect |= DepthStencilAspectBit::kStencil;
 							aspect |= DepthStencilAspectBit::kStencil;
 						}
 						}
 
 
-						TextureViewPtr view = GrManager::getSingleton().newTextureView(TextureViewInitInfo(tex.get(), surf, aspect));
-
-						fbInit.m_depthStencilAttachment.m_textureView = std::move(view);
-						fbInit.m_depthStencilAttachment.m_loadOperation = AttachmentLoadOperation::kClear;
-						fbInit.m_depthStencilAttachment.m_stencilLoadOperation = AttachmentLoadOperation::kClear;
-						fbInit.m_depthStencilAttachment.m_clearValue = clearVal;
-
-						dsUsage = TextureUsageBit::kFramebufferWrite;
+						view = GrManager::getSingleton().newTextureView(TextureViewInitInfo(tex.get(), surf, aspect));
+						rt.m_aspect = aspect;
+						rt.m_view = view.get();
 					}
 					}
 					else
 					else
 					{
 					{
-						TextureViewPtr view = GrManager::getSingleton().newTextureView(TextureViewInitInfo(tex.get(), surf));
-
-						fbInit.m_colorAttachmentCount = 1;
-						fbInit.m_colorAttachments[0].m_textureView = view;
-						fbInit.m_colorAttachments[0].m_loadOperation = AttachmentLoadOperation::kClear;
-						fbInit.m_colorAttachments[0].m_clearValue = clearVal;
-
-						colUsage[0] = TextureUsageBit::kFramebufferWrite;
+						view = GrManager::getSingleton().newTextureView(TextureViewInitInfo(tex.get(), surf));
+						rt.m_view = view.get();
 					}
 					}
-					FramebufferPtr fb = GrManager::getSingleton().newFramebuffer(fbInit);
 
 
 					TextureBarrierInfo barrier = {tex.get(), TextureUsageBit::kNone, TextureUsageBit::kFramebufferWrite, surf};
 					TextureBarrierInfo barrier = {tex.get(), TextureUsageBit::kNone, TextureUsageBit::kFramebufferWrite, surf};
 					barrier.m_subresource.m_depthStencilAspect = tex->getDepthStencilAspect();
 					barrier.m_subresource.m_depthStencilAspect = tex->getDepthStencilAspect();
 					cmdb->setPipelineBarrier({&barrier, 1}, {}, {});
 					cmdb->setPipelineBarrier({&barrier, 1}, {}, {});
 
 
-					cmdb->beginRenderPass(fb.get(), colUsage, dsUsage);
+					if(getFormatInfo(inf.m_format).isDepthStencil())
+					{
+						cmdb->beginRenderPass({}, &rt);
+					}
+					else
+					{
+						cmdb->beginRenderPass({rt});
+					}
 					cmdb->endRenderPass();
 					cmdb->endRenderPass();
 
 
 					if(!!initialUsage)
 					if(!!initialUsage)
@@ -593,7 +589,10 @@ TexturePtr Renderer::createAndClearRenderTarget(const TextureInitInfo& inf, Text
 	}
 	}
 
 
 	cmdb->endRecording();
 	cmdb->endRecording();
-	GrManager::getSingleton().submit(cmdb.get());
+
+	FencePtr fence;
+	GrManager::getSingleton().submit(cmdb.get(), {}, &fence);
+	fence->clientWait(10.0_sec);
 
 
 	return tex;
 	return tex;
 }
 }

+ 3 - 6
AnKi/Renderer/Scale.cpp

@@ -140,9 +140,6 @@ Error Scale::init()
 		m_tonemapedRtDescr.bake();
 		m_tonemapedRtDescr.bake();
 	}
 	}
 
 
-	m_fbDescr.m_colorAttachmentCount = 1;
-	m_fbDescr.bake();
-
 	return Error::kNone;
 	return Error::kNone;
 }
 }
 
 
@@ -202,7 +199,7 @@ void Scale::populateRenderGraph(RenderingContext& ctx)
 		else
 		else
 		{
 		{
 			GraphicsRenderPassDescription& pass = ctx.m_renderGraphDescr.newGraphicsRenderPass("Scale");
 			GraphicsRenderPassDescription& pass = ctx.m_renderGraphDescr.newGraphicsRenderPass("Scale");
-			pass.setFramebufferInfo(m_fbDescr, {outRt});
+			pass.setRenderpassInfo({RenderTargetInfo(outRt)});
 			pass.newTextureDependency(inRt, TextureUsageBit::kSampledFragment);
 			pass.newTextureDependency(inRt, TextureUsageBit::kSampledFragment);
 			pass.newTextureDependency(outRt, TextureUsageBit::kFramebufferWrite);
 			pass.newTextureDependency(outRt, TextureUsageBit::kFramebufferWrite);
 
 
@@ -239,7 +236,7 @@ void Scale::populateRenderGraph(RenderingContext& ctx)
 		else
 		else
 		{
 		{
 			GraphicsRenderPassDescription& pass = ctx.m_renderGraphDescr.newGraphicsRenderPass("Sharpen");
 			GraphicsRenderPassDescription& pass = ctx.m_renderGraphDescr.newGraphicsRenderPass("Sharpen");
-			pass.setFramebufferInfo(m_fbDescr, {outRt});
+			pass.setRenderpassInfo({RenderTargetInfo(outRt)});
 			pass.newTextureDependency(inRt, TextureUsageBit::kSampledFragment);
 			pass.newTextureDependency(inRt, TextureUsageBit::kSampledFragment);
 			pass.newTextureDependency(outRt, TextureUsageBit::kFramebufferWrite);
 			pass.newTextureDependency(outRt, TextureUsageBit::kFramebufferWrite);
 
 
@@ -273,7 +270,7 @@ void Scale::populateRenderGraph(RenderingContext& ctx)
 		else
 		else
 		{
 		{
 			GraphicsRenderPassDescription& pass = ctx.m_renderGraphDescr.newGraphicsRenderPass("Sharpen");
 			GraphicsRenderPassDescription& pass = ctx.m_renderGraphDescr.newGraphicsRenderPass("Sharpen");
-			pass.setFramebufferInfo(m_fbDescr, {outRt});
+			pass.setRenderpassInfo({RenderTargetInfo(outRt)});
 			pass.newTextureDependency(inRt, TextureUsageBit::kSampledFragment);
 			pass.newTextureDependency(inRt, TextureUsageBit::kSampledFragment);
 			pass.newTextureDependency(outRt, TextureUsageBit::kFramebufferWrite);
 			pass.newTextureDependency(outRt, TextureUsageBit::kFramebufferWrite);
 
 

+ 0 - 1
AnKi/Renderer/Scale.h

@@ -54,7 +54,6 @@ private:
 
 
 	GrUpscalerPtr m_grUpscaler;
 	GrUpscalerPtr m_grUpscaler;
 
 
-	FramebufferDescription m_fbDescr;
 	RenderTargetDescription m_upscaleAndSharpenRtDescr;
 	RenderTargetDescription m_upscaleAndSharpenRtDescr;
 	RenderTargetDescription m_tonemapedRtDescr;
 	RenderTargetDescription m_tonemapedRtDescr;
 
 

+ 5 - 10
AnKi/Renderer/ShadowMapping.cpp

@@ -96,15 +96,6 @@ Error ShadowMapping::initInternal()
 	// Tiles
 	// Tiles
 	m_tileAlloc.init(m_tileCountBothAxis, m_tileCountBothAxis, kTileAllocHierarchyCount, true);
 	m_tileAlloc.init(m_tileCountBothAxis, m_tileCountBothAxis, kTileAllocHierarchyCount, true);
 
 
-	m_loadFbDescr.m_depthStencilAttachment.m_aspect = DepthStencilAspectBit::kDepth;
-	m_loadFbDescr.m_depthStencilAttachment.m_loadOperation = AttachmentLoadOperation::kLoad;
-	m_loadFbDescr.bake();
-
-	m_clearFbDescr.m_depthStencilAttachment.m_aspect = DepthStencilAspectBit::kDepth;
-	m_clearFbDescr.m_depthStencilAttachment.m_loadOperation = AttachmentLoadOperation::kClear;
-	m_clearFbDescr.m_depthStencilAttachment.m_clearValue.m_depthStencil.m_depth = 1.0f;
-	m_clearFbDescr.bake();
-
 	ANKI_CHECK(loadShaderProgram("ShaderBinaries/ShadowMappingClearDepth.ankiprogbin", m_clearDepthProg, m_clearDepthGrProg));
 	ANKI_CHECK(loadShaderProgram("ShaderBinaries/ShadowMappingClearDepth.ankiprogbin", m_clearDepthProg, m_clearDepthGrProg));
 	ANKI_CHECK(loadShaderProgram("ShaderBinaries/ShadowMappingVetVisibility.ankiprogbin", m_vetVisibilityProg, m_vetVisibilityGrProg));
 	ANKI_CHECK(loadShaderProgram("ShaderBinaries/ShadowMappingVetVisibility.ankiprogbin", m_vetVisibilityProg, m_vetVisibilityGrProg));
 
 
@@ -663,7 +654,11 @@ void ShadowMapping::createDrawShadowsPass(ConstWeakArray<ShadowSubpassInfo> subp
 
 
 	const Bool loadFb = !(subpasses.getSize() == 1 && subpasses[0].m_clearTileIndirectArgs.m_buffer == nullptr);
 	const Bool loadFb = !(subpasses.getSize() == 1 && subpasses[0].m_clearTileIndirectArgs.m_buffer == nullptr);
 
 
-	pass.setFramebufferInfo((loadFb) ? m_loadFbDescr : m_clearFbDescr, {}, m_runCtx.m_rt, {}, viewport[0], viewport[1], viewport[2], viewport[3]);
+	RenderTargetInfo smRti(m_runCtx.m_rt);
+	smRti.m_loadOperation = (loadFb) ? RenderTargetLoadOperation::kLoad : RenderTargetLoadOperation::kClear;
+	smRti.m_clearValue.m_depthStencil.m_depth = 1.0f;
+	smRti.m_aspect = DepthStencilAspectBit::kDepth;
+	pass.setRenderpassInfo({}, &smRti, viewport[0], viewport[1], viewport[2], viewport[3]);
 
 
 	pass.newBufferDependency((meshletVisOut.isFilled()) ? meshletVisOut.m_dependency : visOut.m_dependency, BufferUsageBit::kIndirectDraw);
 	pass.newBufferDependency((meshletVisOut.isFilled()) ? meshletVisOut.m_dependency : visOut.m_dependency, BufferUsageBit::kIndirectDraw);
 	pass.newTextureDependency(m_runCtx.m_rt, TextureUsageBit::kFramebufferWrite, TextureSubresourceInfo(DepthStencilAspectBit::kDepth));
 	pass.newTextureDependency(m_runCtx.m_rt, TextureUsageBit::kFramebufferWrite, TextureSubresourceInfo(DepthStencilAspectBit::kDepth));

+ 0 - 3
AnKi/Renderer/ShadowMapping.h

@@ -56,9 +56,6 @@ private:
 	U32 m_tileResolution = 0; ///< Tile resolution.
 	U32 m_tileResolution = 0; ///< Tile resolution.
 	U32 m_tileCountBothAxis = 0;
 	U32 m_tileCountBothAxis = 0;
 
 
-	FramebufferDescription m_loadFbDescr;
-	FramebufferDescription m_clearFbDescr;
-
 	ShaderProgramResourcePtr m_clearDepthProg;
 	ShaderProgramResourcePtr m_clearDepthProg;
 	ShaderProgramPtr m_clearDepthGrProg;
 	ShaderProgramPtr m_clearDepthGrProg;
 
 

+ 4 - 7
AnKi/Renderer/ShadowmapsResolve.cpp

@@ -39,10 +39,6 @@ Error ShadowmapsResolve::initInternal()
 	m_rtDescr = getRenderer().create2DRenderTargetDescription(width, height, Format::kR8G8B8A8_Unorm, "SM resolve");
 	m_rtDescr = getRenderer().create2DRenderTargetDescription(width, height, Format::kR8G8B8A8_Unorm, "SM resolve");
 	m_rtDescr.bake();
 	m_rtDescr.bake();
 
 
-	// Create FB descr
-	m_fbDescr.m_colorAttachmentCount = 1;
-	m_fbDescr.bake();
-
 	// Prog
 	// Prog
 	ANKI_CHECK(loadShaderProgram(
 	ANKI_CHECK(loadShaderProgram(
 		"ShaderBinaries/ShadowmapsResolve.ankiprogbin",
 		"ShaderBinaries/ShadowmapsResolve.ankiprogbin",
@@ -70,7 +66,7 @@ void ShadowmapsResolve::populateRenderGraph(RenderingContext& ctx)
 
 
 		rpass.newTextureDependency(m_runCtx.m_rt, TextureUsageBit::kStorageComputeWrite);
 		rpass.newTextureDependency(m_runCtx.m_rt, TextureUsageBit::kStorageComputeWrite);
 		rpass.newTextureDependency((m_quarterRez) ? getRenderer().getDepthDownscale().getRt() : getRenderer().getGBuffer().getDepthRt(),
 		rpass.newTextureDependency((m_quarterRez) ? getRenderer().getDepthDownscale().getRt() : getRenderer().getGBuffer().getDepthRt(),
-								   TextureUsageBit::kSampledCompute, TextureSurfaceInfo(0, 0, 0, 0));
+								   TextureUsageBit::kSampledCompute, TextureSurfaceInfo(0, 0, 0));
 		rpass.newTextureDependency(getRenderer().getShadowMapping().getShadowmapRt(), TextureUsageBit::kSampledCompute);
 		rpass.newTextureDependency(getRenderer().getShadowMapping().getShadowmapRt(), TextureUsageBit::kSampledCompute);
 
 
 		rpass.newBufferDependency(getRenderer().getClusterBinning().getClustersBufferHandle(), BufferUsageBit::kStorageComputeRead);
 		rpass.newBufferDependency(getRenderer().getClusterBinning().getClustersBufferHandle(), BufferUsageBit::kStorageComputeRead);
@@ -85,7 +81,8 @@ void ShadowmapsResolve::populateRenderGraph(RenderingContext& ctx)
 	else
 	else
 	{
 	{
 		GraphicsRenderPassDescription& rpass = rgraph.newGraphicsRenderPass("ResolveShadows");
 		GraphicsRenderPassDescription& rpass = rgraph.newGraphicsRenderPass("ResolveShadows");
-		rpass.setFramebufferInfo(m_fbDescr, {m_runCtx.m_rt});
+
+		rpass.setRenderpassInfo({RenderTargetInfo(m_runCtx.m_rt)});
 
 
 		rpass.setWork([this, &ctx](RenderPassWorkContext& rgraphCtx) {
 		rpass.setWork([this, &ctx](RenderPassWorkContext& rgraphCtx) {
 			run(rgraphCtx, ctx);
 			run(rgraphCtx, ctx);
@@ -93,7 +90,7 @@ void ShadowmapsResolve::populateRenderGraph(RenderingContext& ctx)
 
 
 		rpass.newTextureDependency(m_runCtx.m_rt, TextureUsageBit::kFramebufferWrite);
 		rpass.newTextureDependency(m_runCtx.m_rt, TextureUsageBit::kFramebufferWrite);
 		rpass.newTextureDependency((m_quarterRez) ? getRenderer().getDepthDownscale().getRt() : getRenderer().getGBuffer().getDepthRt(),
 		rpass.newTextureDependency((m_quarterRez) ? getRenderer().getDepthDownscale().getRt() : getRenderer().getGBuffer().getDepthRt(),
-								   TextureUsageBit::kSampledFragment, TextureSurfaceInfo(0, 0, 0, 0));
+								   TextureUsageBit::kSampledFragment, TextureSurfaceInfo(0, 0, 0));
 		rpass.newTextureDependency(getRenderer().getShadowMapping().getShadowmapRt(), TextureUsageBit::kSampledFragment);
 		rpass.newTextureDependency(getRenderer().getShadowMapping().getShadowmapRt(), TextureUsageBit::kSampledFragment);
 
 
 		rpass.newBufferDependency(getRenderer().getClusterBinning().getClustersBufferHandle(), BufferUsageBit::kStorageFragmentRead);
 		rpass.newBufferDependency(getRenderer().getClusterBinning().getClustersBufferHandle(), BufferUsageBit::kStorageFragmentRead);

+ 0 - 1
AnKi/Renderer/ShadowmapsResolve.h

@@ -43,7 +43,6 @@ public:
 	ShaderProgramResourcePtr m_prog;
 	ShaderProgramResourcePtr m_prog;
 	ShaderProgramPtr m_grProg;
 	ShaderProgramPtr m_grProg;
 	RenderTargetDescription m_rtDescr;
 	RenderTargetDescription m_rtDescr;
-	FramebufferDescription m_fbDescr;
 	Bool m_quarterRez = false;
 	Bool m_quarterRez = false;
 	ImageResourcePtr m_noiseImage;
 	ImageResourcePtr m_noiseImage;
 
 

+ 3 - 6
AnKi/Renderer/Ssao.cpp

@@ -52,9 +52,6 @@ Error Ssao::initInternal()
 		getRenderer().create2DRenderTargetDescription(rez.x(), rez.y(), Format::kR8G8B8A8_Snorm, "Bent normals + SSAO temp");
 		getRenderer().create2DRenderTargetDescription(rez.x(), rez.y(), Format::kR8G8B8A8_Snorm, "Bent normals + SSAO temp");
 	m_bentNormalsAndSsaoRtDescr.bake();
 	m_bentNormalsAndSsaoRtDescr.bake();
 
 
-	m_fbDescr.m_colorAttachmentCount = 1;
-	m_fbDescr.bake();
-
 	ANKI_CHECK(
 	ANKI_CHECK(
 		loadShaderProgram("ShaderBinaries/Ssao.ankiprogbin", {{"SPATIAL_DENOISE_QUALITY", g_ssaoSpatialQuality.get()}}, m_prog, m_grProg, "Ssao"));
 		loadShaderProgram("ShaderBinaries/Ssao.ankiprogbin", {{"SPATIAL_DENOISE_QUALITY", g_ssaoSpatialQuality.get()}}, m_prog, m_grProg, "Ssao"));
 	ANKI_CHECK(loadShaderProgram("ShaderBinaries/Ssao.ankiprogbin", {{"SPATIAL_DENOISE_QUALITY", g_ssaoSpatialQuality.get()}}, m_prog,
 	ANKI_CHECK(loadShaderProgram("ShaderBinaries/Ssao.ankiprogbin", {{"SPATIAL_DENOISE_QUALITY", g_ssaoSpatialQuality.get()}}, m_prog,
@@ -119,7 +116,7 @@ void Ssao::populateRenderGraph(RenderingContext& ctx)
 		else
 		else
 		{
 		{
 			GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("SSAO");
 			GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("SSAO");
-			pass.setFramebufferInfo(m_fbDescr, {finalRt}, {});
+			pass.setRenderpassInfo({RenderTargetInfo(finalRt)});
 			ppass = &pass;
 			ppass = &pass;
 		}
 		}
 
 
@@ -182,7 +179,7 @@ void Ssao::populateRenderGraph(RenderingContext& ctx)
 		else
 		else
 		{
 		{
 			GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("SSAO spatial denoise");
 			GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("SSAO spatial denoise");
-			pass.setFramebufferInfo(m_fbDescr, {bentNormalsAndSsaoTempRt}, {});
+			pass.setRenderpassInfo({RenderTargetInfo(bentNormalsAndSsaoTempRt)});
 			ppass = &pass;
 			ppass = &pass;
 		}
 		}
 
 
@@ -231,7 +228,7 @@ void Ssao::populateRenderGraph(RenderingContext& ctx)
 		else
 		else
 		{
 		{
 			GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("SSAO temporal denoise");
 			GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("SSAO temporal denoise");
-			pass.setFramebufferInfo(m_fbDescr, {finalRt}, {});
+			pass.setRenderpassInfo({RenderTargetInfo(finalRt)});
 			ppass = &pass;
 			ppass = &pass;
 		}
 		}
 
 

+ 0 - 1
AnKi/Renderer/Ssao.h

@@ -45,7 +45,6 @@ public:
 	ShaderProgramPtr m_spatialDenoiseGrProg;
 	ShaderProgramPtr m_spatialDenoiseGrProg;
 	ShaderProgramPtr m_tempralDenoiseGrProg;
 	ShaderProgramPtr m_tempralDenoiseGrProg;
 
 
-	FramebufferDescription m_fbDescr;
 	RenderTargetDescription m_bentNormalsAndSsaoRtDescr;
 	RenderTargetDescription m_bentNormalsAndSsaoRtDescr;
 
 
 	Array<TexturePtr, 2> m_tex;
 	Array<TexturePtr, 2> m_tex;

+ 2 - 4
AnKi/Renderer/Ssr.cpp

@@ -64,9 +64,6 @@ Error Ssr::initInternal()
 	m_ssrRtDescr = getRenderer().create2DRenderTargetDescription(rez.x(), rez.y(), Format::kR16G16B16A16_Sfloat, "SSR");
 	m_ssrRtDescr = getRenderer().create2DRenderTargetDescription(rez.x(), rez.y(), Format::kR16G16B16A16_Sfloat, "SSR");
 	m_ssrRtDescr.bake();
 	m_ssrRtDescr.bake();
 
 
-	m_fbDescr.m_colorAttachmentCount = 1;
-	m_fbDescr.bake();
-
 	ANKI_CHECK(loadShaderProgram("ShaderBinaries/Ssr.ankiprogbin", {}, m_prog, m_ssrGrProg, "Ssr"));
 	ANKI_CHECK(loadShaderProgram("ShaderBinaries/Ssr.ankiprogbin", {}, m_prog, m_ssrGrProg, "Ssr"));
 
 
 	return Error::kNone;
 	return Error::kNone;
@@ -96,7 +93,8 @@ void Ssr::populateRenderGraph(RenderingContext& ctx)
 	{
 	{
 		// TODO
 		// TODO
 		GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("SSR");
 		GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("SSR");
-		pass.setFramebufferInfo(m_fbDescr, {m_runCtx.m_ssrRt}, {});
+
+		pass.setRenderpassInfo({RenderTargetInfo(m_runCtx.m_ssrRt)});
 
 
 		ppass = &pass;
 		ppass = &pass;
 
 

+ 0 - 1
AnKi/Renderer/Ssr.h

@@ -44,7 +44,6 @@ public:
 	ShaderProgramPtr m_ssrGrProg;
 	ShaderProgramPtr m_ssrGrProg;
 
 
 	RenderTargetDescription m_ssrRtDescr;
 	RenderTargetDescription m_ssrRtDescr;
-	FramebufferDescription m_fbDescr;
 
 
 	class
 	class
 	{
 	{

+ 1 - 4
AnKi/Renderer/TemporalAA.cpp

@@ -49,9 +49,6 @@ Error TemporalAA::initInternal()
 		"TemporalAA Tonemapped");
 		"TemporalAA Tonemapped");
 	m_tonemappedRtDescr.bake();
 	m_tonemappedRtDescr.bake();
 
 
-	m_fbDescr.m_colorAttachmentCount = 2;
-	m_fbDescr.bake();
-
 	return Error::kNone;
 	return Error::kNone;
 }
 }
 
 
@@ -95,7 +92,7 @@ void TemporalAA::populateRenderGraph(RenderingContext& ctx)
 	else
 	else
 	{
 	{
 		GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("TemporalAA");
 		GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("TemporalAA");
-		pass.setFramebufferInfo(m_fbDescr, {m_runCtx.m_renderRt, m_runCtx.m_tonemappedRt});
+		pass.setRenderpassInfo({RenderTargetInfo(m_runCtx.m_renderRt), RenderTargetInfo(m_runCtx.m_tonemappedRt)});
 
 
 		pass.newTextureDependency(m_runCtx.m_renderRt, TextureUsageBit::kFramebufferWrite);
 		pass.newTextureDependency(m_runCtx.m_renderRt, TextureUsageBit::kFramebufferWrite);
 		pass.newTextureDependency(m_runCtx.m_tonemappedRt, TextureUsageBit::kFramebufferWrite);
 		pass.newTextureDependency(m_runCtx.m_tonemappedRt, TextureUsageBit::kFramebufferWrite);

+ 0 - 1
AnKi/Renderer/TemporalAA.h

@@ -39,7 +39,6 @@ private:
 	ShaderProgramPtr m_grProg;
 	ShaderProgramPtr m_grProg;
 
 
 	RenderTargetDescription m_tonemappedRtDescr;
 	RenderTargetDescription m_tonemappedRtDescr;
-	FramebufferDescription m_fbDescr;
 
 
 	class
 	class
 	{
 	{

+ 5 - 6
AnKi/Renderer/Utils/HzbGenerator.cpp

@@ -81,11 +81,6 @@ Error HzbGenerator::init()
 	memcpy(mappedMem, kBoxIndices, sizeof(kBoxIndices));
 	memcpy(mappedMem, kBoxIndices, sizeof(kBoxIndices));
 	m_boxIndexBuffer->unmap();
 	m_boxIndexBuffer->unmap();
 
 
-	m_fbDescr.m_depthStencilAttachment.m_aspect = DepthStencilAspectBit::kDepth;
-	m_fbDescr.m_depthStencilAttachment.m_clearValue.m_depthStencil.m_depth = 0.0f;
-	m_fbDescr.m_depthStencilAttachment.m_loadOperation = AttachmentLoadOperation::kClear;
-	m_fbDescr.bake();
-
 	return Error::kNone;
 	return Error::kNone;
 }
 }
 
 
@@ -267,7 +262,11 @@ void HzbGenerator::populateRenderGraphDirectionalLight(const HzbDirectionalLight
 
 
 		GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("HZB boxes");
 		GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("HZB boxes");
 
 
-		pass.setFramebufferInfo(m_fbDescr, {}, depthRts[i]);
+		RenderTargetInfo depthRt(depthRts[i]);
+		depthRt.m_aspect = DepthStencilAspectBit::kDepth;
+		depthRt.m_clearValue.m_depthStencil.m_depth = 0.0f;
+		depthRt.m_loadOperation = RenderTargetLoadOperation::kClear;
+		pass.setRenderpassInfo({}, &depthRt);
 
 
 		pass.newTextureDependency(maxDepthRt, TextureUsageBit::kSampledFragment);
 		pass.newTextureDependency(maxDepthRt, TextureUsageBit::kSampledFragment);
 		pass.newTextureDependency(depthRts[i], TextureUsageBit::kFramebufferWrite, DepthStencilAspectBit::kDepth);
 		pass.newTextureDependency(depthRts[i], TextureUsageBit::kFramebufferWrite, DepthStencilAspectBit::kDepth);

+ 0 - 2
AnKi/Renderer/Utils/HzbGenerator.h

@@ -76,8 +76,6 @@ private:
 
 
 	BufferPtr m_boxIndexBuffer;
 	BufferPtr m_boxIndexBuffer;
 
 
-	FramebufferDescription m_fbDescr;
-
 #if ANKI_ASSERTIONS_ENABLED
 #if ANKI_ASSERTIONS_ENABLED
 	// Some helper things to make sure that we don't re-use the counters inside a frame
 	// Some helper things to make sure that we don't re-use the counters inside a frame
 	mutable U64 m_crntFrame = 0;
 	mutable U64 m_crntFrame = 0;

+ 1 - 1
AnKi/Renderer/VrsSriGeneration.cpp

@@ -31,7 +31,7 @@ Error VrsSriGeneration::initInternal()
 		return Error::kNone;
 		return Error::kNone;
 	}
 	}
 
 
-	m_sriTexelDimension = GrManager::getSingleton().getDeviceCapabilities().m_minShadingRateImageTexelSize;
+	m_sriTexelDimension = U8(GrManager::getSingleton().getDeviceCapabilities().m_minShadingRateImageTexelSize);
 	ANKI_ASSERT(m_sriTexelDimension == 8 || m_sriTexelDimension == 16);
 	ANKI_ASSERT(m_sriTexelDimension == 8 || m_sriTexelDimension == 16);
 	const UVec2 rez = (getRenderer().getInternalResolution() + m_sriTexelDimension - 1) / m_sriTexelDimension;
 	const UVec2 rez = (getRenderer().getInternalResolution() + m_sriTexelDimension - 1) / m_sriTexelDimension;
 
 

+ 2 - 2
AnKi/Renderer/VrsSriGeneration.h

@@ -39,7 +39,7 @@ public:
 		return m_runCtx.m_downscaledRt;
 		return m_runCtx.m_downscaledRt;
 	}
 	}
 
 
-	U32 getSriTexelDimension() const
+	U8 getSriTexelDimension() const
 	{
 	{
 		return m_sriTexelDimension;
 		return m_sriTexelDimension;
 	}
 	}
@@ -58,7 +58,7 @@ public:
 	TexturePtr m_downscaledSriTex;
 	TexturePtr m_downscaledSriTex;
 	Bool m_sriTexImportedOnce = false;
 	Bool m_sriTexImportedOnce = false;
 
 
-	U32 m_sriTexelDimension = 16;
+	U8 m_sriTexelDimension = 16;
 
 
 	class
 	class
 	{
 	{

+ 3 - 3
AnKi/Resource/ImageResource.cpp

@@ -273,7 +273,7 @@ Error ImageResource::load(LoadingContext& ctx)
 			}
 			}
 			else
 			else
 			{
 			{
-				barrier.m_subresource = TextureSurfaceInfo(mip, 0, face, layer);
+				barrier.m_subresource = TextureSurfaceInfo(mip, face, layer);
 			}
 			}
 		}
 		}
 		cmdb->setPipelineBarrier({&barriers[0], barrierCount}, {}, {});
 		cmdb->setPipelineBarrier({&barriers[0], barrierCount}, {}, {});
@@ -324,7 +324,7 @@ Error ImageResource::load(LoadingContext& ctx)
 			}
 			}
 			else
 			else
 			{
 			{
-				subresource = TextureSubresourceInfo(TextureSurfaceInfo(mip, 0, face, layer));
+				subresource = TextureSubresourceInfo(TextureSurfaceInfo(mip, face, layer));
 			}
 			}
 
 
 			TextureViewPtr tmpView = GrManager::getSingleton().newTextureView(TextureViewInitInfo(ctx.m_tex.get(), subresource, "RsrcTmp"));
 			TextureViewPtr tmpView = GrManager::getSingleton().newTextureView(TextureViewInitInfo(ctx.m_tex.get(), subresource, "RsrcTmp"));
@@ -349,7 +349,7 @@ Error ImageResource::load(LoadingContext& ctx)
 			}
 			}
 			else
 			else
 			{
 			{
-				barrier.m_subresource = TextureSurfaceInfo(mip, 0, face, layer);
+				barrier.m_subresource = TextureSurfaceInfo(mip, face, layer);
 			}
 			}
 		}
 		}
 		cmdb->setPipelineBarrier({&barriers[0], barrierCount}, {}, {});
 		cmdb->setPipelineBarrier({&barriers[0], barrierCount}, {}, {});

+ 1 - 0
AnKi/Scene/Components/GlobalIlluminationProbeComponent.cpp

@@ -10,6 +10,7 @@
 #include <AnKi/Core/CVarSet.h>
 #include <AnKi/Core/CVarSet.h>
 #include <AnKi/Resource/ResourceManager.h>
 #include <AnKi/Resource/ResourceManager.h>
 #include <AnKi/Gr/Texture.h>
 #include <AnKi/Gr/Texture.h>
+#include <AnKi/Gr/TextureView.h>
 #include <AnKi/Gr/CommandBuffer.h>
 #include <AnKi/Gr/CommandBuffer.h>
 
 
 namespace anki {
 namespace anki {

+ 1 - 1
AnKi/Ui/Font.cpp

@@ -83,7 +83,7 @@ void Font::createTexture(const void* data, U32 width, U32 height)
 	m_imFontAtlas->SetTexID(UiImageId(m_texView));
 	m_imFontAtlas->SetTexID(UiImageId(m_texView));
 
 
 	// Do the copy
 	// Do the copy
-	constexpr TextureSurfaceInfo surf(0, 0, 0, 0);
+	constexpr TextureSurfaceInfo surf(0, 0, 0);
 	CommandBufferInitInfo cmdbInit;
 	CommandBufferInitInfo cmdbInit;
 	cmdbInit.m_flags = CommandBufferFlag::kGeneralWork | CommandBufferFlag::kSmallBatch;
 	cmdbInit.m_flags = CommandBufferFlag::kGeneralWork | CommandBufferFlag::kSmallBatch;
 	CommandBufferPtr cmdb = GrManager::getSingleton().newCommandBuffer(cmdbInit);
 	CommandBufferPtr cmdb = GrManager::getSingleton().newCommandBuffer(cmdbInit);

+ 46 - 130
Tests/Gr/Gr.cpp

@@ -318,20 +318,6 @@ static ShaderProgramPtr createProgram(CString vertSrc, CString fragSrc, GrManage
 	return gr.newShaderProgram(inf);
 	return gr.newShaderProgram(inf);
 }
 }
 
 
-static FramebufferPtr createColorFb(GrManager& gr, TexturePtr tex)
-{
-	TextureViewInitInfo init;
-	init.m_texture = tex.get();
-	TextureViewPtr view = gr.newTextureView(init);
-
-	FramebufferInitInfo fbinit;
-	fbinit.m_colorAttachmentCount = 1;
-	fbinit.m_colorAttachments[0].m_clearValue.m_colorf = {{1.0, 0.0, 1.0, 1.0}};
-	fbinit.m_colorAttachments[0].m_textureView = view;
-
-	return gr.newFramebuffer(fbinit);
-}
-
 static void createCube(GrManager& gr, BufferPtr& verts, BufferPtr& indices)
 static void createCube(GrManager& gr, BufferPtr& verts, BufferPtr& indices)
 {
 {
 	static const Array<F32, 8 * 3> pos = {{1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1}};
 	static const Array<F32, 8 * 3> pos = {{1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1}};
@@ -486,21 +472,31 @@ ANKI_TEST(Gr, ClearScreen)
 	COMMON_BEGIN()
 	COMMON_BEGIN()
 	ANKI_TEST_LOGI("Expect to see a magenta background");
 	ANKI_TEST_LOGI("Expect to see a magenta background");
 
 
-	U iterations = 100;
+	constexpr U kIterations = 100;
+	U iterations = kIterations;
 	while(iterations--)
 	while(iterations--)
 	{
 	{
 		HighRezTimer timer;
 		HighRezTimer timer;
 		timer.start();
 		timer.start();
 
 
 		TexturePtr presentTex = g_gr->acquireNextPresentableTexture();
 		TexturePtr presentTex = g_gr->acquireNextPresentableTexture();
-		FramebufferPtr fb = createColorFb(*g_gr, presentTex);
 
 
 		CommandBufferInitInfo cinit;
 		CommandBufferInitInfo cinit;
 		cinit.m_flags = CommandBufferFlag::kGeneralWork | CommandBufferFlag::kSmallBatch;
 		cinit.m_flags = CommandBufferFlag::kGeneralWork | CommandBufferFlag::kSmallBatch;
 		CommandBufferPtr cmdb = g_gr->newCommandBuffer(cinit);
 		CommandBufferPtr cmdb = g_gr->newCommandBuffer(cinit);
 
 
 		presentBarrierA(cmdb, presentTex);
 		presentBarrierA(cmdb, presentTex);
-		cmdb->beginRenderPass(fb.get(), {TextureUsageBit::kFramebufferWrite}, {});
+
+		TextureViewInitInfo init;
+		init.m_texture = presentTex.get();
+		TextureViewPtr view = g_gr->newTextureView(init);
+
+		RenderTarget rt;
+		rt.m_view = view.get();
+		const F32 col = 1.0f - F32(iterations) / F32(kIterations);
+		rt.m_clearValue.m_colorf = {col, 0.0f, col, 1.0f};
+		cmdb->beginRenderPass({rt});
+
 		cmdb->endRenderPass();
 		cmdb->endRenderPass();
 		presentBarrierB(cmdb, presentTex);
 		presentBarrierB(cmdb, presentTex);
 		cmdb->endRecording();
 		cmdb->endRecording();
@@ -521,6 +517,7 @@ ANKI_TEST(Gr, ClearScreen)
 
 
 ANKI_TEST(Gr, SimpleDrawcall)
 ANKI_TEST(Gr, SimpleDrawcall)
 {
 {
+#if 0
 	COMMON_BEGIN()
 	COMMON_BEGIN()
 
 
 	constexpr const char* kVertSrc = R"(
 	constexpr const char* kVertSrc = R"(
@@ -562,7 +559,15 @@ void main()
 		cmdb->setViewport(0, 0, g_win->getWidth(), g_win->getHeight());
 		cmdb->setViewport(0, 0, g_win->getWidth(), g_win->getHeight());
 		cmdb->bindShaderProgram(prog.get());
 		cmdb->bindShaderProgram(prog.get());
 		presentBarrierA(cmdb, presentTex);
 		presentBarrierA(cmdb, presentTex);
-		cmdb->beginRenderPass(fb.get(), {{TextureUsageBit::kFramebufferWrite}}, {});
+
+		TextureViewInitInfo init;
+		init.m_texture = presentTex.get();
+		TextureViewPtr view = g_gr->newTextureView(init);
+
+		RenderTarget rt;
+		rt.m_view = view.get();
+		cmdb->beginRenderPass({rt});
+
 		cmdb->draw(PrimitiveTopology::kTriangles, 3);
 		cmdb->draw(PrimitiveTopology::kTriangles, 3);
 		cmdb->endRenderPass();
 		cmdb->endRenderPass();
 		presentBarrierB(cmdb, presentTex);
 		presentBarrierB(cmdb, presentTex);
@@ -580,6 +585,7 @@ void main()
 	}
 	}
 
 
 	COMMON_END()
 	COMMON_END()
+#endif
 }
 }
 
 
 ANKI_TEST(Gr, ViewportAndScissor)
 ANKI_TEST(Gr, ViewportAndScissor)
@@ -654,6 +660,7 @@ ANKI_TEST(Gr, ViewportAndScissor)
 
 
 ANKI_TEST(Gr, ViewportAndScissorOffscreen)
 ANKI_TEST(Gr, ViewportAndScissorOffscreen)
 {
 {
+#if 0
 	srand(U32(time(nullptr)));
 	srand(U32(time(nullptr)));
 	COMMON_BEGIN()
 	COMMON_BEGIN()
 
 
@@ -781,6 +788,7 @@ void main()
 	}
 	}
 
 
 	COMMON_END()
 	COMMON_END()
+#endif
 }
 }
 
 
 ANKI_TEST(Gr, Buffer)
 ANKI_TEST(Gr, Buffer)
@@ -816,6 +824,7 @@ ANKI_TEST(Gr, Buffer)
 
 
 ANKI_TEST(Gr, DrawWithUniforms)
 ANKI_TEST(Gr, DrawWithUniforms)
 {
 {
+#if 0
 	COMMON_BEGIN()
 	COMMON_BEGIN()
 
 
 	// A non-uploaded buffer
 	// A non-uploaded buffer
@@ -923,10 +932,12 @@ float4 main(VertOut i) : SV_TARGET0
 	}
 	}
 
 
 	COMMON_END()
 	COMMON_END()
+#endif
 }
 }
 
 
 ANKI_TEST(Gr, DrawWithVertex)
 ANKI_TEST(Gr, DrawWithVertex)
 {
 {
+#if 0
 	COMMON_BEGIN()
 	COMMON_BEGIN()
 
 
 	// The buffers
 	// The buffers
@@ -1004,6 +1015,7 @@ ANKI_TEST(Gr, DrawWithVertex)
 	}
 	}
 
 
 	COMMON_END()
 	COMMON_END()
+#endif
 }
 }
 
 
 ANKI_TEST(Gr, Sampler)
 ANKI_TEST(Gr, Sampler)
@@ -1043,6 +1055,7 @@ ANKI_TEST(Gr, Texture)
 
 
 ANKI_TEST(Gr, DrawWithTexture)
 ANKI_TEST(Gr, DrawWithTexture)
 {
 {
+#if 0
 	COMMON_BEGIN()
 	COMMON_BEGIN()
 
 
 	//
 	//
@@ -1225,6 +1238,7 @@ void main()
 	}
 	}
 
 
 	COMMON_END()
 	COMMON_END()
+#endif
 }
 }
 
 
 static void drawOffscreenDrawcalls([[maybe_unused]] GrManager& gr, ShaderProgramPtr prog, CommandBufferPtr cmdb, U32 viewPortSize,
 static void drawOffscreenDrawcalls([[maybe_unused]] GrManager& gr, ShaderProgramPtr prog, CommandBufferPtr cmdb, U32 viewPortSize,
@@ -1269,6 +1283,7 @@ static void drawOffscreenDrawcalls([[maybe_unused]] GrManager& gr, ShaderProgram
 
 
 static void drawOffscreen(GrManager& gr)
 static void drawOffscreen(GrManager& gr)
 {
 {
+#if 0
 	//
 	//
 	// Create textures
 	// Create textures
 	//
 	//
@@ -1380,6 +1395,7 @@ static void drawOffscreen(GrManager& gr)
 			HighRezTimer::sleep(TICK - timer.getElapsedTime());
 			HighRezTimer::sleep(TICK - timer.getElapsedTime());
 		}
 		}
 	}
 	}
+#endif
 }
 }
 
 
 ANKI_TEST(Gr, DrawOffscreen)
 ANKI_TEST(Gr, DrawOffscreen)
@@ -1393,6 +1409,7 @@ ANKI_TEST(Gr, DrawOffscreen)
 
 
 ANKI_TEST(Gr, ImageLoadStore)
 ANKI_TEST(Gr, ImageLoadStore)
 {
 {
+#if 0
 	COMMON_BEGIN()
 	COMMON_BEGIN()
 
 
 	SamplerInitInfo samplerInit;
 	SamplerInitInfo samplerInit;
@@ -1496,10 +1513,12 @@ ANKI_TEST(Gr, ImageLoadStore)
 	}
 	}
 
 
 	COMMON_END()
 	COMMON_END()
+#endif
 }
 }
 
 
 ANKI_TEST(Gr, 3DTextures)
 ANKI_TEST(Gr, 3DTextures)
 {
 {
+#if 0
 	COMMON_BEGIN()
 	COMMON_BEGIN()
 
 
 	SamplerInitInfo samplerInit;
 	SamplerInitInfo samplerInit;
@@ -1609,6 +1628,7 @@ ANKI_TEST(Gr, 3DTextures)
 	}
 	}
 
 
 	COMMON_END()
 	COMMON_END()
+#endif
 }
 }
 
 
 static RenderTargetDescription newRTDescr(CString name)
 static RenderTargetDescription newRTDescr(CString name)
@@ -1667,7 +1687,7 @@ ANKI_TEST(Gr, RenderGraph)
 	RenderTargetHandle giGiLightRt = descr.importRenderTarget(dummyTex.get(), TextureUsageBit::kSampledFragment);
 	RenderTargetHandle giGiLightRt = descr.importRenderTarget(dummyTex.get(), TextureUsageBit::kSampledFragment);
 	for(U32 faceIdx = 0; faceIdx < 6; ++faceIdx)
 	for(U32 faceIdx = 0; faceIdx < 6; ++faceIdx)
 	{
 	{
-		TextureSubresourceInfo subresource(TextureSurfaceInfo(0, 0, faceIdx, 0));
+		TextureSubresourceInfo subresource(TextureSurfaceInfo(0, faceIdx, 0));
 
 
 		GraphicsRenderPassDescription& pass = descr.newGraphicsRenderPass(String().sprintf("GI lp%u", faceIdx).toCString());
 		GraphicsRenderPassDescription& pass = descr.newGraphicsRenderPass(String().sprintf("GI lp%u", faceIdx).toCString());
 		pass.newTextureDependency(giGiLightRt, TextureUsageBit::kFramebufferWrite, subresource);
 		pass.newTextureDependency(giGiLightRt, TextureUsageBit::kFramebufferWrite, subresource);
@@ -1684,7 +1704,7 @@ ANKI_TEST(Gr, RenderGraph)
 
 
 			for(U32 mip = 0; mip < GI_MIP_COUNT; ++mip)
 			for(U32 mip = 0; mip < GI_MIP_COUNT; ++mip)
 			{
 			{
-				TextureSurfaceInfo surf(mip, 0, faceIdx, 0);
+				TextureSurfaceInfo surf(mip, faceIdx, 0);
 				pass.newTextureDependency(giGiLightRt, TextureUsageBit::kGenerateMipmaps, surf);
 				pass.newTextureDependency(giGiLightRt, TextureUsageBit::kGenerateMipmaps, surf);
 			}
 			}
 		}
 		}
@@ -1911,9 +1931,9 @@ void main()
 	subresource.m_mipmapCount = texInit.m_mipmapCount;
 	subresource.m_mipmapCount = texInit.m_mipmapCount;
 	setTextureBarrier(cmdb, tex, TextureUsageBit::kNone, TextureUsageBit::kTransferDestination, subresource);
 	setTextureBarrier(cmdb, tex, TextureUsageBit::kNone, TextureUsageBit::kTransferDestination, subresource);
 	cmdb->copyBufferToTextureView(uploadBuff.get(), 0, uploadBuff->getSize(),
 	cmdb->copyBufferToTextureView(uploadBuff.get(), 0, uploadBuff->getSize(),
-								  g_gr->newTextureView(TextureViewInitInfo(tex.get(), TextureSurfaceInfo(0, 0, 0, 0))).get());
+								  g_gr->newTextureView(TextureViewInitInfo(tex.get(), TextureSurfaceInfo(0, 0, 0))).get());
 	cmdb->copyBufferToTextureView(uploadBuff2.get(), 0, uploadBuff2->getSize(),
 	cmdb->copyBufferToTextureView(uploadBuff2.get(), 0, uploadBuff2->getSize(),
-								  g_gr->newTextureView(TextureViewInitInfo(tex.get(), TextureSurfaceInfo(1, 0, 0, 0))).get());
+								  g_gr->newTextureView(TextureViewInitInfo(tex.get(), TextureSurfaceInfo(1, 0, 0))).get());
 
 
 	setTextureBarrier(cmdb, tex, TextureUsageBit::kTransferDestination, TextureUsageBit::kSampledCompute, subresource);
 	setTextureBarrier(cmdb, tex, TextureUsageBit::kTransferDestination, TextureUsageBit::kSampledCompute, subresource);
 	cmdb->bindShaderProgram(prog.get());
 	cmdb->bindShaderProgram(prog.get());
@@ -1938,116 +1958,9 @@ void main()
 	COMMON_END()
 	COMMON_END()
 }
 }
 
 
-ANKI_TEST(Gr, SpecConsts)
-{
-	COMMON_BEGIN()
-
-	static const char* VERT_SRC = R"(
-layout(constant_id = 0) const int const0 = 0;
-layout(constant_id = 2) const float const1 = 0.0;
-
-out gl_PerVertex
-{
-	vec4 gl_Position;
-};
-
-layout(location = 0) flat out int out_const0;
-layout(location = 1) flat out float out_const1;
-
-void main()
-{
-	vec2 uv = vec2(gl_VertexID & 1, gl_VertexID >> 1) * 2.0;
-	vec2 pos = uv * 2.0 - 1.0;
-
-	gl_Position = vec4(pos, 0.0, 1.0);
-
-	out_const0 = const0;
-	out_const1 = const1;
-}
-)";
-
-	static const char* FRAG_SRC = R"(
-layout(constant_id = 0) const int const0 = 0;
-layout(constant_id = 1) const float const1 = 0.0;
-
-layout(location = 0) flat in int in_const0;
-layout(location = 1) flat in float in_const1;
-
-layout(location = 0) out vec4 out_color;
-
-layout(set = 0, binding = 0) buffer s_
-{
-	uvec4 u_result;
-};
-
-void main()
-{
-	out_color = vec4(1.0);
-
-	if(gl_FragCoord.x == 0.5 && gl_FragCoord.y == 0.5)
-	{
-		if(in_const0 != 2147483647 || in_const1 != 1234.5678 || const0 != -2147483647 || const1 != -1.0)
-		{
-			u_result = uvec4(1u);
-		}
-		else
-		{
-			u_result = uvec4(2u);
-		}
-	}
-}
-)";
-
-	ShaderPtr vert =
-		createShader(VERT_SRC, ShaderType::kVertex, *g_gr,
-					 Array<ShaderSpecializationConstValue, 3>{{ShaderSpecializationConstValue(2147483647), ShaderSpecializationConstValue(-1.0f),
-															   ShaderSpecializationConstValue(1234.5678f)}});
-	ShaderPtr frag =
-		createShader(FRAG_SRC, ShaderType::kFragment, *g_gr,
-					 Array<ShaderSpecializationConstValue, 2>{{ShaderSpecializationConstValue(-2147483647), ShaderSpecializationConstValue(-1.0f)}});
-	ShaderProgramInitInfo sinf;
-	sinf.m_graphicsShaders[ShaderType::kVertex] = vert.get();
-	sinf.m_graphicsShaders[ShaderType::kFragment] = frag.get();
-	ShaderProgramPtr prog = g_gr->newShaderProgram(sinf);
-
-	// Create the result buffer
-	BufferPtr resultBuff = g_gr->newBuffer(BufferInitInfo(sizeof(UVec4), BufferUsageBit::kStorageComputeWrite, BufferMapAccessBit::kRead));
-
-	// Draw
-
-	CommandBufferInitInfo cinit;
-	cinit.m_flags = CommandBufferFlag::kGeneralWork;
-	CommandBufferPtr cmdb = g_gr->newCommandBuffer(cinit);
-
-	cmdb->setViewport(0, 0, WIDTH, HEIGHT);
-	cmdb->bindShaderProgram(prog.get());
-	cmdb->bindStorageBuffer(0, 0, resultBuff.get(), 0, resultBuff->getSize());
-	TexturePtr presentTex = g_gr->acquireNextPresentableTexture();
-	FramebufferPtr dfb = createColorFb(*g_gr, presentTex);
-	presentBarrierA(cmdb, presentTex);
-	cmdb->beginRenderPass(dfb.get(), {TextureUsageBit::kFramebufferWrite}, {});
-	cmdb->draw(PrimitiveTopology::kTriangles, 3);
-	cmdb->endRenderPass();
-	presentBarrierB(cmdb, presentTex);
-	cmdb->endRecording();
-	GrManager::getSingleton().submit(cmdb.get());
-
-	g_gr->swapBuffers();
-	g_gr->finish();
-
-	// Get the result
-	UVec4* result = static_cast<UVec4*>(resultBuff->map(0, resultBuff->getSize(), BufferMapAccessBit::kRead));
-	ANKI_TEST_EXPECT_EQ(result->x(), 2);
-	ANKI_TEST_EXPECT_EQ(result->y(), 2);
-	ANKI_TEST_EXPECT_EQ(result->z(), 2);
-	ANKI_TEST_EXPECT_EQ(result->w(), 2);
-	resultBuff->unmap();
-
-	COMMON_END()
-}
-
 ANKI_TEST(Gr, PushConsts)
 ANKI_TEST(Gr, PushConsts)
 {
 {
+#if 0
 	COMMON_BEGIN()
 	COMMON_BEGIN()
 
 
 	static const char* VERT_SRC = R"(
 	static const char* VERT_SRC = R"(
@@ -2171,6 +2084,7 @@ void main()
 	resultBuff->unmap();
 	resultBuff->unmap();
 
 
 	COMMON_END()
 	COMMON_END()
+#endif
 }
 }
 
 
 ANKI_TEST(Gr, BindingWithArray)
 ANKI_TEST(Gr, BindingWithArray)
@@ -2457,6 +2371,7 @@ void main()
 
 
 ANKI_TEST(Gr, RayQuery)
 ANKI_TEST(Gr, RayQuery)
 {
 {
+#if 0
 	COMMON_BEGIN();
 	COMMON_BEGIN();
 
 
 	const Bool useRayTracing = g_gr->getDeviceCapabilities().m_rayTracingEnabled;
 	const Bool useRayTracing = g_gr->getDeviceCapabilities().m_rayTracingEnabled;
@@ -2726,6 +2641,7 @@ void main()
 	}
 	}
 
 
 	COMMON_END();
 	COMMON_END();
+#endif
 }
 }
 
 
 static void createCubeBuffers(GrManager& gr, Vec3 min, Vec3 max, BufferPtr& indexBuffer, BufferPtr& vertBuffer, Bool turnInsideOut = false)
 static void createCubeBuffers(GrManager& gr, Vec3 min, Vec3 max, BufferPtr& indexBuffer, BufferPtr& vertBuffer, Bool turnInsideOut = false)

+ 4 - 7
Tests/Gr/GrMeshShaders.cpp

@@ -226,12 +226,6 @@ float3 main(VertOut input) : SV_TARGET0
 			TextureViewInitInfo viewInit(swapchainTex.get(), "RTView");
 			TextureViewInitInfo viewInit(swapchainTex.get(), "RTView");
 			TextureViewPtr swapchainView = gr->newTextureView(viewInit);
 			TextureViewPtr swapchainView = gr->newTextureView(viewInit);
 
 
-			FramebufferInitInfo fbInit("FB");
-			fbInit.m_colorAttachmentCount = 1;
-			fbInit.m_colorAttachments[0].m_textureView = swapchainView;
-			fbInit.m_colorAttachments[0].m_clearValue.m_colorf = {1.0f, 0.0f, 1.0f, 0.0f};
-			FramebufferPtr fb = gr->newFramebuffer(fbInit);
-
 			CommandBufferInitInfo cmdbinit;
 			CommandBufferInitInfo cmdbinit;
 			CommandBufferPtr cmdb = gr->newCommandBuffer(cmdbinit);
 			CommandBufferPtr cmdb = gr->newCommandBuffer(cmdbinit);
 
 
@@ -243,7 +237,10 @@ float3 main(VertOut input) : SV_TARGET0
 			barrier.m_nextUsage = TextureUsageBit::kFramebufferWrite;
 			barrier.m_nextUsage = TextureUsageBit::kFramebufferWrite;
 			cmdb->setPipelineBarrier({&barrier, 1}, {}, {});
 			cmdb->setPipelineBarrier({&barrier, 1}, {}, {});
 
 
-			cmdb->beginRenderPass(fb.get(), {TextureUsageBit::kFramebufferWrite}, TextureUsageBit::kNone);
+			RenderTarget rt;
+			rt.m_view = swapchainView.get();
+			rt.m_clearValue.m_colorf = {1.0f, 0.0f, 1.0f, 0.0f};
+			cmdb->beginRenderPass({rt});
 
 
 			cmdb->bindStorageBuffer(0, 0, indexBuff.get(), 0, kMaxPtrSize);
 			cmdb->bindStorageBuffer(0, 0, indexBuff.get(), 0, kMaxPtrSize);
 			cmdb->bindStorageBuffer(0, 1, positionsBuff.get(), 0, kMaxPtrSize);
 			cmdb->bindStorageBuffer(0, 1, positionsBuff.get(), 0, kMaxPtrSize);

+ 9 - 14
Tests/Ui/Ui.cpp

@@ -99,19 +99,6 @@ ANKI_TEST(Ui, Ui)
 			label->build(canvas);
 			label->build(canvas);
 
 
 			TexturePtr presentTex = gr->acquireNextPresentableTexture();
 			TexturePtr presentTex = gr->acquireNextPresentableTexture();
-			FramebufferPtr fb;
-			{
-				TextureViewInitInfo init;
-				init.m_texture = presentTex.get();
-				TextureViewPtr view = gr->newTextureView(init);
-
-				FramebufferInitInfo fbinit;
-				fbinit.m_colorAttachmentCount = 1;
-				fbinit.m_colorAttachments[0].m_clearValue.m_colorf = {{1.0, 0.0, 1.0, 1.0}};
-				fbinit.m_colorAttachments[0].m_textureView = view;
-
-				fb = gr->newFramebuffer(fbinit);
-			}
 
 
 			CommandBufferInitInfo cinit;
 			CommandBufferInitInfo cinit;
 			cinit.m_flags = CommandBufferFlag::kGeneralWork | CommandBufferFlag::kSmallBatch;
 			cinit.m_flags = CommandBufferFlag::kGeneralWork | CommandBufferFlag::kSmallBatch;
@@ -123,7 +110,15 @@ ANKI_TEST(Ui, Ui)
 			barrier.m_texture = presentTex.get();
 			barrier.m_texture = presentTex.get();
 			cmdb->setPipelineBarrier({&barrier, 1}, {}, {});
 			cmdb->setPipelineBarrier({&barrier, 1}, {}, {});
 
 
-			cmdb->beginRenderPass(fb.get(), {{TextureUsageBit::kFramebufferWrite}}, {});
+			TextureViewInitInfo init;
+			init.m_texture = presentTex.get();
+			TextureViewPtr view = gr->newTextureView(init);
+
+			RenderTarget rt;
+			rt.m_view = view.get();
+			rt.m_clearValue.m_colorf = {{1.0, 0.0, 1.0, 1.0}};
+			cmdb->beginRenderPass({rt});
+
 			canvas->appendToCommandBuffer(*cmdb);
 			canvas->appendToCommandBuffer(*cmdb);
 			cmdb->endRenderPass();
 			cmdb->endRenderPass();