blob: 10e2b0624679df5dd2d705f7e83c74f8e776928f [file] [log] [blame]
Alexis Hetu767b41b2018-09-26 11:25:46 -04001// 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
Antonio Maiorano42fd1592020-04-27 11:30:40 -040018#include "VkConfig.hpp"
Ben Clayton225a1302019-04-02 12:28:22 +010019#include "VkDescriptorSet.hpp"
Ben Clayton2ed93ab2019-12-17 20:38:03 +000020#include "VkObject.hpp"
Chris Forbesa30de542019-03-18 18:51:55 -070021#include "Device/Context.hpp"
Ben Claytona4e06ca2019-12-03 12:38:14 +000022
Alexis Hetu072dc0d2018-10-31 11:41:25 -040023#include <memory>
24#include <vector>
Alexis Hetu767b41b2018-09-26 11:25:46 -040025
Nicolas Capens157ba262019-12-10 17:49:14 -050026namespace sw {
Alexis Hetuc65473d2018-12-07 16:26:05 -050027
Nicolas Capens157ba262019-12-10 17:49:14 -050028class Context;
29class Renderer;
30class TaskEvents;
31
32} // namespace sw
33
34namespace vk {
Alexis Hetu767b41b2018-09-26 11:25:46 -040035
Ben Claytona4e06ca2019-12-03 12:38:14 +000036namespace dbg {
37class File;
38} // namespace dbg
39
40class Device;
Alexis Hetu63ae9242019-06-06 13:52:15 -040041class Buffer;
Alexis Hetu7d96f512019-06-13 18:23:56 -040042class Event;
Alexis Hetu1cd31ea2019-01-17 17:14:57 -050043class Framebuffer;
Alexis Hetu7d96f512019-06-13 18:23:56 -040044class Image;
Alexis Hetu1cd31ea2019-01-17 17:14:57 -050045class Pipeline;
Alexis Hetu7d96f512019-06-13 18:23:56 -040046class PipelineLayout;
47class QueryPool;
Alexis Hetu1cd31ea2019-01-17 17:14:57 -050048class RenderPass;
49
Alexis Hetu767b41b2018-09-26 11:25:46 -040050class CommandBuffer
51{
52public:
53 static constexpr VkSystemAllocationScope GetAllocationScope() { return VK_SYSTEM_ALLOCATION_SCOPE_OBJECT; }
54
Ben Claytona4e06ca2019-12-03 12:38:14 +000055 CommandBuffer(Device *device, VkCommandBufferLevel pLevel);
Alexis Hetu767b41b2018-09-26 11:25:46 -040056
Ben Clayton2ed93ab2019-12-17 20:38:03 +000057 void destroy(const VkAllocationCallbacks *pAllocator);
Alexis Hetua9999ce2018-10-17 08:00:43 -040058
Ben Clayton2ed93ab2019-12-17 20:38:03 +000059 VkResult begin(VkCommandBufferUsageFlags flags, const VkCommandBufferInheritanceInfo *pInheritanceInfo);
Alexis Hetua9999ce2018-10-17 08:00:43 -040060 VkResult end();
61 VkResult reset(VkCommandPoolResetFlags flags);
62
Ben Clayton2ed93ab2019-12-17 20:38:03 +000063 void beginRenderPass(RenderPass *renderPass, Framebuffer *framebuffer, VkRect2D renderArea,
64 uint32_t clearValueCount, const VkClearValue *pClearValues, VkSubpassContents contents);
Alexis Hetua9999ce2018-10-17 08:00:43 -040065 void nextSubpass(VkSubpassContents contents);
66 void endRenderPass();
Ben Clayton2ed93ab2019-12-17 20:38:03 +000067 void executeCommands(uint32_t commandBufferCount, const VkCommandBuffer *pCommandBuffers);
Alexis Hetua9999ce2018-10-17 08:00:43 -040068
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,
Ben Clayton2ed93ab2019-12-17 20:38:03 +000074 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);
Alexis Hetua9999ce2018-10-17 08:00:43 -040078 void bindVertexBuffers(uint32_t firstBinding, uint32_t bindingCount,
Ben Clayton2ed93ab2019-12-17 20:38:03 +000079 const VkBuffer *pBuffers, const VkDeviceSize *pOffsets);
Alexis Hetua9999ce2018-10-17 08:00:43 -040080
Ben Clayton2ed93ab2019-12-17 20:38:03 +000081 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);
Alexis Hetua9999ce2018-10-17 08:00:43 -040089
Ben Clayton2ed93ab2019-12-17 20:38:03 +000090 void setViewport(uint32_t firstViewport, uint32_t viewportCount, const VkViewport *pViewports);
91 void setScissor(uint32_t firstScissor, uint32_t scissorCount, const VkRect2D *pScissors);
Alexis Hetua9999ce2018-10-17 08:00:43 -040092 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);
Ben Clayton2ed93ab2019-12-17 20:38:03 +000099 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);
Alexis Hetua9999ce2018-10-17 08:00:43 -0400103 void dispatch(uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ);
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000104 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);
Alexis Hetua9999ce2018-10-17 08:00:43 -0400130
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);
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000133 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);
Alexis Hetua9999ce2018-10-17 08:00:43 -0400135
Alexis Hetu9bc7a812018-12-07 16:13:34 -0500136 // TODO(sugoi): Move ExecutionState out of CommandBuffer (possibly into Device)
137 struct ExecutionState
138 {
Ben Clayton225a1302019-04-02 12:28:22 +0100139 struct PipelineState
140 {
141 Pipeline *pipeline = nullptr;
Alexis Hetu4f438a52020-06-15 16:13:51 -0400142 vk::DescriptorSet::Array descriptorSetObjects = {};
Ben Clayton225a1302019-04-02 12:28:22 +0100143 vk::DescriptorSet::Bindings descriptorSets = {};
144 vk::DescriptorSet::DynamicOffsets descriptorDynamicOffsets = {};
145 };
146
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000147 sw::Renderer *renderer = nullptr;
148 sw::TaskEvents *events = nullptr;
149 RenderPass *renderPass = nullptr;
150 Framebuffer *renderPassFramebuffer = nullptr;
Antonio Maiorano941293d2020-04-27 10:22:49 -0400151 std::array<PipelineState, vk::VK_PIPELINE_BIND_POINT_RANGE_SIZE> pipelineState;
Alexis Hetu73832432019-04-11 16:43:18 -0400152
153 struct DynamicState
154 {
155 VkViewport viewport;
156 VkRect2D scissor;
Nicolas Capens68d9ad82020-04-02 05:22:04 -0400157 sw::float4 blendConstants;
Alexis Hetu73832432019-04-11 16:43:18 -0400158 float depthBiasConstantFactor = 0.0f;
159 float depthBiasClamp = 0.0f;
160 float depthBiasSlopeFactor = 0.0f;
161 float minDepthBounds = 0.0f;
162 float maxDepthBounds = 0.0f;
163
164 uint32_t compareMask[2] = { 0 };
165 uint32_t writeMask[2] = { 0 };
166 uint32_t reference[2] = { 0 };
167 };
168 DynamicState dynamicState;
169
Chris Forbesa30de542019-03-18 18:51:55 -0700170 sw::PushConstantStorage pushConstants;
Alexis Hetu9bc7a812018-12-07 16:13:34 -0500171
172 struct VertexInputBinding
173 {
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000174 Buffer *buffer;
Alexis Hetu9bc7a812018-12-07 16:13:34 -0500175 VkDeviceSize offset;
176 };
177 VertexInputBinding vertexInputBindings[MAX_VERTEX_INPUT_BINDINGS] = {};
Chris Forbesbaf7ad32019-02-25 18:14:42 -0800178 VertexInputBinding indexBufferBinding;
179 VkIndexType indexType;
Chris Forbes2995dc22019-03-02 14:57:20 -0800180
Chris Forbesd6dc4b72019-08-23 08:23:27 -0700181 uint32_t subpassIndex = 0;
182
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000183 void bindAttachments(sw::Context &context);
184 void bindVertexInputs(sw::Context &context, int firstInstance);
Alexis Hetu9bc7a812018-12-07 16:13:34 -0500185 };
186
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000187 void submit(CommandBuffer::ExecutionState &executionState);
188 void submitSecondary(CommandBuffer::ExecutionState &executionState) const;
Alexis Hetua9999ce2018-10-17 08:00:43 -0400189
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400190 class Command;
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000191
Alexis Hetu767b41b2018-09-26 11:25:46 -0400192private:
Alexis Hetud2791c22018-12-10 14:41:03 -0500193 void resetState();
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000194 template<typename T, typename... Args>
195 void addCommand(Args &&... args);
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400196
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000197 enum State
198 {
199 INITIAL,
200 RECORDING,
201 EXECUTABLE,
202 PENDING,
203 INVALID
204 };
Ben Claytona4e06ca2019-12-03 12:38:14 +0000205
206 Device *const device;
Alexis Hetua9999ce2018-10-17 08:00:43 -0400207 State state = INITIAL;
Alexis Hetu767b41b2018-09-26 11:25:46 -0400208 VkCommandBufferLevel level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400209
210 // FIXME (b/119409619): replace this vector by an allocator so we can control all memory allocations
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000211 std::vector<std::unique_ptr<Command>> *commands;
Ben Claytona4e06ca2019-12-03 12:38:14 +0000212
213#ifdef ENABLE_VK_DEBUGGER
214 std::shared_ptr<vk::dbg::File> debuggerFile;
215#endif // ENABLE_VK_DEBUGGER
Alexis Hetu767b41b2018-09-26 11:25:46 -0400216};
217
218using DispatchableCommandBuffer = DispatchableObject<CommandBuffer, VkCommandBuffer>;
219
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000220static inline CommandBuffer *Cast(VkCommandBuffer object)
Alexis Hetu767b41b2018-09-26 11:25:46 -0400221{
222 return DispatchableCommandBuffer::Cast(object);
223}
224
Nicolas Capens157ba262019-12-10 17:49:14 -0500225} // namespace vk
Alexis Hetu767b41b2018-09-26 11:25:46 -0400226
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000227#endif // VK_COMMAND_BUFFER_HPP_