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 namespace dbg {
36 class File;
37 } // namespace dbg
38
39 class Device;
40 class Buffer;
41 class Event;
42 class Framebuffer;
43 class Image;
44 class Pipeline;
45 class PipelineLayout;
46 class QueryPool;
47 class RenderPass;
48
49 class CommandBuffer
50 {
51 public:
GetAllocationScope()52 static constexpr VkSystemAllocationScope GetAllocationScope() { return VK_SYSTEM_ALLOCATION_SCOPE_OBJECT; }
53
54 CommandBuffer(Device *device, VkCommandBufferLevel pLevel);
55
56 void destroy(const VkAllocationCallbacks *pAllocator);
57
58 VkResult begin(VkCommandBufferUsageFlags flags, const VkCommandBufferInheritanceInfo *pInheritanceInfo);
59 VkResult end();
60 VkResult reset(VkCommandPoolResetFlags flags);
61
62 void beginRenderPass(RenderPass *renderPass, Framebuffer *framebuffer, VkRect2D renderArea,
63 uint32_t clearValueCount, const VkClearValue *pClearValues, VkSubpassContents contents,
64 const VkRenderPassAttachmentBeginInfo *attachmentBeginInfo);
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 void beginDebugUtilsLabel(const VkDebugUtilsLabelEXT *pLabelInfo);
137 void endDebugUtilsLabel();
138 void insertDebugUtilsLabel(const VkDebugUtilsLabelEXT *pLabelInfo);
139
140 // TODO(sugoi): Move ExecutionState out of CommandBuffer (possibly into Device)
141 struct ExecutionState
142 {
143 struct PipelineState
144 {
145 Pipeline *pipeline = nullptr;
146 vk::DescriptorSet::Array descriptorSetObjects = {};
147 vk::DescriptorSet::Bindings descriptorSets = {};
148 vk::DescriptorSet::DynamicOffsets descriptorDynamicOffsets = {};
149 };
150
151 sw::Renderer *renderer = nullptr;
152 sw::CountedEvent *events = nullptr;
153 RenderPass *renderPass = nullptr;
154 Framebuffer *renderPassFramebuffer = nullptr;
155 std::array<PipelineState, vk::VK_PIPELINE_BIND_POINT_RANGE_SIZE> pipelineState;
156
157 vk::DynamicState dynamicState;
158
159 vk::Pipeline::PushConstantStorage pushConstants;
160
161 VertexInputBinding vertexInputBindings[MAX_VERTEX_INPUT_BINDINGS] = {};
162 VertexInputBinding indexBufferBinding;
163 VkIndexType indexType;
164
165 uint32_t subpassIndex = 0;
166
167 void bindAttachments(Attachments *attachments);
168 };
169
170 void submit(CommandBuffer::ExecutionState &executionState);
171 void submitSecondary(CommandBuffer::ExecutionState &executionState) const;
172
173 class Command
174 {
175 public:
176 virtual void play(ExecutionState &executionState) = 0;
177 virtual std::string description() = 0;
~Command()178 virtual ~Command() {}
179 };
180
181 private:
182 void resetState();
183 template<typename T, typename... Args>
184 void addCommand(Args &&... args);
185
186 enum State
187 {
188 INITIAL,
189 RECORDING,
190 EXECUTABLE,
191 PENDING,
192 INVALID
193 };
194
195 Device *const device;
196 State state = INITIAL;
197 VkCommandBufferLevel level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
198
199 // FIXME (b/119409619): replace this vector by an allocator so we can control all memory allocations
200 std::vector<std::unique_ptr<Command>> commands;
201
202 #ifdef ENABLE_VK_DEBUGGER
203 std::shared_ptr<vk::dbg::File> debuggerFile;
204 #endif // ENABLE_VK_DEBUGGER
205 };
206
207 using DispatchableCommandBuffer = DispatchableObject<CommandBuffer, VkCommandBuffer>;
208
Cast(VkCommandBuffer object)209 static inline CommandBuffer *Cast(VkCommandBuffer object)
210 {
211 return DispatchableCommandBuffer::Cast(object);
212 }
213
214 } // namespace vk
215
216 #endif // VK_COMMAND_BUFFER_HPP_
217