|  | // 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. | 
|  |  | 
|  | #ifndef VK_COMMAND_BUFFER_HPP_ | 
|  | #define VK_COMMAND_BUFFER_HPP_ | 
|  |  | 
|  | #include "VkConfig.hpp" | 
|  | #include "VkDescriptorSet.hpp" | 
|  | #include "VkPipeline.hpp" | 
|  | #include "System/Synchronization.hpp" | 
|  |  | 
|  | #include <memory> | 
|  | #include <vector> | 
|  |  | 
|  | namespace sw { | 
|  |  | 
|  | class Context; | 
|  | class Renderer; | 
|  |  | 
|  | }  // namespace sw | 
|  |  | 
|  | namespace vk { | 
|  |  | 
|  | namespace dbg { | 
|  | class File; | 
|  | }  // namespace dbg | 
|  |  | 
|  | class Device; | 
|  | class Buffer; | 
|  | class Event; | 
|  | class Framebuffer; | 
|  | class Image; | 
|  | class Pipeline; | 
|  | class PipelineLayout; | 
|  | class QueryPool; | 
|  | class RenderPass; | 
|  |  | 
|  | class CommandBuffer | 
|  | { | 
|  | public: | 
|  | static constexpr VkSystemAllocationScope GetAllocationScope() { return VK_SYSTEM_ALLOCATION_SCOPE_OBJECT; } | 
|  |  | 
|  | CommandBuffer(Device *device, VkCommandBufferLevel pLevel); | 
|  |  | 
|  | void destroy(const VkAllocationCallbacks *pAllocator); | 
|  |  | 
|  | VkResult begin(VkCommandBufferUsageFlags flags, const VkCommandBufferInheritanceInfo *pInheritanceInfo); | 
|  | VkResult end(); | 
|  | VkResult reset(VkCommandPoolResetFlags flags); | 
|  |  | 
|  | void beginRenderPass(RenderPass *renderPass, Framebuffer *framebuffer, VkRect2D renderArea, | 
|  | uint32_t clearValueCount, const VkClearValue *pClearValues, VkSubpassContents contents, | 
|  | const VkRenderPassAttachmentBeginInfo *attachmentBeginInfo); | 
|  | void nextSubpass(VkSubpassContents contents); | 
|  | void endRenderPass(); | 
|  | void executeCommands(uint32_t commandBufferCount, const VkCommandBuffer *pCommandBuffers); | 
|  |  | 
|  | void setDeviceMask(uint32_t deviceMask); | 
|  | void dispatchBase(uint32_t baseGroupX, uint32_t baseGroupY, uint32_t baseGroupZ, | 
|  | uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ); | 
|  |  | 
|  | void 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); | 
|  | void bindPipeline(VkPipelineBindPoint pipelineBindPoint, Pipeline *pipeline); | 
|  | void bindVertexBuffers(uint32_t firstBinding, uint32_t bindingCount, | 
|  | const VkBuffer *pBuffers, const VkDeviceSize *pOffsets); | 
|  |  | 
|  | void beginQuery(QueryPool *queryPool, uint32_t query, VkQueryControlFlags flags); | 
|  | void endQuery(QueryPool *queryPool, uint32_t query); | 
|  | void resetQueryPool(QueryPool *queryPool, uint32_t firstQuery, uint32_t queryCount); | 
|  | void writeTimestamp(VkPipelineStageFlagBits pipelineStage, QueryPool *queryPool, uint32_t query); | 
|  | void copyQueryPoolResults(const QueryPool *queryPool, uint32_t firstQuery, uint32_t queryCount, | 
|  | Buffer *dstBuffer, VkDeviceSize dstOffset, VkDeviceSize stride, VkQueryResultFlags flags); | 
|  | void pushConstants(PipelineLayout *layout, VkShaderStageFlags stageFlags, | 
|  | uint32_t offset, uint32_t size, const void *pValues); | 
|  |  | 
|  | void setViewport(uint32_t firstViewport, uint32_t viewportCount, const VkViewport *pViewports); | 
|  | void setScissor(uint32_t firstScissor, uint32_t scissorCount, const VkRect2D *pScissors); | 
|  | void setLineWidth(float lineWidth); | 
|  | void setDepthBias(float depthBiasConstantFactor, float depthBiasClamp, float depthBiasSlopeFactor); | 
|  | void setBlendConstants(const float blendConstants[4]); | 
|  | void setDepthBounds(float minDepthBounds, float maxDepthBounds); | 
|  | void setStencilCompareMask(VkStencilFaceFlags faceMask, uint32_t compareMask); | 
|  | void setStencilWriteMask(VkStencilFaceFlags faceMask, uint32_t writeMask); | 
|  | void setStencilReference(VkStencilFaceFlags faceMask, uint32_t reference); | 
|  | void bindDescriptorSets(VkPipelineBindPoint pipelineBindPoint, const PipelineLayout *layout, | 
|  | uint32_t firstSet, uint32_t descriptorSetCount, const VkDescriptorSet *pDescriptorSets, | 
|  | uint32_t dynamicOffsetCount, const uint32_t *pDynamicOffsets); | 
|  | void bindIndexBuffer(Buffer *buffer, VkDeviceSize offset, VkIndexType indexType); | 
|  | void dispatch(uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ); | 
|  | void dispatchIndirect(Buffer *buffer, VkDeviceSize offset); | 
|  | void copyBuffer(const Buffer *srcBuffer, Buffer *dstBuffer, uint32_t regionCount, const VkBufferCopy *pRegions); | 
|  | void copyImage(const Image *srcImage, VkImageLayout srcImageLayout, Image *dstImage, VkImageLayout dstImageLayout, | 
|  | uint32_t regionCount, const VkImageCopy *pRegions); | 
|  | void blitImage(const Image *srcImage, VkImageLayout srcImageLayout, Image *dstImage, VkImageLayout dstImageLayout, | 
|  | uint32_t regionCount, const VkImageBlit *pRegions, VkFilter filter); | 
|  | void copyBufferToImage(Buffer *srcBuffer, Image *dstImage, VkImageLayout dstImageLayout, | 
|  | uint32_t regionCount, const VkBufferImageCopy *pRegions); | 
|  | void copyImageToBuffer(Image *srcImage, VkImageLayout srcImageLayout, Buffer *dstBuffer, | 
|  | uint32_t regionCount, const VkBufferImageCopy *pRegions); | 
|  | void updateBuffer(Buffer *dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const void *pData); | 
|  | void fillBuffer(Buffer *dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data); | 
|  | void clearColorImage(Image *image, VkImageLayout imageLayout, const VkClearColorValue *pColor, | 
|  | uint32_t rangeCount, const VkImageSubresourceRange *pRanges); | 
|  | void clearDepthStencilImage(Image *image, VkImageLayout imageLayout, const VkClearDepthStencilValue *pDepthStencil, | 
|  | uint32_t rangeCount, const VkImageSubresourceRange *pRanges); | 
|  | void clearAttachments(uint32_t attachmentCount, const VkClearAttachment *pAttachments, | 
|  | uint32_t rectCount, const VkClearRect *pRects); | 
|  | void resolveImage(const Image *srcImage, VkImageLayout srcImageLayout, Image *dstImage, VkImageLayout dstImageLayout, | 
|  | uint32_t regionCount, const VkImageResolve *pRegions); | 
|  | void setEvent(Event *event, VkPipelineStageFlags stageMask); | 
|  | void resetEvent(Event *event, VkPipelineStageFlags stageMask); | 
|  | void 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); | 
|  |  | 
|  | void draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance); | 
|  | void drawIndexed(uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance); | 
|  | void drawIndirect(Buffer *buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride); | 
|  | void drawIndexedIndirect(Buffer *buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride); | 
|  |  | 
|  | void beginDebugUtilsLabel(const VkDebugUtilsLabelEXT *pLabelInfo); | 
|  | void endDebugUtilsLabel(); | 
|  | void insertDebugUtilsLabel(const VkDebugUtilsLabelEXT *pLabelInfo); | 
|  |  | 
|  | // TODO(sugoi): Move ExecutionState out of CommandBuffer (possibly into Device) | 
|  | struct ExecutionState | 
|  | { | 
|  | struct PipelineState | 
|  | { | 
|  | Pipeline *pipeline = nullptr; | 
|  | vk::DescriptorSet::Array descriptorSetObjects = {}; | 
|  | vk::DescriptorSet::Bindings descriptorSets = {}; | 
|  | vk::DescriptorSet::DynamicOffsets descriptorDynamicOffsets = {}; | 
|  | }; | 
|  |  | 
|  | sw::Renderer *renderer = nullptr; | 
|  | sw::CountedEvent *events = nullptr; | 
|  | RenderPass *renderPass = nullptr; | 
|  | Framebuffer *renderPassFramebuffer = nullptr; | 
|  |  | 
|  | // VK_PIPELINE_BIND_POINT_GRAPHICS = 0 | 
|  | // VK_PIPELINE_BIND_POINT_COMPUTE = 1 | 
|  | std::array<PipelineState, 2> pipelineState; | 
|  |  | 
|  | vk::DynamicState dynamicState; | 
|  |  | 
|  | vk::Pipeline::PushConstantStorage pushConstants; | 
|  |  | 
|  | VertexInputBinding vertexInputBindings[MAX_VERTEX_INPUT_BINDINGS] = {}; | 
|  | VertexInputBinding indexBufferBinding; | 
|  | VkIndexType indexType; | 
|  |  | 
|  | uint32_t subpassIndex = 0; | 
|  |  | 
|  | void bindAttachments(Attachments *attachments); | 
|  |  | 
|  | uint32_t viewCount() const; | 
|  | }; | 
|  |  | 
|  | void submit(CommandBuffer::ExecutionState &executionState); | 
|  | void submitSecondary(CommandBuffer::ExecutionState &executionState) const; | 
|  |  | 
|  | class Command | 
|  | { | 
|  | public: | 
|  | virtual void execute(ExecutionState &executionState) = 0; | 
|  | virtual std::string description() = 0; | 
|  | virtual ~Command() {} | 
|  | }; | 
|  |  | 
|  | private: | 
|  | void resetState(); | 
|  | template<typename T, typename... Args> | 
|  | void addCommand(Args &&...args); | 
|  |  | 
|  | enum State | 
|  | { | 
|  | INITIAL, | 
|  | RECORDING, | 
|  | EXECUTABLE, | 
|  | PENDING, | 
|  | INVALID | 
|  | }; | 
|  |  | 
|  | Device *const device; | 
|  | State state = INITIAL; | 
|  | VkCommandBufferLevel level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; | 
|  |  | 
|  | // FIXME (b/119409619): replace this vector by an allocator so we can control all memory allocations | 
|  | std::vector<std::unique_ptr<Command>> commands; | 
|  |  | 
|  | #ifdef ENABLE_VK_DEBUGGER | 
|  | std::shared_ptr<vk::dbg::File> debuggerFile; | 
|  | #endif  // ENABLE_VK_DEBUGGER | 
|  | }; | 
|  |  | 
|  | using DispatchableCommandBuffer = DispatchableObject<CommandBuffer, VkCommandBuffer>; | 
|  |  | 
|  | static inline CommandBuffer *Cast(VkCommandBuffer object) | 
|  | { | 
|  | return DispatchableCommandBuffer::Cast(object); | 
|  | } | 
|  |  | 
|  | }  // namespace vk | 
|  |  | 
|  | #endif  // VK_COMMAND_BUFFER_HPP_ |