/*
 * MVKCommandPool.h
 *
 * Copyright (c) 2014-2019 The Brenwill Workshop Ltd. (http://www.brenwill.com)
 *
 * 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.
 */

#pragma once

#include "MVKDevice.h"
#include "MVKCommandBuffer.h"
#include "MVKCommandEncodingPool.h"
#include "MVKCommand.h"
#include "MVKCmdPipeline.h"
#include "MVKCmdRenderPass.h"
#include "MVKCmdDispatch.h"
#include "MVKCmdDraw.h"
#include "MVKCmdTransfer.h"
#include "MVKCmdQueries.h"
#include "MVKCmdDebug.h"
#include "MVKMTLBufferAllocation.h"
#include <unordered_set>

#import <Metal/Metal.h>


#pragma mark -
#pragma mark MVKCommandPool

/** 
 * Represents a Vulkan command pool.
 *
 * Access to a command pool in Vulkan is externally synchronized.
 * As such, unless indicated otherwise, access to the content within this command pool 
 * is generally NOT thread-safe.
 *
 * Except where noted otherwise on specific member functions, all access to the content 
 * of this pool should be done during the setContent() function of each MVKCommand, and NOT 
 * during the execution of the command via the MVKCommand::encode() member function.
 */
class MVKCommandPool : public MVKVulkanAPIDeviceObject {

public:

	/** Returns the debug report object type of this object. */
	VkDebugReportObjectTypeEXT getVkDebugReportObjectType() override { return VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT; }

#pragma mark Command type pools

	MVKCommandTypePool<MVKCmdPipelineBarrier> _cmdPipelineBarrierPool;

	MVKCommandTypePool<MVKCmdBindPipeline> _cmdBindPipelinePool;

	MVKCommandTypePool<MVKCmdBeginRenderPass> _cmdBeginRenderPassPool;

	MVKCommandTypePool<MVKCmdNextSubpass> _cmdNextSubpassPool;

	MVKCommandTypePool<MVKCmdEndRenderPass> _cmdEndRenderPassPool;

	MVKCommandTypePool<MVKCmdExecuteCommands> _cmdExecuteCommandsPool;

	MVKCommandTypePool<MVKCmdBindDescriptorSets> _cmdBindDescriptorSetsPool;

	MVKCommandTypePool<MVKCmdSetViewport> _cmdSetViewportPool;

	MVKCommandTypePool<MVKCmdSetScissor> _cmdSetScissorPool;

    MVKCommandTypePool<MVKCmdSetLineWidth> _cmdSetLineWidthPool;

    MVKCommandTypePool<MVKCmdSetDepthBias> _cmdSetDepthBiasPool;

    MVKCommandTypePool<MVKCmdSetBlendConstants> _cmdSetBlendConstantsPool;

    MVKCommandTypePool<MVKCmdSetDepthBounds> _cmdSetDepthBoundsPool;

    MVKCommandTypePool<MVKCmdSetStencilCompareMask> _cmdSetStencilCompareMaskPool;

    MVKCommandTypePool<MVKCmdSetStencilWriteMask> _cmdSetStencilWriteMaskPool;

    MVKCommandTypePool<MVKCmdSetStencilReference> _cmdSetStencilReferencePool;

	MVKCommandTypePool<MVKCmdBindVertexBuffers> _cmdBindVertexBuffersPool;

	MVKCommandTypePool<MVKCmdBindIndexBuffer> _cmdBindIndexBufferPool;

	MVKCommandTypePool<MVKCmdDraw> _cmdDrawPool;

	MVKCommandTypePool<MVKCmdDrawIndexed> _cmdDrawIndexedPool;

	MVKCommandTypePool<MVKCmdDrawIndirect> _cmdDrawIndirectPool;

	MVKCommandTypePool<MVKCmdDrawIndexedIndirect> _cmdDrawIndexedIndirectPool;

	MVKCommandTypePool<MVKCmdCopyImage> _cmdCopyImagePool;

	MVKCommandTypePool<MVKCmdBlitImage> _cmdBlitImagePool;

    MVKCommandTypePool<MVKCmdResolveImage> _cmdResolveImagePool;

    MVKCommandTypePool<MVKCmdFillBuffer> _cmdFillBufferPool;

    MVKCommandTypePool<MVKCmdUpdateBuffer> _cmdUpdateBufferPool;

	MVKCommandTypePool<MVKCmdCopyBuffer> _cmdCopyBufferPool;

    MVKCommandTypePool<MVKCmdBufferImageCopy> _cmdBufferImageCopyPool;

	MVKCommandTypePool<MVKCmdClearAttachments> _cmdClearAttachmentsPool;

	MVKCommandTypePool<MVKCmdClearImage> _cmdClearImagePool;

    MVKCommandTypePool<MVKCmdBeginQuery> _cmdBeginQueryPool;

    MVKCommandTypePool<MVKCmdEndQuery> _cmdEndQueryPool;

	MVKCommandTypePool<MVKCmdWriteTimestamp> _cmdWriteTimestampPool;

    MVKCommandTypePool<MVKCmdResetQueryPool> _cmdResetQueryPoolPool;

    MVKCommandTypePool<MVKCmdCopyQueryPoolResults> _cmdCopyQueryPoolResultsPool;

	MVKCommandTypePool<MVKCmdPushConstants> _cmdPushConstantsPool;

    MVKCommandTypePool<MVKCmdDispatch> _cmdDispatchPool;

    MVKCommandTypePool<MVKCmdDispatchIndirect> _cmdDispatchIndirectPool;

    MVKCommandTypePool<MVKCmdPushDescriptorSet> _cmdPushDescriptorSetPool;

    MVKCommandTypePool<MVKCmdPushDescriptorSetWithTemplate> _cmdPushSetWithTemplatePool;

	MVKCommandTypePool<MVKCmdDebugMarkerBegin> _cmdDebugMarkerBeginPool;

	MVKCommandTypePool<MVKCmdDebugMarkerEnd> _cmdDebugMarkerEndPool;

	MVKCommandTypePool<MVKCmdDebugMarkerInsert> _cmdDebugMarkerInsertPool;


#pragma mark Command resources

	/** Allocates command buffers from this pool. */
	VkResult allocateCommandBuffers(const VkCommandBufferAllocateInfo* pAllocateInfo,
									VkCommandBuffer* pCmdBuffer);

	/** Frees the specified command buffers from this pool. */
	void freeCommandBuffers(uint32_t commandBufferCount,
							const VkCommandBuffer* pCommandBuffers);

	/** Returns the command encoding pool. */
	inline MVKCommandEncodingPool* getCommandEncodingPool() { return &_commandEncodingPool; }

	/**
	 * Returns a retained MTLCommandBuffer created from the indexed queue
	 * within the queue family for which this command pool was created.
	 */
	id<MTLCommandBuffer> newMTLCommandBuffer(uint32_t queueIndex);

	/** Release any held but unused memory back to the system. */
	void trim();


#pragma mark Construction

	/** Resets the command pool. */
	VkResult reset( VkCommandPoolResetFlags flags);

	MVKCommandPool(MVKDevice* device, const VkCommandPoolCreateInfo* pCreateInfo);

	~MVKCommandPool() override;

protected:
	void propogateDebugName() override {}
	MVKDeviceObjectPool<MVKCommandBuffer> _commandBufferPool;
	std::unordered_set<MVKCommandBuffer*> _allocatedCommandBuffers;
	MVKCommandEncodingPool _commandEncodingPool;
	uint32_t _queueFamilyIndex;
};

