Query implementation

Re-enabled the Renderer object's occlusion queries and linked them
to the queries in the query pool. Removed the old Query structure.

Passes all tests in:
Tests: dEQP-VK.query_pool.*

Note: The dEQP-VK.query_pool.*_discard tests currently fail as discard
      appears to disable the occlusion queries. Will fix in next cl.

Bug b/129706526

Change-Id: I937dcf64d2990758d31a1ed6a13af5cf9f0a627b
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/28288
Tested-by: Alexis Hétu <sugoi@google.com>
Presubmit-Ready: Alexis Hétu <sugoi@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/Vulkan/VkQueryPool.hpp b/src/Vulkan/VkQueryPool.hpp
index 9f8072e..06161a9 100644
--- a/src/Vulkan/VkQueryPool.hpp
+++ b/src/Vulkan/VkQueryPool.hpp
@@ -16,23 +16,53 @@
 #define VK_QUERY_POOL_HPP_
 
 #include "VkObject.hpp"
+#include <atomic>
+#include <condition_variable>
+#include <mutex>

 
 namespace vk
 {
 
+struct Query
+{
+	enum State
+	{
+		UNAVAILABLE,
+		ACTIVE,
+		FINISHED
+	};
+
+	std::mutex mutex;

+	std::condition_variable condition;
+	State state;  // guarded by mutex
+	int64_t data; // guarded by mutex
+	std::atomic<int> reference;
+	VkQueryType type;
+};
+
 class QueryPool : public Object<QueryPool, VkQueryPool>
 {
 public:
 	QueryPool(const VkQueryPoolCreateInfo* pCreateInfo, void* mem);
 	~QueryPool() = delete;
+	void destroy(const VkAllocationCallbacks* pAllocator);
 
 	static size_t ComputeRequiredAllocationSize(const VkQueryPoolCreateInfo* pCreateInfo);
 
-	void getResults(uint32_t pFirstQuery, uint32_t pQueryCount, size_t pDataSize,
-		            void* pData, VkDeviceSize pStride, VkQueryResultFlags pFlags) const;
+	VkResult getResults(uint32_t firstQuery, uint32_t queryCount, size_t dataSize,
+		                void* pData, VkDeviceSize stride, VkQueryResultFlags flags) const;
+	void begin(uint32_t query, VkQueryControlFlags flags);
+	void end(uint32_t query);
+	void reset(uint32_t firstQuery, uint32_t queryCount);
+	
+	void writeTimestamp(uint32_t query);
+
+	inline Query* getQuery(uint32_t query) const { return &(pool[query]); }
 
 private:
-	uint32_t queryCount;
+	Query* pool;
+	VkQueryType type;
+	uint32_t count;
 };
 
 static inline QueryPool* Cast(VkQueryPool object)