blob: dbcb386439a5a056daf444df94f0416316f6ccd1 [file] [log] [blame]
// 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 "VkCommandBuffer.hpp"
#include <cstring>
namespace vk
{
class CommandBuffer::Command
{
public:
// FIXME (b/119421344): change the commandBuffer argument to a CommandBuffer state
virtual void play(CommandBuffer* commandBuffer) = 0;
virtual ~Command() {}
};
class BeginRenderPass : public CommandBuffer::Command
{
public:
BeginRenderPass(VkRenderPass pRenderPass, VkFramebuffer pFramebuffer, VkRect2D pRenderArea,
uint32_t pClearValueCount, const VkClearValue* pClearValues) :
renderPass(pRenderPass), framebuffer(pFramebuffer), renderArea(pRenderArea),
clearValueCount(pClearValueCount)
{
// FIXME (b/119409619): use an allocator here so we can control all memory allocations
clearValues = new VkClearValue[clearValueCount];
memcpy(clearValues, pClearValues, clearValueCount * sizeof(VkClearValue));
}
~BeginRenderPass() override
{
delete clearValues;
}
protected:
void play(CommandBuffer* commandBuffer)
{
UNIMPLEMENTED();
}
private:
VkRenderPass renderPass;
VkFramebuffer framebuffer;
VkRect2D renderArea;
uint32_t clearValueCount;
VkClearValue* clearValues;
};
class EndRenderPass : public CommandBuffer::Command
{
public:
EndRenderPass()
{
}
protected:
void play(CommandBuffer* commandBuffer)
{
UNIMPLEMENTED();
}
private:
};
class PipelineBind : public CommandBuffer::Command
{
public:
PipelineBind(VkPipelineBindPoint pPipelineBindPoint, VkPipeline pPipeline) :
pipelineBindPoint(pPipelineBindPoint), pipeline(pPipeline)
{
}
protected:
void play(CommandBuffer* commandBuffer)
{
UNIMPLEMENTED();
}
private:
VkPipelineBindPoint pipelineBindPoint;
VkPipeline pipeline;
};
struct VertexBufferBind : public CommandBuffer::Command
{
VertexBufferBind(uint32_t pBinding, const VkBuffer pBuffer, const VkDeviceSize pOffset) :
binding(pBinding), buffer(pBuffer), offset(pOffset)
{
}
void play(CommandBuffer* commandBuffer)
{
UNIMPLEMENTED();
}
uint32_t binding;
const VkBuffer buffer;
const VkDeviceSize offset;
};
struct Draw : public CommandBuffer::Command
{
Draw(uint32_t pVertexCount) : vertexCount(pVertexCount)
{
}
void play(CommandBuffer* commandBuffer)
{
UNIMPLEMENTED();
}
uint32_t vertexCount;
};
struct ImageToBufferCopy : public CommandBuffer::Command
{
ImageToBufferCopy(VkImage pSrcImage, VkBuffer pDstBuffer, const VkBufferImageCopy& pRegion) :
srcImage(pSrcImage), dstBuffer(pDstBuffer), region(pRegion)
{
}
void play(CommandBuffer* commandBuffer)
{
UNIMPLEMENTED();
}
private:
VkImage srcImage;
VkBuffer dstBuffer;
const VkBufferImageCopy region;
};
CommandBuffer::CommandBuffer(VkCommandBufferLevel pLevel) : level(pLevel)
{
// FIXME (b/119409619): replace this vector by an allocator so we can control all memory allocations
commands = new std::vector<std::unique_ptr<Command> >();
pipelines[VK_PIPELINE_BIND_POINT_GRAPHICS] = VK_NULL_HANDLE;
pipelines[VK_PIPELINE_BIND_POINT_COMPUTE] = VK_NULL_HANDLE;
}
void CommandBuffer::destroy(const VkAllocationCallbacks* pAllocator)
{
deleteCommands();
}
void CommandBuffer::deleteCommands()
{
// FIXME (b/119409619): replace this vector by an allocator so we can control all memory allocations
delete commands;
}
VkResult CommandBuffer::begin(VkCommandBufferUsageFlags flags, const VkCommandBufferInheritanceInfo* pInheritanceInfo)
{
ASSERT((state != RECORDING) && (state != PENDING));
if((flags != VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT) || pInheritanceInfo)
{
UNIMPLEMENTED();
}
state = RECORDING;
return VK_SUCCESS;
}
VkResult CommandBuffer::end()
{
ASSERT(state == RECORDING);
state = EXECUTABLE;
return VK_SUCCESS;
}
VkResult CommandBuffer::reset(VkCommandPoolResetFlags flags)
{
ASSERT(state != PENDING);
deleteCommands();
state = INITIAL;
return VK_SUCCESS;
}
void CommandBuffer::beginRenderPass(VkRenderPass renderPass, VkFramebuffer framebuffer, VkRect2D renderArea,
uint32_t clearValueCount, const VkClearValue* clearValues, VkSubpassContents contents)
{
ASSERT(state == RECORDING);
if(contents != VK_SUBPASS_CONTENTS_INLINE)
{
UNIMPLEMENTED();
}
commands->push_back(std::make_unique<BeginRenderPass>(renderPass, framebuffer, renderArea, clearValueCount, clearValues));
}
void CommandBuffer::nextSubpass(VkSubpassContents contents)
{
UNIMPLEMENTED();
}
void CommandBuffer::endRenderPass()
{
commands->push_back(std::make_unique<EndRenderPass>());
}
void CommandBuffer::executeCommands(uint32_t commandBufferCount, const VkCommandBuffer* pCommandBuffers)
{
UNIMPLEMENTED();
}
void CommandBuffer::setDeviceMask(uint32_t deviceMask)
{
UNIMPLEMENTED();
}
void CommandBuffer::dispatchBase(uint32_t baseGroupX, uint32_t baseGroupY, uint32_t baseGroupZ,
uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ)
{
UNIMPLEMENTED();
}
void CommandBuffer::pipelineBarrier(VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask,
VkDependencyFlags dependencyFlags,
uint32_t memoryBarrierCount, const VkMemoryBarrier* pMemoryBarriers,
uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier* pBufferMemoryBarriers,
uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier* pImageMemoryBarriers)
{
UNIMPLEMENTED();
}
void CommandBuffer::bindPipeline(VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline)
{
if(pipelineBindPoint != VK_PIPELINE_BIND_POINT_GRAPHICS)
{
UNIMPLEMENTED();
}
commands->push_back(std::make_unique<PipelineBind>(pipelineBindPoint, pipeline));
}
void CommandBuffer::bindVertexBuffers(uint32_t firstBinding, uint32_t bindingCount,
const VkBuffer* pBuffers, const VkDeviceSize* pOffsets)
{
for(uint32_t i = firstBinding; i < (firstBinding + bindingCount); ++i)
{
commands->push_back(std::make_unique<VertexBufferBind>(i, pBuffers[i], pOffsets[i]));
}
}
void CommandBuffer::beginQuery(VkQueryPool queryPool, uint32_t query, VkQueryControlFlags flags)
{
UNIMPLEMENTED();
}
void CommandBuffer::endQuery(VkQueryPool queryPool, uint32_t query)
{
UNIMPLEMENTED();
}
void CommandBuffer::resetQueryPool(VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount)
{
UNIMPLEMENTED();
}
void CommandBuffer::writeTimestamp(VkPipelineStageFlagBits pipelineStage, VkQueryPool queryPool, uint32_t query)
{
UNIMPLEMENTED();
}
void CommandBuffer::copyQueryPoolResults(VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount,
VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize stride, VkQueryResultFlags flags)
{
UNIMPLEMENTED();
}
void CommandBuffer::pushConstants(VkPipelineLayout layout, VkShaderStageFlags stageFlags,
uint32_t offset, uint32_t size, const void* pValues)
{
UNIMPLEMENTED();
}
void CommandBuffer::setViewport(uint32_t firstViewport, uint32_t viewportCount, const VkViewport* pViewports)
{
// Note: The bound graphics pipeline must have been created with the VK_DYNAMIC_STATE_VIEWPORT dynamic state enabled
UNIMPLEMENTED();
}
void CommandBuffer::setScissor(uint32_t firstScissor, uint32_t scissorCount, const VkRect2D* pScissors)
{
// Note: The bound graphics pipeline must have been created with the VK_DYNAMIC_STATE_SCISSOR dynamic state enabled
UNIMPLEMENTED();
}
void CommandBuffer::setLineWidth(float lineWidth)
{
// Note: The bound graphics pipeline must have been created with the VK_DYNAMIC_STATE_LINE_WIDTH dynamic state enabled
// If the wide lines feature is not enabled, lineWidth must be 1.0
ASSERT(lineWidth == 1.0f);
UNIMPLEMENTED();
}
void CommandBuffer::setDepthBias(float depthBiasConstantFactor, float depthBiasClamp, float depthBiasSlopeFactor)
{
// Note: The bound graphics pipeline must have been created with the VK_DYNAMIC_STATE_DEPTH_BIAS dynamic state enabled
// If the depth bias clamping feature is not enabled, depthBiasClamp must be 0.0
ASSERT(depthBiasClamp == 0.0f);
UNIMPLEMENTED();
}
void CommandBuffer::setBlendConstants(const float blendConstants[4])
{
// Note: The bound graphics pipeline must have been created with the VK_DYNAMIC_STATE_BLEND_CONSTANTS dynamic state enabled
// blendConstants is an array of four values specifying the R, G, B, and A components
// of the blend constant color used in blending, depending on the blend factor.
UNIMPLEMENTED();
}
void CommandBuffer::setDepthBounds(float minDepthBounds, float maxDepthBounds)
{
// Note: The bound graphics pipeline must have been created with the VK_DYNAMIC_STATE_DEPTH_BOUNDS dynamic state enabled
// Unless the VK_EXT_depth_range_unrestricted extension is enabled minDepthBounds and maxDepthBounds must be between 0.0 and 1.0, inclusive
ASSERT(minDepthBounds >= 0.0f && minDepthBounds <= 1.0f);
ASSERT(maxDepthBounds >= 0.0f && maxDepthBounds <= 1.0f);
UNIMPLEMENTED();
}
void CommandBuffer::setStencilCompareMask(VkStencilFaceFlags faceMask, uint32_t compareMask)
{
// Note: The bound graphics pipeline must have been created with the VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK dynamic state enabled
// faceMask must not be 0
ASSERT(faceMask != 0);
UNIMPLEMENTED();
}
void CommandBuffer::setStencilWriteMask(VkStencilFaceFlags faceMask, uint32_t writeMask)
{
// Note: The bound graphics pipeline must have been created with the VK_DYNAMIC_STATE_STENCIL_WRITE_MASK dynamic state enabled
// faceMask must not be 0
ASSERT(faceMask != 0);
UNIMPLEMENTED();
}
void CommandBuffer::setStencilReference(VkStencilFaceFlags faceMask, uint32_t reference)
{
// Note: The bound graphics pipeline must have been created with the VK_DYNAMIC_STATE_STENCIL_REFERENCE dynamic state enabled
// faceMask must not be 0
ASSERT(faceMask != 0);
UNIMPLEMENTED();
}
void CommandBuffer::bindDescriptorSets(VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout,
uint32_t firstSet, uint32_t descriptorSetCount, const VkDescriptorSet* pDescriptorSets,
uint32_t dynamicOffsetCount, const uint32_t* pDynamicOffsets)
{
UNIMPLEMENTED();
}
void CommandBuffer::bindIndexBuffer(VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType)
{
UNIMPLEMENTED();
}
void CommandBuffer::dispatch(uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ)
{
UNIMPLEMENTED();
}
void CommandBuffer::dispatchIndirect(VkBuffer buffer, VkDeviceSize offset)
{
UNIMPLEMENTED();
}
void CommandBuffer::copyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferCopy* pRegions)
{
UNIMPLEMENTED();
}
void CommandBuffer::copyImage(VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout,
uint32_t regionCount, const VkImageCopy* pRegions)
{
UNIMPLEMENTED();
}
void CommandBuffer::blitImage(VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout,
uint32_t regionCount, const VkImageBlit* pRegions, VkFilter filter)
{
UNIMPLEMENTED();
}
void CommandBuffer::copyBufferToImage(VkBuffer srcBuffer, VkImage dstImage, VkImageLayout dstImageLayout,
uint32_t regionCount, const VkBufferImageCopy* pRegions)
{
UNIMPLEMENTED();
}
void CommandBuffer::copyImageToBuffer(VkImage srcImage, VkImageLayout srcImageLayout, VkBuffer dstBuffer,
uint32_t regionCount, const VkBufferImageCopy* pRegions)
{
ASSERT(srcImageLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
for(uint32_t i = 0; i < regionCount; i++)
{
commands->push_back(std::make_unique<ImageToBufferCopy>(srcImage, dstBuffer, pRegions[i]));
}
}
void CommandBuffer::updateBuffer(VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const void* pData)
{
UNIMPLEMENTED();
}
void CommandBuffer::fillBuffer(VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data)
{
UNIMPLEMENTED();
}
void CommandBuffer::clearColorImage(VkImage image, VkImageLayout imageLayout, const VkClearColorValue* pColor,
uint32_t rangeCount, const VkImageSubresourceRange* pRanges)
{
UNIMPLEMENTED();
}
void CommandBuffer::clearDepthStencilImage(VkImage image, VkImageLayout imageLayout, const VkClearDepthStencilValue* pDepthStencil,
uint32_t rangeCount, const VkImageSubresourceRange* pRanges)
{
UNIMPLEMENTED();
}
void CommandBuffer::clearAttachments(uint32_t attachmentCount, const VkClearAttachment* pAttachments,
uint32_t rectCount, const VkClearRect* pRects)
{
UNIMPLEMENTED();
}
void CommandBuffer::resolveImage(VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout,
uint32_t regionCount, const VkImageResolve* pRegions)
{
UNIMPLEMENTED();
}
void CommandBuffer::setEvent(VkEvent event, VkPipelineStageFlags stageMask)
{
UNIMPLEMENTED();
}
void CommandBuffer::resetEvent(VkEvent event, VkPipelineStageFlags stageMask)
{
UNIMPLEMENTED();
}
void CommandBuffer::waitEvents(uint32_t eventCount, const VkEvent* pEvents, VkPipelineStageFlags srcStageMask,
VkPipelineStageFlags dstStageMask, uint32_t memoryBarrierCount, const VkMemoryBarrier* pMemoryBarriers,
uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier* pBufferMemoryBarriers,
uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier* pImageMemoryBarriers)
{
UNIMPLEMENTED();
}
void CommandBuffer::draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance)
{
if(instanceCount > 1 || firstVertex != 0 || firstInstance != 0)
{
UNIMPLEMENTED();
}
commands->push_back(std::make_unique<Draw>(vertexCount));
}
void CommandBuffer::drawIndexed(uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance)
{
UNIMPLEMENTED();
}
void CommandBuffer::drawIndirect(VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride)
{
UNIMPLEMENTED();
}
void CommandBuffer::drawIndexedIndirect(VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride)
{
UNIMPLEMENTED();
}
void CommandBuffer::submit()
{
// Perform recorded work
state = PENDING;
for(auto& command : *commands)
{
command->play(this);
}
// After work is completed
state = EXECUTABLE;
}
} // namespace vk