// 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 "VkDevice.hpp"

#include "VkConfig.hpp"
#include "VkDescriptorSetLayout.hpp"
#include "VkFence.hpp"
#include "VkQueue.hpp"
#include "VkSemaphore.hpp"
#include "VkTimelineSemaphore.hpp"
#include "Debug/Context.hpp"
#include "Debug/Server.hpp"
#include "Device/Blitter.hpp"
#include "System/Debug.hpp"

#include <chrono>
#include <climits>
#include <new>  // Must #include this to use "placement new"

namespace {

using time_point = std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds>;

time_point now()
{
	return std::chrono::time_point_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now());
}

const time_point getEndTimePoint(uint64_t timeout, bool &infiniteTimeout)
{
	const time_point start = now();
	const uint64_t max_timeout = (LLONG_MAX - start.time_since_epoch().count());
	infiniteTimeout = (timeout > max_timeout);
	return start + std::chrono::nanoseconds(std::min(max_timeout, timeout));
}

}  // anonymous namespace

namespace vk {

void Device::SamplingRoutineCache::updateSnapshot()
{
	marl::lock lock(mutex);

	if(snapshotNeedsUpdate)
	{
		snapshot.clear();

		for(auto it : cache)
		{
			snapshot[it.key()] = it.data();
		}

		snapshotNeedsUpdate = false;
	}
}

Device::SamplerIndexer::~SamplerIndexer()
{
	ASSERT(map.empty());
}

uint32_t Device::SamplerIndexer::index(const SamplerState &samplerState)
{
	marl::lock lock(mutex);

	auto it = map.find(samplerState);

	if(it != map.end())
	{
		it->second.count++;
		return it->second.id;
	}

	nextID++;

	map.emplace(samplerState, Identifier{ nextID, 1 });

	return nextID;
}

void Device::SamplerIndexer::remove(const SamplerState &samplerState)
{
	marl::lock lock(mutex);

	auto it = map.find(samplerState);
	ASSERT(it != map.end());

	auto count = --it->second.count;
	if(count == 0)
	{
		map.erase(it);
	}
}

Device::Device(const VkDeviceCreateInfo *pCreateInfo, void *mem, PhysicalDevice *physicalDevice, const VkPhysicalDeviceFeatures *enabledFeatures, const std::shared_ptr<marl::Scheduler> &scheduler)
    : physicalDevice(physicalDevice)
    , queues(reinterpret_cast<Queue *>(mem))
    , enabledExtensionCount(pCreateInfo->enabledExtensionCount)
    , enabledFeatures(enabledFeatures ? *enabledFeatures : VkPhysicalDeviceFeatures{})
    ,  // "Setting pEnabledFeatures to NULL and not including a VkPhysicalDeviceFeatures2 in the pNext member of VkDeviceCreateInfo is equivalent to setting all members of the structure to VK_FALSE."
    scheduler(scheduler)
{
	for(uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++)
	{
		const VkDeviceQueueCreateInfo &queueCreateInfo = pCreateInfo->pQueueCreateInfos[i];
		queueCount += queueCreateInfo.queueCount;
	}

	uint32_t queueID = 0;
	for(uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++)
	{
		const VkDeviceQueueCreateInfo &queueCreateInfo = pCreateInfo->pQueueCreateInfos[i];

		for(uint32_t j = 0; j < queueCreateInfo.queueCount; j++, queueID++)
		{
			new(&queues[queueID]) Queue(this, scheduler.get());
		}
	}

	extensions = reinterpret_cast<ExtensionName *>(static_cast<uint8_t *>(mem) + (sizeof(Queue) * queueCount));
	for(uint32_t i = 0; i < enabledExtensionCount; i++)
	{
		strncpy(extensions[i], pCreateInfo->ppEnabledExtensionNames[i], VK_MAX_EXTENSION_NAME_SIZE);
	}

	if(pCreateInfo->enabledLayerCount)
	{
		// "The ppEnabledLayerNames and enabledLayerCount members of VkDeviceCreateInfo are deprecated and their values must be ignored by implementations."
		UNSUPPORTED("enabledLayerCount");
	}

	// FIXME (b/119409619): use an allocator here so we can control all memory allocations
	blitter.reset(new sw::Blitter());
	samplingRoutineCache.reset(new SamplingRoutineCache());
	samplerIndexer.reset(new SamplerIndexer());

#ifdef ENABLE_VK_DEBUGGER
	static auto port = getenv("VK_DEBUGGER_PORT");
	if(port)
	{
		// Construct the debugger context and server - this may block for a
		// debugger connection, allowing breakpoints to be set before they're
		// executed.
		debugger.context = vk::dbg::Context::create();
		debugger.server = vk::dbg::Server::create(debugger.context, atoi(port));
	}
#endif  // ENABLE_VK_DEBUGGER

#ifdef SWIFTSHADER_DEVICE_MEMORY_REPORT
	const VkBaseInStructure *extensionCreateInfo = reinterpret_cast<const VkBaseInStructure *>(pCreateInfo->pNext);
	while(extensionCreateInfo)
	{
		if(extensionCreateInfo->sType == VK_STRUCTURE_TYPE_DEVICE_DEVICE_MEMORY_REPORT_CREATE_INFO_EXT)
		{
			auto deviceMemoryReportCreateInfo = reinterpret_cast<const VkDeviceDeviceMemoryReportCreateInfoEXT *>(pCreateInfo->pNext);
			if(deviceMemoryReportCreateInfo->pfnUserCallback != nullptr)
			{
				deviceMemoryReportCallbacks.emplace_back(deviceMemoryReportCreateInfo->pfnUserCallback, deviceMemoryReportCreateInfo->pUserData);
			}
		}
		extensionCreateInfo = extensionCreateInfo->pNext;
	}
#endif  // SWIFTSHADER_DEVICE_MEMORY_REPORT
}

void Device::destroy(const VkAllocationCallbacks *pAllocator)
{
	for(uint32_t i = 0; i < queueCount; i++)
	{
		queues[i].~Queue();
	}

	vk::deallocate(queues, pAllocator);
}

size_t Device::ComputeRequiredAllocationSize(const VkDeviceCreateInfo *pCreateInfo)
{
	uint32_t queueCount = 0;
	for(uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++)
	{
		queueCount += pCreateInfo->pQueueCreateInfos[i].queueCount;
	}

	return (sizeof(Queue) * queueCount) + (pCreateInfo->enabledExtensionCount * sizeof(ExtensionName));
}

bool Device::hasExtension(const char *extensionName) const
{
	for(uint32_t i = 0; i < enabledExtensionCount; i++)
	{
		if(strncmp(extensions[i], extensionName, VK_MAX_EXTENSION_NAME_SIZE) == 0)
		{
			return true;
		}
	}
	return false;
}

VkQueue Device::getQueue(uint32_t queueFamilyIndex, uint32_t queueIndex) const
{
	ASSERT(queueFamilyIndex == 0);

	return queues[queueIndex];
}

VkResult Device::waitForFences(uint32_t fenceCount, const VkFence *pFences, VkBool32 waitAll, uint64_t timeout)
{
	bool infiniteTimeout = false;
	const time_point end_ns = getEndTimePoint(timeout, infiniteTimeout);

	if(waitAll != VK_FALSE)  // All fences must be signaled
	{
		for(uint32_t i = 0; i < fenceCount; i++)
		{
			if(timeout == 0)
			{
				if(Cast(pFences[i])->getStatus() != VK_SUCCESS)  // At least one fence is not signaled
				{
					return VK_TIMEOUT;
				}
			}
			else if(infiniteTimeout)
			{
				if(Cast(pFences[i])->wait() != VK_SUCCESS)  // At least one fence is not signaled
				{
					return VK_TIMEOUT;
				}
			}
			else
			{
				if(Cast(pFences[i])->wait(end_ns) != VK_SUCCESS)  // At least one fence is not signaled
				{
					return VK_TIMEOUT;
				}
			}
		}

		return VK_SUCCESS;
	}
	else  // At least one fence must be signaled
	{
		marl::containers::vector<marl::Event, 8> events;
		for(uint32_t i = 0; i < fenceCount; i++)
		{
			events.push_back(Cast(pFences[i])->getCountedEvent()->event());
		}

		auto any = marl::Event::any(events.begin(), events.end());

		if(timeout == 0)
		{
			return any.isSignalled() ? VK_SUCCESS : VK_TIMEOUT;
		}
		else if(infiniteTimeout)
		{
			any.wait();
			return VK_SUCCESS;
		}
		else
		{
			return any.wait_until(end_ns) ? VK_SUCCESS : VK_TIMEOUT;
		}
	}
}

VkResult Device::waitForSemaphores(const VkSemaphoreWaitInfo *pWaitInfo, uint64_t timeout)
{
	bool infiniteTimeout = false;
	const time_point end_ns = getEndTimePoint(timeout, infiniteTimeout);

	if(pWaitInfo->flags & VK_SEMAPHORE_WAIT_ANY_BIT)
	{
		TimelineSemaphore any = TimelineSemaphore();

		for(uint32_t i = 0; i < pWaitInfo->semaphoreCount; i++)
		{
			TimelineSemaphore *semaphore = DynamicCast<TimelineSemaphore>(pWaitInfo->pSemaphores[i]);
			uint64_t waitValue = pWaitInfo->pValues[i];

			if(semaphore->getCounterValue() == waitValue)
			{
				return VK_SUCCESS;
			}

			semaphore->addDependent(any, waitValue);
		}

		if(infiniteTimeout)
		{
			any.wait(1ull);
			return VK_SUCCESS;
		}
		else
		{
			if(any.wait(1, end_ns) == VK_SUCCESS)
			{
				return VK_SUCCESS;
			}
		}

		return VK_TIMEOUT;
	}
	else
	{
		ASSERT(pWaitInfo->flags == 0);
		for(uint32_t i = 0; i < pWaitInfo->semaphoreCount; i++)
		{
			TimelineSemaphore *semaphore = DynamicCast<TimelineSemaphore>(pWaitInfo->pSemaphores[i]);
			uint64_t value = pWaitInfo->pValues[i];
			if(infiniteTimeout)
			{
				semaphore->wait(value);
			}
			else if(semaphore->wait(pWaitInfo->pValues[i], end_ns) != VK_SUCCESS)
			{
				return VK_TIMEOUT;
			}
		}
		return VK_SUCCESS;
	}
}

VkResult Device::waitIdle()
{
	for(uint32_t i = 0; i < queueCount; i++)
	{
		queues[i].waitIdle();
	}

	return VK_SUCCESS;
}

void Device::getDescriptorSetLayoutSupport(const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
                                           VkDescriptorSetLayoutSupport *pSupport) const
{
	// From Vulkan Spec 13.2.1 Descriptor Set Layout, in description of vkGetDescriptorSetLayoutSupport:
	// "This command does not consider other limits such as maxPerStageDescriptor*, and so a descriptor
	// set layout that is supported according to this command must still satisfy the pipeline layout limits
	// such as maxPerStageDescriptor* in order to be used in a pipeline layout."

	// We have no "strange" limitations to enforce beyond the device limits, so we can safely always claim support.
	pSupport->supported = VK_TRUE;
}

void Device::updateDescriptorSets(uint32_t descriptorWriteCount, const VkWriteDescriptorSet *pDescriptorWrites,
                                  uint32_t descriptorCopyCount, const VkCopyDescriptorSet *pDescriptorCopies)
{
	for(uint32_t i = 0; i < descriptorWriteCount; i++)
	{
		DescriptorSetLayout::WriteDescriptorSet(this, pDescriptorWrites[i]);
	}

	for(uint32_t i = 0; i < descriptorCopyCount; i++)
	{
		DescriptorSetLayout::CopyDescriptorSet(pDescriptorCopies[i]);
	}
}

void Device::getRequirements(VkMemoryDedicatedRequirements *requirements) const
{
	requirements->prefersDedicatedAllocation = VK_FALSE;
	requirements->requiresDedicatedAllocation = VK_FALSE;
}

Device::SamplingRoutineCache *Device::getSamplingRoutineCache() const
{
	return samplingRoutineCache.get();
}

void Device::updateSamplingRoutineSnapshotCache()
{
	samplingRoutineCache->updateSnapshot();
}

uint32_t Device::indexSampler(const SamplerState &samplerState)
{
	return samplerIndexer->index(samplerState);
}

void Device::removeSampler(const SamplerState &samplerState)
{
	samplerIndexer->remove(samplerState);
}

VkResult Device::setDebugUtilsObjectName(const VkDebugUtilsObjectNameInfoEXT *pNameInfo)
{
	// Optionally maps user-friendly name to an object
	return VK_SUCCESS;
}

VkResult Device::setDebugUtilsObjectTag(const VkDebugUtilsObjectTagInfoEXT *pTagInfo)
{
	// Optionally attach arbitrary data to an object
	return VK_SUCCESS;
}

void Device::registerImageView(ImageView *imageView)
{
	if(imageView != nullptr)
	{
		marl::lock lock(imageViewSetMutex);
		imageViewSet.insert(imageView);
	}
}

void Device::unregisterImageView(ImageView *imageView)
{
	if(imageView != nullptr)
	{
		marl::lock lock(imageViewSetMutex);
		auto it = imageViewSet.find(imageView);
		if(it != imageViewSet.end())
		{
			imageViewSet.erase(it);
		}
	}
}

void Device::prepareForSampling(ImageView *imageView)
{
	if(imageView != nullptr)
	{
		marl::lock lock(imageViewSetMutex);

		auto it = imageViewSet.find(imageView);
		if(it != imageViewSet.end())
		{
			imageView->prepareForSampling();
		}
	}
}

void Device::contentsChanged(ImageView *imageView)
{
	if(imageView != nullptr)
	{
		marl::lock lock(imageViewSetMutex);

		auto it = imageViewSet.find(imageView);
		if(it != imageViewSet.end())
		{
			imageView->contentsChanged();
		}
	}
}

#ifdef SWIFTSHADER_DEVICE_MEMORY_REPORT
void Device::emitDeviceMemoryReport(VkDeviceMemoryReportEventTypeEXT type, uint64_t memoryObjectId, VkDeviceSize size, VkObjectType objectType, uint64_t objectHandle, uint32_t heapIndex)
{
	if(deviceMemoryReportCallbacks.empty()) return;

	const VkDeviceMemoryReportCallbackDataEXT callbackData = {
		VK_STRUCTURE_TYPE_DEVICE_MEMORY_REPORT_CALLBACK_DATA_EXT,  // sType
		nullptr,                                                   // pNext
		0,                                                         // flags
		type,                                                      // type
		memoryObjectId,                                            // memoryObjectId
		size,                                                      // size
		objectType,                                                // objectType
		objectHandle,                                              // objectHandle
		heapIndex,                                                 // heapIndex
	};
	for(const auto &callback : deviceMemoryReportCallbacks)
	{
		callback.first(&callbackData, callback.second);
	}
}
#endif  // SWIFTSHADER_DEVICE_MEMORY_REPORT

}  // namespace vk
