فهرست منبع

Android and Adreno fixes

Panagiotis Christopoulos Charitos 3 سال پیش
والد
کامیت
479717d75c

+ 1 - 1
AnKi/Gr/Common.cpp

@@ -7,7 +7,7 @@
 
 namespace anki {
 
-Array<CString, U(GpuVendor::COUNT)> GPU_VENDOR_STR = {"UNKNOWN", "ARM", "NVIDIA", "AMD", "INTEL"};
+Array<CString, U(GpuVendor::COUNT)> GPU_VENDOR_STR = {"UNKNOWN", "ARM", "NVIDIA", "AMD", "INTEL", "QUALCOMM"};
 
 PtrSize computeSurfaceSize(U32 width32, U32 height32, Format fmt)
 {

+ 5 - 1
AnKi/Gr/Common.h

@@ -106,6 +106,7 @@ enum class GpuVendor : U8
 	NVIDIA,
 	AMD,
 	INTEL,
+	QUALCOMM,
 	COUNT
 };
 
@@ -146,6 +147,9 @@ public:
 	/// GPU vendor.
 	GpuVendor m_gpuVendor = GpuVendor::UNKNOWN;
 
+	/// Descrete or integrated GPU.
+	Bool m_discreteGpu = false;
+
 	/// API version.
 	U8 m_minorApiVersion = 0;
 
@@ -169,7 +173,7 @@ public:
 };
 ANKI_END_PACKED_STRUCT
 static_assert(sizeof(GpuDeviceCapabilities)
-				  == sizeof(PtrSize) * 4 + sizeof(U32) * 5 + sizeof(U8) * 3 + sizeof(Bool) * 5,
+				  == sizeof(PtrSize) * 4 + sizeof(U32) * 5 + sizeof(U8) * 3 + sizeof(Bool) * 6,
 			  "Should be packed");
 
 /// The type of the allocator for heap allocations

+ 43 - 30
AnKi/Gr/Vulkan/BufferImpl.cpp

@@ -75,43 +75,50 @@ Error BufferImpl::init(const BufferInitInfo& inf)
 	VkMemoryRequirements req;
 	vkGetBufferMemoryRequirements(getDevice(), m_handle, &req);
 	U32 memIdx = MAX_U32;
+	const Bool isDiscreteGpu = getGrManagerImpl().getDeviceCapabilities().m_discreteGpu;
 
 	if(access == BufferMapAccessBit::WRITE)
 	{
 		// Only write, probably for uploads
 
-		VkMemoryPropertyFlags preferDeviceLocal = 0;
-		VkMemoryPropertyFlags avoidDeviceLocal = 0;
-#if !ANKI_PLATFORM_MOBILE
-		if((usage & (~BufferUsageBit::ALL_TRANSFER)) != BufferUsageBit::NONE)
-		{
-			// Will be used for something other than transfer, try to put it in the device
-			preferDeviceLocal = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
-			avoidDeviceLocal = 0;
-		}
-		else
+		// 1st try: Device & host & coherent but not cached
+		VkMemoryPropertyFlags prefer = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
+		VkMemoryPropertyFlags avoid = VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
+
+		if(isDiscreteGpu)
 		{
-			// Will be used only for transfers, don't want it in the device
-			preferDeviceLocal = 0;
-			avoidDeviceLocal = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
+			if((usage & (~BufferUsageBit::ALL_TRANSFER)) != BufferUsageBit::NONE)
+			{
+				// Will be used for something other than transfer, try to put it in the device
+				prefer |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
+			}
+			else
+			{
+				// Will be used only for transfers, don't want it in the device
+				avoid |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
+			}
 		}
-#endif
 
-		// Device & host & coherent but not cached
-		memIdx = getGrManagerImpl().getGpuMemoryManager().findMemoryType(
-			req.memoryTypeBits,
-			VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | preferDeviceLocal,
-			VK_MEMORY_PROPERTY_HOST_CACHED_BIT | avoidDeviceLocal);
+		memIdx = getGrManagerImpl().getGpuMemoryManager().findMemoryType(req.memoryTypeBits, prefer, avoid);
 
-		// Fallback: host & coherent and not cached
+		// 2nd try: host & coherent
 		if(memIdx == MAX_U32)
 		{
-#if !ANKI_PLATFORM_MOBILE
-			ANKI_VK_LOGW("Using a fallback mode for write-only buffer");
-#endif
-			memIdx = getGrManagerImpl().getGpuMemoryManager().findMemoryType(
-				req.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
-				VK_MEMORY_PROPERTY_HOST_CACHED_BIT | avoidDeviceLocal);
+			prefer = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
+			avoid = 0;
+
+			if(isDiscreteGpu)
+			{
+				ANKI_VK_LOGW("Using a fallback mode for write-only buffer");
+
+				if((usage & (~BufferUsageBit::ALL_TRANSFER)) == BufferUsageBit::NONE)
+				{
+					// Will be used only for transfers, don't want it in the device
+					avoid |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
+				}
+			}
+
+			memIdx = getGrManagerImpl().getGpuMemoryManager().findMemoryType(req.memoryTypeBits, prefer, avoid);
 		}
 	}
 	else if(!!(access & BufferMapAccessBit::READ))
@@ -128,9 +135,11 @@ Error BufferImpl::init(const BufferInitInfo& inf)
 		// Fallback: Just cached
 		if(memIdx == MAX_U32)
 		{
-#if !ANKI_PLATFORM_MOBILE
-			ANKI_VK_LOGW("Using a fallback mode for read/write buffer");
-#endif
+			if(isDiscreteGpu)
+			{
+				ANKI_VK_LOGW("Using a fallback mode for read/write buffer");
+			}
+
 			memIdx = getGrManagerImpl().getGpuMemoryManager().findMemoryType(
 				req.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT, 0);
 		}
@@ -153,7 +162,11 @@ Error BufferImpl::init(const BufferInitInfo& inf)
 		}
 	}
 
-	ANKI_ASSERT(memIdx != MAX_U32);
+	if(memIdx == MAX_U32)
+	{
+		ANKI_VK_LOGE("Failed to find appropriate memory type for buffer: %s", getName().cstr());
+		return Error::FUNCTION_FAILED;
+	}
 
 	const VkPhysicalDeviceMemoryProperties& props = getGrManagerImpl().getMemoryProperties();
 	m_memoryFlags = props.memoryTypes[memIdx].propertyFlags;

+ 6 - 1
AnKi/Gr/Vulkan/GrManagerImpl.cpp

@@ -451,10 +451,12 @@ Error GrManagerImpl::initInstance(const GrManagerInitInfo& init)
 
 		if(firstChoice != VK_NULL_HANDLE)
 		{
+			m_capabilities.m_discreteGpu = true;
 			m_physicalDevice = firstChoice;
 		}
 		else if(secondChoice != VK_NULL_HANDLE)
 		{
+			m_capabilities.m_discreteGpu = false;
 			m_physicalDevice = secondChoice;
 		}
 		else
@@ -489,6 +491,9 @@ Error GrManagerImpl::initInstance(const GrManagerInitInfo& init)
 	case 0x8086:
 		m_capabilities.m_gpuVendor = GpuVendor::INTEL;
 		break;
+	case 0x5143:
+		m_capabilities.m_gpuVendor = GpuVendor::QUALCOMM;
+		break;
 	default:
 		m_capabilities.m_gpuVendor = GpuVendor::UNKNOWN;
 	}
@@ -525,7 +530,7 @@ Error GrManagerImpl::initDevice(const GrManagerInitInfo& init)
 	queueInfos.create(count);
 	vkGetPhysicalDeviceQueueFamilyProperties(m_physicalDevice, &count, &queueInfos[0]);
 
-	const VkQueueFlags GENERAL_QUEUE_FLAGS = VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT;
+	const VkQueueFlags GENERAL_QUEUE_FLAGS = VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT;
 	for(U32 i = 0; i < count; ++i)
 	{
 		VkBool32 supportsPresent = false;

+ 7 - 5
AnKi/Scene/SceneGraph.cpp

@@ -253,16 +253,20 @@ Error SceneGraph::updateNode(Second prevTime, Second crntTime, SceneNode& node)
 	// Components update
 	Timestamp componentTimestamp = 0;
 	Bool atLeastOneComponentUpdated = false;
-	err = node.iterateComponents([&](SceneComponent& comp, Bool isFeedbackComponent) -> Error {
+	node.iterateComponents([&](SceneComponent& comp, Bool isFeedbackComponent) {
+		if(err)
+		{
+			return;
+		}
+
 		Bool updated = false;
-		Error e = Error::NONE;
 		if(!atLeastOneComponentUpdated && isFeedbackComponent)
 		{
 			// Skip feedback component if prior components didn't got updated
 		}
 		else
 		{
-			e = comp.update(node, prevTime, crntTime, updated);
+			err = comp.update(node, prevTime, crntTime, updated);
 		}
 
 		if(updated)
@@ -273,8 +277,6 @@ Error SceneGraph::updateNode(Second prevTime, Second crntTime, SceneNode& node)
 			ANKI_ASSERT(componentTimestamp > 0);
 			atLeastOneComponentUpdated = true;
 		}
-
-		return e;
 	});
 
 	// Update children

+ 2 - 2
AnKi/Scene/SceneNode.cpp

@@ -26,13 +26,13 @@ SceneNode::~SceneNode()
 	auto end = m_components.getEnd();
 	for(; it != end; ++it)
 	{
-		SceneComponent* comp = *it;
-		alloc.deleteInstance(comp);
+		alloc.deleteInstance(*it);
 	}
 
 	Base::destroy(alloc);
 	m_name.destroy(alloc);
 	m_components.destroy(alloc);
+	m_componentInfos.destroy(alloc);
 }
 
 void SceneNode::setMarkedForDeletion()

+ 39 - 87
AnKi/Scene/SceneNode.h

@@ -105,48 +105,35 @@ public:
 
 	/// Iterate all components.
 	template<typename TFunct>
-	ANKI_USE_RESULT Error iterateComponents(TFunct func) const
+	void iterateComponents(TFunct func) const
 	{
-		Error err = Error::NONE;
-		auto it = m_components.getBegin();
-		auto end = m_components.getEnd();
-		for(; !err && it != end; ++it)
+		for(U32 i = 0; i < m_componentInfos.getSize(); ++i)
 		{
-			const SceneComponent* c = *it;
-			err = func(*c, it->isFeedbackComponent());
+			// Use the m_componentInfos to check if it's feedback component for possibly less cache misses
+			func(*m_components[i], m_componentInfos[i].isFeedbackComponent());
 		}
-
-		return err;
 	}
 
 	/// Iterate all components.
 	template<typename TFunct>
-	ANKI_USE_RESULT Error iterateComponents(TFunct func)
+	void iterateComponents(TFunct func)
 	{
-		Error err = Error::NONE;
-		auto it = m_components.getBegin();
-		auto end = m_components.getEnd();
-		for(; !err && it != end; ++it)
+		for(U32 i = 0; i < m_componentInfos.getSize(); ++i)
 		{
-			SceneComponent* c = *it;
-			err = func(*c, it->isFeedbackComponent());
+			// Use the m_componentInfos to check if it's feedback component for possibly less cache misses
+			func(*m_components[i], m_componentInfos[i].isFeedbackComponent());
 		}
-
-		return err;
 	}
 
 	/// Iterate all components of a specific type
 	template<typename TComponent, typename TFunct>
 	void iterateComponentsOfType(TFunct func) const
 	{
-		auto it = m_components.getBegin();
-		auto end = m_components.getEnd();
-		for(; it != end; ++it)
+		for(U32 i = 0; i < m_componentInfos.getSize(); ++i)
 		{
-			if(it->getComponentClassId() == TComponent::getStaticClassId())
+			if(m_componentInfos[i].getComponentClassId() == TComponent::getStaticClassId())
 			{
-				const SceneComponent* comp = *it;
-				func(static_cast<const TComponent&>(*comp));
+				func(static_cast<const TComponent&>(*m_components[i]));
 			}
 		}
 	}
@@ -155,14 +142,11 @@ public:
 	template<typename TComponent, typename TFunct>
 	void iterateComponentsOfType(TFunct func)
 	{
-		auto it = m_components.getBegin();
-		auto end = m_components.getEnd();
-		for(; it != end; ++it)
+		for(U32 i = 0; i < m_componentInfos.getSize(); ++i)
 		{
-			if(it->getComponentClassId() == TComponent::getStaticClassId())
+			if(m_componentInfos[i].getComponentClassId() == TComponent::getStaticClassId())
 			{
-				SceneComponent* comp = *it;
-				func(static_cast<TComponent&>(*comp));
+				func(static_cast<TComponent&>(*m_components[i]));
 			}
 		}
 	}
@@ -171,12 +155,11 @@ public:
 	template<typename TComponent>
 	const TComponent* tryGetFirstComponentOfType() const
 	{
-		for(const ComponentsArrayElement& el : m_components)
+		for(U32 i = 0; i < m_componentInfos.getSize(); ++i)
 		{
-			if(el.getComponentClassId() == TComponent::getStaticClassId())
+			if(m_componentInfos[i].getComponentClassId() == TComponent::getStaticClassId())
 			{
-				const SceneComponent* comp = el;
-				return static_cast<const TComponent*>(comp);
+				return static_cast<const TComponent*>(m_components[i]);
 			}
 		}
 		return nullptr;
@@ -212,12 +195,11 @@ public:
 	const TComponent* tryGetNthComponentOfType(U32 nth) const
 	{
 		I32 inth = I32(nth);
-		for(const ComponentsArrayElement& el : m_components)
+		for(U32 i = 0; i < m_componentInfos.getSize(); ++i)
 		{
-			if(el.getComponentClassId() == TComponent::getStaticClassId() && inth-- == 0)
+			if(m_componentInfos[i].getComponentClassId() == TComponent::getStaticClassId() && inth-- == 0)
 			{
-				const SceneComponent* comp = el;
-				return static_cast<const TComponent*>(comp);
+				return static_cast<const TComponent*>(m_components[i]);
 			}
 		}
 		return nullptr;
@@ -251,7 +233,7 @@ public:
 	template<typename TComponent>
 	TComponent& getComponentAt(U32 idx)
 	{
-		ANKI_ASSERT(m_components[idx].getComponentClassId() == TComponent::getStaticClassId());
+		ANKI_ASSERT(m_componentInfos[idx].getComponentClassId() == TComponent::getStaticClassId());
 		SceneComponent* c = m_components[idx];
 		return *static_cast<TComponent*>(c);
 	}
@@ -260,7 +242,7 @@ public:
 	template<typename TComponent>
 	const TComponent& getComponentAt(U32 idx) const
 	{
-		ANKI_ASSERT(m_components[idx].getComponentClassId() == TComponent::getStaticClassId());
+		ANKI_ASSERT(m_componentInfos[idx].getComponentClassId() == TComponent::getStaticClassId());
 		const SceneComponent* c = m_components[idx];
 		return *static_cast<const TComponent*>(c);
 	}
@@ -287,90 +269,60 @@ protected:
 	{
 		TComponent* comp = getAllocator().newInstance<TComponent>(this);
 		m_components.emplaceBack(getAllocator(), comp);
+		m_componentInfos.emplaceBack(getAllocator(), *comp);
 		return comp;
 	}
 
 	ResourceManager& getResourceManager();
 
 private:
-	/// This class packs a pointer to a SceneComponent and its type at the same 64bit value. Used to avoid cache misses
-	/// when iterating the m_components.
+	/// This class packs a few info used by components.
 	class ComponentsArrayElement
 	{
 	public:
-		/// Encodes the SceneComponent's class ID, the SceneComponent* and if it's feedback component or not.
-		PtrSize m_combo;
-
-		ComponentsArrayElement(SceneComponent* comp)
+		ComponentsArrayElement(const SceneComponent& comp)
 		{
-			set(comp);
+			m_classId = comp.getClassId();
+			ANKI_ASSERT(m_classId == comp.getClassId());
+			m_feedbackComponent = comp.isFeedbackComponent();
 		}
 
 		ComponentsArrayElement(const ComponentsArrayElement& b)
-			: m_combo(b.m_combo)
+			: m_feedbackComponent(b.m_feedbackComponent)
+			, m_classId(b.m_classId)
 		{
 		}
 
 		ComponentsArrayElement& operator=(const ComponentsArrayElement& b)
 		{
-			m_combo = b.m_combo;
+			m_feedbackComponent = b.m_feedbackComponent;
+			m_classId = b.m_classId;
 			return *this;
 		}
 
-		operator SceneComponent*()
-		{
-			return getPtr();
-		}
-
-		operator const SceneComponent*() const
-		{
-			return getPtr();
-		}
-
-		const SceneComponent* operator->() const
-		{
-			return getPtr();
-		}
-
-		SceneComponent* operator->()
-		{
-			return getPtr();
-		}
-
 		U8 getComponentClassId() const
 		{
-			return m_combo & 0x7F;
+			return m_classId;
 		}
 
 		Bool isFeedbackComponent() const
 		{
-			return m_combo & PtrSize(1 << 7);
+			return m_feedbackComponent;
 		}
 
 	private:
-		void set(SceneComponent* comp)
-		{
-			m_combo = ptrToNumber(comp) << 8;
-			m_combo |= PtrSize(comp->isFeedbackComponent()) << 7;
-			m_combo |= PtrSize(comp->getClassId()) & 0x7F;
-			ANKI_ASSERT(getPtr() == comp);
-			ANKI_ASSERT(getComponentClassId() == comp->getClassId());
-			ANKI_ASSERT(isFeedbackComponent() == comp->isFeedbackComponent());
-		}
-
-		SceneComponent* getPtr() const
-		{
-			return numberToPtr<SceneComponent*>(m_combo >> 8);
-		}
+		U8 m_feedbackComponent : 1;
+		U8 m_classId : 7;
 	};
 
-	static_assert(sizeof(ComponentsArrayElement) == sizeof(void*), "Wrong size");
+	static_assert(sizeof(ComponentsArrayElement) == sizeof(U8), "Wrong size");
 
 	SceneGraph* m_scene = nullptr;
 	U64 m_uuid;
 	String m_name; ///< A unique name.
 
-	DynamicArray<ComponentsArrayElement> m_components;
+	DynamicArray<SceneComponent*> m_components;
+	DynamicArray<ComponentsArrayElement> m_componentInfos; ///< Same size as m_components. Used to iterate fast.
 
 	Timestamp m_maxComponentTimestamp = 0;
 

+ 5 - 5
AnKi/Script/LuaBinder.h

@@ -61,7 +61,7 @@ public:
 		ANKI_ASSERT(info);
 		m_sig = info->m_signature;
 		m_info = info;
-		m_addressOrGarbageCollect = GC_MASK;
+		m_addressOrGarbageCollect = GARBAGE_COLLECTED;
 	}
 
 	/// @note Accepting const void* is wrong because getData returns a mutable pointer. Fix that.
@@ -71,14 +71,14 @@ public:
 		m_sig = info->m_signature;
 		m_info = info;
 		const U64 addr = ptrToNumber(ptrToObject);
-		ANKI_ASSERT((addr & GC_MASK) == 0 && "Address too high, cannot encode a flag");
+		ANKI_ASSERT(addr != GARBAGE_COLLECTED && "Can't use this address");
 		m_addressOrGarbageCollect = addr;
 	}
 
 	Bool isGarbageCollected() const
 	{
 		ANKI_ASSERT(m_addressOrGarbageCollect != 0);
-		return m_addressOrGarbageCollect == GC_MASK;
+		return m_addressOrGarbageCollect == GARBAGE_COLLECTED;
 	}
 
 	template<typename T>
@@ -122,11 +122,11 @@ public:
 	static const LuaUserDataTypeInfo& getDataTypeInfoFor();
 
 private:
-	static constexpr U64 GC_MASK = U64(1) << U64(63);
+	static constexpr U64 GARBAGE_COLLECTED = 0xFAFC0FEEDEADB1FF;
 
 	I64 m_sig = 0; ///< Signature to identify the user data.
 
-	U64 m_addressOrGarbageCollect = 0; ///< Encodes an address or a flag if it's for garbage collection.
+	U64 m_addressOrGarbageCollect = 0; ///< Encodes an address or a special address if it's for garbage collection.
 
 	const LuaUserDataTypeInfo* m_info = nullptr;
 };

+ 2 - 3
CMakeLists.txt

@@ -86,10 +86,9 @@ endif()
 set(X86 FALSE)
 set(ARM FALSE)
 if(GCC OR CLANG)
-	execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpmachine OUTPUT_VARIABLE target_arch)
-	if(target_arch MATCHES "x86")
+	if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "x86")
 		set(X86 TRUE)
-	elseif(target_arch MATCHES "aarch")
+	elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch")
 		set(ARM TRUE)
 	else()
 		message(FATAL_ERROR "Couldn't find the target architecture from: ${target_arch}")