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.hpp"
19 #include "VkDescriptorSet.hpp"
20 #include "VkPipeline.hpp"
21 #include "System/Synchronization.hpp"
22
23 #include <memory>
24 #include <vector>
25
26 namespace sw {
27
28 class Context;
29 class Renderer;
30
31 } // namespace sw
32
33 namespace vk {
34
35 class Device;
36 class Buffer;
37 class Event;
38 class Framebuffer;
39 class Image;
40 class Pipeline;
41 class PipelineLayout;
42 class QueryPool;
43 class RenderPass;
44
45 struct DynamicRendering
46 {
47 DynamicRendering(const VkRenderingInfo *pRenderingInfo);
48
49 void getAttachments(Attachments *attachments) const;
getRenderAreavk::DynamicRendering50 VkRect2D getRenderArea() const { return renderArea; }
getLayerCountvk::DynamicRendering51 uint32_t getLayerCount() const { return layerCount; }
getViewMaskvk::DynamicRendering52 uint32_t getViewMask() const { return viewMask; }
getColorAttachmentCountvk::DynamicRendering53 uint32_t getColorAttachmentCount() const { return colorAttachmentCount; }
getColorAttachmentvk::DynamicRendering54 const VkRenderingAttachmentInfo *getColorAttachment(uint32_t i) const
55 {
56 return (i < colorAttachmentCount) ? &(colorAttachments[i]) : nullptr;
57 }
getDepthAttachmentvk::DynamicRendering58 const VkRenderingAttachmentInfo &getDepthAttachment() const
59 {
60 return depthAttachment;
61 }
getStencilAttachmentvk::DynamicRendering62 const VkRenderingAttachmentInfo &getStencilAttachment() const
63 {
64 return stencilAttachment;
65 }
suspendvk::DynamicRendering66 bool suspend() const { return flags & VK_RENDERING_SUSPENDING_BIT; }
resumevk::DynamicRendering67 bool resume() const { return flags & VK_RENDERING_RESUMING_BIT; }
68
69 private:
70 VkRect2D renderArea = {};
71 uint32_t layerCount = 0;
72 uint32_t viewMask = 0;
73 uint32_t colorAttachmentCount = 0;
74 VkRenderingAttachmentInfo colorAttachments[sw::MAX_COLOR_BUFFERS] = { {} };
75 bool hasDepthAttachment = false;
76 VkRenderingAttachmentInfo depthAttachment = {};
77 bool hasStencilAttachment = false;
78 VkRenderingAttachmentInfo stencilAttachment = {};
79 VkRenderingFlags flags = VkRenderingFlags(0);
80 };
81
82 class CommandBuffer
83 {
84 public:
GetAllocationScope()85 static constexpr VkSystemAllocationScope GetAllocationScope() { return VK_SYSTEM_ALLOCATION_SCOPE_OBJECT; }
86
87 CommandBuffer(Device *device, VkCommandBufferLevel pLevel);
88
89 void destroy(const VkAllocationCallbacks *pAllocator);
90
91 VkResult begin(VkCommandBufferUsageFlags flags, const VkCommandBufferInheritanceInfo *pInheritanceInfo);
92 VkResult end();
93 VkResult reset(VkCommandPoolResetFlags flags);
94
95 void beginRenderPass(RenderPass *renderPass, Framebuffer *framebuffer, VkRect2D renderArea,
96 uint32_t clearValueCount, const VkClearValue *pClearValues, VkSubpassContents contents,
97 const VkRenderPassAttachmentBeginInfo *attachmentBeginInfo);
98 void nextSubpass(VkSubpassContents contents);
99 void endRenderPass();
100 void executeCommands(uint32_t commandBufferCount, const VkCommandBuffer *pCommandBuffers);
101 void beginRendering(const VkRenderingInfo *pRenderingInfo);
102 void endRendering();
103
104 void setDeviceMask(uint32_t deviceMask);
105 void dispatchBase(uint32_t baseGroupX, uint32_t baseGroupY, uint32_t baseGroupZ,
106 uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ);
107
108 void pipelineBarrier(const VkDependencyInfo &pDependencyInfo);
109 void bindPipeline(VkPipelineBindPoint pipelineBindPoint, Pipeline *pipeline);
110 void bindVertexBuffers(uint32_t firstBinding, uint32_t bindingCount,
111 const VkBuffer *pBuffers, const VkDeviceSize *pOffsets,
112 const VkDeviceSize *pSizes, const VkDeviceSize *pStrides);
113
114 void beginQuery(QueryPool *queryPool, uint32_t query, VkQueryControlFlags flags);
115 void endQuery(QueryPool *queryPool, uint32_t query);
116 void resetQueryPool(QueryPool *queryPool, uint32_t firstQuery, uint32_t queryCount);
117 void writeTimestamp(VkPipelineStageFlags2 pipelineStage, QueryPool *queryPool, uint32_t query);
118 void copyQueryPoolResults(const QueryPool *queryPool, uint32_t firstQuery, uint32_t queryCount,
119 Buffer *dstBuffer, VkDeviceSize dstOffset, VkDeviceSize stride, VkQueryResultFlags flags);
120 void pushConstants(PipelineLayout *layout, VkShaderStageFlags stageFlags,
121 uint32_t offset, uint32_t size, const void *pValues);
122
123 void setViewport(uint32_t firstViewport, uint32_t viewportCount, const VkViewport *pViewports);
124 void setScissor(uint32_t firstScissor, uint32_t scissorCount, const VkRect2D *pScissors);
125 void setLineWidth(float lineWidth);
126 void setDepthBias(float depthBiasConstantFactor, float depthBiasClamp, float depthBiasSlopeFactor);
127 void setBlendConstants(const float blendConstants[4]);
128 void setDepthBounds(float minDepthBounds, float maxDepthBounds);
129 void setStencilCompareMask(VkStencilFaceFlags faceMask, uint32_t compareMask);
130 void setStencilWriteMask(VkStencilFaceFlags faceMask, uint32_t writeMask);
131 void setStencilReference(VkStencilFaceFlags faceMask, uint32_t reference);
132 void setCullMode(VkCullModeFlags cullMode);
133 void setDepthBoundsTestEnable(VkBool32 depthBoundsTestEnable);
134 void setDepthCompareOp(VkCompareOp depthCompareOp);
135 void setDepthTestEnable(VkBool32 depthTestEnable);
136 void setDepthWriteEnable(VkBool32 depthWriteEnable);
137 void setFrontFace(VkFrontFace frontFace);
138 void setPrimitiveTopology(VkPrimitiveTopology primitiveTopology);
139 void setScissorWithCount(uint32_t scissorCount, const VkRect2D *pScissors);
140 void setStencilOp(VkStencilFaceFlags faceMask, VkStencilOp failOp, VkStencilOp passOp, VkStencilOp depthFailOp, VkCompareOp compareOp);
141 void setStencilTestEnable(VkBool32 stencilTestEnable);
142 void setViewportWithCount(uint32_t viewportCount, const VkViewport *pViewports);
143 void setRasterizerDiscardEnable(VkBool32 rasterizerDiscardEnable);
144 void setDepthBiasEnable(VkBool32 depthBiasEnable);
145 void setPrimitiveRestartEnable(VkBool32 primitiveRestartEnable);
146 void setVertexInput(uint32_t vertexBindingDescriptionCount,
147 const VkVertexInputBindingDescription2EXT* pVertexBindingDescriptions,
148 uint32_t vertexAttributeDescriptionCount,
149 const VkVertexInputAttributeDescription2EXT* pVertexAttributeDescriptions);
150 void bindDescriptorSets(VkPipelineBindPoint pipelineBindPoint, const PipelineLayout *layout,
151 uint32_t firstSet, uint32_t descriptorSetCount, const VkDescriptorSet *pDescriptorSets,
152 uint32_t dynamicOffsetCount, const uint32_t *pDynamicOffsets);
153 void bindIndexBuffer(Buffer *buffer, VkDeviceSize offset, VkIndexType indexType);
154 void dispatch(uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ);
155 void dispatchIndirect(Buffer *buffer, VkDeviceSize offset);
156 void copyBuffer(const VkCopyBufferInfo2 ©BufferInfo);
157 void copyImage(const VkCopyImageInfo2 ©ImageInfo);
158 void blitImage(const VkBlitImageInfo2 &blitImageInfo);
159 void copyBufferToImage(const VkCopyBufferToImageInfo2 ©BufferToImageInfo);
160 void copyImageToBuffer(const VkCopyImageToBufferInfo2 ©ImageToBufferInfo);
161 void updateBuffer(Buffer *dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const void *pData);
162 void fillBuffer(Buffer *dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data);
163 void clearColorImage(Image *image, VkImageLayout imageLayout, const VkClearColorValue *pColor,
164 uint32_t rangeCount, const VkImageSubresourceRange *pRanges);
165 void clearDepthStencilImage(Image *image, VkImageLayout imageLayout, const VkClearDepthStencilValue *pDepthStencil,
166 uint32_t rangeCount, const VkImageSubresourceRange *pRanges);
167 void clearAttachments(uint32_t attachmentCount, const VkClearAttachment *pAttachments,
168 uint32_t rectCount, const VkClearRect *pRects);
169 void resolveImage(const VkResolveImageInfo2 &resolveImageInfo);
170 void setEvent(Event *event, const VkDependencyInfo &pDependencyInfo);
171 void resetEvent(Event *event, VkPipelineStageFlags2 stageMask);
172 void waitEvents(uint32_t eventCount, const VkEvent *pEvents, const VkDependencyInfo &pDependencyInfo);
173
174 void draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance);
175 void drawIndexed(uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance);
176 void drawIndirect(Buffer *buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride);
177 void drawIndexedIndirect(Buffer *buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride);
178
179 void beginDebugUtilsLabel(const VkDebugUtilsLabelEXT *pLabelInfo);
180 void endDebugUtilsLabel();
181 void insertDebugUtilsLabel(const VkDebugUtilsLabelEXT *pLabelInfo);
182
183 // TODO(sugoi): Move ExecutionState out of CommandBuffer (possibly into Device)
184 struct ExecutionState
185 {
186 struct PipelineState
187 {
188 Pipeline *pipeline = nullptr;
189 vk::DescriptorSet::Array descriptorSetObjects = {};
190 vk::DescriptorSet::Bindings descriptorSets = {};
191 vk::DescriptorSet::DynamicOffsets descriptorDynamicOffsets = {};
192 };
193
194 sw::Renderer *renderer = nullptr;
195 sw::CountedEvent *events = nullptr;
196 RenderPass *renderPass = nullptr;
197 Framebuffer *renderPassFramebuffer = nullptr;
198 DynamicRendering *dynamicRendering = nullptr;
199
200 // VK_PIPELINE_BIND_POINT_GRAPHICS = 0
201 // VK_PIPELINE_BIND_POINT_COMPUTE = 1
202 std::array<PipelineState, 2> pipelineState;
203
204 vk::DynamicState dynamicState;
205
206 vk::Pipeline::PushConstantStorage pushConstants;
207
208 VertexInputBinding vertexInputBindings[MAX_VERTEX_INPUT_BINDINGS] = {};
209 VertexInputBinding indexBufferBinding;
210 VkIndexType indexType;
211
212 uint32_t subpassIndex = 0;
213
214 void bindAttachments(Attachments *attachments);
215
216 VkRect2D getRenderArea() const;
217 uint32_t getLayerMask() const;
218 uint32_t viewCount() const;
219 };
220
221 void submit(CommandBuffer::ExecutionState &executionState);
222 void submitSecondary(CommandBuffer::ExecutionState &executionState) const;
223
224 class Command
225 {
226 public:
227 virtual void execute(ExecutionState &executionState) = 0;
228 virtual std::string description() = 0;
~Command()229 virtual ~Command() {}
230 };
231
232 private:
233 void resetState();
234 template<typename T, typename... Args>
235 void addCommand(Args &&...args);
236
237 enum State
238 {
239 INITIAL,
240 RECORDING,
241 EXECUTABLE,
242 PENDING,
243 INVALID
244 };
245
246 Device *const device;
247 State state = INITIAL;
248 VkCommandBufferLevel level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
249
250 // FIXME (b/119409619): replace this vector by an allocator so we can control all memory allocations
251 std::vector<std::unique_ptr<Command>> commands;
252 };
253
254 using DispatchableCommandBuffer = DispatchableObject<CommandBuffer, VkCommandBuffer>;
255
Cast(VkCommandBuffer object)256 static inline CommandBuffer *Cast(VkCommandBuffer object)
257 {
258 return DispatchableCommandBuffer::Cast(object);
259 }
260
261 } // namespace vk
262
263 #endif // VK_COMMAND_BUFFER_HPP_
264