// Copyright 2018 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef VK_QUERY_POOL_HPP_
#define VK_QUERY_POOL_HPP_

#include "System/Synchronization.hpp"

#include "VkObject.hpp"
#include <atomic>
#include <condition_variable>
#include <mutex>

namespace vk
{

class Query
{
public:
	static auto constexpr INVALID_TYPE = VK_QUERY_TYPE_MAX_ENUM;

	Query();

	enum State
	{
		UNAVAILABLE,
		ACTIVE,
		FINISHED
	};

	struct Data
	{
		State state;   // The current query state.
		int64_t value; // The current query value.
	};

	// reset() sets the state of the Query to UNAVAILABLE, sets the type to
	// INVALID_TYPE and clears the query value.
	// reset() must not be called while the query is in the ACTIVE state.
	void reset();

	// prepare() sets the Query type to ty, and sets the state to ACTIVE.
	// prepare() must not be called when the query is already ACTIVE.
	void prepare(VkQueryType ty);

	// start() begins a query task which is closed with a call to finish().
	// Query tasks can be nested.
	// start() must only be called when in the ACTIVE state.
	void start();

	// finish() ends a query task begun with a call to start().
	// Once all query tasks are complete the query will transition to the
	// FINISHED state.
	// finish() must only be called when in the ACTIVE state.
	void finish();

	// wait() blocks until the query reaches the FINISHED state.
	void wait();

	// getData() returns the current query state and value.
	Data getData() const;

	// getType() returns the type of query.
	VkQueryType getType() const;

	// set() replaces the current query value with val.
	void set(int64_t val);

	// add() adds val to the current query value.
	void add(int64_t val);

private:
	sw::WaitGroup wg;
	sw::Event finished;
	std::atomic<State> state;
	std::atomic<VkQueryType> type;
	std::atomic<int64_t> value;
};

class QueryPool : public Object<QueryPool, VkQueryPool>
{
public:
	QueryPool(const VkQueryPoolCreateInfo* pCreateInfo, void* mem);
	void destroy(const VkAllocationCallbacks* pAllocator);

	static size_t ComputeRequiredAllocationSize(const VkQueryPoolCreateInfo* pCreateInfo);

	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:
	Query* pool;
	VkQueryType type;
	uint32_t count;
};

static inline QueryPool* Cast(VkQueryPool object)
{
	return QueryPool::Cast(object);
}

} // namespace vk

#endif // VK_QUERY_POOL_HPP_
