• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 bindDescriptorSets(VkPipelineBindPoint pipelineBindPoint, const PipelineLayout *layout,
147 	                        uint32_t firstSet, uint32_t descriptorSetCount, const VkDescriptorSet *pDescriptorSets,
148 	                        uint32_t dynamicOffsetCount, const uint32_t *pDynamicOffsets);
149 	void bindIndexBuffer(Buffer *buffer, VkDeviceSize offset, VkIndexType indexType);
150 	void dispatch(uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ);
151 	void dispatchIndirect(Buffer *buffer, VkDeviceSize offset);
152 	void copyBuffer(const VkCopyBufferInfo2 &copyBufferInfo);
153 	void copyImage(const VkCopyImageInfo2 &copyImageInfo);
154 	void blitImage(const VkBlitImageInfo2 &blitImageInfo);
155 	void copyBufferToImage(const VkCopyBufferToImageInfo2 &copyBufferToImageInfo);
156 	void copyImageToBuffer(const VkCopyImageToBufferInfo2 &copyImageToBufferInfo);
157 	void updateBuffer(Buffer *dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const void *pData);
158 	void fillBuffer(Buffer *dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data);
159 	void clearColorImage(Image *image, VkImageLayout imageLayout, const VkClearColorValue *pColor,
160 	                     uint32_t rangeCount, const VkImageSubresourceRange *pRanges);
161 	void clearDepthStencilImage(Image *image, VkImageLayout imageLayout, const VkClearDepthStencilValue *pDepthStencil,
162 	                            uint32_t rangeCount, const VkImageSubresourceRange *pRanges);
163 	void clearAttachments(uint32_t attachmentCount, const VkClearAttachment *pAttachments,
164 	                      uint32_t rectCount, const VkClearRect *pRects);
165 	void resolveImage(const VkResolveImageInfo2 &resolveImageInfo);
166 	void setEvent(Event *event, const VkDependencyInfo &pDependencyInfo);
167 	void resetEvent(Event *event, VkPipelineStageFlags2 stageMask);
168 	void waitEvents(uint32_t eventCount, const VkEvent *pEvents, const VkDependencyInfo &pDependencyInfo);
169 
170 	void draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance);
171 	void drawIndexed(uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance);
172 	void drawIndirect(Buffer *buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride);
173 	void drawIndexedIndirect(Buffer *buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride);
174 
175 	void beginDebugUtilsLabel(const VkDebugUtilsLabelEXT *pLabelInfo);
176 	void endDebugUtilsLabel();
177 	void insertDebugUtilsLabel(const VkDebugUtilsLabelEXT *pLabelInfo);
178 
179 	// TODO(sugoi): Move ExecutionState out of CommandBuffer (possibly into Device)
180 	struct ExecutionState
181 	{
182 		struct PipelineState
183 		{
184 			Pipeline *pipeline = nullptr;
185 			vk::DescriptorSet::Array descriptorSetObjects = {};
186 			vk::DescriptorSet::Bindings descriptorSets = {};
187 			vk::DescriptorSet::DynamicOffsets descriptorDynamicOffsets = {};
188 		};
189 
190 		sw::Renderer *renderer = nullptr;
191 		sw::CountedEvent *events = nullptr;
192 		RenderPass *renderPass = nullptr;
193 		Framebuffer *renderPassFramebuffer = nullptr;
194 		DynamicRendering *dynamicRendering = nullptr;
195 
196 		// VK_PIPELINE_BIND_POINT_GRAPHICS = 0
197 		// VK_PIPELINE_BIND_POINT_COMPUTE = 1
198 		std::array<PipelineState, 2> pipelineState;
199 
200 		vk::DynamicState dynamicState;
201 
202 		vk::Pipeline::PushConstantStorage pushConstants;
203 
204 		VertexInputBinding vertexInputBindings[MAX_VERTEX_INPUT_BINDINGS] = {};
205 		VertexInputBinding indexBufferBinding;
206 		VkIndexType indexType;
207 
208 		uint32_t subpassIndex = 0;
209 
210 		void bindAttachments(Attachments *attachments);
211 
212 		VkRect2D getRenderArea() const;
213 		uint32_t getLayerMask() const;
214 		uint32_t viewCount() const;
215 	};
216 
217 	void submit(CommandBuffer::ExecutionState &executionState);
218 	void submitSecondary(CommandBuffer::ExecutionState &executionState) const;
219 
220 	class Command
221 	{
222 	public:
223 		virtual void execute(ExecutionState &executionState) = 0;
224 		virtual std::string description() = 0;
~Command()225 		virtual ~Command() {}
226 	};
227 
228 private:
229 	void resetState();
230 	template<typename T, typename... Args>
231 	void addCommand(Args &&...args);
232 
233 	enum State
234 	{
235 		INITIAL,
236 		RECORDING,
237 		EXECUTABLE,
238 		PENDING,
239 		INVALID
240 	};
241 
242 	Device *const device;
243 	State state = INITIAL;
244 	VkCommandBufferLevel level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
245 
246 	// FIXME (b/119409619): replace this vector by an allocator so we can control all memory allocations
247 	std::vector<std::unique_ptr<Command>> commands;
248 };
249 
250 using DispatchableCommandBuffer = DispatchableObject<CommandBuffer, VkCommandBuffer>;
251 
Cast(VkCommandBuffer object)252 static inline CommandBuffer *Cast(VkCommandBuffer object)
253 {
254 	return DispatchableCommandBuffer::Cast(object);
255 }
256 
257 }  // namespace vk
258 
259 #endif  // VK_COMMAND_BUFFER_HPP_
260