Jelajahi Sumber

Work on the vulkan backend (presentation)

Panagiotis Christopoulos Charitos 9 tahun lalu
induk
melakukan
244029eb70

+ 12 - 1
include/anki/gr/vulkan/GrManagerImpl.h

@@ -33,6 +33,10 @@ public:
 
 
 	GrAllocator<U8> getAllocator() const;
 	GrAllocator<U8> getAllocator() const;
 
 
+	void beginFrame();
+
+	void endFrame();
+
 	VkDevice getDevice() const
 	VkDevice getDevice() const
 	{
 	{
 		ANKI_ASSERT(m_device);
 		ANKI_ASSERT(m_device);
@@ -64,6 +68,14 @@ private:
 		VkImage m_image = VK_NULL_HANDLE;
 		VkImage m_image = VK_NULL_HANDLE;
 		VkImageView m_imageView = VK_NULL_HANDLE;
 		VkImageView m_imageView = VK_NULL_HANDLE;
 		VkFramebuffer m_fb = VK_NULL_HANDLE;
 		VkFramebuffer m_fb = VK_NULL_HANDLE;
+
+		VkFence m_presentFence = VK_NULL_HANDLE;
+		VkSemaphore m_acquireSemaphore = VK_NULL_HANDLE;
+
+		/// The semaphores that of those submits that render to the default FB.
+		DynamicArray<VkSemaphore> m_renderSemaphores;
+
+		U32 m_renderSemaphoresCount = 0;
 	};
 	};
 
 
 	VkSurfaceKHR m_surface = VK_NULL_HANDLE;
 	VkSurfaceKHR m_surface = VK_NULL_HANDLE;
@@ -97,7 +109,6 @@ private:
 	ANKI_USE_RESULT Error initFramebuffers(const GrManagerInitInfo& init);
 	ANKI_USE_RESULT Error initFramebuffers(const GrManagerInitInfo& init);
 	void initGlobalDsetLayout();
 	void initGlobalDsetLayout();
 	void initGlobalPplineLayout();
 	void initGlobalPplineLayout();
-
 	void initMemory();
 	void initMemory();
 
 
 	/// Find a suitable memory type.
 	/// Find a suitable memory type.

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

@@ -40,8 +40,8 @@ public:
 		m_window = init.m_window->getNative().m_window;
 		m_window = init.m_window->getNative().m_window;
 
 
 		ANKI_LOGI("Creating GL %u.%u context...",
 		ANKI_LOGI("Creating GL %u.%u context...",
-			init.m_majorVersion,
-			init.m_minorVersion);
+			init.m_config->getNumber("glmajor"),
+			init.m_config->getNumber("glminor"));
 
 
 		if(init.m_config->getNumber("debugContext"))
 		if(init.m_config->getNumber("debugContext"))
 		{
 		{
@@ -53,10 +53,10 @@ public:
 			}
 			}
 		}
 		}
 
 
-		if(SDL_GL_SetAttribute(
-			   SDL_GL_CONTEXT_MAJOR_VERSION, init.m_majorVersion)
-			|| SDL_GL_SetAttribute(
-				   SDL_GL_CONTEXT_MINOR_VERSION, init.m_minorVersion)
+		if(SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION,
+			   init.m_config->getNumber("glmajor"))
+			|| SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION,
+				   init.m_config->getNumber("glminor"))
 			|| SDL_GL_SetAttribute(
 			|| SDL_GL_SetAttribute(
 				   SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE))
 				   SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE))
 		{
 		{

+ 63 - 0
src/gr/vulkan/GrManagerImpl.cpp

@@ -718,4 +718,67 @@ void GrManagerImpl::freeCallback(void* userData, void* ptr)
 	self->getAllocator().getMemoryPool().free(ptr);
 	self->getAllocator().getMemoryPool().free(ptr);
 }
 }
 
 
+//==============================================================================
+void GrManagerImpl::beginFrame()
+{
+	PerFrame& frame = m_perFrame[m_frame];
+
+	// Create a semaphore
+	VkSemaphoreCreateInfo semaphoreCi = {};
+	semaphoreCi.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
+	ANKI_ASSERT(frame.m_acquireSemaphore == VK_NULL_HANDLE);
+
+	ANKI_VK_CHECKF(vkCreateSemaphore(
+		m_device, &semaphoreCi, nullptr, &frame.m_acquireSemaphore));
+
+	// Get new image
+	uint32_t imageIdx;
+	ANKI_VK_CHECKF(vkAcquireNextImageKHR(m_device,
+		m_swapchain,
+		UINT64_MAX,
+		frame.m_acquireSemaphore,
+		0,
+		&imageIdx));
+	ANKI_ASSERT(imageIdx == m_frame && "Wrong assumption");
+}
+
+//==============================================================================
+void GrManagerImpl::endFrame()
+{
+	PerFrame& frame = m_perFrame[m_frame];
+
+	// Wait for the fence of N-2 frame
+	U waitFrameIdx = (m_frame + 1) % MAX_FRAMES_IN_FLIGHT;
+	PerFrame& waitFrame = m_perFrame[waitFrameIdx];
+	VkFence& waitFence = waitFrame.m_presentFence;
+	if(waitFence)
+	{
+		// Wait
+		ANKI_VK_CHECKF(vkWaitForFences(m_device, 1, &waitFence, true, MAX_U64));
+
+		// Recycle fence
+		ANKI_VK_CHECKF(vkResetFences(m_device, 1, &waitFence));
+	}
+
+	// Cleanup various objects from the wait frame
+	if(waitFrame.m_acquireSemaphore)
+	{
+		vkDestroySemaphore(m_device, frame.m_acquireSemaphore, nullptr);
+	}
+
+	for(U i = 0; i < waitFrame.m_renderSemaphoresCount; ++i)
+	{
+		ANKI_ASSERT(waitFrame.m_renderSemaphores[i]);
+		vkDestroySemaphore(m_device, waitFrame.m_renderSemaphores[i], nullptr);
+		waitFrame.m_renderSemaphores[i] = VK_NULL_HANDLE;
+	}
+
+	if(frame.m_renderSemaphoresCount == 0)
+	{
+		ANKI_LOGW("Nobody draw to the default framebuffer");
+	}
+
+	++m_frame;
+}
+
 } // end namespace anki
 } // end namespace anki