1// Copyright 2018 The SwiftShader Authors. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#ifndef VK_COMMAND_BUFFER_HPP_
16#define VK_COMMAND_BUFFER_HPP_
17
18#include "VkConfig.h"
19#include "VkObject.hpp"
20#include "VkDescriptorSet.hpp"
21#include "Device/Color.hpp"
22#include "Device/Context.hpp"
23#include <memory>
24#include <vector>
25
26namespace sw
27{
28 class Context;
29 class Renderer;
30 class TaskEvents;
31}
32
33namespace vk
34{
35
36class Buffer;
37class Event;
38class Framebuffer;
39class Image;
40class Pipeline;
41class PipelineLayout;
42class QueryPool;
43class RenderPass;
44
45class CommandBuffer
46{
47public:
48 static constexpr VkSystemAllocationScope GetAllocationScope() { return VK_SYSTEM_ALLOCATION_SCOPE_OBJECT; }
49
50 CommandBuffer(VkCommandBufferLevel pLevel);
51
52 static inline CommandBuffer* Cast(VkCommandBuffer object)
53 {
54 return reinterpret_cast<CommandBuffer*>(object);
55 }
56
57 void destroy(const VkAllocationCallbacks* pAllocator);
58
59 VkResult begin(VkCommandBufferUsageFlags flags, const VkCommandBufferInheritanceInfo* pInheritanceInfo);
60 VkResult end();
61 VkResult reset(VkCommandPoolResetFlags flags);
62
63 void beginRenderPass(RenderPass* renderPass, Framebuffer* framebuffer, VkRect2D renderArea,
64 uint32_t clearValueCount, const VkClearValue* pClearValues, VkSubpassContents contents);
65 void nextSubpass(VkSubpassContents contents);
66 void endRenderPass();
67 void executeCommands(uint32_t commandBufferCount, const VkCommandBuffer* pCommandBuffers);
68
69 void setDeviceMask(uint32_t deviceMask);
70 void dispatchBase(uint32_t baseGroupX, uint32_t baseGroupY, uint32_t baseGroupZ,
71 uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ);
72
73 void pipelineBarrier(VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags,
74 uint32_t memoryBarrierCount, const VkMemoryBarrier* pMemoryBarriers,
75 uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier* pBufferMemoryBarriers,
76 uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier* pImageMemoryBarriers);
77 void bindPipeline(VkPipelineBindPoint pipelineBindPoint, Pipeline* pipeline);
78 void bindVertexBuffers(uint32_t firstBinding, uint32_t bindingCount,
79 const VkBuffer* pBuffers, const VkDeviceSize* pOffsets);
80
81 void beginQuery(QueryPool* queryPool, uint32_t query, VkQueryControlFlags flags);
82 void endQuery(QueryPool* queryPool, uint32_t query);
83 void resetQueryPool(QueryPool* queryPool, uint32_t firstQuery, uint32_t queryCount);
84 void writeTimestamp(VkPipelineStageFlagBits pipelineStage, QueryPool* queryPool, uint32_t query);
85 void copyQueryPoolResults(const QueryPool* queryPool, uint32_t firstQuery, uint32_t queryCount,
86 Buffer* dstBuffer, VkDeviceSize dstOffset, VkDeviceSize stride, VkQueryResultFlags flags);
87 void pushConstants(PipelineLayout* layout, VkShaderStageFlags stageFlags,
88 uint32_t offset, uint32_t size, const void* pValues);
89
90 void setViewport(uint32_t firstViewport, uint32_t viewportCount, const VkViewport* pViewports);
91 void setScissor(uint32_t firstScissor, uint32_t scissorCount, const VkRect2D* pScissors);
92 void setLineWidth(float lineWidth);
93 void setDepthBias(float depthBiasConstantFactor, float depthBiasClamp, float depthBiasSlopeFactor);
94 void setBlendConstants(const float blendConstants[4]);
95 void setDepthBounds(float minDepthBounds, float maxDepthBounds);
96 void setStencilCompareMask(VkStencilFaceFlags faceMask, uint32_t compareMask);
97 void setStencilWriteMask(VkStencilFaceFlags faceMask, uint32_t writeMask);
98 void setStencilReference(VkStencilFaceFlags faceMask, uint32_t reference);
99 void bindDescriptorSets(VkPipelineBindPoint pipelineBindPoint, const PipelineLayout* layout,
100 uint32_t firstSet, uint32_t descriptorSetCount, const VkDescriptorSet* pDescriptorSets,
101 uint32_t dynamicOffsetCount, const uint32_t* pDynamicOffsets);
102 void bindIndexBuffer(Buffer* buffer, VkDeviceSize offset, VkIndexType indexType);
103 void dispatch(uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ);
104 void dispatchIndirect(Buffer* buffer, VkDeviceSize offset);
105 void copyBuffer(const Buffer* srcBuffer, Buffer* dstBuffer, uint32_t regionCount, const VkBufferCopy* pRegions);
106 void copyImage(const Image* srcImage, VkImageLayout srcImageLayout, Image* dstImage, VkImageLayout dstImageLayout,
107 uint32_t regionCount, const VkImageCopy* pRegions);
108 void blitImage(const Image* srcImage, VkImageLayout srcImageLayout, Image* dstImage, VkImageLayout dstImageLayout,
109 uint32_t regionCount, const VkImageBlit* pRegions, VkFilter filter);
110 void copyBufferToImage(Buffer* srcBuffer, Image* dstImage, VkImageLayout dstImageLayout,
111 uint32_t regionCount, const VkBufferImageCopy* pRegions);
112 void copyImageToBuffer(Image* srcImage, VkImageLayout srcImageLayout, Buffer* dstBuffer,
113 uint32_t regionCount, const VkBufferImageCopy* pRegions);
114 void updateBuffer(Buffer* dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const void* pData);
115 void fillBuffer(Buffer* dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data);
116 void clearColorImage(Image* image, VkImageLayout imageLayout, const VkClearColorValue* pColor,
117 uint32_t rangeCount, const VkImageSubresourceRange* pRanges);
118 void clearDepthStencilImage(Image* image, VkImageLayout imageLayout, const VkClearDepthStencilValue* pDepthStencil,
119 uint32_t rangeCount, const VkImageSubresourceRange* pRanges);
120 void clearAttachments(uint32_t attachmentCount, const VkClearAttachment* pAttachments,
121 uint32_t rectCount, const VkClearRect* pRects);
122 void resolveImage(const Image* srcImage, VkImageLayout srcImageLayout, Image* dstImage, VkImageLayout dstImageLayout,
123 uint32_t regionCount, const VkImageResolve* pRegions);
124 void setEvent(Event* event, VkPipelineStageFlags stageMask);
125 void resetEvent(Event* event, VkPipelineStageFlags stageMask);
126 void waitEvents(uint32_t eventCount, const VkEvent* pEvents, VkPipelineStageFlags srcStageMask,
127 VkPipelineStageFlags dstStageMask, uint32_t memoryBarrierCount, const VkMemoryBarrier* pMemoryBarriers,
128 uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier* pBufferMemoryBarriers,
129 uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier* pImageMemoryBarriers);
130
131 void draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance);
132 void drawIndexed(uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance);
133 void drawIndirect(Buffer* buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride);
134 void drawIndexedIndirect(Buffer* buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride);
135
136 // TODO(sugoi): Move ExecutionState out of CommandBuffer (possibly into Device)
137 struct ExecutionState
138 {
139 struct PipelineState
140 {
141 Pipeline *pipeline = nullptr;
142 vk::DescriptorSet::Bindings descriptorSets = {};
143 vk::DescriptorSet::DynamicOffsets descriptorDynamicOffsets = {};
144 };
145
146 sw::Renderer* renderer = nullptr;
147 sw::TaskEvents* events = nullptr;
148 RenderPass* renderPass = nullptr;
149 Framebuffer* renderPassFramebuffer = nullptr;
150 std::array<PipelineState, VK_PIPELINE_BIND_POINT_RANGE_SIZE> pipelineState;
151
152 struct DynamicState
153 {
154 VkViewport viewport;
155 VkRect2D scissor;
156 sw::Color<float> blendConstants;
157 float depthBiasConstantFactor = 0.0f;
158 float depthBiasClamp = 0.0f;
159 float depthBiasSlopeFactor = 0.0f;
160 float minDepthBounds = 0.0f;
161 float maxDepthBounds = 0.0f;
162
163 uint32_t compareMask[2] = { 0 };
164 uint32_t writeMask[2] = { 0 };
165 uint32_t reference[2] = { 0 };
166 };
167 DynamicState dynamicState;
168
169 sw::PushConstantStorage pushConstants;
170
171 struct VertexInputBinding
172 {
173 Buffer* buffer;
174 VkDeviceSize offset;
175 };
176 VertexInputBinding vertexInputBindings[MAX_VERTEX_INPUT_BINDINGS] = {};
177 VertexInputBinding indexBufferBinding;
178 VkIndexType indexType;
179
180 uint32_t subpassIndex = 0;
181
182 void bindAttachments(sw::Context& context);
183 void bindVertexInputs(sw::Context& context, int firstInstance);
184 };
185
186 void submit(CommandBuffer::ExecutionState& executionState);
187 void submitSecondary(CommandBuffer::ExecutionState& executionState) const;
188
189 class Command;
190private:
191 void resetState();
192 template<typename T, typename... Args> void addCommand(Args&&... args);
193
194 enum State { INITIAL, RECORDING, EXECUTABLE, PENDING, INVALID };
195 State state = INITIAL;
196 VkCommandBufferLevel level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
197
198 // FIXME (b/119409619): replace this vector by an allocator so we can control all memory allocations
199 std::vector<std::unique_ptr<Command>>* commands;
200};
201
202using DispatchableCommandBuffer = DispatchableObject<CommandBuffer, VkCommandBuffer>;
203
204static inline CommandBuffer* Cast(VkCommandBuffer object)
205{
206 return DispatchableCommandBuffer::Cast(object);
207}
208
209} // namespace vk
210
211#endif // VK_COMMAND_BUFFER_HPP_
212