/*
 * MVKCmdQueries.mm
 *
 * Copyright (c) 2015-2020 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.
 */

#include "MVKCmdQueries.h"
#include "MVKCommandBuffer.h"
#include "MVKCommandPool.h"
#include "MVKQueryPool.h"


#pragma mark -
#pragma mark MVKCmdQuery

VkResult MVKCmdQuery::setContent(MVKCommandBuffer* cmdBuff,
								 VkQueryPool queryPool,
								 uint32_t query) {
    _queryPool = (MVKQueryPool*)queryPool;
    _query = query;

	return VK_SUCCESS;
}


#pragma mark -
#pragma mark MVKCmdBeginQuery

VkResult MVKCmdBeginQuery::setContent(MVKCommandBuffer* cmdBuff,
									  VkQueryPool queryPool,
									  uint32_t query,
									  VkQueryControlFlags flags) {

    VkResult rslt = MVKCmdQuery::setContent(cmdBuff, queryPool, query);

	_flags = flags;
	_queryPool->beginQueryAddedTo(_query, cmdBuff);

	return rslt;
}

void MVKCmdBeginQuery::encode(MVKCommandEncoder* cmdEncoder) {
    // In a multiview render pass, multiple queries are produced, one for each view.
    // Therefore, when encoding, we must offset the query by the number of views already
    // drawn in all previous Metal passes.
    uint32_t query = _query;
    if (cmdEncoder->getMultiviewPassIndex() > 0)
        query += cmdEncoder->getSubpass()->getViewCountUpToMetalPass(cmdEncoder->getMultiviewPassIndex() - 1);
    _queryPool->beginQuery(query, _flags, cmdEncoder);
}


#pragma mark -
#pragma mark MVKCmdEndQuery

void MVKCmdEndQuery::encode(MVKCommandEncoder* cmdEncoder) {
    uint32_t query = _query;
    if (cmdEncoder->getMultiviewPassIndex() > 0)
        query += cmdEncoder->getSubpass()->getViewCountUpToMetalPass(cmdEncoder->getMultiviewPassIndex() - 1);
    _queryPool->endQuery(query, cmdEncoder);
}


#pragma mark -
#pragma mark MVKCmdWriteTimestamp

VkResult MVKCmdWriteTimestamp::setContent(MVKCommandBuffer* cmdBuff,
										  VkPipelineStageFlagBits pipelineStage,
										  VkQueryPool queryPool,
										  uint32_t query) {

	VkResult rslt = MVKCmdQuery::setContent(cmdBuff, queryPool, query);

	_pipelineStage = pipelineStage;

	return rslt;
}

void MVKCmdWriteTimestamp::encode(MVKCommandEncoder* cmdEncoder) {
    uint32_t query = _query;
    if (cmdEncoder->getMultiviewPassIndex() > 0)
        query += cmdEncoder->getSubpass()->getViewCountUpToMetalPass(cmdEncoder->getMultiviewPassIndex() - 1);
    cmdEncoder->markTimestamp(_queryPool, query);
}


#pragma mark -
#pragma mark MVKCmdResetQueryPool

VkResult MVKCmdResetQueryPool::setContent(MVKCommandBuffer* cmdBuff,
										  VkQueryPool queryPool,
										  uint32_t firstQuery,
										  uint32_t queryCount) {

	VkResult rslt = MVKCmdQuery::setContent(cmdBuff, queryPool, firstQuery);

	_queryCount = queryCount;

	return rslt;
}

void MVKCmdResetQueryPool::encode(MVKCommandEncoder* cmdEncoder) {
    _queryPool->resetResults(_query, _queryCount, cmdEncoder);
}


#pragma mark -
#pragma mark MVKCmdCopyQueryPoolResults

VkResult MVKCmdCopyQueryPoolResults::setContent(MVKCommandBuffer* cmdBuff,
												VkQueryPool queryPool,
												uint32_t firstQuery,
												uint32_t queryCount,
												VkBuffer destBuffer,
												VkDeviceSize destOffset,
												VkDeviceSize destStride,
												VkQueryResultFlags flags) {

	VkResult rslt = MVKCmdQuery::setContent(cmdBuff, queryPool, firstQuery);

	_queryCount = queryCount;
    _destBuffer = (MVKBuffer*) destBuffer;
    _destOffset = destOffset;
    _destStride = destStride;
    _flags = flags;

	return rslt;
}

void MVKCmdCopyQueryPoolResults::encode(MVKCommandEncoder* cmdEncoder) {
    // What happens now depends on whether or not I was added before or after the query ended.
    if (!_queryPool->areQueriesDeviceAvailable(_query, _queryCount) && mvkIsAnyFlagEnabled(_flags, VK_QUERY_RESULT_WAIT_BIT)) {
        // Defer this until the queries will be done.
        _queryPool->deferCopyResults(_query, _queryCount, _destBuffer, _destOffset, _destStride, _flags);
    } else {
        _queryPool->encodeCopyResults(cmdEncoder, _query, _queryCount, _destBuffer, _destOffset, _destStride, _flags);
    }
}

