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 | |
26 | namespace sw |
27 | { |
28 | class Context; |
29 | class Renderer; |
30 | class TaskEvents; |
31 | } |
32 | |
33 | namespace vk |
34 | { |
35 | |
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 | class CommandBuffer |
46 | { |
47 | public: |
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; |
190 | private: |
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 | |
202 | using DispatchableCommandBuffer = DispatchableObject<CommandBuffer, VkCommandBuffer>; |
203 | |
204 | static inline CommandBuffer* Cast(VkCommandBuffer object) |
205 | { |
206 | return DispatchableCommandBuffer::Cast(object); |
207 | } |
208 | |
209 | } // namespace vk |
210 | |
211 | #endif // VK_COMMAND_BUFFER_HPP_ |
212 | |