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