Browse Source

Add timestamp query support

Panagiotis Christopoulos Charitos 6 years ago
parent
commit
e55dfb0020

+ 1 - 0
src/anki/Gr.h

@@ -14,6 +14,7 @@
 #include <anki/gr/Framebuffer.h>
 #include <anki/gr/CommandBuffer.h>
 #include <anki/gr/OcclusionQuery.h>
+#include <anki/gr/TimestampQuery.h>
 #include <anki/gr/Fence.h>
 #include <anki/gr/GrManager.h>
 #include <anki/gr/RenderGraph.h>

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

@@ -68,6 +68,7 @@ ANKI_GR_CLASS(CommandBuffer)
 ANKI_GR_CLASS(Shader)
 ANKI_GR_CLASS(Framebuffer)
 ANKI_GR_CLASS(OcclusionQuery)
+ANKI_GR_CLASS(TimestampQuery)
 ANKI_GR_CLASS(ShaderProgram)
 ANKI_GR_CLASS(Fence)
 ANKI_GR_CLASS(RenderGraph)

+ 7 - 0
src/anki/gr/Enums.h

@@ -526,6 +526,13 @@ enum class OcclusionQueryResult : U8
 	NOT_VISIBLE
 };
 
+/// Timestamp query result.
+enum class TimestampQueryResult : U8
+{
+	NOT_AVAILABLE,
+	AVAILABLE
+};
+
 /// Attachment load operation.
 enum class AttachmentLoadOperation : U8
 {

+ 1 - 0
src/anki/gr/GrManager.h

@@ -77,6 +77,7 @@ public:
 	ANKI_USE_RESULT CommandBufferPtr newCommandBuffer(const CommandBufferInitInfo& init);
 	ANKI_USE_RESULT FramebufferPtr newFramebuffer(const FramebufferInitInfo& init);
 	ANKI_USE_RESULT OcclusionQueryPtr newOcclusionQuery();
+	ANKI_USE_RESULT TimestampQueryPtr newTimestampQuery();
 	ANKI_USE_RESULT RenderGraphPtr newRenderGraph();
 	/// @}
 

+ 2 - 1
src/anki/gr/GrObject.h

@@ -16,12 +16,13 @@ namespace anki
 /// @{
 
 /// Graphics object type.
-enum GrObjectType : U16
+enum GrObjectType : U8
 {
 	BUFFER,
 	COMMAND_BUFFER,
 	FRAMEBUFFER,
 	OCCLUSION_QUERY,
+	TIMESTAMP_QUERY,
 	SAMPLER,
 	SHADER,
 	TEXTURE,

+ 3 - 0
src/anki/gr/OcclusionQuery.h

@@ -33,6 +33,9 @@ protected:
 	{
 	}
 
+	/// Get the occlusion query result. It won't block.
+	OcclusionQueryResult getResult() const;
+
 private:
 	/// Allocate and initialize new instance.
 	static ANKI_USE_RESULT OcclusionQuery* newInstance(GrManager* manager);

+ 45 - 0
src/anki/gr/TimestampQuery.h

@@ -0,0 +1,45 @@
+// Copyright (C) 2009-2019, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#pragma once
+
+#include <anki/gr/GrObject.h>
+
+namespace anki
+{
+
+/// @addtogroup graphics
+/// @{
+
+/// Timestamp query.
+class TimestampQuery : public GrObject
+{
+	ANKI_GR_OBJECT
+
+public:
+	static const GrObjectType CLASS_TYPE = GrObjectType::TIMESTAMP_QUERY;
+
+protected:
+	/// Construct.
+	TimestampQuery(GrManager* manager, CString name)
+		: GrObject(manager, CLASS_TYPE, name)
+	{
+	}
+
+	/// Destroy.
+	~TimestampQuery()
+	{
+	}
+
+	/// Get the result if it's available. It won't block.
+	TimestampQueryResult getResult(U64& timestamp) const;
+
+private:
+	/// Allocate and initialize new instance.
+	static ANKI_USE_RESULT TimestampQuery* newInstance(GrManager* manager);
+};
+/// @}
+
+} // end namespace anki

+ 2 - 0
src/anki/gr/common/InstantiationMacros.h

@@ -15,6 +15,8 @@ ANKI_INSTANTIATE_GR_OBJECT(Framebuffer)
 ANKI_INSTANTIATE_GR_OBJECT_DELIMITER()
 ANKI_INSTANTIATE_GR_OBJECT(OcclusionQuery)
 ANKI_INSTANTIATE_GR_OBJECT_DELIMITER()
+ANKI_INSTANTIATE_GR_OBJECT(TimestampQuery)
+ANKI_INSTANTIATE_GR_OBJECT_DELIMITER()
 ANKI_INSTANTIATE_GR_OBJECT(Sampler)
 ANKI_INSTANTIATE_GR_OBJECT_DELIMITER()
 ANKI_INSTANTIATE_GR_OBJECT(Shader)

+ 6 - 0
src/anki/gr/vulkan/GrManager.cpp

@@ -15,6 +15,7 @@
 #include <anki/gr/CommandBuffer.h>
 #include <anki/gr/Framebuffer.h>
 #include <anki/gr/OcclusionQuery.h>
+#include <anki/gr/TimestampQuery.h>
 #include <anki/gr/RenderGraph.h>
 
 namespace anki
@@ -140,6 +141,11 @@ OcclusionQueryPtr GrManager::newOcclusionQuery()
 	return OcclusionQueryPtr(OcclusionQuery::newInstance(this));
 }
 
+TimestampQueryPtr GrManager::newTimestampQuery()
+{
+	return TimestampQueryPtr(TimestampQuery::newInstance(this));
+}
+
 RenderGraphPtr GrManager::newRenderGraph()
 {
 	return RenderGraphPtr(RenderGraph::newInstance(this));

+ 2 - 1
src/anki/gr/vulkan/GrManagerImpl.cpp

@@ -129,7 +129,8 @@ Error GrManagerImpl::initInternal(const GrManagerInitInfo& init)
 	m_semaphores.init(getAllocator(), m_device);
 	m_samplerFactory.init(this);
 	m_barrierFactory.init(getAllocator(), m_device);
-	m_queryAlloc.init(getAllocator(), m_device);
+	m_occlusionQueryFactory.init(getAllocator(), m_device, VK_QUERY_TYPE_OCCLUSION);
+	m_timestampQueryFactory.init(getAllocator(), m_device, VK_QUERY_TYPE_TIMESTAMP);
 
 	// Set m_r8g8b8ImagesSupported
 	{

+ 9 - 3
src/anki/gr/vulkan/GrManagerImpl.h

@@ -118,9 +118,14 @@ public:
 	}
 	/// @}
 
-	QueryFactory& getQueryAllocator()
+	QueryFactory& getOcclusionQueryFactory()
 	{
-		return m_queryAlloc;
+		return m_occlusionQueryFactory;
+	}
+
+	QueryFactory& getTimestampQueryFactory()
+	{
+		return m_timestampQueryFactory;
 	}
 
 	Bool getR8g8b8ImagesSupported() const
@@ -302,7 +307,8 @@ private:
 
 	DescriptorSetFactory m_descrFactory;
 
-	QueryFactory m_queryAlloc;
+	QueryFactory m_occlusionQueryFactory;
+	QueryFactory m_timestampQueryFactory;
 
 	PipelineCache m_pplineCache;
 

+ 6 - 1
src/anki/gr/vulkan/OcclusionQuery.cpp

@@ -13,7 +13,7 @@ namespace anki
 OcclusionQuery* OcclusionQuery::newInstance(GrManager* manager)
 {
 	OcclusionQueryImpl* impl = manager->getAllocator().newInstance<OcclusionQueryImpl>(manager, "N/A");
-	Error err = impl->init();
+	const Error err = impl->init();
 	if(err)
 	{
 		manager->getAllocator().deleteInstance(impl);
@@ -21,4 +21,9 @@ OcclusionQuery* OcclusionQuery::newInstance(GrManager* manager)
 	return impl;
 }
 
+OcclusionQueryResult OcclusionQuery::getResult() const
+{
+	return static_cast<const OcclusionQueryImpl*>(this)->getResultInternal();
+}
+
 } // end namespace anki

+ 3 - 3
src/anki/gr/vulkan/OcclusionQueryImpl.cpp

@@ -13,17 +13,17 @@ OcclusionQueryImpl::~OcclusionQueryImpl()
 {
 	if(m_handle)
 	{
-		getGrManagerImpl().getQueryAllocator().deleteQuery(m_handle);
+		getGrManagerImpl().getOcclusionQueryFactory().deleteQuery(m_handle);
 	}
 }
 
 Error OcclusionQueryImpl::init()
 {
-	ANKI_CHECK(getGrManagerImpl().getQueryAllocator().newQuery(m_handle));
+	ANKI_CHECK(getGrManagerImpl().getOcclusionQueryFactory().newQuery(m_handle));
 	return Error::NONE;
 }
 
-OcclusionQueryResult OcclusionQueryImpl::getResult() const
+OcclusionQueryResult OcclusionQueryImpl::getResultInternal() const
 {
 	ANKI_ASSERT(m_handle);
 	U64 out = 0;

+ 1 - 1
src/anki/gr/vulkan/OcclusionQueryImpl.h

@@ -32,7 +32,7 @@ public:
 	ANKI_USE_RESULT Error init();
 
 	/// Get query result.
-	OcclusionQueryResult getResult() const;
+	OcclusionQueryResult getResultInternal() const;
 };
 /// @}
 

+ 3 - 1
src/anki/gr/vulkan/QueryFactory.h

@@ -71,10 +71,11 @@ public:
 
 	~QueryFactory();
 
-	void init(GrAllocator<U8> alloc, VkDevice dev)
+	void init(GrAllocator<U8> alloc, VkDevice dev, VkQueryType poolType)
 	{
 		m_alloc = alloc;
 		m_dev = dev;
+		m_poolType = poolType;
 	}
 
 	/// @note It's thread-safe.
@@ -90,6 +91,7 @@ private:
 	VkDevice m_dev;
 	IntrusiveList<Chunk> m_chunks;
 	Mutex m_mtx;
+	VkQueryType m_poolType = VK_QUERY_TYPE_MAX_ENUM;
 };
 /// @}
 

+ 29 - 0
src/anki/gr/vulkan/TimestampQuery.cpp

@@ -0,0 +1,29 @@
+// Copyright (C) 2009-2019, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include <anki/gr/TimestampQuery.h>
+#include <anki/gr/vulkan/TimestampQueryImpl.h>
+#include <anki/gr/GrManager.h>
+
+namespace anki
+{
+
+TimestampQuery* TimestampQuery::newInstance(GrManager* manager)
+{
+	TimestampQueryImpl* impl = manager->getAllocator().newInstance<TimestampQueryImpl>(manager, "N/A");
+	const Error err = impl->init();
+	if(err)
+	{
+		manager->getAllocator().deleteInstance(impl);
+	}
+	return impl;
+}
+
+TimestampQueryResult TimestampQuery::getResult(U64& timestamp) const
+{
+	return static_cast<const TimestampQueryImpl*>(this)->getResultInternal(timestamp);
+}
+
+} // end namespace anki

+ 57 - 0
src/anki/gr/vulkan/TimestampQueryImpl.cpp

@@ -0,0 +1,57 @@
+// Copyright (C) 2009-2019, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include <anki/gr/vulkan/TimestampQueryImpl.h>
+#include <anki/gr/vulkan/GrManagerImpl.h>
+
+namespace anki
+{
+
+TimestampQueryImpl::~TimestampQueryImpl()
+{
+	if(m_handle)
+	{
+		getGrManagerImpl().getTimestampQueryFactory().deleteQuery(m_handle);
+	}
+}
+
+Error TimestampQueryImpl::init()
+{
+	ANKI_CHECK(getGrManagerImpl().getTimestampQueryFactory().newQuery(m_handle));
+	return Error::NONE;
+}
+
+TimestampQueryResult TimestampQueryImpl::getResultInternal(U64& timestamp) const
+{
+	ANKI_ASSERT(m_handle);
+
+	VkResult res;
+	ANKI_VK_CHECKF(res = vkGetQueryPoolResults(getDevice(),
+					   m_handle.getQueryPool(),
+					   m_handle.getQueryIndex(),
+					   1,
+					   sizeof(timestamp),
+					   &timestamp,
+					   sizeof(timestamp),
+					   VK_QUERY_RESULT_64_BIT));
+
+	TimestampQueryResult qout = TimestampQueryResult::NOT_AVAILABLE;
+	if(res == VK_SUCCESS)
+	{
+		qout = TimestampQueryResult::AVAILABLE;
+	}
+	else if(res == VK_NOT_READY)
+	{
+		qout = TimestampQueryResult::NOT_AVAILABLE;
+	}
+	else
+	{
+		ANKI_ASSERT(0);
+	}
+
+	return qout;
+}
+
+} // end namespace anki

+ 39 - 0
src/anki/gr/vulkan/TimestampQueryImpl.h

@@ -0,0 +1,39 @@
+// Copyright (C) 2009-2019, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#pragma once
+
+#include <anki/gr/TimestampQuery.h>
+#include <anki/gr/vulkan/VulkanObject.h>
+#include <anki/gr/vulkan/QueryFactory.h>
+
+namespace anki
+{
+
+/// @addtogroup vulkan
+/// @{
+
+/// Occlusion query.
+class TimestampQueryImpl final : public TimestampQuery, public VulkanObject<TimestampQuery, TimestampQueryImpl>
+{
+public:
+	MicroQuery m_handle = {};
+
+	TimestampQueryImpl(GrManager* manager, CString name)
+		: TimestampQuery(manager, name)
+	{
+	}
+
+	~TimestampQueryImpl();
+
+	/// Create the query.
+	ANKI_USE_RESULT Error init();
+
+	/// Get query result.
+	TimestampQueryResult getResultInternal(U64& timestamp) const;
+};
+/// @}
+
+} // end namespace anki

+ 1 - 0
src/anki/gr/vulkan/VulkanObject.cpp

@@ -15,6 +15,7 @@
 #include <anki/gr/vulkan/CommandBufferImpl.h>
 #include <anki/gr/vulkan/FramebufferImpl.h>
 #include <anki/gr/vulkan/OcclusionQueryImpl.h>
+#include <anki/gr/vulkan/TimestampQueryImpl.h>
 #include <anki/gr/vulkan/FenceImpl.h>
 
 namespace anki