// Copyright 2019 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 "Device.hpp"
#include "Driver.hpp"

Device::Device()
    : driver(nullptr)
    , device(nullptr)
    , physicalDevice(nullptr)
    , queueFamilyIndex(0)
{}

Device::Device(
    Driver const *driver, VkDevice device, VkPhysicalDevice physicalDevice,
    uint32_t queueFamilyIndex)
    : driver(driver)
    , device(device)
    , physicalDevice(physicalDevice)
    , queueFamilyIndex(queueFamilyIndex)
{}

Device::~Device()
{
	if(device != nullptr)
	{
		driver->vkDeviceWaitIdle(device);
		driver->vkDestroyDevice(device, nullptr);
	}
}

bool Device::IsValid() const
{
	return device != nullptr;
}

VkResult Device::CreateComputeDevice(
    Driver const *driver, VkInstance instance, std::unique_ptr<Device> &out)
{
	VkResult result;

	// Gather all physical devices
	std::vector<VkPhysicalDevice> physicalDevices;
	result = GetPhysicalDevices(driver, instance, physicalDevices);
	if(result != VK_SUCCESS)
	{
		return result;
	}

	// Inspect each physical device's queue families for compute support.
	for(auto physicalDevice : physicalDevices)
	{
		int queueFamilyIndex = GetComputeQueueFamilyIndex(driver, physicalDevice);
		if(queueFamilyIndex < 0)
		{
			continue;
		}

		const float queuePrioritory = 1.0f;
		const VkDeviceQueueCreateInfo deviceQueueCreateInfo = {
			VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,  // sType
			nullptr,                                     // pNext
			0,                                           // flags
			(uint32_t)queueFamilyIndex,                  // queueFamilyIndex
			1,                                           // queueCount
			&queuePrioritory,                            // pQueuePriorities
		};

		const VkDeviceCreateInfo deviceCreateInfo = {
			VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,  // sType
			nullptr,                               // pNext
			0,                                     // flags
			1,                                     // queueCreateInfoCount
			&deviceQueueCreateInfo,                // pQueueCreateInfos
			0,                                     // enabledLayerCount
			nullptr,                               // ppEnabledLayerNames
			0,                                     // enabledExtensionCount
			nullptr,                               // ppEnabledExtensionNames
			nullptr,                               // pEnabledFeatures
		};

		VkDevice device;
		result = driver->vkCreateDevice(physicalDevice, &deviceCreateInfo, nullptr, &device);
		if(result != VK_SUCCESS)
		{
			return result;
		}

		out.reset(new Device(driver, device, physicalDevice, static_cast<uint32_t>(queueFamilyIndex)));
		return VK_SUCCESS;
	}

	return VK_SUCCESS;
}

int Device::GetComputeQueueFamilyIndex(
    Driver const *driver, VkPhysicalDevice device)
{
	auto properties = GetPhysicalDeviceQueueFamilyProperties(driver, device);
	for(uint32_t i = 0; i < properties.size(); i++)
	{
		if((properties[i].queueFlags & VK_QUEUE_COMPUTE_BIT) != 0)
		{
			return static_cast<int>(i);
		}
	}
	return -1;
}

std::vector<VkQueueFamilyProperties>
Device::GetPhysicalDeviceQueueFamilyProperties(
    Driver const *driver, VkPhysicalDevice device)
{
	std::vector<VkQueueFamilyProperties> out;
	uint32_t count = 0;
	driver->vkGetPhysicalDeviceQueueFamilyProperties(device, &count, nullptr);
	out.resize(count);
	driver->vkGetPhysicalDeviceQueueFamilyProperties(device, &count, out.data());
	return out;
}

VkResult Device::GetPhysicalDevices(
    const Driver *driver, VkInstance instance,
    std::vector<VkPhysicalDevice> &out)
{
	uint32_t count = 0;
	VkResult result = driver->vkEnumeratePhysicalDevices(instance, &count, 0);
	if(result != VK_SUCCESS)
	{
		return result;
	}
	out.resize(count);
	return driver->vkEnumeratePhysicalDevices(instance, &count, out.data());
}

VkResult Device::CreateStorageBuffer(
    VkDeviceMemory memory, VkDeviceSize size,
    VkDeviceSize offset, VkBuffer *out) const
{
	const VkBufferCreateInfo info = {
		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,  // sType
		nullptr,                               // pNext
		0,                                     // flags
		size,                                  // size
		VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,    // usage
		VK_SHARING_MODE_EXCLUSIVE,             // sharingMode
		0,                                     // queueFamilyIndexCount
		nullptr,                               // pQueueFamilyIndices
	};

	VkBuffer buffer;
	VkResult result = driver->vkCreateBuffer(device, &info, 0, &buffer);
	if(result != VK_SUCCESS)
	{
		return result;
	}

	result = driver->vkBindBufferMemory(device, buffer, memory, offset);
	if(result != VK_SUCCESS)
	{
		return result;
	}

	*out = buffer;
	return VK_SUCCESS;
}

void Device::DestroyBuffer(VkBuffer buffer) const
{
	driver->vkDestroyBuffer(device, buffer, nullptr);
}

VkResult Device::CreateShaderModule(
    const std::vector<uint32_t> &spirv, VkShaderModule *out) const
{
	VkShaderModuleCreateInfo info = {
		VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,  // sType
		nullptr,                                      // pNext
		0,                                            // flags
		spirv.size() * 4,                             // codeSize
		spirv.data(),                                 // pCode
	};
	return driver->vkCreateShaderModule(device, &info, 0, out);
}

void Device::DestroyShaderModule(VkShaderModule shaderModule) const
{
	driver->vkDestroyShaderModule(device, shaderModule, nullptr);
}

VkResult Device::CreateDescriptorSetLayout(
    const std::vector<VkDescriptorSetLayoutBinding> &bindings,
    VkDescriptorSetLayout *out) const
{
	VkDescriptorSetLayoutCreateInfo info = {
		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,  // sType
		nullptr,                                              // pNext
		0,                                                    // flags
		(uint32_t)bindings.size(),                            // bindingCount
		bindings.data(),                                      // pBindings
	};

	return driver->vkCreateDescriptorSetLayout(device, &info, 0, out);
}

void Device::DestroyDescriptorSetLayout(VkDescriptorSetLayout descriptorSetLayout) const
{
	driver->vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr);
}

VkResult Device::CreatePipelineLayout(
    VkDescriptorSetLayout layout, VkPipelineLayout *out) const
{
	VkPipelineLayoutCreateInfo info = {
		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,  // sType
		nullptr,                                        // pNext
		0,                                              // flags
		1,                                              // setLayoutCount
		&layout,                                        // pSetLayouts
		0,                                              // pushConstantRangeCount
		nullptr,                                        // pPushConstantRanges
	};

	return driver->vkCreatePipelineLayout(device, &info, 0, out);
}

void Device::DestroyPipelineLayout(VkPipelineLayout pipelineLayout) const
{
	driver->vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
}

VkResult Device::CreateComputePipeline(
    VkShaderModule module, VkPipelineLayout pipelineLayout,
    VkPipeline *out) const
{
	VkComputePipelineCreateInfo info = {
		VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,  // sType
		nullptr,                                         // pNext
		0,                                               // flags
		{
		    // stage
		    VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,  // sType
		    nullptr,                                              // pNext
		    0,                                                    // flags
		    VK_SHADER_STAGE_COMPUTE_BIT,                          // stage
		    module,                                               // module
		    "main",                                               // pName
		    nullptr,                                              // pSpecializationInfo
		},
		pipelineLayout,  // layout
		0,               // basePipelineHandle
		0,               // basePipelineIndex
	};

	return driver->vkCreateComputePipelines(device, 0, 1, &info, 0, out);
}

void Device::DestroyPipeline(VkPipeline pipeline) const
{
	driver->vkDestroyPipeline(device, pipeline, nullptr);
}

VkResult Device::CreateStorageBufferDescriptorPool(uint32_t descriptorCount,
                                                   VkDescriptorPool *out) const
{
	VkDescriptorPoolSize size = {
		VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,  // type
		descriptorCount,                    // descriptorCount
	};

	VkDescriptorPoolCreateInfo info = {
		VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,  // sType
		nullptr,                                        // pNext
		0,                                              // flags
		1,                                              // maxSets
		1,                                              // poolSizeCount
		&size,                                          // pPoolSizes
	};

	return driver->vkCreateDescriptorPool(device, &info, 0, out);
}

void Device::DestroyDescriptorPool(VkDescriptorPool descriptorPool) const
{
	driver->vkDestroyDescriptorPool(device, descriptorPool, nullptr);
}

VkResult Device::AllocateDescriptorSet(
    VkDescriptorPool pool, VkDescriptorSetLayout layout,
    VkDescriptorSet *out) const
{
	VkDescriptorSetAllocateInfo info = {
		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,  // sType
		nullptr,                                         // pNext
		pool,                                            // descriptorPool
		1,                                               // descriptorSetCount
		&layout,                                         // pSetLayouts
	};

	return driver->vkAllocateDescriptorSets(device, &info, out);
}

void Device::UpdateStorageBufferDescriptorSets(
    VkDescriptorSet descriptorSet,
    const std::vector<VkDescriptorBufferInfo> &bufferInfos) const
{
	std::vector<VkWriteDescriptorSet> writes;
	writes.reserve(bufferInfos.size());
	for(uint32_t i = 0; i < bufferInfos.size(); i++)
	{
		writes.push_back(VkWriteDescriptorSet{
		    VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,  // sType
		    nullptr,                                 // pNext
		    descriptorSet,                           // dstSet
		    i,                                       // dstBinding
		    0,                                       // dstArrayElement
		    1,                                       // descriptorCount
		    VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,       // descriptorType
		    nullptr,                                 // pImageInfo
		    &bufferInfos[i],                         // pBufferInfo
		    nullptr,                                 // pTexelBufferView
		});
	}

	driver->vkUpdateDescriptorSets(device, writes.size(), writes.data(), 0, nullptr);
}

VkResult Device::AllocateMemory(size_t size, VkMemoryPropertyFlags flags, VkDeviceMemory *out) const
{
	VkPhysicalDeviceMemoryProperties properties;
	driver->vkGetPhysicalDeviceMemoryProperties(physicalDevice, &properties);

	for(uint32_t type = 0; type < properties.memoryTypeCount; type++)
	{
		if((flags & properties.memoryTypes[type].propertyFlags) == 0)
		{
			continue;  // Type mismatch
		}

		if(size > properties.memoryHeaps[properties.memoryTypes[type].heapIndex].size)
		{
			continue;  // Too small.
		}

		const VkMemoryAllocateInfo info = {
			VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,  // sType
			nullptr,                                 // pNext
			size,                                    // allocationSize
			type,                                    // memoryTypeIndex
		};

		return driver->vkAllocateMemory(device, &info, 0, out);
	}

	return VK_ERROR_OUT_OF_DEVICE_MEMORY;  // TODO: Change to something not made up?
}

void Device::FreeMemory(VkDeviceMemory memory) const
{
	driver->vkFreeMemory(device, memory, nullptr);
}

VkResult Device::MapMemory(VkDeviceMemory memory, VkDeviceSize offset,
                           VkDeviceSize size, VkMemoryMapFlags flags, void **ppData) const
{
	return driver->vkMapMemory(device, memory, offset, size, flags, ppData);
}

void Device::UnmapMemory(VkDeviceMemory memory) const
{
	driver->vkUnmapMemory(device, memory);
}

VkResult Device::CreateCommandPool(VkCommandPool *out) const
{
	VkCommandPoolCreateInfo info = {
		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,  // sType
		nullptr,                                     // pNext
		0,                                           // flags
		queueFamilyIndex,                            // queueFamilyIndex
	};
	return driver->vkCreateCommandPool(device, &info, 0, out);
}

void Device::DestroyCommandPool(VkCommandPool commandPool) const
{
	return driver->vkDestroyCommandPool(device, commandPool, nullptr);
}

VkResult Device::AllocateCommandBuffer(
    VkCommandPool pool, VkCommandBuffer *out) const
{
	VkCommandBufferAllocateInfo info = {
		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,  // sType
		nullptr,                                         // pNext
		pool,                                            // commandPool
		VK_COMMAND_BUFFER_LEVEL_PRIMARY,                 // level
		1,                                               // commandBufferCount
	};
	return driver->vkAllocateCommandBuffers(device, &info, out);
}

void Device::FreeCommandBuffer(VkCommandPool pool, VkCommandBuffer buffer)
{
	driver->vkFreeCommandBuffers(device, pool, 1, &buffer);
}

VkResult Device::BeginCommandBuffer(
    VkCommandBufferUsageFlags usage, VkCommandBuffer commandBuffer) const
{
	VkCommandBufferBeginInfo info = {
		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,  // sType
		nullptr,                                      // pNext
		usage,                                        // flags
		nullptr,                                      // pInheritanceInfo
	};

	return driver->vkBeginCommandBuffer(commandBuffer, &info);
}

VkResult Device::QueueSubmitAndWait(VkCommandBuffer commandBuffer) const
{
	VkQueue queue;
	driver->vkGetDeviceQueue(device, queueFamilyIndex, 0, &queue);

	VkSubmitInfo info = {
		VK_STRUCTURE_TYPE_SUBMIT_INFO,  // sType
		nullptr,                        // pNext
		0,                              // waitSemaphoreCount
		nullptr,                        // pWaitSemaphores
		nullptr,                        // pWaitDstStageMask
		1,                              // commandBufferCount
		&commandBuffer,                 // pCommandBuffers
		0,                              // signalSemaphoreCount
		nullptr,                        // pSignalSemaphores
	};

	VkResult result = driver->vkQueueSubmit(queue, 1, &info, 0);
	if(result != VK_SUCCESS)
	{
		return result;
	}

	return driver->vkQueueWaitIdle(queue);
}
