blob: 4d46a5b6f6461236b1a7861bfbb829d0c786ad39 [file] [log] [blame]
/*
* MVKCmdRenderPass.mm
*
* 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.
*/
#include "MVKCmdRenderPass.h"
#include "MVKCommandBuffer.h"
#include "MVKCommandPool.h"
#include "MVKRenderPass.h"
#include "MVKPipeline.h"
#include "MVKFoundation.h"
#include "mvk_datatypes.hpp"
#pragma mark -
#pragma mark MVKCmdBeginRenderPass
void MVKCmdBeginRenderPass::setContent(const VkRenderPassBeginInfo* pRenderPassBegin,
VkSubpassContents contents) {
_info = *pRenderPassBegin;
_contents = contents;
_renderPass = (MVKRenderPass*)_info.renderPass;
_framebuffer = (MVKFramebuffer*)_info.framebuffer;
_loadOverride = false;
_storeOverride = false;
// Add clear values
_clearValues.clear(); // Clear for reuse
_clearValues.reserve(_info.clearValueCount);
for (uint32_t i = 0; i < _info.clearValueCount; i++) {
_clearValues.push_back(_info.pClearValues[i]);
}
}
void MVKCmdBeginRenderPass::encode(MVKCommandEncoder* cmdEncoder) {
// MVKLogDebug("Encoding vkCmdBeginRenderPass(). Elapsed time: %.6f ms.", mvkGetElapsedMilliseconds());
cmdEncoder->beginRenderpass(_contents, _renderPass, _framebuffer, _info.renderArea, &_clearValues, _loadOverride, _storeOverride);
}
MVKCmdBeginRenderPass::MVKCmdBeginRenderPass(MVKCommandTypePool<MVKCmdBeginRenderPass>* pool)
: MVKCommand::MVKCommand((MVKCommandTypePool<MVKCommand>*)pool) {}
#pragma mark -
#pragma mark MVKCmdNextSubpass
void MVKCmdNextSubpass::setContent(VkSubpassContents contents) {
_contents = contents;
}
void MVKCmdNextSubpass::encode(MVKCommandEncoder* cmdEncoder) {
cmdEncoder->beginNextSubpass(_contents);
}
MVKCmdNextSubpass::MVKCmdNextSubpass(MVKCommandTypePool<MVKCmdNextSubpass>* pool)
: MVKCommand::MVKCommand((MVKCommandTypePool<MVKCommand>*)pool) {}
#pragma mark -
#pragma mark MVKCmdEndRenderPass
void MVKCmdEndRenderPass::encode(MVKCommandEncoder* cmdEncoder) {
// MVKLogDebug("Encoding vkCmdEndRenderPass(). Elapsed time: %.6f ms.", mvkGetElapsedMilliseconds());
cmdEncoder->endRenderpass();
}
MVKCmdEndRenderPass::MVKCmdEndRenderPass(MVKCommandTypePool<MVKCmdEndRenderPass>* pool)
: MVKCommand::MVKCommand((MVKCommandTypePool<MVKCommand>*)pool) {}
#pragma mark -
#pragma mark MVKCmdExecuteCommands
void MVKCmdExecuteCommands::setContent(uint32_t commandBuffersCount,
const VkCommandBuffer* pCommandBuffers) {
// Add clear values
_secondaryCommandBuffers.clear(); // Clear for reuse
_secondaryCommandBuffers.reserve(commandBuffersCount);
for (uint32_t cbIdx = 0; cbIdx < commandBuffersCount; cbIdx++) {
_secondaryCommandBuffers.push_back(MVKCommandBuffer::getMVKCommandBuffer(pCommandBuffers[cbIdx]));
}
}
void MVKCmdExecuteCommands::encode(MVKCommandEncoder* cmdEncoder) {
for (auto& cb : _secondaryCommandBuffers) { cmdEncoder->encodeSecondary(cb); }
}
MVKCmdExecuteCommands::MVKCmdExecuteCommands(MVKCommandTypePool<MVKCmdExecuteCommands>* pool)
: MVKCommand::MVKCommand((MVKCommandTypePool<MVKCommand>*)pool) {}
#pragma mark -
#pragma mark MVKCmdSetViewport
void MVKCmdSetViewport::setContent(uint32_t firstViewport, uint32_t viewportCount, const VkViewport* pViewports) {
_firstViewport = firstViewport;
_mtlViewports.clear(); // Clear for reuse
_mtlViewports.reserve(viewportCount);
for (uint32_t i = 0; i < viewportCount; i++) {
_mtlViewports.push_back(mvkMTLViewportFromVkViewport(pViewports[i]));
}
}
void MVKCmdSetViewport::encode(MVKCommandEncoder* cmdEncoder) {
cmdEncoder->_viewportState.setViewports(_mtlViewports, _firstViewport, true);
}
MVKCmdSetViewport::MVKCmdSetViewport(MVKCommandTypePool<MVKCmdSetViewport>* pool)
: MVKCommand::MVKCommand((MVKCommandTypePool<MVKCommand>*)pool) {}
#pragma mark -
#pragma mark MVKCmdSetScissor
void MVKCmdSetScissor::setContent(uint32_t firstScissor, uint32_t scissorCount, const VkRect2D* pScissors) {
_firstScissor = firstScissor;
_mtlScissors.clear(); // Clear for reuse
_mtlScissors.reserve(scissorCount);
for (uint32_t i = 0; i < scissorCount; i++) {
_mtlScissors.push_back(mvkMTLScissorRectFromVkRect2D(pScissors[i]));
}
}
void MVKCmdSetScissor::encode(MVKCommandEncoder* cmdEncoder) {
cmdEncoder->_scissorState.setScissors(_mtlScissors, _firstScissor, true);
}
MVKCmdSetScissor::MVKCmdSetScissor(MVKCommandTypePool<MVKCmdSetScissor>* pool)
: MVKCommand::MVKCommand((MVKCommandTypePool<MVKCommand>*)pool) {}
#pragma mark -
#pragma mark MVKCmdSetLineWidth
void MVKCmdSetLineWidth::setContent(float lineWidth) {
_lineWidth = lineWidth;
// Validate
if (_lineWidth != 1.0 || getDevice()->_enabledFeatures.wideLines) {
setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCmdSetLineWidth(): The current device does not support wide lines."));
}
}
void MVKCmdSetLineWidth::encode(MVKCommandEncoder* cmdEncoder) {}
MVKCmdSetLineWidth::MVKCmdSetLineWidth(MVKCommandTypePool<MVKCmdSetLineWidth>* pool)
: MVKCommand::MVKCommand((MVKCommandTypePool<MVKCommand>*)pool) {}
#pragma mark -
#pragma mark MVKCmdSetDepthBias
void MVKCmdSetDepthBias::setContent(float depthBiasConstantFactor,
float depthBiasSlopeFactor,
float depthBiasClamp) {
_depthBiasConstantFactor = depthBiasConstantFactor;
_depthBiasSlopeFactor = depthBiasSlopeFactor;
_depthBiasClamp = depthBiasClamp;
}
void MVKCmdSetDepthBias::encode(MVKCommandEncoder* cmdEncoder) {
cmdEncoder->_depthBiasState.setDepthBias(_depthBiasConstantFactor,
_depthBiasSlopeFactor,
_depthBiasClamp);
}
MVKCmdSetDepthBias::MVKCmdSetDepthBias(MVKCommandTypePool<MVKCmdSetDepthBias>* pool)
: MVKCommand::MVKCommand((MVKCommandTypePool<MVKCommand>*)pool) {}
#pragma mark -
#pragma mark MVKCmdSetBlendConstants
void MVKCmdSetBlendConstants::setContent(const float blendConst[4]) {
_red = blendConst[0];
_green = blendConst[1];
_blue = blendConst[2];
_alpha = blendConst[3];
}
void MVKCmdSetBlendConstants::encode(MVKCommandEncoder* cmdEncoder) {
cmdEncoder->_blendColorState.setBlendColor(_red, _green, _blue, _alpha, true);
}
MVKCmdSetBlendConstants::MVKCmdSetBlendConstants(MVKCommandTypePool<MVKCmdSetBlendConstants>* pool)
: MVKCommand::MVKCommand((MVKCommandTypePool<MVKCommand>*)pool) {}
#pragma mark -
#pragma mark MVKCmdSetDepthBounds
void MVKCmdSetDepthBounds::setContent(float minDepthBounds, float maxDepthBounds) {
_minDepthBounds = minDepthBounds;
_maxDepthBounds = maxDepthBounds;
// Validate
if (getDevice()->_enabledFeatures.depthBounds) {
setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCmdSetDepthBounds(): The current device does not support setting depth bounds."));
}
}
void MVKCmdSetDepthBounds::encode(MVKCommandEncoder* cmdEncoder) {}
MVKCmdSetDepthBounds::MVKCmdSetDepthBounds(MVKCommandTypePool<MVKCmdSetDepthBounds>* pool)
: MVKCommand::MVKCommand((MVKCommandTypePool<MVKCommand>*)pool) {}
#pragma mark -
#pragma mark MVKCmdSetStencilCompareMask
void MVKCmdSetStencilCompareMask::setContent(VkStencilFaceFlags faceMask,
uint32_t stencilCompareMask) {
_faceMask = faceMask;
_stencilCompareMask = stencilCompareMask;
}
void MVKCmdSetStencilCompareMask::encode(MVKCommandEncoder* cmdEncoder) {
cmdEncoder->_depthStencilState.setStencilCompareMask(_faceMask, _stencilCompareMask);
}
MVKCmdSetStencilCompareMask::MVKCmdSetStencilCompareMask(MVKCommandTypePool<MVKCmdSetStencilCompareMask>* pool)
: MVKCommand::MVKCommand((MVKCommandTypePool<MVKCommand>*)pool) {}
#pragma mark -
#pragma mark MVKCmdSetStencilWriteMask
void MVKCmdSetStencilWriteMask::setContent(VkStencilFaceFlags faceMask,
uint32_t stencilWriteMask) {
_faceMask = faceMask;
_stencilWriteMask = stencilWriteMask;
}
void MVKCmdSetStencilWriteMask::encode(MVKCommandEncoder* cmdEncoder) {
cmdEncoder->_depthStencilState.setStencilWriteMask(_faceMask, _stencilWriteMask);
}
MVKCmdSetStencilWriteMask::MVKCmdSetStencilWriteMask(MVKCommandTypePool<MVKCmdSetStencilWriteMask>* pool)
: MVKCommand::MVKCommand((MVKCommandTypePool<MVKCommand>*)pool) {}
#pragma mark -
#pragma mark MVKCmdSetStencilReference
void MVKCmdSetStencilReference::setContent(VkStencilFaceFlags faceMask,
uint32_t stencilReference) {
_faceMask = faceMask;
_stencilReference = stencilReference;
}
void MVKCmdSetStencilReference::encode(MVKCommandEncoder* cmdEncoder) {
cmdEncoder->_stencilReferenceValueState.setReferenceValues(_faceMask, _stencilReference);
}
MVKCmdSetStencilReference::MVKCmdSetStencilReference(MVKCommandTypePool<MVKCmdSetStencilReference>* pool)
: MVKCommand::MVKCommand((MVKCommandTypePool<MVKCommand>*)pool) {}
#pragma mark -
#pragma mark Command creation functions
void mvkCmdBeginRenderPass(MVKCommandBuffer* cmdBuff,
const VkRenderPassBeginInfo* pRenderPassBegin,
VkSubpassContents contents) {
MVKCmdBeginRenderPass* cmd = cmdBuff->_commandPool->_cmdBeginRenderPassPool.acquireObject();
cmd->setContent(pRenderPassBegin, contents);
cmdBuff->recordBeginRenderPass(cmd);
cmdBuff->addCommand(cmd);
}
void mvkCmdNextSubpass(MVKCommandBuffer* cmdBuff, VkSubpassContents contents) {
MVKCmdNextSubpass* cmd = cmdBuff->_commandPool->_cmdNextSubpassPool.acquireObject();
cmd->setContent(contents);
cmdBuff->addCommand(cmd);
}
void mvkCmdEndRenderPass(MVKCommandBuffer* cmdBuff) {
MVKCmdEndRenderPass* cmd = cmdBuff->_commandPool->_cmdEndRenderPassPool.acquireObject();
cmdBuff->recordEndRenderPass(cmd);
cmdBuff->addCommand(cmd);
}
void mvkCmdExecuteCommands(MVKCommandBuffer* cmdBuff,
uint32_t commandBuffersCount,
const VkCommandBuffer* pCommandBuffers) {
MVKCmdExecuteCommands* cmd = cmdBuff->_commandPool->_cmdExecuteCommandsPool.acquireObject();
cmd->setContent(commandBuffersCount, pCommandBuffers);
cmdBuff->addCommand(cmd);
}
void mvkCmdSetViewport(MVKCommandBuffer* cmdBuff,
uint32_t firstViewport,
uint32_t viewportCount,
const VkViewport* pViewports) {
if (viewportCount == 0 || firstViewport > 0) { return; } // Nothing to set
MVKCmdSetViewport* cmd = cmdBuff->_commandPool->_cmdSetViewportPool.acquireObject();
cmd->setContent(firstViewport, viewportCount, pViewports);
cmdBuff->addCommand(cmd);
}
void mvkCmdSetScissor(MVKCommandBuffer* cmdBuff,
uint32_t firstScissor,
uint32_t scissorCount,
const VkRect2D* pScissors) {
if (scissorCount == 0) { return; } // Nothing to set
MVKCmdSetScissor* cmd = cmdBuff->_commandPool->_cmdSetScissorPool.acquireObject();
cmd->setContent(firstScissor, scissorCount, pScissors);
cmdBuff->addCommand(cmd);
}
void mvkCmdSetLineWidth(MVKCommandBuffer* cmdBuff, float lineWidth) {
MVKCmdSetLineWidth* cmd = cmdBuff->_commandPool->_cmdSetLineWidthPool.acquireObject();
cmd->setContent(lineWidth);
cmdBuff->addCommand(cmd);
}
void mvkCmdSetDepthBias(MVKCommandBuffer* cmdBuff,
float depthBiasConstantFactor,
float depthBiasClamp,
float depthBiasSlopeFactor) {
MVKCmdSetDepthBias* cmd = cmdBuff->_commandPool->_cmdSetDepthBiasPool.acquireObject();
cmd->setContent(depthBiasConstantFactor, depthBiasSlopeFactor, depthBiasClamp);
cmdBuff->addCommand(cmd);
}
void mvkCmdSetBlendConstants(MVKCommandBuffer* cmdBuff,
const float blendConst[4]) {
MVKCmdSetBlendConstants* cmd = cmdBuff->_commandPool->_cmdSetBlendConstantsPool.acquireObject();
cmd->setContent(blendConst);
cmdBuff->addCommand(cmd);
}
void mvkCmdSetDepthBounds(MVKCommandBuffer* cmdBuff,
float minDepthBounds,
float maxDepthBounds) {
MVKCmdSetDepthBounds* cmd = cmdBuff->_commandPool->_cmdSetDepthBoundsPool.acquireObject();
cmd->setContent(minDepthBounds, maxDepthBounds);
cmdBuff->addCommand(cmd);
}
void mvkCmdSetStencilCompareMask(MVKCommandBuffer* cmdBuff,
VkStencilFaceFlags faceMask,
uint32_t stencilCompareMask) {
MVKCmdSetStencilCompareMask* cmd = cmdBuff->_commandPool->_cmdSetStencilCompareMaskPool.acquireObject();
cmd->setContent(faceMask, stencilCompareMask);
cmdBuff->addCommand(cmd);
}
void mvkCmdSetStencilWriteMask(MVKCommandBuffer* cmdBuff,
VkStencilFaceFlags faceMask,
uint32_t stencilWriteMask) {
MVKCmdSetStencilWriteMask* cmd = cmdBuff->_commandPool->_cmdSetStencilWriteMaskPool.acquireObject();
cmd->setContent(faceMask, stencilWriteMask);
cmdBuff->addCommand(cmd);
}
void mvkCmdSetStencilReference(MVKCommandBuffer* cmdBuff,
VkStencilFaceFlags faceMask,
uint32_t stencilReference) {
MVKCmdSetStencilReference* cmd = cmdBuff->_commandPool->_cmdSetStencilReferencePool.acquireObject();
cmd->setContent(faceMask, stencilReference);
cmdBuff->addCommand(cmd);
}