// 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.

#include "VkQueryPool.hpp"

#include <chrono>
#include <cstring>
#include <new>

namespace vk
{
	Query::Query() : finished(marl::Event::Mode::Manual), state(UNAVAILABLE), type(INVALID_TYPE), value(0) {}

	void Query::reset()
	{
		finished.clear();
		auto prevState = state.exchange(UNAVAILABLE);
		ASSERT(prevState != ACTIVE);
		type = INVALID_TYPE;
		value = 0;
	}

	void Query::prepare(VkQueryType ty)
	{
		auto prevState = state.exchange(ACTIVE);
		ASSERT(prevState == UNAVAILABLE);
		type = ty;
	}

	void Query::start()
	{
		ASSERT(state == ACTIVE);
		wg.add();
	}

	void Query::finish()
	{
		if (wg.done())
		{
			auto prevState = state.exchange(FINISHED);
			ASSERT(prevState == ACTIVE);
			finished.signal();
		}
	}

	Query::Data Query::getData() const
	{
		Data out;
		out.state = state;
		out.value = value;
		return out;
	}

	VkQueryType Query::getType() const
	{
		return type;
	}

	void Query::wait()
	{
		finished.wait();
	}

	void Query::set(int64_t v)
	{
		value = v;
	}

	void Query::add(int64_t v)
	{
		value += v;
	}

	QueryPool::QueryPool(const VkQueryPoolCreateInfo* pCreateInfo, void* mem) :
		pool(reinterpret_cast<Query*>(mem)), type(pCreateInfo->queryType),
		count(pCreateInfo->queryCount)
	{
		// According to the Vulkan spec, section 34.1. Features:
		// "pipelineStatisticsQuery specifies whether the pipeline statistics
		//  queries are supported. If this feature is not enabled, queries of
		//  type VK_QUERY_TYPE_PIPELINE_STATISTICS cannot be created, and
		//  none of the VkQueryPipelineStatisticFlagBits bits can be set in the
		//  pipelineStatistics member of the VkQueryPoolCreateInfo structure."
		if(type == VK_QUERY_TYPE_PIPELINE_STATISTICS)
		{
			UNIMPLEMENTED("pCreateInfo->queryType");
		}

		// Construct all queries
		for(uint32_t i = 0; i < count; i++)
		{
			new (&pool[i]) Query();
		}
	}

	void QueryPool::destroy(const VkAllocationCallbacks* pAllocator)
	{
		vk::deallocate(pool, pAllocator);
	}

	size_t QueryPool::ComputeRequiredAllocationSize(const VkQueryPoolCreateInfo* pCreateInfo)
	{
		return sizeof(Query) * pCreateInfo->queryCount;
	}

	VkResult QueryPool::getResults(uint32_t firstQuery, uint32_t queryCount, size_t dataSize,
	                               void* pData, VkDeviceSize stride, VkQueryResultFlags flags) const
	{
		// dataSize must be large enough to contain the result of each query
		ASSERT(static_cast<size_t>(stride * queryCount) <= dataSize);

		// The sum of firstQuery and queryCount must be less than or equal to the number of queries
		ASSERT((firstQuery + queryCount) <= count);

		VkResult result = VK_SUCCESS;
		uint8_t* data = static_cast<uint8_t*>(pData);
		for(uint32_t i = firstQuery; i < (firstQuery + queryCount); i++, data += stride)
		{
			// If VK_QUERY_RESULT_WAIT_BIT and VK_QUERY_RESULT_PARTIAL_BIT are both not set
			// then no result values are written to pData for queries that are in the
			// unavailable state at the time of the call, and vkGetQueryPoolResults returns
			// VK_NOT_READY. However, availability state is still written to pData for those
			// queries if VK_QUERY_RESULT_WITH_AVAILABILITY_BIT is set.
			auto &query = pool[i];

			if(flags & VK_QUERY_RESULT_WAIT_BIT) // Must wait for query to finish
			{
				query.wait();
			}

			const auto current = query.getData();

			bool writeResult = true;
			if(current.state == Query::ACTIVE)
			{
				result = VK_NOT_READY;
				writeResult = (flags & VK_QUERY_RESULT_PARTIAL_BIT); // Allow writing partial results
			}

			if(flags & VK_QUERY_RESULT_64_BIT)
			{
				uint64_t* result64 = reinterpret_cast<uint64_t*>(data);
				if(writeResult)
				{
					result64[0] = current.value;
				}
				if(flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT) // Output query availablity
				{
					result64[1] = current.state;
				}
			}
			else
			{
				uint32_t* result32 = reinterpret_cast<uint32_t*>(data);
				if(writeResult)
				{
					result32[0] = static_cast<uint32_t>(current.value);
				}
				if(flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT) // Output query availablity
				{
					result32[1] = current.state;
				}
			}
		}

		return result;
	}

	void QueryPool::begin(uint32_t query, VkQueryControlFlags flags)
	{
		ASSERT(query < count);

		if(flags != 0)
		{
			UNIMPLEMENTED("flags");
		}

		pool[query].prepare(type);
		pool[query].start();
	}

	void QueryPool::end(uint32_t query)
	{
		ASSERT(query < count);
		pool[query].finish();
	}

	void QueryPool::reset(uint32_t firstQuery, uint32_t queryCount)
	{
		// The sum of firstQuery and queryCount must be less than or equal to the number of queries
		ASSERT((firstQuery + queryCount) <= count);

		for(uint32_t i = firstQuery; i < (firstQuery + queryCount); i++)
		{
			pool[i].reset();
		}
	}

	void QueryPool::writeTimestamp(uint32_t query)
	{
		ASSERT(query < count);
		ASSERT(type == VK_QUERY_TYPE_TIMESTAMP);

		pool[query].set(std::chrono::time_point_cast<std::chrono::nanoseconds>(
			std::chrono::system_clock::now()).time_since_epoch().count());
	}
} // namespace vk
