Browse Source

Vulkan & GL: Some refactoring and adding proper buffer usage

Panagiotis Christopoulos Charitos 9 years ago
parent
commit
a9b3450648
48 changed files with 397 additions and 354 deletions
  1. 2 2
      include/anki/gr/Buffer.h
  2. 2 4
      include/anki/gr/CommandBuffer.h
  3. 1 1
      include/anki/gr/Common.h
  4. 41 76
      include/anki/gr/Enums.h
  5. 3 3
      include/anki/gr/GrManager.h
  6. 46 0
      include/anki/gr/common/Misc.h
  7. 4 4
      include/anki/gr/gl/BufferImpl.h
  8. 0 1
      include/anki/gr/gl/CommandBufferImpl.h
  9. 0 1
      include/anki/gr/gl/GlState.h
  10. 8 8
      include/anki/gr/gl/GrManagerImpl.h
  11. 13 23
      include/anki/gr/gl/TransientMemoryManager.h
  12. 3 3
      include/anki/gr/vulkan/BufferImpl.h
  13. 8 5
      include/anki/gr/vulkan/TransientMemoryManager.h
  14. 4 4
      src/gr/gl/Buffer.cpp
  15. 6 6
      src/gr/gl/BufferImpl.cpp
  16. 13 9
      src/gr/gl/CommandBuffer.cpp
  17. 3 3
      src/gr/gl/GrManager.cpp
  18. 4 3
      src/gr/gl/GrManagerImpl.cpp
  19. 6 4
      src/gr/gl/RenderingThread.cpp
  20. 4 3
      src/gr/gl/ResourceGroupImpl.cpp
  21. 4 0
      src/gr/gl/ShaderImpl.cpp
  22. 22 56
      src/gr/gl/TransientMemoryManager.cpp
  23. 2 2
      src/gr/vulkan/Buffer.cpp
  24. 44 12
      src/gr/vulkan/BufferImpl.cpp
  25. 2 8
      src/gr/vulkan/CommandBuffer.cpp
  26. 10 5
      src/gr/vulkan/Common.cpp
  27. 1 1
      src/gr/vulkan/GrManager.cpp
  28. 4 3
      src/gr/vulkan/ResourceGroupImpl.cpp
  29. 5 0
      src/gr/vulkan/ShaderImpl.cpp
  30. 16 18
      src/gr/vulkan/TransientMemoryManager.cpp
  31. 4 3
      src/renderer/Bloom.cpp
  32. 3 4
      src/renderer/DebugDrawer.cpp
  33. 1 1
      src/renderer/Drawer.cpp
  34. 4 3
      src/renderer/Ir.cpp
  35. 1 1
      src/renderer/Is.cpp
  36. 3 3
      src/renderer/Lf.cpp
  37. 5 5
      src/renderer/LightBin.cpp
  38. 1 1
      src/renderer/Renderer.cpp
  39. 1 1
      src/renderer/Ssao.cpp
  40. 2 2
      src/renderer/Tiler.cpp
  41. 7 6
      src/renderer/Tm.cpp
  42. 4 3
      src/renderer/Upsample.cpp
  43. 4 3
      src/renderer/Volumetric.cpp
  44. 14 8
      src/resource/Mesh.cpp
  45. 1 1
      src/resource/TextureResource.cpp
  46. 4 5
      src/scene/ParticleEmitter.cpp
  47. 3 3
      src/ui/UiInterfaceImpl.cpp
  48. 54 33
      tests/gr/Gr.cpp

+ 2 - 2
include/anki/gr/Buffer.h

@@ -32,10 +32,10 @@ public:
 	}
 	}
 
 
 	/// Allocate the buffer.
 	/// Allocate the buffer.
-	void init(PtrSize size, BufferUsageBit usage, BufferAccessBit access);
+	void init(PtrSize size, BufferUsageBit usage, BufferMapAccessBit access);
 
 
 	/// Map the buffer.
 	/// Map the buffer.
-	void* map(PtrSize offset, PtrSize range, BufferAccessBit access);
+	void* map(PtrSize offset, PtrSize range, BufferMapAccessBit access);
 
 
 	/// Unmap the buffer.
 	/// Unmap the buffer.
 	void unmap();
 	void unmap();

+ 2 - 4
include/anki/gr/CommandBuffer.h

@@ -226,10 +226,8 @@ public:
 		TextureUsageBit nextUsage,
 		TextureUsageBit nextUsage,
 		const TextureSurfaceInfo& surf);
 		const TextureSurfaceInfo& surf);
 
 
-	void setPipelineBarrier(PipelineStageBit src, PipelineStageBit dst);
-
-	void setBufferMemoryBarrier(
-		BufferPtr buff, ResourceAccessBit src, ResourceAccessBit dst);
+	void setBufferBarrier(
+		BufferPtr buff, BufferUsageBit prevUsage, BufferUsageBit nextUsage);
 	/// @}
 	/// @}
 
 
 	/// @name Other
 	/// @name Other

+ 1 - 1
include/anki/gr/Common.h

@@ -142,7 +142,7 @@ anki_internal:
 	PtrSize m_range = 0;
 	PtrSize m_range = 0;
 	TransientMemoryTokenLifetime m_lifetime =
 	TransientMemoryTokenLifetime m_lifetime =
 		TransientMemoryTokenLifetime::PER_FRAME;
 		TransientMemoryTokenLifetime::PER_FRAME;
-	BufferUsage m_usage = BufferUsage::COUNT;
+	BufferUsageBit m_usage = BufferUsageBit::NONE;
 
 
 	void markUnused()
 	void markUnused()
 	{
 	{

+ 41 - 76
include/anki/gr/Enums.h

@@ -322,90 +322,55 @@ enum class AttachmentStoreOperation : U8
 };
 };
 
 
 /// Buffer usage modes.
 /// Buffer usage modes.
-enum class BufferUsage : U8
-{
-	UNIFORM,
-	STORAGE,
-	INDEX,
-	VERTEX,
-	INDIRECT,
-	TRANSFER, ///< For texture upload and buffer write.
-
-	COUNT,
-	FIRST = UNIFORM
-};
-ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(BufferUsage, inline)
-
-/// Buffer usage modes.
-enum class BufferUsageBit : U8
+enum class BufferUsageBit : U32
 {
 {
 	NONE = 0,
 	NONE = 0,
-	UNIFORM = 1 << 0,
-	STORAGE = 1 << 1,
-	INDEX = 1 << 2,
-	VERTEX = 1 << 3,
-	INDIRECT = 1 << 4,
-	TRANSFER = 1 << 5
-};
-ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(BufferUsageBit, inline)
 
 
-/// Buffer access from client modes.
-enum class BufferAccessBit : U8
-{
-	NONE = 0,
-	CLIENT_MAP_READ = 1 << 0,
-	CLIENT_MAP_WRITE = 1 << 1,
-	CLIENT_WRITE = 1 << 2,
+	UNIFORM_VERTEX_SHADER = 1 << 0,
+	UNIFORM_TESSELLATION_EVALUATION_SHADER = 1 << 1,
+	UNIFORM_TESSELLATION_CONTROL_SHADER = 1 << 2,
+	UNIFORM_GEOMETRY_SHADER = 1 << 3,
+	UNIFORM_FRAGMENT_SHADER = 1 << 4,
+	UNIFORM_COMPUTE_SHADER = 1 << 5,
+	UNIFORM_ANY_SHADER = UNIFORM_VERTEX_SHADER
+		| UNIFORM_TESSELLATION_EVALUATION_SHADER
+		| UNIFORM_TESSELLATION_CONTROL_SHADER
+		| UNIFORM_GEOMETRY_SHADER
+		| UNIFORM_FRAGMENT_SHADER
+		| UNIFORM_COMPUTE_SHADER,
+
+	STORAGE_VERTEX_SHADER = 1 << 6,
+	STORAGE_TESSELLATION_EVALUATION_SHADER = 1 << 7,
+	STORAGE_TESSELLATION_CONTROL_SHADER = 1 << 8,
+	STORAGE_GEOMETRY_SHADER = 1 << 9,
+	STORAGE_FRAGMENT_SHADER = 1 << 10,
+	STORAGE_COMPUTE_SHADER_READ = 1 << 11,
+	STORAGE_COMPUTE_SHADER_WRITE = 1 << 12,
+	STORAGE_ANY = STORAGE_VERTEX_SHADER | STORAGE_TESSELLATION_EVALUATION_SHADER
+		| STORAGE_TESSELLATION_CONTROL_SHADER
+		| STORAGE_GEOMETRY_SHADER
+		| STORAGE_FRAGMENT_SHADER
+		| STORAGE_COMPUTE_SHADER_READ
+		| STORAGE_COMPUTE_SHADER_WRITE,
+
+	INDEX = 1 << 13,
+	VERTEX = 1 << 14,
+	INDIRECT = 1 << 15,
+
+	TRANSFER_SOURCE = 1 << 16,
+	TRANSFER_DESTINATION = 1 << 17,
+	TRANSFER_ANY = TRANSFER_SOURCE | TRANSFER_DESTINATION
 };
 };
-ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(BufferAccessBit, inline)
-
-/// GPU pipeline stages.
-enum class PipelineStageBit : U8
-{
-	NONE = 0,
-	VERTEX = 1 << 0,
-	FRAGMENT = 1 << 1,
-	COMPUTE = 1 << 2,
-	TRANSFER = 1 << 3,
-	CLIENT = 1 << 4
-};
-ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(PipelineStageBit, inline)
+ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(BufferUsageBit, inline)
 
 
-enum class ResourceAccessBit : U16
+/// Buffer access when mapped.
+enum class BufferMapAccessBit : U8
 {
 {
 	NONE = 0,
 	NONE = 0,
-
-	/// Read from any of the bellow.
-	INDIRECT_OR_INDEX_OR_VERTEX_READ = 1 << 0,
-
-	/// Read from a uniform buffer.
-	UNIFORM_READ = 1 << 1,
-
-	/// Read an attachment (eg blending).
-	ATTACHMENT_READ = 1 << 2,
-
-	/// Write to an attachment.
-	ATTACHMENT_WRITE = 1 << 3,
-
-	/// Any resource is read from any shader.
-	SHADER_READ = 1 << 4,
-
-	/// Any resource is written from any shader.
-	SHADER_WRITE = 1 << 5,
-
-	/// Client read.
-	CLIENT_READ = 1 << 6,
-
-	/// Client write.
-	CLIENT_WRITE = 1 << 7,
-
-	/// Read as part of texture upload or buffer write commands.
-	TRANSFER_READ = 1 << 8,
-
-	/// Written as part of texture upload or buffer write commands.
-	TRANSFER_WRITE = 1 << 9
+	READ = 1 << 0,
+	WRITE = 1 << 1
 };
 };
-ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(ResourceAccessBit, inline)
+ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(BufferMapAccessBit, inline)
 /// @}
 /// @}
 
 
 } // end namespace anki
 } // end namespace anki

+ 3 - 3
include/anki/gr/GrManager.h

@@ -68,10 +68,10 @@ public:
 	template<typename T, typename TArg>
 	template<typename T, typename TArg>
 	GrObjectPtr<T> newInstanceCached(const TArg& arg);
 	GrObjectPtr<T> newInstanceCached(const TArg& arg);
 
 
-	/// Allocate memory for dynamic buffers. The memory will be reclaimed at
-	/// the begining of the N-(MAX_FRAMES_IN_FLIGHT-1) frame.
+	/// Allocate transient memory for various operations. The memory will be
+	/// reclaimed at the begining of the N-(MAX_FRAMES_IN_FLIGHT-1) frame.
 	void* allocateFrameTransientMemory(PtrSize size,
 	void* allocateFrameTransientMemory(PtrSize size,
-		BufferUsage usage,
+		BufferUsageBit usage,
 		TransientMemoryToken& token,
 		TransientMemoryToken& token,
 		Error* err = nullptr);
 		Error* err = nullptr);
 
 

+ 46 - 0
include/anki/gr/common/Misc.h

@@ -0,0 +1,46 @@
+// Copyright (C) 2009-2016, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#pragma once
+
+#include <anki/gr/Enums.h>
+
+namespace anki
+{
+
+enum class TransientBufferType
+{
+	UNIFORM,
+	STORAGE,
+	VERTEX,
+	TRANSFER,
+	COUNT
+};
+ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(TransientBufferType, inline)
+
+/// Convert buff usage to TransientBufferType.
+inline TransientBufferType bufferUsageToTransient(BufferUsageBit bit)
+{
+	if((bit & BufferUsageBit::UNIFORM_ANY_SHADER) != BufferUsageBit::NONE)
+	{
+		return TransientBufferType::UNIFORM;
+	}
+	else if((bit & BufferUsageBit::STORAGE_ANY) != BufferUsageBit::NONE)
+	{
+		return TransientBufferType::STORAGE;
+	}
+	else if((bit & BufferUsageBit::VERTEX) != BufferUsageBit::NONE)
+	{
+		return TransientBufferType::VERTEX;
+	}
+	else
+	{
+		ANKI_ASSERT(
+			(bit & BufferUsageBit::TRANSFER_SOURCE) != BufferUsageBit::NONE);
+		return TransientBufferType::TRANSFER;
+	}
+}
+
+} // end namespace anki

+ 4 - 4
include/anki/gr/gl/BufferImpl.h

@@ -20,7 +20,7 @@ public:
 	U32 m_size = 0; ///< The size of the buffer
 	U32 m_size = 0; ///< The size of the buffer
 	void* m_persistentMapping = nullptr;
 	void* m_persistentMapping = nullptr;
 	BufferUsageBit m_usage = BufferUsageBit::NONE;
 	BufferUsageBit m_usage = BufferUsageBit::NONE;
-	BufferAccessBit m_access = BufferAccessBit::NONE;
+	BufferMapAccessBit m_access = BufferMapAccessBit::NONE;
 	GLenum m_target = GL_NONE; ///< A guess
 	GLenum m_target = GL_NONE; ///< A guess
 #if ANKI_ASSERTIONS
 #if ANKI_ASSERTIONS
 	Bool m_mapped = false;
 	Bool m_mapped = false;
@@ -36,7 +36,7 @@ public:
 		destroyDeferred(glDeleteBuffers);
 		destroyDeferred(glDeleteBuffers);
 	}
 	}
 
 
-	void init(PtrSize size, BufferUsageBit usage, BufferAccessBit access);
+	void init(PtrSize size, BufferUsageBit usage, BufferMapAccessBit access);
 
 
 	void bind(GLenum target, U32 binding, PtrSize offset, PtrSize size) const
 	void bind(GLenum target, U32 binding, PtrSize offset, PtrSize size) const
 	{
 	{
@@ -50,8 +50,8 @@ public:
 	{
 	{
 		ANKI_ASSERT(isCreated());
 		ANKI_ASSERT(isCreated());
 		ANKI_ASSERT(offset + size <= m_size);
 		ANKI_ASSERT(offset + size <= m_size);
-		ANKI_ASSERT((m_access & BufferAccessBit::CLIENT_WRITE)
-			!= BufferAccessBit::NONE);
+		ANKI_ASSERT((m_usage & BufferUsageBit::TRANSFER_DESTINATION)
+			!= BufferUsageBit::NONE);
 		glBindBuffer(m_target, m_glName);
 		glBindBuffer(m_target, m_glName);
 		glBufferSubData(m_target, offset, size, buff);
 		glBufferSubData(m_target, offset, size, buff);
 	}
 	}

+ 0 - 1
include/anki/gr/gl/CommandBufferImpl.h

@@ -6,7 +6,6 @@
 #pragma once
 #pragma once
 
 
 #include <anki/gr/CommandBuffer.h>
 #include <anki/gr/CommandBuffer.h>
-#include <anki/gr/gl/DynamicMemoryManager.h>
 #include <anki/util/Assert.h>
 #include <anki/util/Assert.h>
 #include <anki/util/Allocator.h>
 #include <anki/util/Allocator.h>
 
 

+ 0 - 1
include/anki/gr/gl/GlState.h

@@ -6,7 +6,6 @@
 #pragma once
 #pragma once
 
 
 #include <anki/gr/gl/Common.h>
 #include <anki/gr/gl/Common.h>
-#include <anki/gr/gl/DynamicMemoryManager.h>
 #include <anki/util/DynamicArray.h>
 #include <anki/util/DynamicArray.h>
 
 
 namespace anki
 namespace anki

+ 8 - 8
include/anki/gr/gl/GrManagerImpl.h

@@ -14,7 +14,7 @@ namespace anki
 class RenderingThread;
 class RenderingThread;
 class WindowingBackend;
 class WindowingBackend;
 class GlState;
 class GlState;
-class DynamicMemoryManager;
+class TransientMemoryManager;
 
 
 /// @addtogroup opengl
 /// @addtogroup opengl
 /// @{
 /// @{
@@ -57,16 +57,16 @@ public:
 		return *m_state;
 		return *m_state;
 	}
 	}
 
 
-	DynamicMemoryManager& getDynamicMemoryManager()
+	TransientMemoryManager& getTransientMemoryManager()
 	{
 	{
-		ANKI_ASSERT(m_dynManager);
-		return *m_dynManager;
+		ANKI_ASSERT(m_transManager);
+		return *m_transManager;
 	}
 	}
 
 
-	const DynamicMemoryManager& getDynamicMemoryManager() const
+	const TransientMemoryManager& getTransientMemoryManager() const
 	{
 	{
-		ANKI_ASSERT(m_dynManager);
-		return *m_dynManager;
+		ANKI_ASSERT(m_transManager);
+		return *m_transManager;
 	}
 	}
 
 
 	GrAllocator<U8> getAllocator() const;
 	GrAllocator<U8> getAllocator() const;
@@ -80,7 +80,7 @@ private:
 	GlState* m_state = nullptr;
 	GlState* m_state = nullptr;
 	RenderingThread* m_thread = nullptr;
 	RenderingThread* m_thread = nullptr;
 	WindowingBackend* m_backend = nullptr; ///< The backend of the backend.
 	WindowingBackend* m_backend = nullptr; ///< The backend of the backend.
-	DynamicMemoryManager* m_dynManager = nullptr;
+	TransientMemoryManager* m_transManager = nullptr;
 
 
 	ANKI_USE_RESULT Error createBackend(GrManagerInitInfo& init);
 	ANKI_USE_RESULT Error createBackend(GrManagerInitInfo& init);
 	void destroyBackend();
 	void destroyBackend();

+ 13 - 23
include/anki/gr/gl/DynamicMemoryManager.h → include/anki/gr/gl/TransientMemoryManager.h

@@ -8,6 +8,7 @@
 #include <anki/gr/gl/Common.h>
 #include <anki/gr/gl/Common.h>
 #include <anki/gr/common/GpuFrameRingAllocator.h>
 #include <anki/gr/common/GpuFrameRingAllocator.h>
 #include <anki/gr/common/GpuBlockAllocator.h>
 #include <anki/gr/common/GpuBlockAllocator.h>
+#include <anki/gr/common/Misc.h>
 
 
 namespace anki
 namespace anki
 {
 {
@@ -19,14 +20,14 @@ class ConfigSet;
 /// @{
 /// @{
 
 
 /// Manages all dynamic memory.
 /// Manages all dynamic memory.
-class DynamicMemoryManager : public NonCopyable
+class TransientMemoryManager : public NonCopyable
 {
 {
 public:
 public:
-	DynamicMemoryManager()
+	TransientMemoryManager()
 	{
 	{
 	}
 	}
 
 
-	~DynamicMemoryManager();
+	~TransientMemoryManager();
 
 
 	void initMainThread(
 	void initMainThread(
 		GenericMemoryPoolAllocator<U8> alloc, const ConfigSet& cfg);
 		GenericMemoryPoolAllocator<U8> alloc, const ConfigSet& cfg);
@@ -38,7 +39,7 @@ public:
 	void endFrame();
 	void endFrame();
 
 
 	void allocate(PtrSize size,
 	void allocate(PtrSize size,
-		BufferUsage usage,
+		BufferUsageBit usage,
 		TransientMemoryTokenLifetime lifespan,
 		TransientMemoryTokenLifetime lifespan,
 		TransientMemoryToken& token,
 		TransientMemoryToken& token,
 		void*& ptr,
 		void*& ptr,
@@ -48,7 +49,6 @@ public:
 	{
 	{
 		ANKI_ASSERT(
 		ANKI_ASSERT(
 			token.m_lifetime == TransientMemoryTokenLifetime::PERSISTENT);
 			token.m_lifetime == TransientMemoryTokenLifetime::PERSISTENT);
-		m_persistentBuffers[token.m_usage].m_alloc.free(token.m_offset);
 	}
 	}
 
 
 	void* getBaseAddress(const TransientMemoryToken& token) const
 	void* getBaseAddress(const TransientMemoryToken& token) const
@@ -56,11 +56,12 @@ public:
 		void* addr;
 		void* addr;
 		if(token.m_lifetime == TransientMemoryTokenLifetime::PER_FRAME)
 		if(token.m_lifetime == TransientMemoryTokenLifetime::PER_FRAME)
 		{
 		{
-			addr = m_perFrameBuffers[token.m_usage].m_mappedMem;
+			addr = m_perFrameBuffers[bufferUsageToTransient(token.m_usage)]
+					   .m_mappedMem;
 		}
 		}
 		else
 		else
 		{
 		{
-			addr = m_persistentBuffers[token.m_usage].m_mappedMem;
+			ANKI_ASSERT(0);
 		}
 		}
 		ANKI_ASSERT(addr);
 		ANKI_ASSERT(addr);
 		return addr;
 		return addr;
@@ -71,11 +72,12 @@ public:
 		GLuint name;
 		GLuint name;
 		if(token.m_lifetime == TransientMemoryTokenLifetime::PER_FRAME)
 		if(token.m_lifetime == TransientMemoryTokenLifetime::PER_FRAME)
 		{
 		{
-			name = m_perFrameBuffers[token.m_usage].m_name;
+			name =
+				m_perFrameBuffers[bufferUsageToTransient(token.m_usage)].m_name;
 		}
 		}
 		else
 		else
 		{
 		{
-			name = m_persistentBuffers[token.m_usage].m_name;
+			ANKI_ASSERT(0);
 		}
 		}
 		ANKI_ASSERT(name);
 		ANKI_ASSERT(name);
 		return name;
 		return name;
@@ -98,21 +100,9 @@ private:
 		GpuFrameRingAllocator m_alloc;
 		GpuFrameRingAllocator m_alloc;
 	};
 	};
 
 
-	class PersistentBuffer
-	{
-	public:
-		PtrSize m_size = 0;
-		GLuint m_name = 0;
-		U32 m_alignment = 0;
-		DynamicArray<Aligned16Type> m_cpuBuff;
-		U8* m_mappedMem = nullptr;
-		GpuBlockAllocator m_alloc;
-	};
-
 	GenericMemoryPoolAllocator<U8> m_alloc;
 	GenericMemoryPoolAllocator<U8> m_alloc;
-	Array<PerFrameBuffer, U(BufferUsage::COUNT)> m_perFrameBuffers;
-	Array<PersistentBuffer, U(BufferUsage::COUNT)> m_persistentBuffers;
+	Array<PerFrameBuffer, U(TransientBufferType::COUNT)> m_perFrameBuffers;
 };
 };
 /// @}
 /// @}
 
 
-} // end namespace anki
+} // end namespace anki

+ 3 - 3
include/anki/gr/vulkan/BufferImpl.h

@@ -26,10 +26,10 @@ public:
 	~BufferImpl();
 	~BufferImpl();
 
 
 	ANKI_USE_RESULT Error init(
 	ANKI_USE_RESULT Error init(
-		PtrSize size, BufferUsageBit usage, BufferAccessBit access);
+		PtrSize size, BufferUsageBit usage, BufferMapAccessBit access);
 
 
 	ANKI_USE_RESULT void* map(
 	ANKI_USE_RESULT void* map(
-		PtrSize offset, PtrSize range, BufferAccessBit access);
+		PtrSize offset, PtrSize range, BufferMapAccessBit access);
 
 
 	void unmap()
 	void unmap()
 	{
 	{
@@ -51,7 +51,7 @@ private:
 	VkBuffer m_handle = VK_NULL_HANDLE;
 	VkBuffer m_handle = VK_NULL_HANDLE;
 	GpuMemoryAllocationHandle m_memHandle;
 	GpuMemoryAllocationHandle m_memHandle;
 	U32 m_memIdx = 0;
 	U32 m_memIdx = 0;
-	BufferAccessBit m_access = BufferAccessBit::NONE;
+	BufferMapAccessBit m_access = BufferMapAccessBit::NONE;
 	U32 m_size = 0;
 	U32 m_size = 0;
 
 
 #if ANKI_ASSERTIONS
 #if ANKI_ASSERTIONS

+ 8 - 5
include/anki/gr/vulkan/TransientMemoryManager.h

@@ -7,6 +7,7 @@
 
 
 #include <anki/gr/vulkan/GpuMemoryAllocator.h>
 #include <anki/gr/vulkan/GpuMemoryAllocator.h>
 #include <anki/gr/common/GpuFrameRingAllocator.h>
 #include <anki/gr/common/GpuFrameRingAllocator.h>
+#include <anki/gr/common/Misc.h>
 
 
 namespace anki
 namespace anki
 {
 {
@@ -39,7 +40,7 @@ public:
 	void endFrame();
 	void endFrame();
 
 
 	void allocate(PtrSize size,
 	void allocate(PtrSize size,
-		BufferUsage usage,
+		BufferUsageBit usage,
 		TransientMemoryToken& token,
 		TransientMemoryToken& token,
 		void*& ptr,
 		void*& ptr,
 		Error* outErr);
 		Error* outErr);
@@ -48,15 +49,17 @@ public:
 	{
 	{
 		ANKI_ASSERT(
 		ANKI_ASSERT(
 			token.m_lifetime == TransientMemoryTokenLifetime::PER_FRAME);
 			token.m_lifetime == TransientMemoryTokenLifetime::PER_FRAME);
-		const PerFrameBuffer& frame = m_perFrameBuffers[token.m_usage];
+		const PerFrameBuffer& frame =
+			m_perFrameBuffers[bufferUsageToTransient(token.m_usage)];
 		void* addr = frame.m_mappedMem;
 		void* addr = frame.m_mappedMem;
 		ANKI_ASSERT(addr);
 		ANKI_ASSERT(addr);
 		return addr;
 		return addr;
 	}
 	}
 
 
-	VkBuffer getBufferHandle(BufferUsage usage) const
+	VkBuffer getBufferHandle(BufferUsageBit usage) const
 	{
 	{
-		const PerFrameBuffer& frame = m_perFrameBuffers[usage];
+		const PerFrameBuffer& frame =
+			m_perFrameBuffers[bufferUsageToTransient(usage)];
 		ANKI_ASSERT(frame.m_bufferHandle);
 		ANKI_ASSERT(frame.m_bufferHandle);
 		return frame.m_bufferHandle;
 		return frame.m_bufferHandle;
 	}
 	}
@@ -75,7 +78,7 @@ private:
 
 
 	GrManager* m_manager = nullptr;
 	GrManager* m_manager = nullptr;
 
 
-	Array<PerFrameBuffer, U(BufferUsage::COUNT)> m_perFrameBuffers;
+	Array<PerFrameBuffer, U(TransientBufferType::COUNT)> m_perFrameBuffers;
 };
 };
 /// @}
 /// @}
 
 

+ 4 - 4
src/gr/gl/Buffer.cpp

@@ -29,12 +29,12 @@ public:
 	BufferPtr m_buff;
 	BufferPtr m_buff;
 	PtrSize m_size;
 	PtrSize m_size;
 	BufferUsageBit m_usage;
 	BufferUsageBit m_usage;
-	BufferAccessBit m_access;
+	BufferMapAccessBit m_access;
 
 
 	BufferCreateCommand(Buffer* buff,
 	BufferCreateCommand(Buffer* buff,
 		PtrSize size,
 		PtrSize size,
 		BufferUsageBit usage,
 		BufferUsageBit usage,
-		BufferAccessBit access)
+		BufferMapAccessBit access)
 		: m_buff(buff)
 		: m_buff(buff)
 		, m_size(size)
 		, m_size(size)
 		, m_usage(usage)
 		, m_usage(usage)
@@ -58,7 +58,7 @@ public:
 	}
 	}
 };
 };
 
 
-void Buffer::init(PtrSize size, BufferUsageBit usage, BufferAccessBit access)
+void Buffer::init(PtrSize size, BufferUsageBit usage, BufferMapAccessBit access)
 {
 {
 	m_impl.reset(getAllocator().newInstance<BufferImpl>(&getManager()));
 	m_impl.reset(getAllocator().newInstance<BufferImpl>(&getManager()));
 
 
@@ -71,7 +71,7 @@ void Buffer::init(PtrSize size, BufferUsageBit usage, BufferAccessBit access)
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-void* Buffer::map(PtrSize offset, PtrSize range, BufferAccessBit access)
+void* Buffer::map(PtrSize offset, PtrSize range, BufferMapAccessBit access)
 {
 {
 	// Wait for its creation
 	// Wait for its creation
 	if(m_impl->serializeRenderingThread())
 	if(m_impl->serializeRenderingThread())

+ 6 - 6
src/gr/gl/BufferImpl.cpp

@@ -12,7 +12,7 @@ namespace anki
 
 
 //==============================================================================
 //==============================================================================
 void BufferImpl::init(
 void BufferImpl::init(
-	PtrSize size, BufferUsageBit usage, BufferAccessBit access)
+	PtrSize size, BufferUsageBit usage, BufferMapAccessBit access)
 {
 {
 	ANKI_ASSERT(!isCreated());
 	ANKI_ASSERT(!isCreated());
 	m_usage = usage;
 	m_usage = usage;
@@ -28,7 +28,7 @@ void BufferImpl::init(
 	// creation
 	// creation
 	m_target = GL_ARRAY_BUFFER;
 	m_target = GL_ARRAY_BUFFER;
 
 
-	if((usage & BufferUsageBit::UNIFORM) != BufferUsageBit::NONE)
+	if((usage & BufferUsageBit::UNIFORM_ANY_SHADER) != BufferUsageBit::NONE)
 	{
 	{
 		GLint64 maxBufferSize;
 		GLint64 maxBufferSize;
 		glGetInteger64v(GL_MAX_UNIFORM_BLOCK_SIZE, &maxBufferSize);
 		glGetInteger64v(GL_MAX_UNIFORM_BLOCK_SIZE, &maxBufferSize);
@@ -50,7 +50,7 @@ void BufferImpl::init(
 		m_target = GL_UNIFORM_BUFFER;
 		m_target = GL_UNIFORM_BUFFER;
 	}
 	}
 
 
-	if((usage & BufferUsageBit::STORAGE) != BufferUsageBit::NONE)
+	if((usage & BufferUsageBit::STORAGE_ANY) != BufferUsageBit::NONE)
 	{
 	{
 		GLint64 maxBufferSize;
 		GLint64 maxBufferSize;
 		glGetInteger64v(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, &maxBufferSize);
 		glGetInteger64v(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, &maxBufferSize);
@@ -79,12 +79,12 @@ void BufferImpl::init(
 	//
 	//
 	GLbitfield flags = 0;
 	GLbitfield flags = 0;
 	Bool shouldMap = false;
 	Bool shouldMap = false;
-	if((access & BufferAccessBit::CLIENT_WRITE) != BufferAccessBit::NONE)
+	if((usage & BufferUsageBit::TRANSFER_ANY) != BufferUsageBit::NONE)
 	{
 	{
 		flags |= GL_DYNAMIC_STORAGE_BIT;
 		flags |= GL_DYNAMIC_STORAGE_BIT;
 	}
 	}
 
 
-	if((access & BufferAccessBit::CLIENT_MAP_WRITE) != BufferAccessBit::NONE)
+	if((access & BufferMapAccessBit::WRITE) != BufferMapAccessBit::NONE)
 	{
 	{
 		flags |= GL_MAP_WRITE_BIT;
 		flags |= GL_MAP_WRITE_BIT;
 		flags |= GL_MAP_PERSISTENT_BIT;
 		flags |= GL_MAP_PERSISTENT_BIT;
@@ -93,7 +93,7 @@ void BufferImpl::init(
 		shouldMap = true;
 		shouldMap = true;
 	}
 	}
 
 
-	if((access & BufferAccessBit::CLIENT_MAP_READ) != BufferAccessBit::NONE)
+	if((access & BufferMapAccessBit::READ) != BufferMapAccessBit::NONE)
 	{
 	{
 		flags |= GL_MAP_READ_BIT;
 		flags |= GL_MAP_READ_BIT;
 		flags |= GL_MAP_PERSISTENT_BIT;
 		flags |= GL_MAP_PERSISTENT_BIT;

+ 13 - 9
src/gr/gl/CommandBuffer.cpp

@@ -9,6 +9,7 @@
 #include <anki/gr/gl/GrManagerImpl.h>
 #include <anki/gr/gl/GrManagerImpl.h>
 #include <anki/gr/gl/RenderingThread.h>
 #include <anki/gr/gl/RenderingThread.h>
 #include <anki/gr/gl/GlState.h>
 #include <anki/gr/gl/GlState.h>
+#include <anki/gr/gl/TransientMemoryManager.h>
 
 
 #include <anki/gr/Pipeline.h>
 #include <anki/gr/Pipeline.h>
 #include <anki/gr/gl/PipelineImpl.h>
 #include <anki/gr/gl/PipelineImpl.h>
@@ -351,7 +352,7 @@ public:
 	Error operator()(GlState& state)
 	Error operator()(GlState& state)
 	{
 	{
 		void* data = state.m_manager->getImplementation()
 		void* data = state.m_manager->getImplementation()
-						 .getDynamicMemoryManager()
+						 .getTransientMemoryManager()
 						 .getBaseAddress(m_token);
 						 .getBaseAddress(m_token);
 		data = static_cast<void*>(static_cast<U8*>(data) + m_token.m_offset);
 		data = static_cast<void*>(static_cast<U8*>(data) + m_token.m_offset);
 
 
@@ -359,8 +360,9 @@ public:
 
 
 		if(m_token.m_lifetime == TransientMemoryTokenLifetime::PERSISTENT)
 		if(m_token.m_lifetime == TransientMemoryTokenLifetime::PERSISTENT)
 		{
 		{
-			state.m_manager->getImplementation().getDynamicMemoryManager().free(
-				m_token);
+			state.m_manager->getImplementation()
+				.getTransientMemoryManager()
+				.free(m_token);
 		}
 		}
 
 
 		return ErrorCode::NONE;
 		return ErrorCode::NONE;
@@ -398,7 +400,7 @@ public:
 	Error operator()(GlState& state)
 	Error operator()(GlState& state)
 	{
 	{
 		void* data = state.m_manager->getImplementation()
 		void* data = state.m_manager->getImplementation()
-						 .getDynamicMemoryManager()
+						 .getTransientMemoryManager()
 						 .getBaseAddress(m_token);
 						 .getBaseAddress(m_token);
 		data = static_cast<void*>(static_cast<U8*>(data) + m_token.m_offset);
 		data = static_cast<void*>(static_cast<U8*>(data) + m_token.m_offset);
 
 
@@ -406,8 +408,9 @@ public:
 
 
 		if(m_token.m_lifetime == TransientMemoryTokenLifetime::PERSISTENT)
 		if(m_token.m_lifetime == TransientMemoryTokenLifetime::PERSISTENT)
 		{
 		{
-			state.m_manager->getImplementation().getDynamicMemoryManager().free(
-				m_token);
+			state.m_manager->getImplementation()
+				.getTransientMemoryManager()
+				.free(m_token);
 		}
 		}
 
 
 		return ErrorCode::NONE;
 		return ErrorCode::NONE;
@@ -548,12 +551,12 @@ public:
 	}
 	}
 };
 };
 
 
-void CommandBuffer::setBufferMemoryBarrier(
-	BufferPtr buff, ResourceAccessBit src, ResourceAccessBit dst)
+void CommandBuffer::setBufferBarrier(
+	BufferPtr buff, BufferUsageBit prevUsage, BufferUsageBit nextUsage)
 {
 {
-	const ResourceAccessBit c = dst;
 	GLenum d = GL_NONE;
 	GLenum d = GL_NONE;
 
 
+#if 0
 	if((c & ResourceAccessBit::INDIRECT_OR_INDEX_OR_VERTEX_READ)
 	if((c & ResourceAccessBit::INDIRECT_OR_INDEX_OR_VERTEX_READ)
 		!= ResourceAccessBit::NONE)
 		!= ResourceAccessBit::NONE)
 	{
 	{
@@ -590,6 +593,7 @@ void CommandBuffer::setBufferMemoryBarrier(
 	{
 	{
 		d |= GL_BUFFER_UPDATE_BARRIER_BIT | GL_TEXTURE_UPDATE_BARRIER_BIT;
 		d |= GL_BUFFER_UPDATE_BARRIER_BIT | GL_TEXTURE_UPDATE_BARRIER_BIT;
 	}
 	}
+#endif
 
 
 	ANKI_ASSERT(d != GL_NONE);
 	ANKI_ASSERT(d != GL_NONE);
 	m_impl->pushBackNewCommand<SetBufferMemBarrierCommand>(d);
 	m_impl->pushBackNewCommand<SetBufferMemBarrierCommand>(d);

+ 3 - 3
src/gr/gl/GrManager.cpp

@@ -6,7 +6,7 @@
 #include <anki/gr/GrManager.h>
 #include <anki/gr/GrManager.h>
 #include <anki/gr/gl/GrManagerImpl.h>
 #include <anki/gr/gl/GrManagerImpl.h>
 #include <anki/gr/gl/RenderingThread.h>
 #include <anki/gr/gl/RenderingThread.h>
-#include <anki/gr/gl/DynamicMemoryManager.h>
+#include <anki/gr/gl/TransientMemoryManager.h>
 #include <anki/core/Timestamp.h>
 #include <anki/core/Timestamp.h>
 #include <cstring>
 #include <cstring>
 
 
@@ -62,10 +62,10 @@ void GrManager::finish()
 
 
 //==============================================================================
 //==============================================================================
 void* GrManager::allocateFrameTransientMemory(
 void* GrManager::allocateFrameTransientMemory(
-	PtrSize size, BufferUsage usage, TransientMemoryToken& token, Error* err)
+	PtrSize size, BufferUsageBit usage, TransientMemoryToken& token, Error* err)
 {
 {
 	void* data = nullptr;
 	void* data = nullptr;
-	m_impl->getDynamicMemoryManager().allocate(
+	m_impl->getTransientMemoryManager().allocate(
 		size, usage, TransientMemoryTokenLifetime::PER_FRAME, token, data, err);
 		size, usage, TransientMemoryTokenLifetime::PER_FRAME, token, data, err);
 
 
 	return data;
 	return data;

+ 4 - 3
src/gr/gl/GrManagerImpl.cpp

@@ -7,6 +7,7 @@
 #include <anki/gr/GrManager.h>
 #include <anki/gr/GrManager.h>
 #include <anki/gr/gl/RenderingThread.h>
 #include <anki/gr/gl/RenderingThread.h>
 #include <anki/gr/gl/GlState.h>
 #include <anki/gr/gl/GlState.h>
+#include <anki/gr/gl/TransientMemoryManager.h>
 
 
 namespace anki
 namespace anki
 {
 {
@@ -47,9 +48,9 @@ Error GrManagerImpl::init(GrManagerInitInfo& init)
 	m_state->initMainThread(*init.m_config);
 	m_state->initMainThread(*init.m_config);
 
 
 	// Dyn manager
 	// Dyn manager
-	m_dynManager =
-		m_manager->getAllocator().newInstance<DynamicMemoryManager>();
-	m_dynManager->initMainThread(m_manager->getAllocator(), *init.m_config);
+	m_transManager =
+		m_manager->getAllocator().newInstance<TransientMemoryManager>();
+	m_transManager->initMainThread(m_manager->getAllocator(), *init.m_config);
 
 
 	// Create thread
 	// Create thread
 	m_thread =
 	m_thread =

+ 6 - 4
src/gr/gl/RenderingThread.cpp

@@ -8,7 +8,7 @@
 #include <anki/gr/GrManager.h>
 #include <anki/gr/GrManager.h>
 #include <anki/gr/gl/GrManagerImpl.h>
 #include <anki/gr/gl/GrManagerImpl.h>
 #include <anki/gr/gl/GlState.h>
 #include <anki/gr/gl/GlState.h>
-#include <anki/gr/gl/DynamicMemoryManager.h>
+#include <anki/gr/gl/TransientMemoryManager.h>
 #include <anki/util/Logger.h>
 #include <anki/util/Logger.h>
 #include <anki/core/Trace.h>
 #include <anki/core/Trace.h>
 #include <cstdlib>
 #include <cstdlib>
@@ -180,7 +180,9 @@ void RenderingThread::prepare()
 	m_manager->getImplementation().getState().initRenderThread();
 	m_manager->getImplementation().getState().initRenderThread();
 
 
 	// Init dyn mem
 	// Init dyn mem
-	m_manager->getImplementation().getDynamicMemoryManager().initRenderThread();
+	m_manager->getImplementation()
+		.getTransientMemoryManager()
+		.initRenderThread();
 }
 }
 
 
 //==============================================================================
 //==============================================================================
@@ -200,7 +202,7 @@ void RenderingThread::finish()
 	}
 	}
 
 
 	m_manager->getImplementation()
 	m_manager->getImplementation()
-		.getDynamicMemoryManager()
+		.getTransientMemoryManager()
 		.destroyRenderThread();
 		.destroyRenderThread();
 
 
 	// Cleanup GL
 	// Cleanup GL
@@ -310,7 +312,7 @@ void RenderingThread::swapBuffers()
 		m_frameWait = true;
 		m_frameWait = true;
 	}
 	}
 
 
-	m_manager->getImplementation().getDynamicMemoryManager().endFrame();
+	m_manager->getImplementation().getTransientMemoryManager().endFrame();
 
 
 	// ...and then flush a new swap buffers
 	// ...and then flush a new swap buffers
 	flushCommandBuffer(m_swapBuffersCommands);
 	flushCommandBuffer(m_swapBuffersCommands);

+ 4 - 3
src/gr/gl/ResourceGroupImpl.cpp

@@ -15,6 +15,7 @@
 #include <anki/gr/GrManager.h>
 #include <anki/gr/GrManager.h>
 #include <anki/gr/gl/RenderingThread.h>
 #include <anki/gr/gl/RenderingThread.h>
 #include <anki/gr/gl/CommandBufferImpl.h>
 #include <anki/gr/gl/CommandBufferImpl.h>
+#include <anki/gr/gl/TransientMemoryManager.h>
 
 
 namespace anki
 namespace anki
 {
 {
@@ -273,7 +274,7 @@ void ResourceGroupImpl::bind(
 					MAX_UNIFORM_BUFFER_BINDINGS * slot + i,
 					MAX_UNIFORM_BUFFER_BINDINGS * slot + i,
 					getManager()
 					getManager()
 						.getImplementation()
 						.getImplementation()
-						.getDynamicMemoryManager()
+						.getTransientMemoryManager()
 						.getGlName(token),
 						.getGlName(token),
 					token.m_offset,
 					token.m_offset,
 					token.m_range);
 					token.m_range);
@@ -310,7 +311,7 @@ void ResourceGroupImpl::bind(
 					MAX_STORAGE_BUFFER_BINDINGS * slot + i,
 					MAX_STORAGE_BUFFER_BINDINGS * slot + i,
 					getManager()
 					getManager()
 						.getImplementation()
 						.getImplementation()
-						.getDynamicMemoryManager()
+						.getTransientMemoryManager()
 						.getGlName(token),
 						.getGlName(token),
 					token.m_offset,
 					token.m_offset,
 					token.m_range);
 					token.m_range);
@@ -381,7 +382,7 @@ void ResourceGroupImpl::bind(
 					offsets[i] = transientInfo.m_vertexBuffers[i].m_offset;
 					offsets[i] = transientInfo.m_vertexBuffers[i].m_offset;
 					names[i] = getManager()
 					names[i] = getManager()
 								   .getImplementation()
 								   .getImplementation()
-								   .getDynamicMemoryManager()
+								   .getTransientMemoryManager()
 								   .getGlName(transientInfo.m_vertexBuffers[i]);
 								   .getGlName(transientInfo.m_vertexBuffers[i]);
 				}
 				}
 				else
 				else

+ 4 - 0
src/gr/gl/ShaderImpl.cpp

@@ -37,6 +37,10 @@ static const char* SHADER_HEADER = R"(#version %u %s
 #define ANKI_SS_BINDING(set_, binding_) binding = set_ * %u + binding_
 #define ANKI_SS_BINDING(set_, binding_) binding = set_ * %u + binding_
 #define ANKI_TEX_BINDING(set_, binding_) binding = set_ * %u + binding_
 #define ANKI_TEX_BINDING(set_, binding_) binding = set_ * %u + binding_
 
 
+#if defined(FRAGMENT_SHADER)
+#define ANKI_USING_FRAG_COORD(height_) vec4 anki_fragCoord = gl_FragCoord;
+#endif
+
 %s)";
 %s)";
 
 
 //==============================================================================
 //==============================================================================

+ 22 - 56
src/gr/gl/DynamicMemoryManager.cpp → src/gr/gl/TransientMemoryManager.cpp

@@ -3,7 +3,7 @@
 // Code licensed under the BSD License.
 // Code licensed under the BSD License.
 // http://www.anki3d.org/LICENSE
 // http://www.anki3d.org/LICENSE
 
 
-#include <anki/gr/gl/DynamicMemoryManager.h>
+#include <anki/gr/gl/TransientMemoryManager.h>
 #include <anki/gr/gl/Error.h>
 #include <anki/gr/gl/Error.h>
 #include <anki/core/Config.h>
 #include <anki/core/Config.h>
 #include <anki/core/Trace.h>
 #include <anki/core/Trace.h>
@@ -12,23 +12,17 @@ namespace anki
 {
 {
 
 
 //==============================================================================
 //==============================================================================
-DynamicMemoryManager::~DynamicMemoryManager()
+TransientMemoryManager::~TransientMemoryManager()
 {
 {
 	for(PerFrameBuffer& buff : m_perFrameBuffers)
 	for(PerFrameBuffer& buff : m_perFrameBuffers)
 	{
 	{
 		ANKI_ASSERT(buff.m_name == 0);
 		ANKI_ASSERT(buff.m_name == 0);
 		(void)buff;
 		(void)buff;
 	}
 	}
-
-	for(PersistentBuffer& buff : m_persistentBuffers)
-	{
-		ANKI_ASSERT(buff.m_name == 0);
-		(void)buff;
-	}
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-void DynamicMemoryManager::destroyRenderThread()
+void TransientMemoryManager::destroyRenderThread()
 {
 {
 	for(PerFrameBuffer& buff : m_perFrameBuffers)
 	for(PerFrameBuffer& buff : m_perFrameBuffers)
 	{
 	{
@@ -40,50 +34,36 @@ void DynamicMemoryManager::destroyRenderThread()
 
 
 		buff.m_cpuBuff.destroy(m_alloc);
 		buff.m_cpuBuff.destroy(m_alloc);
 	}
 	}
-
-	for(PersistentBuffer& buff : m_persistentBuffers)
-	{
-		if(buff.m_name != 0)
-		{
-			glDeleteBuffers(1, &buff.m_name);
-			buff.m_name = 0;
-		}
-
-		buff.m_cpuBuff.destroy(m_alloc);
-	}
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-void DynamicMemoryManager::initMainThread(
+void TransientMemoryManager::initMainThread(
 	GenericMemoryPoolAllocator<U8> alloc, const ConfigSet& cfg)
 	GenericMemoryPoolAllocator<U8> alloc, const ConfigSet& cfg)
 {
 {
 	m_alloc = alloc;
 	m_alloc = alloc;
 
 
-	m_perFrameBuffers[BufferUsage::UNIFORM].m_size =
+	m_perFrameBuffers[TransientBufferType::UNIFORM].m_size =
 		cfg.getNumber("gr.uniformPerFrameMemorySize");
 		cfg.getNumber("gr.uniformPerFrameMemorySize");
 
 
-	m_perFrameBuffers[BufferUsage::STORAGE].m_size =
+	m_perFrameBuffers[TransientBufferType::STORAGE].m_size =
 		cfg.getNumber("gr.storagePerFrameMemorySize");
 		cfg.getNumber("gr.storagePerFrameMemorySize");
 
 
-	m_perFrameBuffers[BufferUsage::VERTEX].m_size =
+	m_perFrameBuffers[TransientBufferType::VERTEX].m_size =
 		cfg.getNumber("gr.vertexPerFrameMemorySize");
 		cfg.getNumber("gr.vertexPerFrameMemorySize");
 
 
-	m_perFrameBuffers[BufferUsage::TRANSFER].m_size =
+	m_perFrameBuffers[TransientBufferType::TRANSFER].m_size =
 		cfg.getNumber("gr.transferPerFrameMemorySize");
 		cfg.getNumber("gr.transferPerFrameMemorySize");
-
-	m_persistentBuffers[BufferUsage::TRANSFER].m_size =
-		cfg.getNumber("gr.transferPersistentMemorySize");
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-void DynamicMemoryManager::initRenderThread()
+void TransientMemoryManager::initRenderThread()
 {
 {
 	const U BUFF_FLAGS = GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT;
 	const U BUFF_FLAGS = GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT;
 
 
 	// Uniform
 	// Uniform
 	{
 	{
 		// Create buffer
 		// Create buffer
-		PerFrameBuffer& buff = m_perFrameBuffers[BufferUsage::UNIFORM];
+		PerFrameBuffer& buff = m_perFrameBuffers[TransientBufferType::UNIFORM];
 		PtrSize size = buff.m_size;
 		PtrSize size = buff.m_size;
 		glGenBuffers(1, &buff.m_name);
 		glGenBuffers(1, &buff.m_name);
 		glBindBuffer(GL_UNIFORM_BUFFER, buff.m_name);
 		glBindBuffer(GL_UNIFORM_BUFFER, buff.m_name);
@@ -103,7 +83,7 @@ void DynamicMemoryManager::initRenderThread()
 	// Storage
 	// Storage
 	{
 	{
 		// Create buffer
 		// Create buffer
-		PerFrameBuffer& buff = m_perFrameBuffers[BufferUsage::STORAGE];
+		PerFrameBuffer& buff = m_perFrameBuffers[TransientBufferType::STORAGE];
 		PtrSize size = buff.m_size;
 		PtrSize size = buff.m_size;
 		glGenBuffers(1, &buff.m_name);
 		glGenBuffers(1, &buff.m_name);
 		glBindBuffer(GL_SHADER_STORAGE_BUFFER, buff.m_name);
 		glBindBuffer(GL_SHADER_STORAGE_BUFFER, buff.m_name);
@@ -124,7 +104,7 @@ void DynamicMemoryManager::initRenderThread()
 	// Vertex
 	// Vertex
 	{
 	{
 		// Create buffer
 		// Create buffer
-		PerFrameBuffer& buff = m_perFrameBuffers[BufferUsage::VERTEX];
+		PerFrameBuffer& buff = m_perFrameBuffers[TransientBufferType::VERTEX];
 		PtrSize size = buff.m_size;
 		PtrSize size = buff.m_size;
 		glGenBuffers(1, &buff.m_name);
 		glGenBuffers(1, &buff.m_name);
 		glBindBuffer(GL_ARRAY_BUFFER, buff.m_name);
 		glBindBuffer(GL_ARRAY_BUFFER, buff.m_name);
@@ -141,31 +121,18 @@ void DynamicMemoryManager::initRenderThread()
 
 
 	// Transfer
 	// Transfer
 	{
 	{
-		PerFrameBuffer& buff = m_perFrameBuffers[BufferUsage::TRANSFER];
+		PerFrameBuffer& buff = m_perFrameBuffers[TransientBufferType::TRANSFER];
 		PtrSize size = buff.m_size;
 		PtrSize size = buff.m_size;
 		buff.m_cpuBuff.create(m_alloc, size);
 		buff.m_cpuBuff.create(m_alloc, size);
 
 
 		buff.m_mappedMem = reinterpret_cast<U8*>(&buff.m_cpuBuff[0]);
 		buff.m_mappedMem = reinterpret_cast<U8*>(&buff.m_cpuBuff[0]);
 		buff.m_alloc.init(size, 16, MAX_U32);
 		buff.m_alloc.init(size, 16, MAX_U32);
 	}
 	}
-
-	{
-		const U BLOCK_SIZE = (4096 * 4096) / 4 * 16;
-
-		PersistentBuffer& buff = m_persistentBuffers[BufferUsage::TRANSFER];
-		PtrSize size = getAlignedRoundUp(BLOCK_SIZE, buff.m_size);
-		size = max(size, 2 * BLOCK_SIZE);
-		buff.m_cpuBuff.create(m_alloc, size);
-
-		buff.m_mappedMem = reinterpret_cast<U8*>(&buff.m_cpuBuff[0]);
-		buff.m_alloc.init(m_alloc, size, BLOCK_SIZE);
-		buff.m_alignment = 16;
-	}
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-void DynamicMemoryManager::allocate(PtrSize size,
-	BufferUsage usage,
+void TransientMemoryManager::allocate(PtrSize size,
+	BufferUsageBit usage,
 	TransientMemoryTokenLifetime lifespan,
 	TransientMemoryTokenLifetime lifespan,
 	TransientMemoryToken& token,
 	TransientMemoryToken& token,
 	void*& ptr,
 	void*& ptr,
@@ -177,15 +144,13 @@ void DynamicMemoryManager::allocate(PtrSize size,
 
 
 	if(lifespan == TransientMemoryTokenLifetime::PER_FRAME)
 	if(lifespan == TransientMemoryTokenLifetime::PER_FRAME)
 	{
 	{
-		PerFrameBuffer& buff = m_perFrameBuffers[usage];
+		PerFrameBuffer& buff = m_perFrameBuffers[bufferUsageToTransient(usage)];
 		err = buff.m_alloc.allocate(size, token.m_offset);
 		err = buff.m_alloc.allocate(size, token.m_offset);
 		mappedMemBase = buff.m_mappedMem;
 		mappedMemBase = buff.m_mappedMem;
 	}
 	}
 	else
 	else
 	{
 	{
-		PersistentBuffer& buff = m_persistentBuffers[usage];
-		err = buff.m_alloc.allocate(size, buff.m_alignment, token.m_offset);
-		mappedMemBase = buff.m_mappedMem;
+		ANKI_ASSERT(0);
 	}
 	}
 
 
 	if(!err)
 	if(!err)
@@ -206,9 +171,10 @@ void DynamicMemoryManager::allocate(PtrSize size,
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-void DynamicMemoryManager::endFrame()
+void TransientMemoryManager::endFrame()
 {
 {
-	for(BufferUsage usage = BufferUsage::FIRST; usage < BufferUsage::COUNT;
+	for(TransientBufferType usage = TransientBufferType::UNIFORM;
+		usage < TransientBufferType::COUNT;
 		++usage)
 		++usage)
 	{
 	{
 		PerFrameBuffer& buff = m_perFrameBuffers[usage];
 		PerFrameBuffer& buff = m_perFrameBuffers[usage];
@@ -218,11 +184,11 @@ void DynamicMemoryManager::endFrame()
 			// Increase the counters
 			// Increase the counters
 			switch(usage)
 			switch(usage)
 			{
 			{
-			case BufferUsage::UNIFORM:
+			case TransientBufferType::UNIFORM:
 				ANKI_TRACE_INC_COUNTER(GR_DYNAMIC_UNIFORMS_SIZE,
 				ANKI_TRACE_INC_COUNTER(GR_DYNAMIC_UNIFORMS_SIZE,
 					buff.m_alloc.getUnallocatedMemorySize());
 					buff.m_alloc.getUnallocatedMemorySize());
 				break;
 				break;
-			case BufferUsage::STORAGE:
+			case TransientBufferType::STORAGE:
 				ANKI_TRACE_INC_COUNTER(GR_DYNAMIC_STORAGE_SIZE,
 				ANKI_TRACE_INC_COUNTER(GR_DYNAMIC_STORAGE_SIZE,
 					buff.m_alloc.getUnallocatedMemorySize());
 					buff.m_alloc.getUnallocatedMemorySize());
 				break;
 				break;

+ 2 - 2
src/gr/vulkan/Buffer.cpp

@@ -21,7 +21,7 @@ Buffer::~Buffer()
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-void Buffer::init(PtrSize size, BufferUsageBit usage, BufferAccessBit access)
+void Buffer::init(PtrSize size, BufferUsageBit usage, BufferMapAccessBit access)
 {
 {
 	m_impl.reset(getAllocator().newInstance<BufferImpl>(&getManager()));
 	m_impl.reset(getAllocator().newInstance<BufferImpl>(&getManager()));
 
 
@@ -32,7 +32,7 @@ void Buffer::init(PtrSize size, BufferUsageBit usage, BufferAccessBit access)
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-void* Buffer::map(PtrSize offset, PtrSize range, BufferAccessBit access)
+void* Buffer::map(PtrSize offset, PtrSize range, BufferMapAccessBit access)
 {
 {
 	return m_impl->map(offset, range, access);
 	return m_impl->map(offset, range, access);
 }
 }

+ 44 - 12
src/gr/vulkan/BufferImpl.cpp

@@ -27,7 +27,7 @@ BufferImpl::~BufferImpl()
 
 
 //==============================================================================
 //==============================================================================
 Error BufferImpl::init(
 Error BufferImpl::init(
-	PtrSize size, BufferUsageBit usage, BufferAccessBit access)
+	PtrSize size, BufferUsageBit usage, BufferMapAccessBit access)
 {
 {
 	ANKI_ASSERT(!isCreated());
 	ANKI_ASSERT(!isCreated());
 	ANKI_ASSERT(size > 0);
 	ANKI_ASSERT(size > 0);
@@ -47,30 +47,62 @@ Error BufferImpl::init(
 	VkMemoryRequirements req;
 	VkMemoryRequirements req;
 	vkGetBufferMemoryRequirements(getDevice(), m_handle, &req);
 	vkGetBufferMemoryRequirements(getDevice(), m_handle, &req);
 
 
-	if((access & (BufferAccessBit::CLIENT_MAP_READ
-					 | BufferAccessBit::CLIENT_MAP_WRITE))
-		!= BufferAccessBit::NONE)
+	if(access == BufferMapAccessBit::WRITE)
 	{
 	{
+		// Only write
+
+		// Device & host
 		m_memIdx = getGrManagerImpl().findMemoryType(req.memoryTypeBits,
 		m_memIdx = getGrManagerImpl().findMemoryType(req.memoryTypeBits,
 			VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
 			VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
-				| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
-				| VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
+				| VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
 			0);
 			0);
 
 
-		// Fallback
+		// Fallback: host and not coherent
+		if(m_memIdx == MAX_U32)
+		{
+			m_memIdx = getGrManagerImpl().findMemoryType(req.memoryTypeBits,
+				VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
+				VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
+		}
+
+		// Fallback: just host
 		if(m_memIdx == MAX_U32)
 		if(m_memIdx == MAX_U32)
 		{
 		{
 			m_memIdx = getGrManagerImpl().findMemoryType(
 			m_memIdx = getGrManagerImpl().findMemoryType(
-				req.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, 0);
+				req.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, 0);
+		}
+	}
+	else if((access & BufferMapAccessBit::READ) != BufferMapAccessBit::NONE)
+	{
+		// Read or read/write
+
+		// Cached
+		m_memIdx = getGrManagerImpl().findMemoryType(req.memoryTypeBits,
+			VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
+				| VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
+			0);
+
+		// Fallback: Just coherent
+		if(m_memIdx == MAX_U32)
+		{
+			m_memIdx = getGrManagerImpl().findMemoryType(req.memoryTypeBits,
+				VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
+					| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
+				0);
 		}
 		}
 	}
 	}
 	else
 	else
 	{
 	{
+		// Not mapped
+
+		ANKI_ASSERT(access == BufferMapAccessBit::NONE);
+
+		// Device only
 		m_memIdx = getGrManagerImpl().findMemoryType(req.memoryTypeBits,
 		m_memIdx = getGrManagerImpl().findMemoryType(req.memoryTypeBits,
 			VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
 			VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
 			VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
 			VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
 
 
-		// Fallback
+		// Fallback: Device with anything else
 		if(m_memIdx == MAX_U32)
 		if(m_memIdx == MAX_U32)
 		{
 		{
 			m_memIdx = getGrManagerImpl().findMemoryType(
 			m_memIdx = getGrManagerImpl().findMemoryType(
@@ -94,10 +126,10 @@ Error BufferImpl::init(
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-void* BufferImpl::map(PtrSize offset, PtrSize range, BufferAccessBit access)
+void* BufferImpl::map(PtrSize offset, PtrSize range, BufferMapAccessBit access)
 {
 {
 	ANKI_ASSERT(isCreated());
 	ANKI_ASSERT(isCreated());
-	ANKI_ASSERT((access & m_access) != BufferAccessBit::NONE);
+	ANKI_ASSERT((access & m_access) != BufferMapAccessBit::NONE);
 	ANKI_ASSERT(!m_mapped);
 	ANKI_ASSERT(!m_mapped);
 	ANKI_ASSERT(offset + range <= m_size);
 	ANKI_ASSERT(offset + range <= m_size);
 
 
@@ -111,4 +143,4 @@ void* BufferImpl::map(PtrSize offset, PtrSize range, BufferAccessBit access)
 	return static_cast<void*>(static_cast<U8*>(ptr) + offset);
 	return static_cast<void*>(static_cast<U8*>(ptr) + offset);
 }
 }
 
 
-} // end namespace anki
+} // end namespace anki

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

@@ -182,14 +182,8 @@ void CommandBuffer::setTextureBarrier(TexturePtr tex,
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-void CommandBuffer::setPipelineBarrier(
-	PipelineStageBit src, PipelineStageBit dst)
-{
-}
-
-//==============================================================================
-void CommandBuffer::setBufferMemoryBarrier(
-	BufferPtr buff, ResourceAccessBit src, ResourceAccessBit dst)
+void CommandBuffer::setBufferBarrier(
+	BufferPtr buff, BufferUsageBit before, BufferUsageBit after)
 {
 {
 }
 }
 
 

+ 10 - 5
src/gr/vulkan/Common.cpp

@@ -729,12 +729,12 @@ VkBufferUsageFlags convertBufferUsageBit(BufferUsageBit usageMask)
 {
 {
 	VkBufferUsageFlags out = 0;
 	VkBufferUsageFlags out = 0;
 
 
-	if((usageMask & BufferUsageBit::UNIFORM) != BufferUsageBit::NONE)
+	if((usageMask & BufferUsageBit::UNIFORM_ANY_SHADER) != BufferUsageBit::NONE)
 	{
 	{
 		out |= VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
 		out |= VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
 	}
 	}
 
 
-	if((usageMask & BufferUsageBit::STORAGE) != BufferUsageBit::NONE)
+	if((usageMask & BufferUsageBit::STORAGE_ANY) != BufferUsageBit::NONE)
 	{
 	{
 		out |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
 		out |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
 	}
 	}
@@ -754,10 +754,15 @@ VkBufferUsageFlags convertBufferUsageBit(BufferUsageBit usageMask)
 		out |= VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
 		out |= VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
 	}
 	}
 
 
-	if((usageMask & BufferUsageBit::TRANSFER) != BufferUsageBit::NONE)
+	if((usageMask & BufferUsageBit::TRANSFER_DESTINATION)
+		!= BufferUsageBit::NONE)
 	{
 	{
-		out |=
-			VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
+		out |= VK_BUFFER_USAGE_TRANSFER_DST_BIT;
+	}
+
+	if((usageMask & BufferUsageBit::TRANSFER_SOURCE) != BufferUsageBit::NONE)
+	{
+		out |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
 	}
 	}
 
 
 	ANKI_ASSERT(out);
 	ANKI_ASSERT(out);

+ 1 - 1
src/gr/vulkan/GrManager.cpp

@@ -55,7 +55,7 @@ void GrManager::finish()
 
 
 //==============================================================================
 //==============================================================================
 void* GrManager::allocateFrameTransientMemory(
 void* GrManager::allocateFrameTransientMemory(
-	PtrSize size, BufferUsage usage, TransientMemoryToken& token, Error* err)
+	PtrSize size, BufferUsageBit usage, TransientMemoryToken& token, Error* err)
 {
 {
 	void* ptr = nullptr;
 	void* ptr = nullptr;
 	m_impl->getTransientMemoryManager().allocate(size, usage, token, ptr, err);
 	m_impl->getTransientMemoryManager().allocate(size, usage, token, ptr, err);

+ 4 - 3
src/gr/vulkan/ResourceGroupImpl.cpp

@@ -170,7 +170,7 @@ Error ResourceGroupImpl::init(const ResourceGroupInitInfo& init)
 			VkDescriptorBufferInfo& inf = unis[uniCount++];
 			VkDescriptorBufferInfo& inf = unis[uniCount++];
 			inf.buffer =
 			inf.buffer =
 				getGrManagerImpl().getTransientMemoryManager().getBufferHandle(
 				getGrManagerImpl().getTransientMemoryManager().getBufferHandle(
-					BufferUsage::UNIFORM);
+					BufferUsageBit::UNIFORM_ANY_SHADER);
 			inf.range = VK_WHOLE_SIZE;
 			inf.range = VK_WHOLE_SIZE;
 
 
 			m_dynamicBuffersMask.set(i);
 			m_dynamicBuffersMask.set(i);
@@ -252,11 +252,12 @@ void ResourceGroupImpl::setupDynamicOffsets(
 					dynInfo->m_uniformBuffers[i];
 					dynInfo->m_uniformBuffers[i];
 
 
 				ANKI_ASSERT(token.m_range);
 				ANKI_ASSERT(token.m_range);
-				ANKI_ASSERT(token.m_usage == BufferUsage::UNIFORM);
+				ANKI_ASSERT((token.m_usage & BufferUsageBit::UNIFORM_ANY_SHADER)
+					!= BufferUsageBit::NONE);
 				dynOffsets[i] = token.m_offset;
 				dynOffsets[i] = token.m_offset;
 			}
 			}
 		}
 		}
 	}
 	}
 }
 }
 
 
-} // end namespace anki
+} // end namespace anki

+ 5 - 0
src/gr/vulkan/ShaderImpl.cpp

@@ -156,6 +156,11 @@ static const char* SHADER_HEADER = R"(#version 450 core
 #define ANKI_SS_BINDING(set_, binding_) set = set_, binding = %u + binding_
 #define ANKI_SS_BINDING(set_, binding_) set = set_, binding = %u + binding_
 #define ANKI_TEX_BINDING(set_, binding_) set = set_, binding = %u + binding_
 #define ANKI_TEX_BINDING(set_, binding_) set = set_, binding = %u + binding_
 
 
+#if defined(FRAGMENT_SHADER)
+#define ANKI_USING_FRAG_COORD(h_) vec4 anki_fragCoord = \
+	vec4(gl_FragCoord.x, h_ - gl_FragCoord.y, gl_FragCoord.z, gl_FragCoord.w);
+#endif
+
 %s)";
 %s)";
 
 
 //==============================================================================
 //==============================================================================

+ 16 - 18
src/gr/vulkan/TransientMemoryManager.cpp

@@ -15,47 +15,45 @@ namespace anki
 //==============================================================================
 //==============================================================================
 Error TransientMemoryManager::init(const ConfigSet& cfg)
 Error TransientMemoryManager::init(const ConfigSet& cfg)
 {
 {
-	Array<const char*, U(BufferUsage::COUNT)> configVars = {
+	Array<const char*, U(TransientBufferType::COUNT)> configVars = {
 		{"gr.uniformPerFrameMemorySize",
 		{"gr.uniformPerFrameMemorySize",
 			"gr.storagePerFrameMemorySize",
 			"gr.storagePerFrameMemorySize",
-			nullptr,
 			"gr.vertexPerFrameMemorySize",
 			"gr.vertexPerFrameMemorySize",
-			nullptr,
 			"gr.transferPerFrameMemorySize"}};
 			"gr.transferPerFrameMemorySize"}};
 
 
 	const VkPhysicalDeviceLimits& limits =
 	const VkPhysicalDeviceLimits& limits =
 		m_manager->getImplementation().getPhysicalDeviceProperties().limits;
 		m_manager->getImplementation().getPhysicalDeviceProperties().limits;
-	Array<U32, U(BufferUsage::COUNT)> alignments = {
+	Array<U32, U(TransientBufferType::COUNT)> alignments = {
 		{U32(limits.minUniformBufferOffsetAlignment),
 		{U32(limits.minUniformBufferOffsetAlignment),
 			U32(limits.minStorageBufferOffsetAlignment),
 			U32(limits.minStorageBufferOffsetAlignment),
-			0,
 			sizeof(F32) * 4,
 			sizeof(F32) * 4,
-			0,
 			sizeof(F32) * 4}};
 			sizeof(F32) * 4}};
 
 
+	Array<BufferUsageBit, U(TransientBufferType::COUNT)> usages = {
+		{BufferUsageBit::UNIFORM_ANY_SHADER,
+			BufferUsageBit::STORAGE_ANY,
+			BufferUsageBit::VERTEX,
+			BufferUsageBit::TRANSFER_SOURCE}};
+
 	auto alloc = m_manager->getAllocator();
 	auto alloc = m_manager->getAllocator();
-	for(U i = 0; i < U(BufferUsage::COUNT); ++i)
+	for(TransientBufferType i = TransientBufferType::UNIFORM;
+		i < TransientBufferType::COUNT;
+		++i)
 	{
 	{
-		if(configVars[i] == nullptr)
-		{
-			continue;
-		}
-
 		PerFrameBuffer& frame = m_perFrameBuffers[i];
 		PerFrameBuffer& frame = m_perFrameBuffers[i];
 		frame.m_size = cfg.getNumber(configVars[i]);
 		frame.m_size = cfg.getNumber(configVars[i]);
 		ANKI_ASSERT(frame.m_size);
 		ANKI_ASSERT(frame.m_size);
 
 
 		// Create buffer
 		// Create buffer
-		BufferUsageBit usage = BufferUsageBit(1 << i);
 		frame.m_buff = alloc.newInstance<BufferImpl>(m_manager);
 		frame.m_buff = alloc.newInstance<BufferImpl>(m_manager);
 		ANKI_CHECK(frame.m_buff->init(
 		ANKI_CHECK(frame.m_buff->init(
-			frame.m_size, usage, BufferAccessBit::CLIENT_MAP_WRITE));
+			frame.m_size, usages[i], BufferMapAccessBit::WRITE));
 
 
 		frame.m_bufferHandle = frame.m_buff->getHandle();
 		frame.m_bufferHandle = frame.m_buff->getHandle();
 
 
 		// Map once
 		// Map once
-		frame.m_mappedMem = static_cast<U8*>(frame.m_buff->map(
-			0, frame.m_size, BufferAccessBit::CLIENT_MAP_WRITE));
+		frame.m_mappedMem = static_cast<U8*>(
+			frame.m_buff->map(0, frame.m_size, BufferMapAccessBit::WRITE));
 		ANKI_ASSERT(frame.m_mappedMem);
 		ANKI_ASSERT(frame.m_mappedMem);
 
 
 		// Init the allocator
 		// Init the allocator
@@ -80,7 +78,7 @@ void TransientMemoryManager::destroy()
 
 
 //==============================================================================
 //==============================================================================
 void TransientMemoryManager::allocate(PtrSize size,
 void TransientMemoryManager::allocate(PtrSize size,
-	BufferUsage usage,
+	BufferUsageBit usage,
 	TransientMemoryToken& token,
 	TransientMemoryToken& token,
 	void*& ptr,
 	void*& ptr,
 	Error* outErr)
 	Error* outErr)
@@ -88,7 +86,7 @@ void TransientMemoryManager::allocate(PtrSize size,
 	Error err = ErrorCode::NONE;
 	Error err = ErrorCode::NONE;
 	ptr = nullptr;
 	ptr = nullptr;
 
 
-	PerFrameBuffer& buff = m_perFrameBuffers[usage];
+	PerFrameBuffer& buff = m_perFrameBuffers[bufferUsageToTransient(usage)];
 	err = buff.m_alloc.allocate(size, token.m_offset);
 	err = buff.m_alloc.allocate(size, token.m_offset);
 
 
 	if(!err)
 	if(!err)

+ 4 - 3
src/renderer/Bloom.cpp

@@ -163,9 +163,10 @@ void Bloom::run(RenderingContext& ctx)
 	cmdb->bindPipeline(m_tonePpline);
 	cmdb->bindPipeline(m_tonePpline);
 
 
 	TransientMemoryInfo dyn;
 	TransientMemoryInfo dyn;
-	Vec4* uniforms =
-		static_cast<Vec4*>(getGrManager().allocateFrameTransientMemory(
-			sizeof(Vec4), BufferUsage::UNIFORM, dyn.m_uniformBuffers[0]));
+	Vec4* uniforms = static_cast<Vec4*>(
+		getGrManager().allocateFrameTransientMemory(sizeof(Vec4),
+			BufferUsageBit::UNIFORM_ANY_SHADER,
+			dyn.m_uniformBuffers[0]));
 	*uniforms = Vec4(m_threshold, m_scale, 0.0, 0.0);
 	*uniforms = Vec4(m_threshold, m_scale, 0.0, 0.0);
 
 
 	cmdb->bindResourceGroup(m_firstDescrGroup, 0, &dyn);
 	cmdb->bindResourceGroup(m_firstDescrGroup, 0, &dyn);

+ 3 - 4
src/renderer/DebugDrawer.cpp

@@ -82,7 +82,7 @@ Error DebugDrawer::init(Renderer* r)
 	{
 	{
 		v = gr.newInstance<Buffer>(sizeof(Vertex) * MAX_VERTS_PER_FRAME,
 		v = gr.newInstance<Buffer>(sizeof(Vertex) * MAX_VERTS_PER_FRAME,
 			BufferUsageBit::VERTEX,
 			BufferUsageBit::VERTEX,
-			BufferAccessBit::CLIENT_MAP_WRITE);
+			BufferMapAccessBit::WRITE);
 	}
 	}
 
 
 	// Create the resouce groups
 	// Create the resouce groups
@@ -107,9 +107,8 @@ void DebugDrawer::prepareFrame(CommandBufferPtr& jobs)
 	m_cmdb = jobs;
 	m_cmdb = jobs;
 
 
 	U frame = m_r->getFrameCount() % MAX_FRAMES_IN_FLIGHT;
 	U frame = m_r->getFrameCount() % MAX_FRAMES_IN_FLIGHT;
-	void* mapped = m_vertBuff[frame]->map(0,
-		MAX_VERTS_PER_FRAME * sizeof(Vertex),
-		BufferAccessBit::CLIENT_MAP_WRITE);
+	void* mapped = m_vertBuff[frame]->map(
+		0, MAX_VERTS_PER_FRAME * sizeof(Vertex), BufferMapAccessBit::WRITE);
 	m_clientVerts =
 	m_clientVerts =
 		WeakArray<Vertex>(static_cast<Vertex*>(mapped), MAX_VERTS_PER_FRAME);
 		WeakArray<Vertex>(static_cast<Vertex*>(mapped), MAX_VERTS_PER_FRAME);
 
 

+ 1 - 1
src/renderer/Drawer.cpp

@@ -216,7 +216,7 @@ void RenderableDrawer::setupUniforms(DrawContext& ctx,
 	U8* uniforms =
 	U8* uniforms =
 		static_cast<U8*>(m_r->getGrManager().allocateFrameTransientMemory(
 		static_cast<U8*>(m_r->getGrManager().allocateFrameTransientMemory(
 			variant.getDefaultBlockSize(),
 			variant.getDefaultBlockSize(),
-			BufferUsage::UNIFORM,
+			BufferUsageBit::UNIFORM_ANY_SHADER,
 			ctx.m_dynBufferInfo.m_uniformBuffers[0]));
 			ctx.m_dynBufferInfo.m_uniformBuffers[0]));
 
 
 	// Call the visitor
 	// Call the visitor

+ 4 - 3
src/renderer/Ir.cpp

@@ -284,9 +284,10 @@ Error Ir::renderReflection(RenderingContext& ctx,
 	for(U i = 0; i < 6; ++i)
 	for(U i = 0; i < 6; ++i)
 	{
 	{
 		TransientMemoryInfo dinf;
 		TransientMemoryInfo dinf;
-		UVec4* faceIdxArrayIdx =
-			static_cast<UVec4*>(getGrManager().allocateFrameTransientMemory(
-				sizeof(UVec4), BufferUsage::UNIFORM, dinf.m_uniformBuffers[0]));
+		UVec4* faceIdxArrayIdx = static_cast<UVec4*>(
+			getGrManager().allocateFrameTransientMemory(sizeof(UVec4),
+				BufferUsageBit::UNIFORM_ANY_SHADER,
+				dinf.m_uniformBuffers[0]));
 		faceIdxArrayIdx->x() = i;
 		faceIdxArrayIdx->x() = i;
 		faceIdxArrayIdx->y() = cubemapIdx;
 		faceIdxArrayIdx->y() = cubemapIdx;
 
 

+ 1 - 1
src/renderer/Is.cpp

@@ -232,7 +232,7 @@ void Is::updateCommonBlock(RenderingContext& ctx)
 	ShaderCommonUniforms* blk = static_cast<ShaderCommonUniforms*>(
 	ShaderCommonUniforms* blk = static_cast<ShaderCommonUniforms*>(
 		getGrManager().allocateFrameTransientMemory(
 		getGrManager().allocateFrameTransientMemory(
 			sizeof(ShaderCommonUniforms),
 			sizeof(ShaderCommonUniforms),
-			BufferUsage::UNIFORM,
+			BufferUsageBit::UNIFORM_ANY_SHADER,
 			ctx.m_is.m_dynBufferInfo.m_uniformBuffers[COMMON_VARS_LOCATION]));
 			ctx.m_is.m_dynBufferInfo.m_uniformBuffers[COMMON_VARS_LOCATION]));
 
 
 	// Start writing
 	// Start writing

+ 3 - 3
src/renderer/Lf.cpp

@@ -174,14 +174,14 @@ void Lf::runOcclusionTests(RenderingContext& ctx)
 		TransientMemoryToken token;
 		TransientMemoryToken token;
 		Mat4* mvp =
 		Mat4* mvp =
 			static_cast<Mat4*>(getGrManager().allocateFrameTransientMemory(
 			static_cast<Mat4*>(getGrManager().allocateFrameTransientMemory(
-				sizeof(Mat4), BufferUsage::UNIFORM, token));
+				sizeof(Mat4), BufferUsageBit::UNIFORM_ANY_SHADER, token));
 		*mvp = camFr.getViewProjectionMatrix();
 		*mvp = camFr.getViewProjectionMatrix();
 
 
 		// Alloc dyn mem
 		// Alloc dyn mem
 		TransientMemoryToken token2;
 		TransientMemoryToken token2;
 		Vec3* positions =
 		Vec3* positions =
 			static_cast<Vec3*>(getGrManager().allocateFrameTransientMemory(
 			static_cast<Vec3*>(getGrManager().allocateFrameTransientMemory(
-				sizeof(Vec3) * totalCount, BufferUsage::VERTEX, token2));
+				sizeof(Vec3) * totalCount, BufferUsageBit::VERTEX, token2));
 		const Vec3* initialPositions = positions;
 		const Vec3* initialPositions = positions;
 
 
 		// Setup state
 		// Setup state
@@ -259,7 +259,7 @@ void Lf::run(RenderingContext& ctx)
 			Sprite* tmpSprites = static_cast<Sprite*>(
 			Sprite* tmpSprites = static_cast<Sprite*>(
 				getGrManager().allocateFrameTransientMemory(
 				getGrManager().allocateFrameTransientMemory(
 					spritesCount * sizeof(Sprite),
 					spritesCount * sizeof(Sprite),
-					BufferUsage::UNIFORM,
+					BufferUsageBit::UNIFORM_ANY_SHADER,
 					token));
 					token));
 			WeakArray<Sprite> sprites(tmpSprites, spritesCount);
 			WeakArray<Sprite> sprites(tmpSprites, spritesCount);
 
 

+ 5 - 5
src/renderer/LightBin.cpp

@@ -380,7 +380,7 @@ Error LightBin::bin(FrustumComponent& frc,
 		ShaderPointLight* data =
 		ShaderPointLight* data =
 			static_cast<ShaderPointLight*>(m_gr->allocateFrameTransientMemory(
 			static_cast<ShaderPointLight*>(m_gr->allocateFrameTransientMemory(
 				sizeof(ShaderPointLight) * visiblePointLightsCount,
 				sizeof(ShaderPointLight) * visiblePointLightsCount,
-				BufferUsage::UNIFORM,
+				BufferUsageBit::UNIFORM_ANY_SHADER,
 				pointLightsToken));
 				pointLightsToken));
 
 
 		ctx.m_pointLights =
 		ctx.m_pointLights =
@@ -400,7 +400,7 @@ Error LightBin::bin(FrustumComponent& frc,
 		ShaderSpotLight* data =
 		ShaderSpotLight* data =
 			static_cast<ShaderSpotLight*>(m_gr->allocateFrameTransientMemory(
 			static_cast<ShaderSpotLight*>(m_gr->allocateFrameTransientMemory(
 				sizeof(ShaderSpotLight) * visibleSpotLightsCount,
 				sizeof(ShaderSpotLight) * visibleSpotLightsCount,
-				BufferUsage::UNIFORM,
+				BufferUsageBit::UNIFORM_ANY_SHADER,
 				spotLightsToken));
 				spotLightsToken));
 
 
 		ctx.m_spotLights =
 		ctx.m_spotLights =
@@ -422,7 +422,7 @@ Error LightBin::bin(FrustumComponent& frc,
 			ShaderProbe* data =
 			ShaderProbe* data =
 				static_cast<ShaderProbe*>(m_gr->allocateFrameTransientMemory(
 				static_cast<ShaderProbe*>(m_gr->allocateFrameTransientMemory(
 					sizeof(ShaderProbe) * visibleProbeCount,
 					sizeof(ShaderProbe) * visibleProbeCount,
-					BufferUsage::UNIFORM,
+					BufferUsageBit::UNIFORM_ANY_SHADER,
 					*probesToken));
 					*probesToken));
 
 
 			ctx.m_probes = WeakArray<ShaderProbe>(data, visibleProbeCount);
 			ctx.m_probes = WeakArray<ShaderProbe>(data, visibleProbeCount);
@@ -443,7 +443,7 @@ Error LightBin::bin(FrustumComponent& frc,
 	ShaderCluster* data =
 	ShaderCluster* data =
 		static_cast<ShaderCluster*>(m_gr->allocateFrameTransientMemory(
 		static_cast<ShaderCluster*>(m_gr->allocateFrameTransientMemory(
 			sizeof(ShaderCluster) * m_clusterCount,
 			sizeof(ShaderCluster) * m_clusterCount,
-			BufferUsage::STORAGE,
+			BufferUsageBit::UNIFORM_ANY_SHADER,
 			clustersToken));
 			clustersToken));
 
 
 	ctx.m_clusters = WeakArray<ShaderCluster>(data, m_clusterCount);
 	ctx.m_clusters = WeakArray<ShaderCluster>(data, m_clusterCount);
@@ -451,7 +451,7 @@ Error LightBin::bin(FrustumComponent& frc,
 	// Allocate light IDs
 	// Allocate light IDs
 	U32* data2 = static_cast<U32*>(
 	U32* data2 = static_cast<U32*>(
 		m_gr->allocateFrameTransientMemory(maxLightIndices * sizeof(U32),
 		m_gr->allocateFrameTransientMemory(maxLightIndices * sizeof(U32),
-			BufferUsage::STORAGE,
+			BufferUsageBit::UNIFORM_ANY_SHADER,
 			lightIndicesToken));
 			lightIndicesToken));
 
 
 	ctx.m_lightIds = WeakArray<U32>(data2, maxLightIndices);
 	ctx.m_lightIds = WeakArray<U32>(data2, maxLightIndices);

+ 1 - 1
src/renderer/Renderer.cpp

@@ -221,7 +221,7 @@ Error Renderer::render(RenderingContext& ctx)
 	RendererCommonUniforms* commonUniforms =
 	RendererCommonUniforms* commonUniforms =
 		static_cast<RendererCommonUniforms*>(
 		static_cast<RendererCommonUniforms*>(
 			getGrManager().allocateFrameTransientMemory(sizeof(*commonUniforms),
 			getGrManager().allocateFrameTransientMemory(sizeof(*commonUniforms),
-				BufferUsage::UNIFORM,
+				BufferUsageBit::UNIFORM_ANY_SHADER,
 				m_commonUniformsToken));
 				m_commonUniformsToken));
 
 
 	commonUniforms->m_projectionParams = frc.getProjectionParameters();
 	commonUniforms->m_projectionParams = frc.getProjectionParameters();

+ 1 - 1
src/renderer/Ssao.cpp

@@ -125,7 +125,7 @@ Error Ssao::initInternal(const ConfigSet& config)
 
 
 	TransientMemoryToken token;
 	TransientMemoryToken token;
 	Vec3* noise = static_cast<Vec3*>(gr.allocateFrameTransientMemory(
 	Vec3* noise = static_cast<Vec3*>(gr.allocateFrameTransientMemory(
-		noiseSize, BufferUsage::TRANSFER, token));
+		noiseSize, BufferUsageBit::TRANSFER_SOURCE, token));
 
 
 	genNoise(noise, noise + NOISE_TEX_SIZE * NOISE_TEX_SIZE);
 	genNoise(noise, noise + NOISE_TEX_SIZE * NOISE_TEX_SIZE);
 
 

+ 2 - 2
src/renderer/Tiler.cpp

@@ -68,7 +68,7 @@ Error Tiler::initInternal()
 	{
 	{
 		// Create the buffer
 		// Create the buffer
 		m_outBuffers[i] = getGrManager().newInstance<Buffer>(
 		m_outBuffers[i] = getGrManager().newInstance<Buffer>(
-			pboSize, BufferUsageBit::STORAGE, BufferAccessBit::CLIENT_MAP_READ);
+			pboSize, BufferUsageBit::STORAGE_ANY, BufferMapAccessBit::READ);
 
 
 		// Create graphics resources
 		// Create graphics resources
 		ResourceGroupInitInfo rcinit;
 		ResourceGroupInitInfo rcinit;
@@ -104,7 +104,7 @@ void Tiler::prepareForVisibilityTests(const SceneNode& node)
 
 
 	U buffIdx = max<U>(m_r->getFrameCount() % m_outBuffers.getSize(), 2u) - 2;
 	U buffIdx = max<U>(m_r->getFrameCount() % m_outBuffers.getSize(), 2u) - 2;
 	BufferPtr& buff = m_outBuffers[buffIdx];
 	BufferPtr& buff = m_outBuffers[buffIdx];
-	void* mappedMem = buff->map(0, size, BufferAccessBit::CLIENT_MAP_READ);
+	void* mappedMem = buff->map(0, size, BufferMapAccessBit::READ);
 
 
 	ANKI_ASSERT(mappedMem);
 	ANKI_ASSERT(mappedMem);
 	memcpy(&m_currentMinMax[0], mappedMem, size);
 	memcpy(&m_currentMinMax[0], mappedMem, size);

+ 7 - 6
src/renderer/Tm.cpp

@@ -36,14 +36,15 @@ Error Tm::create(const ConfigSet& initializer)
 	m_luminancePpline = getGrManager().newInstance<Pipeline>(pplineInit);
 	m_luminancePpline = getGrManager().newInstance<Pipeline>(pplineInit);
 
 
 	// Create buffer
 	// Create buffer
-	m_luminanceBuff = getGrManager().newInstance<Buffer>(
-		sizeof(Vec4), BufferUsageBit::STORAGE, BufferAccessBit::CLIENT_WRITE);
+	m_luminanceBuff = getGrManager().newInstance<Buffer>(sizeof(Vec4),
+		BufferUsageBit::STORAGE_ANY | BufferUsageBit::UNIFORM_ANY_SHADER,
+		BufferMapAccessBit::NONE);
 
 
 	CommandBufferPtr cmdb =
 	CommandBufferPtr cmdb =
 		getGrManager().newInstance<CommandBuffer>(CommandBufferInitInfo());
 		getGrManager().newInstance<CommandBuffer>(CommandBufferInitInfo());
 	TransientMemoryToken token;
 	TransientMemoryToken token;
 	void* data = getGrManager().allocateFrameTransientMemory(
 	void* data = getGrManager().allocateFrameTransientMemory(
-		sizeof(Vec4), BufferUsage::TRANSFER, token);
+		sizeof(Vec4), BufferUsageBit::TRANSFER_SOURCE, token);
 	*static_cast<Vec4*>(data) = Vec4(0.5);
 	*static_cast<Vec4*>(data) = Vec4(0.5);
 	cmdb->uploadBuffer(m_luminanceBuff, 0, token);
 	cmdb->uploadBuffer(m_luminanceBuff, 0, token);
 	cmdb->flush();
 	cmdb->flush();
@@ -68,9 +69,9 @@ void Tm::run(RenderingContext& ctx)
 	cmdb->bindResourceGroup(m_rcGroup, 0, nullptr);
 	cmdb->bindResourceGroup(m_rcGroup, 0, nullptr);
 
 
 	cmdb->dispatchCompute(1, 1, 1);
 	cmdb->dispatchCompute(1, 1, 1);
-	cmdb->setBufferMemoryBarrier(m_luminanceBuff,
-		ResourceAccessBit::SHADER_WRITE,
-		ResourceAccessBit::SHADER_READ | ResourceAccessBit::UNIFORM_READ);
+	cmdb->setBufferBarrier(m_luminanceBuff,
+		BufferUsageBit::STORAGE_COMPUTE_SHADER_WRITE,
+		BufferUsageBit::UNIFORM_FRAGMENT_SHADER);
 }
 }
 
 
 } // end namespace anki
 } // end namespace anki

+ 4 - 3
src/renderer/Upsample.cpp

@@ -95,9 +95,10 @@ void Upsample::run(RenderingContext& ctx)
 	CommandBufferPtr cmdb = ctx.m_commandBuffer;
 	CommandBufferPtr cmdb = ctx.m_commandBuffer;
 	TransientMemoryInfo dyn;
 	TransientMemoryInfo dyn;
 
 
-	Vec4* linearDepth =
-		static_cast<Vec4*>(getGrManager().allocateFrameTransientMemory(
-			sizeof(Vec4), BufferUsage::UNIFORM, dyn.m_uniformBuffers[0]));
+	Vec4* linearDepth = static_cast<Vec4*>(
+		getGrManager().allocateFrameTransientMemory(sizeof(Vec4),
+			BufferUsageBit::UNIFORM_ANY_SHADER,
+			dyn.m_uniformBuffers[0]));
 	const Frustum& fr = ctx.m_frustumComponent->getFrustum();
 	const Frustum& fr = ctx.m_frustumComponent->getFrustum();
 	computeLinearizeDepthOptimal(
 	computeLinearizeDepthOptimal(
 		fr.getNear(), fr.getFar(), linearDepth->x(), linearDepth->y());
 		fr.getNear(), fr.getFar(), linearDepth->x(), linearDepth->y());

+ 4 - 3
src/renderer/Volumetric.cpp

@@ -49,9 +49,10 @@ void Volumetric::run(RenderingContext& ctx)
 
 
 	// Update uniforms
 	// Update uniforms
 	TransientMemoryInfo dyn;
 	TransientMemoryInfo dyn;
-	Vec4* uniforms =
-		static_cast<Vec4*>(getGrManager().allocateFrameTransientMemory(
-			sizeof(Vec4) * 2, BufferUsage::UNIFORM, dyn.m_uniformBuffers[0]));
+	Vec4* uniforms = static_cast<Vec4*>(
+		getGrManager().allocateFrameTransientMemory(sizeof(Vec4) * 2,
+			BufferUsageBit::UNIFORM_ANY_SHADER,
+			dyn.m_uniformBuffers[0]));
 
 
 	computeLinearizeDepthOptimal(
 	computeLinearizeDepthOptimal(
 		frc.getNear(), frc.getFar(), uniforms[0].x(), uniforms[0].y());
 		frc.getNear(), frc.getFar(), uniforms[0].x(), uniforms[0].y());

+ 14 - 8
src/resource/Mesh.cpp

@@ -46,8 +46,11 @@ Error MeshLoadTask::operator()(AsyncLoaderTaskContext& ctx)
 	{
 	{
 		TransientMemoryToken token;
 		TransientMemoryToken token;
 		Error err = ErrorCode::NONE;
 		Error err = ErrorCode::NONE;
-		void* data = gr.allocateFrameTransientMemory(
-			m_loader.getVertexDataSize(), BufferUsage::TRANSFER, token, &err);
+		void* data =
+			gr.allocateFrameTransientMemory(m_loader.getVertexDataSize(),
+				BufferUsageBit::TRANSFER_SOURCE,
+				token,
+				&err);
 
 
 		if(!err)
 		if(!err)
 		{
 		{
@@ -69,8 +72,11 @@ Error MeshLoadTask::operator()(AsyncLoaderTaskContext& ctx)
 	{
 	{
 		TransientMemoryToken token;
 		TransientMemoryToken token;
 		Error err = ErrorCode::NONE;
 		Error err = ErrorCode::NONE;
-		void* data = gr.allocateFrameTransientMemory(
-			m_loader.getIndexDataSize(), BufferUsage::TRANSFER, token, &err);
+		void* data =
+			gr.allocateFrameTransientMemory(m_loader.getIndexDataSize(),
+				BufferUsageBit::TRANSFER_SOURCE,
+				token,
+				&err);
 
 
 		if(!err)
 		if(!err)
 		{
 		{
@@ -156,12 +162,12 @@ Error Mesh::load(const ResourceFilename& filename)
 	GrManager& gr = getManager().getGrManager();
 	GrManager& gr = getManager().getGrManager();
 
 
 	m_vertBuff = gr.newInstance<Buffer>(loader.getVertexDataSize(),
 	m_vertBuff = gr.newInstance<Buffer>(loader.getVertexDataSize(),
-		BufferUsageBit::VERTEX,
-		BufferAccessBit::CLIENT_WRITE);
+		BufferUsageBit::VERTEX | BufferUsageBit::TRANSFER_DESTINATION,
+		BufferMapAccessBit::NONE);
 
 
 	m_indicesBuff = gr.newInstance<Buffer>(loader.getIndexDataSize(),
 	m_indicesBuff = gr.newInstance<Buffer>(loader.getIndexDataSize(),
-		BufferUsageBit::INDEX,
-		BufferAccessBit::CLIENT_WRITE);
+		BufferUsageBit::INDEX | BufferUsageBit::TRANSFER_DESTINATION,
+		BufferMapAccessBit::NONE);
 
 
 	// Submit the loading task
 	// Submit the loading task
 	task->m_indicesBuff = m_indicesBuff;
 	task->m_indicesBuff = m_indicesBuff;

+ 1 - 1
src/resource/TextureResource.cpp

@@ -65,7 +65,7 @@ Error TexUploadTask::operator()(AsyncLoaderTaskContext& ctx)
 					Error err = ErrorCode::NONE;
 					Error err = ErrorCode::NONE;
 					void* data = m_gr->allocateFrameTransientMemory(
 					void* data = m_gr->allocateFrameTransientMemory(
 						surf.m_data.getSize(),
 						surf.m_data.getSize(),
-						BufferUsage::TRANSFER,
+						BufferUsageBit::TRANSFER_SOURCE,
 						token,
 						token,
 						&err);
 						&err);
 
 

+ 4 - 5
src/scene/ParticleEmitter.cpp

@@ -342,9 +342,8 @@ Error ParticleEmitter::init(const CString& name, const CString& filename)
 
 
 	for(U i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i)
 	for(U i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i)
 	{
 	{
-		m_vertBuffs[i] = gr.newInstance<Buffer>(m_vertBuffSize,
-			BufferUsageBit::VERTEX,
-			BufferAccessBit::CLIENT_MAP_WRITE);
+		m_vertBuffs[i] = gr.newInstance<Buffer>(
+			m_vertBuffSize, BufferUsageBit::VERTEX, BufferMapAccessBit::WRITE);
 
 
 		rcinit.m_vertexBuffers[0].m_buffer = m_vertBuffs[i];
 		rcinit.m_vertexBuffers[0].m_buffer = m_vertBuffs[i];
 
 
@@ -448,8 +447,8 @@ Error ParticleEmitter::frameUpdate(F32 prevUpdateTime, F32 crntTime)
 	m_aliveParticlesCount = 0;
 	m_aliveParticlesCount = 0;
 
 
 	U frame = getGlobalTimestamp() % 3;
 	U frame = getGlobalTimestamp() % 3;
-	F32* verts = static_cast<F32*>(m_vertBuffs[frame]->map(
-		0, m_vertBuffSize, BufferAccessBit::CLIENT_MAP_WRITE));
+	F32* verts = static_cast<F32*>(
+		m_vertBuffs[frame]->map(0, m_vertBuffSize, BufferMapAccessBit::WRITE));
 	const F32* verts_base = verts;
 	const F32* verts_base = verts;
 	(void)verts_base;
 	(void)verts_base;
 
 

+ 3 - 3
src/ui/UiInterfaceImpl.cpp

@@ -80,7 +80,7 @@ Error UiInterfaceImpl::init(GrManager* gr, ResourceManager* rc)
 			m_stages[s].m_vertBuffs[i] =
 			m_stages[s].m_vertBuffs[i] =
 				gr->newInstance<Buffer>(MAX_VERTS * sizeof(Vertex),
 				gr->newInstance<Buffer>(MAX_VERTS * sizeof(Vertex),
 					BufferUsageBit::VERTEX,
 					BufferUsageBit::VERTEX,
-					BufferAccessBit::CLIENT_MAP_WRITE);
+					BufferMapAccessBit::WRITE);
 		}
 		}
 	}
 	}
 
 
@@ -115,7 +115,7 @@ void UiInterfaceImpl::beginRendering(CommandBufferPtr cmdb)
 		BufferPtr buff = m_stages[s].m_vertBuffs[m_timestamp];
 		BufferPtr buff = m_stages[s].m_vertBuffs[m_timestamp];
 
 
 		m_vertMappings[s] = static_cast<Vertex*>(buff->map(
 		m_vertMappings[s] = static_cast<Vertex*>(buff->map(
-			0, sizeof(Vertex) * MAX_VERTS, BufferAccessBit::CLIENT_MAP_WRITE));
+			0, sizeof(Vertex) * MAX_VERTS, BufferMapAccessBit::WRITE));
 
 
 		m_vertCounts[s] = 0;
 		m_vertCounts[s] = 0;
 	}
 	}
@@ -222,7 +222,7 @@ Error UiInterfaceImpl::createR8Image(
 		m_gr->newInstance<CommandBuffer>(CommandBufferInitInfo());
 		m_gr->newInstance<CommandBuffer>(CommandBufferInitInfo());
 	TransientMemoryToken token;
 	TransientMemoryToken token;
 	void* loadData = m_gr->allocateFrameTransientMemory(
 	void* loadData = m_gr->allocateFrameTransientMemory(
-		data.getSize(), BufferUsage::TRANSFER, token);
+		data.getSize(), BufferUsageBit::TRANSFER_SOURCE, token);
 	memcpy(loadData, &data[0], data.getSize());
 	memcpy(loadData, &data[0], data.getSize());
 	cmdb->uploadTextureSurface(tex, TextureSurfaceInfo(0, 0, 0, 0), token);
 	cmdb->uploadTextureSurface(tex, TextureSurfaceInfo(0, 0, 0, 0), token);
 
 

+ 54 - 33
tests/gr/Gr.cpp

@@ -172,13 +172,36 @@ layout(ANKI_UBO_BINDING(0, 0)) uniform u0_
 layout(ANKI_TEX_BINDING(0, 0)) uniform sampler2D u_tex0;
 layout(ANKI_TEX_BINDING(0, 0)) uniform sampler2D u_tex0;
 layout(ANKI_TEX_BINDING(0, 1)) uniform sampler2D u_tex1;
 layout(ANKI_TEX_BINDING(0, 1)) uniform sampler2D u_tex1;
 
 
+ANKI_USING_FRAG_COORD(768)
+
 void main()
 void main()
 {
 {
-	float factor = in_uv.x;
-	vec3 col0 = textureLod(u_tex0, in_uv, factor).rgb;
-	vec3 col1 = textureLod(u_tex1, in_uv, factor * 2.0).rgb;
-	
-	out_color = vec4((col1 + col1) * 0.5, 1.0);
+	if(anki_fragCoord.x < 1024 / 2)
+	{
+		if(anki_fragCoord.y < 768 / 2)
+		{
+			vec2 uv = in_uv * 2.0;
+			out_color = textureLod(u_tex0, uv, 0.0);
+		}
+		else
+		{
+			vec2 uv = in_uv * 2.0 - vec2(0.0, 1.0);
+			out_color = textureLod(u_tex0, uv, 1.0);
+		}
+	}
+	else
+	{
+		if(anki_fragCoord.y < 768 / 2)
+		{
+			vec2 uv = in_uv * 2.0 - vec2(1.0, 0.0);
+			out_color = textureLod(u_tex1, uv, 0.0);
+		}
+		else
+		{
+			vec2 uv = in_uv * 2.0 - vec2(1.0, 1.0);
+			out_color = textureLod(u_tex1, uv, 1.0);
+		}
+	}
 })";
 })";
 
 
 static const char* FRAG_MRT_SRC = R"(layout (location = 0) out vec4 out_color0;
 static const char* FRAG_MRT_SRC = R"(layout (location = 0) out vec4 out_color0;
@@ -346,16 +369,15 @@ static void createCube(GrManager& gr, BufferPtr& verts, BufferPtr& indices)
 		7}};
 		7}};
 
 
 	verts = gr.newInstance<Buffer>(
 	verts = gr.newInstance<Buffer>(
-		sizeof(pos), BufferUsageBit::VERTEX, BufferMapAccessBit::CLIENT_MAP_WRITE);
+		sizeof(pos), BufferUsageBit::VERTEX, BufferMapAccessBit::WRITE);
 
 
-	void* mapped =
-		verts->map(0, sizeof(pos), BufferMapAccessBit::CLIENT_MAP_WRITE);
+	void* mapped = verts->map(0, sizeof(pos), BufferMapAccessBit::WRITE);
 	memcpy(mapped, &pos[0], sizeof(pos));
 	memcpy(mapped, &pos[0], sizeof(pos));
 	verts->unmap();
 	verts->unmap();
 
 
 	indices = gr.newInstance<Buffer>(
 	indices = gr.newInstance<Buffer>(
-		sizeof(idx), BufferUsageBit::INDEX, BufferMapAccessBit::CLIENT_MAP_WRITE);
-	mapped = indices->map(0, sizeof(idx), BufferMapAccessBit::CLIENT_MAP_WRITE);
+		sizeof(idx), BufferUsageBit::INDEX, BufferMapAccessBit::WRITE);
+	mapped = indices->map(0, sizeof(idx), BufferMapAccessBit::WRITE);
 	memcpy(mapped, &idx[0], sizeof(idx));
 	memcpy(mapped, &idx[0], sizeof(idx));
 	indices->unmap();
 	indices->unmap();
 }
 }
@@ -443,21 +465,20 @@ ANKI_TEST(Gr, Buffer)
 
 
 	{
 	{
 		BufferPtr a = gr->newInstance<Buffer>(
 		BufferPtr a = gr->newInstance<Buffer>(
-			512, BufferUsageBit::UNIFORM, BufferMapAccessBit::NONE);
+			512, BufferUsageBit::UNIFORM_ANY_SHADER, BufferMapAccessBit::NONE);
 
 
 		BufferPtr b = gr->newInstance<Buffer>(64,
 		BufferPtr b = gr->newInstance<Buffer>(64,
-			BufferUsageBit::STORAGE,
-			BufferMapAccessBit::CLIENT_MAP_WRITE
-				| BufferMapAccessBit::CLIENT_MAP_READ);
+			BufferUsageBit::STORAGE_ANY,
+			BufferMapAccessBit::WRITE | BufferMapAccessBit::READ);
 
 
-		void* ptr = b->map(0, 64, BufferMapAccessBit::CLIENT_MAP_WRITE);
+		void* ptr = b->map(0, 64, BufferMapAccessBit::WRITE);
 		ANKI_TEST_EXPECT_NEQ(ptr, nullptr);
 		ANKI_TEST_EXPECT_NEQ(ptr, nullptr);
 		U8 ptr2[64];
 		U8 ptr2[64];
 		memset(ptr, 0xCC, 64);
 		memset(ptr, 0xCC, 64);
 		memset(ptr2, 0xCC, 64);
 		memset(ptr2, 0xCC, 64);
 		b->unmap();
 		b->unmap();
 
 
-		ptr = b->map(0, 64, BufferMapAccessBit::CLIENT_MAP_READ);
+		ptr = b->map(0, 64, BufferMapAccessBit::READ);
 		ANKI_TEST_EXPECT_NEQ(ptr, nullptr);
 		ANKI_TEST_EXPECT_NEQ(ptr, nullptr);
 		ANKI_TEST_EXPECT_EQ(memcmp(ptr, ptr2, 64), 0);
 		ANKI_TEST_EXPECT_EQ(memcmp(ptr, ptr2, 64), 0);
 		b->unmap();
 		b->unmap();
@@ -473,8 +494,8 @@ ANKI_TEST(Gr, ResourceGroup)
 
 
 	{
 	{
 		BufferPtr b = gr->newInstance<Buffer>(sizeof(F32) * 4,
 		BufferPtr b = gr->newInstance<Buffer>(sizeof(F32) * 4,
-			BufferUsageBit::UNIFORM,
-			BufferMapAccessBit::CLIENT_MAP_WRITE);
+			BufferUsageBit::UNIFORM_ANY_SHADER,
+			BufferMapAccessBit::WRITE);
 
 
 		ResourceGroupInitInfo rcinit;
 		ResourceGroupInitInfo rcinit;
 		rcinit.m_uniformBuffers[0].m_buffer = b;
 		rcinit.m_uniformBuffers[0].m_buffer = b;
@@ -492,11 +513,11 @@ ANKI_TEST(Gr, DrawWithUniforms)
 	{
 	{
 		// A non-uploaded buffer
 		// A non-uploaded buffer
 		BufferPtr b = gr->newInstance<Buffer>(sizeof(Vec4) * 3,
 		BufferPtr b = gr->newInstance<Buffer>(sizeof(Vec4) * 3,
-			BufferUsageBit::UNIFORM,
-			BufferMapAccessBit::CLIENT_MAP_WRITE);
+			BufferUsageBit::UNIFORM_ANY_SHADER,
+			BufferMapAccessBit::WRITE);
 
 
 		Vec4* ptr = static_cast<Vec4*>(
 		Vec4* ptr = static_cast<Vec4*>(
-			b->map(0, sizeof(Vec4) * 3, BufferMapAccessBit::CLIENT_MAP_WRITE));
+			b->map(0, sizeof(Vec4) * 3, BufferMapAccessBit::WRITE));
 		ANKI_TEST_EXPECT_NEQ(ptr, nullptr);
 		ANKI_TEST_EXPECT_NEQ(ptr, nullptr);
 		ptr[0] = Vec4(1.0, 0.0, 0.0, 0.0);
 		ptr[0] = Vec4(1.0, 0.0, 0.0, 0.0);
 		ptr[1] = Vec4(0.0, 1.0, 0.0, 0.0);
 		ptr[1] = Vec4(0.0, 1.0, 0.0, 0.0);
@@ -529,7 +550,7 @@ ANKI_TEST(Gr, DrawWithUniforms)
 			Error err = ErrorCode::NONE;
 			Error err = ErrorCode::NONE;
 			Vec4* rotMat = static_cast<Vec4*>(
 			Vec4* rotMat = static_cast<Vec4*>(
 				gr->allocateFrameTransientMemory(sizeof(Vec4),
 				gr->allocateFrameTransientMemory(sizeof(Vec4),
-					BufferUsage::UNIFORM,
+					BufferUsageBit::UNIFORM_ANY_SHADER,
 					transientInfo.m_uniformBuffers[1],
 					transientInfo.m_uniformBuffers[1],
 					&err));
 					&err));
 			ANKI_TEST_EXPECT_NO_ERR(err);
 			ANKI_TEST_EXPECT_NO_ERR(err);
@@ -583,10 +604,10 @@ ANKI_TEST(Gr, DrawWithVertex)
 
 
 		BufferPtr b = gr->newInstance<Buffer>(sizeof(Vert) * 3,
 		BufferPtr b = gr->newInstance<Buffer>(sizeof(Vert) * 3,
 			BufferUsageBit::VERTEX,
 			BufferUsageBit::VERTEX,
-			BufferMapAccessBit::CLIENT_MAP_WRITE);
+			BufferMapAccessBit::WRITE);
 
 
 		Vert* ptr = static_cast<Vert*>(
 		Vert* ptr = static_cast<Vert*>(
-			b->map(0, sizeof(Vert) * 3, BufferMapAccessBit::CLIENT_MAP_WRITE));
+			b->map(0, sizeof(Vert) * 3, BufferMapAccessBit::WRITE));
 		ANKI_TEST_EXPECT_NEQ(ptr, nullptr);
 		ANKI_TEST_EXPECT_NEQ(ptr, nullptr);
 
 
 		ptr[0].m_pos = Vec3(-1.0, 1.0, 0.0);
 		ptr[0].m_pos = Vec3(-1.0, 1.0, 0.0);
@@ -600,10 +621,10 @@ ANKI_TEST(Gr, DrawWithVertex)
 
 
 		BufferPtr c = gr->newInstance<Buffer>(sizeof(Vec3) * 3,
 		BufferPtr c = gr->newInstance<Buffer>(sizeof(Vec3) * 3,
 			BufferUsageBit::VERTEX,
 			BufferUsageBit::VERTEX,
-			BufferMapAccessBit::CLIENT_MAP_WRITE);
+			BufferMapAccessBit::WRITE);
 
 
 		Vec3* otherColor = static_cast<Vec3*>(
 		Vec3* otherColor = static_cast<Vec3*>(
-			c->map(0, sizeof(Vec3) * 3, BufferMapAccessBit::CLIENT_MAP_WRITE));
+			c->map(0, sizeof(Vec3) * 3, BufferMapAccessBit::WRITE));
 
 
 		otherColor[0] = Vec3(0.0, 1.0, 1.0);
 		otherColor[0] = Vec3(0.0, 1.0, 1.0);
 		otherColor[1] = Vec3(1.0, 0.0, 1.0);
 		otherColor[1] = Vec3(1.0, 0.0, 1.0);
@@ -863,7 +884,7 @@ ANKI_TEST(Gr, DrawWithTexture)
 		Error err = ErrorCode::NONE;
 		Error err = ErrorCode::NONE;
 		TransientMemoryToken token;
 		TransientMemoryToken token;
 		void* ptr = gr->allocateFrameTransientMemory(
 		void* ptr = gr->allocateFrameTransientMemory(
-			sizeof(mip0), BufferUsage::TRANSFER, token, &err);
+			sizeof(mip0), BufferUsageBit::TRANSFER_SOURCE, token, &err);
 		ANKI_TEST_EXPECT_NEQ(ptr, nullptr);
 		ANKI_TEST_EXPECT_NEQ(ptr, nullptr);
 		ANKI_TEST_EXPECT_NO_ERR(err);
 		ANKI_TEST_EXPECT_NO_ERR(err);
 		memcpy(ptr, &mip0[0], sizeof(mip0));
 		memcpy(ptr, &mip0[0], sizeof(mip0));
@@ -871,7 +892,7 @@ ANKI_TEST(Gr, DrawWithTexture)
 		cmdb->uploadTextureSurface(a, TextureSurfaceInfo(0, 0, 0, 0), token);
 		cmdb->uploadTextureSurface(a, TextureSurfaceInfo(0, 0, 0, 0), token);
 
 
 		ptr = gr->allocateFrameTransientMemory(
 		ptr = gr->allocateFrameTransientMemory(
-			sizeof(mip1), BufferUsage::TRANSFER, token, &err);
+			sizeof(mip1), BufferUsageBit::TRANSFER_SOURCE, token, &err);
 		ANKI_TEST_EXPECT_NEQ(ptr, nullptr);
 		ANKI_TEST_EXPECT_NEQ(ptr, nullptr);
 		ANKI_TEST_EXPECT_NO_ERR(err);
 		ANKI_TEST_EXPECT_NO_ERR(err);
 		memcpy(ptr, &mip1[0], sizeof(mip1));
 		memcpy(ptr, &mip1[0], sizeof(mip1));
@@ -879,7 +900,7 @@ ANKI_TEST(Gr, DrawWithTexture)
 		cmdb->uploadTextureSurface(a, TextureSurfaceInfo(1, 0, 0, 0), token);
 		cmdb->uploadTextureSurface(a, TextureSurfaceInfo(1, 0, 0, 0), token);
 
 
 		ptr = gr->allocateFrameTransientMemory(
 		ptr = gr->allocateFrameTransientMemory(
-			sizeof(bmip0), BufferUsage::TRANSFER, token, &err);
+			sizeof(bmip0), BufferUsageBit::TRANSFER_SOURCE, token, &err);
 		ANKI_TEST_EXPECT_NEQ(ptr, nullptr);
 		ANKI_TEST_EXPECT_NEQ(ptr, nullptr);
 		ANKI_TEST_EXPECT_NO_ERR(err);
 		ANKI_TEST_EXPECT_NO_ERR(err);
 		memcpy(ptr, &bmip0[0], sizeof(bmip0));
 		memcpy(ptr, &bmip0[0], sizeof(bmip0));
@@ -1130,14 +1151,14 @@ ANKI_TEST(Gr, DrawOffscreen)
 
 
 			Mat4* mvp = static_cast<Mat4*>(
 			Mat4* mvp = static_cast<Mat4*>(
 				gr->allocateFrameTransientMemory(sizeof(*mvp),
 				gr->allocateFrameTransientMemory(sizeof(*mvp),
-					BufferUsage::UNIFORM,
+					BufferUsageBit::UNIFORM_ANY_SHADER,
 					transientInfo.m_uniformBuffers[0],
 					transientInfo.m_uniformBuffers[0],
 					nullptr));
 					nullptr));
 			*mvp = projMat * viewMat * modelMat;
 			*mvp = projMat * viewMat * modelMat;
 
 
 			Vec4* color = static_cast<Vec4*>(
 			Vec4* color = static_cast<Vec4*>(
 				gr->allocateFrameTransientMemory(sizeof(*color) * 2,
 				gr->allocateFrameTransientMemory(sizeof(*color) * 2,
-					BufferUsage::UNIFORM,
+					BufferUsageBit::UNIFORM_ANY_SHADER,
 					transientInfo.m_uniformBuffers[1],
 					transientInfo.m_uniformBuffers[1],
 					nullptr));
 					nullptr));
 			*color++ = Vec4(1.0, 0.0, 0.0, 0.0);
 			*color++ = Vec4(1.0, 0.0, 0.0, 0.0);
@@ -1155,14 +1176,14 @@ ANKI_TEST(Gr, DrawOffscreen)
 
 
 			mvp = static_cast<Mat4*>(
 			mvp = static_cast<Mat4*>(
 				gr->allocateFrameTransientMemory(sizeof(*mvp),
 				gr->allocateFrameTransientMemory(sizeof(*mvp),
-					BufferUsage::UNIFORM,
+					BufferUsageBit::UNIFORM_ANY_SHADER,
 					transientInfo.m_uniformBuffers[0],
 					transientInfo.m_uniformBuffers[0],
 					nullptr));
 					nullptr));
 			*mvp = projMat * viewMat * modelMat;
 			*mvp = projMat * viewMat * modelMat;
 
 
 			color = static_cast<Vec4*>(
 			color = static_cast<Vec4*>(
 				gr->allocateFrameTransientMemory(sizeof(*color) * 2,
 				gr->allocateFrameTransientMemory(sizeof(*color) * 2,
-					BufferUsage::UNIFORM,
+					BufferUsageBit::UNIFORM_ANY_SHADER,
 					transientInfo.m_uniformBuffers[1],
 					transientInfo.m_uniformBuffers[1],
 					nullptr));
 					nullptr));
 			*color++ = Vec4(0.0, 0.0, 1.0, 0.0);
 			*color++ = Vec4(0.0, 0.0, 1.0, 0.0);