فهرست منبع

Vulkan fixes. Add support for NV_dedicated_allocation

Panagiotis Christopoulos Charitos 8 سال پیش
والد
کامیت
01b5081c3d

+ 3 - 0
src/anki/core/Trace.cpp

@@ -37,6 +37,9 @@ static Array<const char*, U(TraceEventType::COUNT)> eventNames = {{"SCENE_UPDATE
 	"GL_CMD_BUFFER_DESTROY",
 	"VK_ACQUIRE_IMAGE",
 	"VK_QUEUE_SUBMIT",
+	"VK_PIPELINE_CREATE",
+	"VK_BIND_OBJECT",
+	"VK_DESCRIPTOR_SET_GET_OR_CREATE",
 	"SWAP_BUFFERS",
 	"BARRIER_WAIT"}};
 

+ 3 - 0
src/anki/core/Trace.h

@@ -50,6 +50,9 @@ enum class TraceEventType
 	GL_CMD_BUFFER_DESTROY,
 	VK_ACQUIRE_IMAGE,
 	VK_QUEUE_SUBMIT,
+	VK_PIPELINE_CREATE,
+	VK_BIND_OBJECT,
+	VK_DESCRIPTOR_SET_GET_OR_CREATE,
 	SWAP_BUFFERS,
 	BARRIER_WAIT,
 

+ 2 - 0
src/anki/gr/vulkan/BufferImpl.cpp

@@ -125,7 +125,9 @@ Error BufferImpl::init(PtrSize size, BufferUsageBit usage, BufferMapAccessBit ac
 	getGrManagerImpl().getGpuMemoryManager().allocateMemory(memIdx, req.size, req.alignment, true, m_memHandle);
 
 	// Bind mem to buffer
+	ANKI_TRACE_START_EVENT(VK_BIND_OBJECT);
 	ANKI_VK_CHECK(vkBindBufferMemory(getDevice(), m_handle, m_memHandle.m_memory, m_memHandle.m_offset));
+	ANKI_TRACE_STOP_EVENT(VK_BIND_OBJECT);
 
 	m_access = access;
 	m_size = size;

+ 1 - 0
src/anki/gr/vulkan/Common.h

@@ -47,6 +47,7 @@ enum class VulkanExtensions : U8
 	KHR_SWAPCHAIN = 1 << 4,
 	KHR_SURFACE = 1 << 5,
 	EXT_DEBUG_MARKER = 1 << 6,
+	NV_DEDICATED_ALLOCATION = 1 << 7,
 };
 ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(VulkanExtensions, inline)
 

+ 4 - 0
src/anki/gr/vulkan/DescriptorSet.cpp

@@ -616,11 +616,14 @@ Error DescriptorSetFactory::newDescriptorSet(ThreadId tid,
 	Array<U32, MAX_UNIFORM_BUFFER_BINDINGS + MAX_STORAGE_BUFFER_BINDINGS>& dynamicOffsets,
 	U& dynamicOffsetCount)
 {
+	ANKI_TRACE_START_EVENT(VK_DESCRIPTOR_SET_GET_OR_CREATE);
+
 	U64 hash;
 	state.flush(dirty, hash, dynamicOffsets, dynamicOffsetCount);
 
 	if(!dirty)
 	{
+		ANKI_TRACE_STOP_EVENT(VK_DESCRIPTOR_SET_GET_OR_CREATE);
 		return ErrorCode::NONE;
 	}
 
@@ -637,6 +640,7 @@ Error DescriptorSetFactory::newDescriptorSet(ThreadId tid,
 	set.m_handle = s->m_handle;
 	ANKI_ASSERT(set.m_handle != VK_NULL_HANDLE);
 
+	ANKI_TRACE_STOP_EVENT(VK_DESCRIPTOR_SET_GET_OR_CREATE);
 	return ErrorCode::NONE;
 }
 

+ 5 - 0
src/anki/gr/vulkan/GrManagerImpl.cpp

@@ -473,6 +473,11 @@ Error GrManagerImpl::initDevice(const GrManagerInitInfo& init)
 				m_extensions |= VulkanExtensions::EXT_DEBUG_MARKER;
 				extensionsToEnable[extensionsToEnableCount++] = VK_EXT_DEBUG_MARKER_EXTENSION_NAME;
 			}
+			else if(CString(extensionInfos[extCount].extensionName) == VK_NV_DEDICATED_ALLOCATION_EXTENSION_NAME)
+			{
+				m_extensions |= VulkanExtensions::NV_DEDICATED_ALLOCATION;
+				extensionsToEnable[extensionsToEnableCount++] = VK_NV_DEDICATED_ALLOCATION_EXTENSION_NAME;
+			}
 		}
 
 		if(!!(m_extensions & VulkanExtensions::KHR_MAINENANCE1))

+ 2 - 0
src/anki/gr/vulkan/Pipeline.cpp

@@ -414,7 +414,9 @@ void PipelineFactory::newPipeline(PipelineStateTracker& state, Pipeline& ppline,
 		PipelineInternal pp;
 		const VkGraphicsPipelineCreateInfo& ci = state.updatePipelineCreateInfo();
 
+		ANKI_TRACE_START_EVENT(VK_PIPELINE_CREATE);
 		ANKI_VK_CHECKF(vkCreateGraphicsPipelines(m_dev, m_pplineCache, 1, &ci, nullptr, &pp.m_handle));
+		ANKI_TRACE_STOP_EVENT(VK_PIPELINE_CREATE);
 		ANKI_TRACE_INC_COUNTER(VK_PIPELINE_CREATE, 1);
 
 		m_pplines.pushBack(m_alloc, hash, pp);

+ 42 - 4
src/anki/gr/vulkan/TextureImpl.cpp

@@ -42,6 +42,11 @@ TextureImpl::~TextureImpl()
 	{
 		getGrManagerImpl().getGpuMemoryManager().freeMemory(m_memHandle);
 	}
+
+	if(m_dedicatedMem)
+	{
+		vkFreeMemory(getDevice(), m_dedicatedMem, nullptr);
+	}
 }
 
 Error TextureImpl::init(const TextureInitInfo& init_, Texture* tex)
@@ -197,6 +202,8 @@ Bool TextureImpl::imageSupported(const TextureInitInfo& init)
 Error TextureImpl::initImage(const TextureInitInfo& init_)
 {
 	TextureInitInfo init = init_;
+	Bool useDedicatedMemory = !!(init.m_usage & TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE)
+		&& !!(getGrManagerImpl().getExtensions() & VulkanExtensions::NV_DEDICATED_ALLOCATION);
 
 	// Check if format is supported
 	Bool supported;
@@ -302,6 +309,14 @@ Error TextureImpl::initImage(const TextureInitInfo& init_)
 	ci.pQueueFamilyIndices = &queueIdx;
 	ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
 
+	VkDedicatedAllocationImageCreateInfoNV dedicatedMemCi = {};
+	if(useDedicatedMemory)
+	{
+		dedicatedMemCi.sType = VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV;
+		dedicatedMemCi.dedicatedAllocation = true;
+		ci.pNext = &dedicatedMemCi;
+	}
+
 	ANKI_VK_CHECK(vkCreateImage(getDevice(), &ci, nullptr, &m_imageHandle));
 	getGrManagerImpl().trySetVulkanHandleName(
 		init.getName(), VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, ptrToNumber(m_imageHandle));
@@ -323,11 +338,34 @@ Error TextureImpl::initImage(const TextureInitInfo& init_)
 
 	ANKI_ASSERT(memIdx != MAX_U32);
 
-	// Allocate
-	getGrManagerImpl().getGpuMemoryManager().allocateMemory(memIdx, req.size, req.alignment, false, m_memHandle);
+	if(!useDedicatedMemory)
+	{
+		// Allocate
+		getGrManagerImpl().getGpuMemoryManager().allocateMemory(memIdx, req.size, req.alignment, false, m_memHandle);
+
+		// Bind mem to image
+		ANKI_TRACE_START_EVENT(VK_BIND_OBJECT);
+		ANKI_VK_CHECK(vkBindImageMemory(getDevice(), m_imageHandle, m_memHandle.m_memory, m_memHandle.m_offset));
+		ANKI_TRACE_STOP_EVENT(VK_BIND_OBJECT);
+	}
+	else
+	{
+		VkDedicatedAllocationMemoryAllocateInfoNV dedicatedInfo = {};
+		dedicatedInfo.sType = VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV;
+		dedicatedInfo.image = m_imageHandle;
 
-	// Bind mem to image
-	ANKI_VK_CHECK(vkBindImageMemory(getDevice(), m_imageHandle, m_memHandle.m_memory, m_memHandle.m_offset));
+		VkMemoryAllocateInfo memAllocCi = {};
+		memAllocCi.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+		memAllocCi.pNext = &dedicatedInfo;
+		memAllocCi.allocationSize = req.size;
+		memAllocCi.memoryTypeIndex = memIdx;
+
+		ANKI_VK_CHECK(vkAllocateMemory(getDevice(), &memAllocCi, nullptr, &m_dedicatedMem));
+
+		ANKI_TRACE_START_EVENT(VK_BIND_OBJECT);
+		ANKI_VK_CHECK(vkBindImageMemory(getDevice(), m_imageHandle, m_dedicatedMem, 0));
+		ANKI_TRACE_STOP_EVENT(VK_BIND_OBJECT);
+	}
 
 	return ErrorCode::NONE;
 }

+ 2 - 0
src/anki/gr/vulkan/TextureImpl.h

@@ -153,6 +153,8 @@ private:
 	VkImageViewCreateInfo m_viewCreateInfoTemplate;
 	U64 m_uuid; ///< Steal the UUID from the Texture.
 
+	VkDeviceMemory m_dedicatedMem = VK_NULL_HANDLE;
+
 	ANKI_USE_RESULT static VkFormatFeatureFlags calcFeatures(const TextureInitInfo& init);
 
 	ANKI_USE_RESULT static VkImageCreateFlags calcCreateFlags(const TextureInitInfo& init);

+ 1 - 0
src/anki/util/HashMap.h

@@ -492,6 +492,7 @@ public:
 		ANKI_ASSERT(x);
 		IntrusiveHashMapEnabled<TValue>* e = static_cast<IntrusiveHashMapEnabled<TValue>*>(x);
 		e->m_hash = THasher()(key);
+		e->m_left = e->m_right = e->m_parent = nullptr;
 		Base::insertNode(x);
 	}