blob: df555d0e8243db05902ec25b65e1889309474999 [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#include "VkCommandBuffer.hpp"
Nicolas Capens002b7c12020-04-24 01:05:57 -040016
Alexis Hetuc65473d2018-12-07 16:26:05 -050017#include "VkBuffer.hpp"
Antonio Maiorano42fd1592020-04-27 11:30:40 -040018#include "VkConfig.hpp"
Antonio Maiorano6636f142020-03-30 21:29:07 -040019#include "VkDevice.hpp"
Alexis Hetu3f5a4792019-02-01 17:49:55 -050020#include "VkEvent.hpp"
Alexis Hetue1f51b92019-04-23 15:34:34 -040021#include "VkFence.hpp"
Alexis Hetu9bc7a812018-12-07 16:13:34 -050022#include "VkFramebuffer.hpp"
Alexis Hetu09056de2018-12-07 12:40:00 -050023#include "VkImage.hpp"
Chris Forbes7c33e882019-02-21 14:58:28 -080024#include "VkImageView.hpp"
Alexis Hetuc65473d2018-12-07 16:26:05 -050025#include "VkPipeline.hpp"
Ben Claytonf2be26a2019-03-08 12:02:05 +000026#include "VkPipelineLayout.hpp"
Alexis Hetuf0aa9d52019-04-01 17:06:47 -040027#include "VkQueryPool.hpp"
Chris Forbes50dd2ce2018-12-07 17:54:31 -080028#include "VkRenderPass.hpp"
Alexis Hetuc65473d2018-12-07 16:26:05 -050029#include "Device/Renderer.hpp"
Alexis Hetu767b41b2018-09-26 11:25:46 -040030
Ben Claytona4e06ca2019-12-03 12:38:14 +000031#include "./Debug/Context.hpp"
32#include "./Debug/File.hpp"
33#include "./Debug/Thread.hpp"
34
35#include "marl/defer.h"
36
Chris Forbesf8374cf2018-12-06 13:25:59 -080037#include <cstring>
38
Ben Clayton1e610ee2019-12-03 11:48:25 +000039class vk::CommandBuffer::Command
Alexis Hetu072dc0d2018-10-31 11:41:25 -040040{
41public:
42 // FIXME (b/119421344): change the commandBuffer argument to a CommandBuffer state
Ben Clayton2ed93ab2019-12-17 20:38:03 +000043 virtual void play(vk::CommandBuffer::ExecutionState &executionState) = 0;
Ben Clayton72c398f2019-12-03 11:53:09 +000044 virtual std::string description() = 0;
Alexis Hetu072dc0d2018-10-31 11:41:25 -040045 virtual ~Command() {}
46};
47
Ben Clayton1e610ee2019-12-03 11:48:25 +000048namespace {
49
50class CmdBeginRenderPass : public vk::CommandBuffer::Command
Alexis Hetu072dc0d2018-10-31 11:41:25 -040051{
52public:
Ben Clayton2ed93ab2019-12-17 20:38:03 +000053 CmdBeginRenderPass(vk::RenderPass *renderPass, vk::Framebuffer *framebuffer, VkRect2D renderArea,
54 uint32_t clearValueCount, const VkClearValue *pClearValues)
55 : renderPass(renderPass)
56 , framebuffer(framebuffer)
57 , renderArea(renderArea)
58 , clearValueCount(clearValueCount)
Alexis Hetu072dc0d2018-10-31 11:41:25 -040059 {
60 // FIXME (b/119409619): use an allocator here so we can control all memory allocations
61 clearValues = new VkClearValue[clearValueCount];
62 memcpy(clearValues, pClearValues, clearValueCount * sizeof(VkClearValue));
63 }
64
Ben Clayton1e610ee2019-12-03 11:48:25 +000065 ~CmdBeginRenderPass() override
Alexis Hetu072dc0d2018-10-31 11:41:25 -040066 {
Ben Clayton2ed93ab2019-12-17 20:38:03 +000067 delete[] clearValues;
Alexis Hetu072dc0d2018-10-31 11:41:25 -040068 }
69
Ben Clayton2ed93ab2019-12-17 20:38:03 +000070 void play(vk::CommandBuffer::ExecutionState &executionState) override
Alexis Hetu072dc0d2018-10-31 11:41:25 -040071 {
Alexis Hetu1cd31ea2019-01-17 17:14:57 -050072 executionState.renderPass = renderPass;
73 executionState.renderPassFramebuffer = framebuffer;
Chris Forbesd6dc4b72019-08-23 08:23:27 -070074 executionState.subpassIndex = 0;
Alexis Hetu54ec7592019-03-20 14:37:16 -040075 framebuffer->clear(executionState.renderPass, clearValueCount, clearValues, renderArea);
Alexis Hetu072dc0d2018-10-31 11:41:25 -040076 }
77
Ben Clayton72c398f2019-12-03 11:53:09 +000078 std::string description() override { return "vkCmdBeginRenderPass()"; }
79
Alexis Hetu072dc0d2018-10-31 11:41:25 -040080private:
Ben Clayton2ed93ab2019-12-17 20:38:03 +000081 vk::RenderPass *renderPass;
82 vk::Framebuffer *framebuffer;
Alexis Hetu072dc0d2018-10-31 11:41:25 -040083 VkRect2D renderArea;
84 uint32_t clearValueCount;
Ben Clayton2ed93ab2019-12-17 20:38:03 +000085 VkClearValue *clearValues;
Alexis Hetu072dc0d2018-10-31 11:41:25 -040086};
87
Ben Clayton1e610ee2019-12-03 11:48:25 +000088class CmdNextSubpass : public vk::CommandBuffer::Command
Alexis Hetu1cd31ea2019-01-17 17:14:57 -050089{
90public:
Ben Clayton2ed93ab2019-12-17 20:38:03 +000091 void play(vk::CommandBuffer::ExecutionState &executionState) override
Alexis Hetu1cd31ea2019-01-17 17:14:57 -050092 {
Chris Forbesd6dc4b72019-08-23 08:23:27 -070093 bool hasResolveAttachments = (executionState.renderPass->getSubpass(executionState.subpassIndex).pResolveAttachments != nullptr);
Alexis Hetu54ec7592019-03-20 14:37:16 -040094 if(hasResolveAttachments)
95 {
96 // FIXME(sugoi): remove the following lines and resolve in Renderer::finishRendering()
97 // for a Draw command or after the last command of the current subpass
98 // which modifies pixels.
99 executionState.renderer->synchronize();
Chris Forbesd6dc4b72019-08-23 08:23:27 -0700100 executionState.renderPassFramebuffer->resolve(executionState.renderPass, executionState.subpassIndex);
Alexis Hetu54ec7592019-03-20 14:37:16 -0400101 }
102
Chris Forbesd6dc4b72019-08-23 08:23:27 -0700103 ++executionState.subpassIndex;
Alexis Hetu1cd31ea2019-01-17 17:14:57 -0500104 }
Ben Clayton72c398f2019-12-03 11:53:09 +0000105
106 std::string description() override { return "vkCmdNextSubpass()"; }
Alexis Hetu1cd31ea2019-01-17 17:14:57 -0500107};
108
Ben Clayton1e610ee2019-12-03 11:48:25 +0000109class CmdEndRenderPass : public vk::CommandBuffer::Command
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400110{
111public:
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000112 void play(vk::CommandBuffer::ExecutionState &executionState) override
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400113 {
Chris Forbesfc06fd12019-03-21 08:36:11 -0700114 // Execute (implicit or explicit) VkSubpassDependency to VK_SUBPASS_EXTERNAL
115 // This is somewhat heavier than the actual ordering required.
116 executionState.renderer->synchronize();
Alexis Hetu54ec7592019-03-20 14:37:16 -0400117
118 // FIXME(sugoi): remove the following line and resolve in Renderer::finishRendering()
119 // for a Draw command or after the last command of the current subpass
120 // which modifies pixels.
Chris Forbesd6dc4b72019-08-23 08:23:27 -0700121 executionState.renderPassFramebuffer->resolve(executionState.renderPass, executionState.subpassIndex);
Alexis Hetu54ec7592019-03-20 14:37:16 -0400122 executionState.renderPass = nullptr;
123 executionState.renderPassFramebuffer = nullptr;
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400124 }
Ben Clayton72c398f2019-12-03 11:53:09 +0000125
126 std::string description() override { return "vkCmdEndRenderPass()"; }
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400127};
128
Ben Clayton1e610ee2019-12-03 11:48:25 +0000129class CmdExecuteCommands : public vk::CommandBuffer::Command
Alexis Hetue7b2a052019-03-18 16:16:36 -0400130{
131public:
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000132 CmdExecuteCommands(const vk::CommandBuffer *commandBuffer)
133 : commandBuffer(commandBuffer)
Alexis Hetue7b2a052019-03-18 16:16:36 -0400134 {
135 }
136
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000137 void play(vk::CommandBuffer::ExecutionState &executionState) override
Alexis Hetue7b2a052019-03-18 16:16:36 -0400138 {
Alexis Hetu63ae9242019-06-06 13:52:15 -0400139 commandBuffer->submitSecondary(executionState);
Alexis Hetue7b2a052019-03-18 16:16:36 -0400140 }
141
Ben Clayton72c398f2019-12-03 11:53:09 +0000142 std::string description() override { return "vkCmdExecuteCommands()"; }
143
Alexis Hetue7b2a052019-03-18 16:16:36 -0400144private:
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000145 const vk::CommandBuffer *commandBuffer;
Alexis Hetue7b2a052019-03-18 16:16:36 -0400146};
147
Ben Clayton1e610ee2019-12-03 11:48:25 +0000148class CmdPipelineBind : public vk::CommandBuffer::Command
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400149{
150public:
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000151 CmdPipelineBind(VkPipelineBindPoint pipelineBindPoint, vk::Pipeline *pipeline)
152 : pipelineBindPoint(pipelineBindPoint)
153 , pipeline(pipeline)
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400154 {
155 }
156
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000157 void play(vk::CommandBuffer::ExecutionState &executionState) override
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400158 {
Alexis Hetu63ae9242019-06-06 13:52:15 -0400159 executionState.pipelineState[pipelineBindPoint].pipeline = pipeline;
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400160 }
161
Ben Clayton72c398f2019-12-03 11:53:09 +0000162 std::string description() override { return "vkCmdPipelineBind()"; }
163
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400164private:
165 VkPipelineBindPoint pipelineBindPoint;
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000166 vk::Pipeline *pipeline;
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400167};
168
Ben Clayton1e610ee2019-12-03 11:48:25 +0000169class CmdDispatch : public vk::CommandBuffer::Command
Ben Claytonf2be26a2019-03-08 12:02:05 +0000170{
171public:
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000172 CmdDispatch(uint32_t baseGroupX, uint32_t baseGroupY, uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ)
173 : baseGroupX(baseGroupX)
174 , baseGroupY(baseGroupY)
175 , baseGroupZ(baseGroupZ)
176 , groupCountX(groupCountX)
177 , groupCountY(groupCountY)
178 , groupCountZ(groupCountZ)
Ben Claytonf2be26a2019-03-08 12:02:05 +0000179 {
180 }
181
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000182 void play(vk::CommandBuffer::ExecutionState &executionState) override
Ben Claytonf2be26a2019-03-08 12:02:05 +0000183 {
Ben Clayton225a1302019-04-02 12:28:22 +0100184 auto const &pipelineState = executionState.pipelineState[VK_PIPELINE_BIND_POINT_COMPUTE];
185
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000186 vk::ComputePipeline *pipeline = static_cast<vk::ComputePipeline *>(pipelineState.pipeline);
Chris Forbes4a4c2592019-05-13 08:53:36 -0700187 pipeline->run(baseGroupX, baseGroupY, baseGroupZ,
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000188 groupCountX, groupCountY, groupCountZ,
Alexis Hetu4f438a52020-06-15 16:13:51 -0400189 pipelineState.descriptorSetObjects,
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000190 pipelineState.descriptorSets,
191 pipelineState.descriptorDynamicOffsets,
192 executionState.pushConstants);
Ben Claytonf2be26a2019-03-08 12:02:05 +0000193 }
194
Ben Clayton72c398f2019-12-03 11:53:09 +0000195 std::string description() override { return "vkCmdDispatch()"; }
196
Ben Claytonf2be26a2019-03-08 12:02:05 +0000197private:
Chris Forbes4a4c2592019-05-13 08:53:36 -0700198 uint32_t baseGroupX;
199 uint32_t baseGroupY;
200 uint32_t baseGroupZ;
Ben Claytonf2be26a2019-03-08 12:02:05 +0000201 uint32_t groupCountX;
202 uint32_t groupCountY;
203 uint32_t groupCountZ;
204};
205
Ben Clayton1e610ee2019-12-03 11:48:25 +0000206class CmdDispatchIndirect : public vk::CommandBuffer::Command
Chris Forbesfc8a46d2019-03-22 14:47:47 -0700207{
208public:
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000209 CmdDispatchIndirect(vk::Buffer *buffer, VkDeviceSize offset)
210 : buffer(buffer)
211 , offset(offset)
Chris Forbesfc8a46d2019-03-22 14:47:47 -0700212 {
213 }
214
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000215 void play(vk::CommandBuffer::ExecutionState &executionState) override
Chris Forbesfc8a46d2019-03-22 14:47:47 -0700216 {
Alexis Hetu63ae9242019-06-06 13:52:15 -0400217 auto cmd = reinterpret_cast<VkDispatchIndirectCommand const *>(buffer->getOffsetPointer(offset));
Chris Forbesfc8a46d2019-03-22 14:47:47 -0700218
Ben Clayton225a1302019-04-02 12:28:22 +0100219 auto const &pipelineState = executionState.pipelineState[VK_PIPELINE_BIND_POINT_COMPUTE];
220
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000221 auto pipeline = static_cast<vk::ComputePipeline *>(pipelineState.pipeline);
Chris Forbes4a4c2592019-05-13 08:53:36 -0700222 pipeline->run(0, 0, 0, cmd->x, cmd->y, cmd->z,
Alexis Hetu4f438a52020-06-15 16:13:51 -0400223 pipelineState.descriptorSetObjects,
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000224 pipelineState.descriptorSets,
225 pipelineState.descriptorDynamicOffsets,
226 executionState.pushConstants);
Chris Forbesfc8a46d2019-03-22 14:47:47 -0700227 }
228
Ben Clayton72c398f2019-12-03 11:53:09 +0000229 std::string description() override { return "vkCmdDispatchIndirect()"; }
230
Chris Forbesfc8a46d2019-03-22 14:47:47 -0700231private:
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000232 const vk::Buffer *buffer;
Chris Forbesfc8a46d2019-03-22 14:47:47 -0700233 VkDeviceSize offset;
234};
235
Ben Clayton1e610ee2019-12-03 11:48:25 +0000236class CmdVertexBufferBind : public vk::CommandBuffer::Command
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400237{
Ben Clayton1e610ee2019-12-03 11:48:25 +0000238public:
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000239 CmdVertexBufferBind(uint32_t binding, vk::Buffer *buffer, const VkDeviceSize offset)
240 : binding(binding)
241 , buffer(buffer)
242 , offset(offset)
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400243 {
244 }
245
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000246 void play(vk::CommandBuffer::ExecutionState &executionState) override
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400247 {
Alexis Hetu9bc7a812018-12-07 16:13:34 -0500248 executionState.vertexInputBindings[binding] = { buffer, offset };
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400249 }
250
Ben Clayton72c398f2019-12-03 11:53:09 +0000251 std::string description() override { return "vkCmdVertexBufferBind()"; }
252
Alexis Hetu63ae9242019-06-06 13:52:15 -0400253private:
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400254 uint32_t binding;
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000255 vk::Buffer *buffer;
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400256 const VkDeviceSize offset;
257};
258
Ben Clayton1e610ee2019-12-03 11:48:25 +0000259class CmdIndexBufferBind : public vk::CommandBuffer::Command
Chris Forbesbaf7ad32019-02-25 18:14:42 -0800260{
Ben Clayton1e610ee2019-12-03 11:48:25 +0000261public:
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000262 CmdIndexBufferBind(vk::Buffer *buffer, const VkDeviceSize offset, const VkIndexType indexType)
263 : buffer(buffer)
264 , offset(offset)
265 , indexType(indexType)
Chris Forbesbaf7ad32019-02-25 18:14:42 -0800266 {
Chris Forbesbaf7ad32019-02-25 18:14:42 -0800267 }
268
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000269 void play(vk::CommandBuffer::ExecutionState &executionState) override
Chris Forbesbaf7ad32019-02-25 18:14:42 -0800270 {
Alexis Hetu63ae9242019-06-06 13:52:15 -0400271 executionState.indexBufferBinding = { buffer, offset };
Chris Forbesbaf7ad32019-02-25 18:14:42 -0800272 executionState.indexType = indexType;
273 }
274
Ben Clayton72c398f2019-12-03 11:53:09 +0000275 std::string description() override { return "vkCmdIndexBufferBind()"; }
276
Alexis Hetu63ae9242019-06-06 13:52:15 -0400277private:
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000278 vk::Buffer *buffer;
Chris Forbesbaf7ad32019-02-25 18:14:42 -0800279 const VkDeviceSize offset;
280 const VkIndexType indexType;
281};
282
Ben Clayton1e610ee2019-12-03 11:48:25 +0000283class CmdSetViewport : public vk::CommandBuffer::Command
Alexis Hetu73832432019-04-11 16:43:18 -0400284{
Ben Clayton1e610ee2019-12-03 11:48:25 +0000285public:
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000286 CmdSetViewport(const VkViewport &viewport, uint32_t viewportID)
287 : viewport(viewport)
288 , viewportID(viewportID)
Alexis Hetu73832432019-04-11 16:43:18 -0400289 {
290 }
291
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000292 void play(vk::CommandBuffer::ExecutionState &executionState) override
Alexis Hetu73832432019-04-11 16:43:18 -0400293 {
294 executionState.dynamicState.viewport = viewport;
295 }
296
Ben Clayton72c398f2019-12-03 11:53:09 +0000297 std::string description() override { return "vkCmdSetViewport()"; }
298
Alexis Hetu63ae9242019-06-06 13:52:15 -0400299private:
Alexis Hetu73832432019-04-11 16:43:18 -0400300 const VkViewport viewport;
301 uint32_t viewportID;
302};
303
Ben Clayton1e610ee2019-12-03 11:48:25 +0000304class CmdSetScissor : public vk::CommandBuffer::Command
Alexis Hetu73832432019-04-11 16:43:18 -0400305{
Ben Clayton1e610ee2019-12-03 11:48:25 +0000306public:
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000307 CmdSetScissor(const VkRect2D &scissor, uint32_t scissorID)
308 : scissor(scissor)
309 , scissorID(scissorID)
Alexis Hetu73832432019-04-11 16:43:18 -0400310 {
311 }
312
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000313 void play(vk::CommandBuffer::ExecutionState &executionState) override
Alexis Hetu73832432019-04-11 16:43:18 -0400314 {
315 executionState.dynamicState.scissor = scissor;
316 }
317
Ben Clayton72c398f2019-12-03 11:53:09 +0000318 std::string description() override { return "vkCmdSetScissor()"; }
319
Alexis Hetu63ae9242019-06-06 13:52:15 -0400320private:
Alexis Hetu73832432019-04-11 16:43:18 -0400321 const VkRect2D scissor;
322 uint32_t scissorID;
323};
324
Ben Clayton1e610ee2019-12-03 11:48:25 +0000325class CmdSetDepthBias : public vk::CommandBuffer::Command
Alexis Hetu73832432019-04-11 16:43:18 -0400326{
Ben Clayton1e610ee2019-12-03 11:48:25 +0000327public:
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000328 CmdSetDepthBias(float depthBiasConstantFactor, float depthBiasClamp, float depthBiasSlopeFactor)
329 : depthBiasConstantFactor(depthBiasConstantFactor)
330 , depthBiasClamp(depthBiasClamp)
331 , depthBiasSlopeFactor(depthBiasSlopeFactor)
Alexis Hetu73832432019-04-11 16:43:18 -0400332 {
333 }
334
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000335 void play(vk::CommandBuffer::ExecutionState &executionState) override
Alexis Hetu73832432019-04-11 16:43:18 -0400336 {
337 executionState.dynamicState.depthBiasConstantFactor = depthBiasConstantFactor;
338 executionState.dynamicState.depthBiasClamp = depthBiasClamp;
339 executionState.dynamicState.depthBiasSlopeFactor = depthBiasSlopeFactor;
340 }
341
Ben Clayton72c398f2019-12-03 11:53:09 +0000342 std::string description() override { return "vkCmdSetDepthBias()"; }
343
Alexis Hetu63ae9242019-06-06 13:52:15 -0400344private:
Alexis Hetu73832432019-04-11 16:43:18 -0400345 float depthBiasConstantFactor;
346 float depthBiasClamp;
347 float depthBiasSlopeFactor;
348};
349
Ben Clayton1e610ee2019-12-03 11:48:25 +0000350class CmdSetBlendConstants : public vk::CommandBuffer::Command
Alexis Hetu73832432019-04-11 16:43:18 -0400351{
Ben Clayton1e610ee2019-12-03 11:48:25 +0000352public:
353 CmdSetBlendConstants(const float blendConstants[4])
Alexis Hetu73832432019-04-11 16:43:18 -0400354 {
355 memcpy(this->blendConstants, blendConstants, sizeof(this->blendConstants));
356 }
357
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000358 void play(vk::CommandBuffer::ExecutionState &executionState) override
Alexis Hetu73832432019-04-11 16:43:18 -0400359 {
360 memcpy(&(executionState.dynamicState.blendConstants[0]), blendConstants, sizeof(blendConstants));
361 }
362
Ben Clayton72c398f2019-12-03 11:53:09 +0000363 std::string description() override { return "vkCmdSetBlendConstants()"; }
364
Alexis Hetu63ae9242019-06-06 13:52:15 -0400365private:
Alexis Hetu73832432019-04-11 16:43:18 -0400366 float blendConstants[4];
367};
368
Ben Clayton1e610ee2019-12-03 11:48:25 +0000369class CmdSetDepthBounds : public vk::CommandBuffer::Command
Alexis Hetu73832432019-04-11 16:43:18 -0400370{
Ben Clayton1e610ee2019-12-03 11:48:25 +0000371public:
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000372 CmdSetDepthBounds(float minDepthBounds, float maxDepthBounds)
373 : minDepthBounds(minDepthBounds)
374 , maxDepthBounds(maxDepthBounds)
Alexis Hetu73832432019-04-11 16:43:18 -0400375 {
376 }
377
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000378 void play(vk::CommandBuffer::ExecutionState &executionState) override
Alexis Hetu73832432019-04-11 16:43:18 -0400379 {
380 executionState.dynamicState.minDepthBounds = minDepthBounds;
381 executionState.dynamicState.maxDepthBounds = maxDepthBounds;
382 }
383
Ben Clayton72c398f2019-12-03 11:53:09 +0000384 std::string description() override { return "vkCmdSetDepthBounds()"; }
385
Alexis Hetu63ae9242019-06-06 13:52:15 -0400386private:
Alexis Hetu73832432019-04-11 16:43:18 -0400387 float minDepthBounds;
388 float maxDepthBounds;
389};
Ben Clayton1e610ee2019-12-03 11:48:25 +0000390
391class CmdSetStencilCompareMask : public vk::CommandBuffer::Command
Alexis Hetu73832432019-04-11 16:43:18 -0400392{
Ben Clayton1e610ee2019-12-03 11:48:25 +0000393public:
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000394 CmdSetStencilCompareMask(VkStencilFaceFlags faceMask, uint32_t compareMask)
395 : faceMask(faceMask)
396 , compareMask(compareMask)
Alexis Hetu73832432019-04-11 16:43:18 -0400397 {
398 }
399
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000400 void play(vk::CommandBuffer::ExecutionState &executionState) override
Alexis Hetu73832432019-04-11 16:43:18 -0400401 {
402 if(faceMask & VK_STENCIL_FACE_FRONT_BIT)
403 {
404 executionState.dynamicState.compareMask[0] = compareMask;
405 }
406 if(faceMask & VK_STENCIL_FACE_BACK_BIT)
407 {
408 executionState.dynamicState.compareMask[1] = compareMask;
409 }
410 }
411
Ben Clayton72c398f2019-12-03 11:53:09 +0000412 std::string description() override { return "vkCmdSetStencilCompareMask()"; }
413
Alexis Hetu63ae9242019-06-06 13:52:15 -0400414private:
Alexis Hetu73832432019-04-11 16:43:18 -0400415 VkStencilFaceFlags faceMask;
416 uint32_t compareMask;
417};
418
Ben Clayton1e610ee2019-12-03 11:48:25 +0000419class CmdSetStencilWriteMask : public vk::CommandBuffer::Command
Alexis Hetu73832432019-04-11 16:43:18 -0400420{
Ben Clayton1e610ee2019-12-03 11:48:25 +0000421public:
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000422 CmdSetStencilWriteMask(VkStencilFaceFlags faceMask, uint32_t writeMask)
423 : faceMask(faceMask)
424 , writeMask(writeMask)
Alexis Hetu73832432019-04-11 16:43:18 -0400425 {
426 }
427
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000428 void play(vk::CommandBuffer::ExecutionState &executionState) override
Alexis Hetu73832432019-04-11 16:43:18 -0400429 {
430 if(faceMask & VK_STENCIL_FACE_FRONT_BIT)
431 {
432 executionState.dynamicState.writeMask[0] = writeMask;
433 }
434 if(faceMask & VK_STENCIL_FACE_BACK_BIT)
435 {
436 executionState.dynamicState.writeMask[1] = writeMask;
437 }
438 }
439
Ben Clayton72c398f2019-12-03 11:53:09 +0000440 std::string description() override { return "vkCmdSetStencilWriteMask()"; }
441
Alexis Hetu63ae9242019-06-06 13:52:15 -0400442private:
Alexis Hetu73832432019-04-11 16:43:18 -0400443 VkStencilFaceFlags faceMask;
444 uint32_t writeMask;
445};
446
Ben Clayton1e610ee2019-12-03 11:48:25 +0000447class CmdSetStencilReference : public vk::CommandBuffer::Command
Alexis Hetu73832432019-04-11 16:43:18 -0400448{
Ben Clayton1e610ee2019-12-03 11:48:25 +0000449public:
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000450 CmdSetStencilReference(VkStencilFaceFlags faceMask, uint32_t reference)
451 : faceMask(faceMask)
452 , reference(reference)
Alexis Hetu73832432019-04-11 16:43:18 -0400453 {
454 }
455
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000456 void play(vk::CommandBuffer::ExecutionState &executionState) override
Alexis Hetu73832432019-04-11 16:43:18 -0400457 {
458 if(faceMask & VK_STENCIL_FACE_FRONT_BIT)
459 {
460 executionState.dynamicState.reference[0] = reference;
461 }
462 if(faceMask & VK_STENCIL_FACE_BACK_BIT)
463 {
464 executionState.dynamicState.reference[1] = reference;
465 }
466 }
467
Ben Clayton72c398f2019-12-03 11:53:09 +0000468 std::string description() override { return "vkCmdSetStencilReference()"; }
469
Alexis Hetu63ae9242019-06-06 13:52:15 -0400470private:
Alexis Hetu73832432019-04-11 16:43:18 -0400471 VkStencilFaceFlags faceMask;
472 uint32_t reference;
473};
474
Ben Clayton1e610ee2019-12-03 11:48:25 +0000475class CmdDrawBase : public vk::CommandBuffer::Command
Chris Forbes00ba1762019-03-08 17:10:41 -0800476{
Ben Clayton1e610ee2019-12-03 11:48:25 +0000477public:
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000478 int bytesPerIndex(vk::CommandBuffer::ExecutionState const &executionState)
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400479 {
Chris Forbes48b35872019-03-22 14:12:50 -0700480 return executionState.indexType == VK_INDEX_TYPE_UINT16 ? 2 : 4;
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400481 }
482
Alexis Hetu7fe5a062019-05-09 15:35:33 -0400483 template<typename T>
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000484 void processPrimitiveRestart(T *indexBuffer,
Alexis Hetu7fe5a062019-05-09 15:35:33 -0400485 uint32_t count,
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000486 vk::GraphicsPipeline *pipeline,
487 std::vector<std::pair<uint32_t, void *>> &indexBuffers)
Alexis Hetu7fe5a062019-05-09 15:35:33 -0400488 {
489 static const T RestartIndex = static_cast<T>(-1);
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000490 T *indexBufferStart = indexBuffer;
Alexis Hetu7fe5a062019-05-09 15:35:33 -0400491 uint32_t vertexCount = 0;
492 for(uint32_t i = 0; i < count; i++)
493 {
494 if(indexBuffer[i] == RestartIndex)
495 {
496 // Record previous segment
497 if(vertexCount > 0)
498 {
499 uint32_t primitiveCount = pipeline->computePrimitiveCount(vertexCount);
500 if(primitiveCount > 0)
501 {
502 indexBuffers.push_back({ primitiveCount, indexBufferStart });
503 }
504 }
505 vertexCount = 0;
506 }
507 else
508 {
509 if(vertexCount == 0)
510 {
511 indexBufferStart = indexBuffer + i;
512 }
513 vertexCount++;
514 }
515 }
516
517 // Record last segment
518 if(vertexCount > 0)
519 {
520 uint32_t primitiveCount = pipeline->computePrimitiveCount(vertexCount);
521 if(primitiveCount > 0)
522 {
523 indexBuffers.push_back({ primitiveCount, indexBufferStart });
524 }
525 }
526 }
527
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000528 void draw(vk::CommandBuffer::ExecutionState &executionState, bool indexed,
529 uint32_t count, uint32_t instanceCount, uint32_t first, int32_t vertexOffset, uint32_t firstInstance)
Chris Forbesbaf7ad32019-02-25 18:14:42 -0800530 {
Ben Clayton225a1302019-04-02 12:28:22 +0100531 auto const &pipelineState = executionState.pipelineState[VK_PIPELINE_BIND_POINT_GRAPHICS];
532
Ben Clayton1e610ee2019-12-03 11:48:25 +0000533 auto *pipeline = static_cast<vk::GraphicsPipeline *>(pipelineState.pipeline);
Chris Forbesbaf7ad32019-02-25 18:14:42 -0800534
535 sw::Context context = pipeline->getContext();
Chris Forbese1cf8632019-03-08 18:17:35 -0800536
Alexis Hetu90df5272019-11-12 13:44:12 -0500537 executionState.bindVertexInputs(context, firstInstance);
Chris Forbesbaf7ad32019-02-25 18:14:42 -0800538
Alexis Hetu4f438a52020-06-15 16:13:51 -0400539 context.descriptorSetObjects = pipelineState.descriptorSetObjects;
Ben Clayton225a1302019-04-02 12:28:22 +0100540 context.descriptorSets = pipelineState.descriptorSets;
541 context.descriptorDynamicOffsets = pipelineState.descriptorDynamicOffsets;
Chris Forbesa30de542019-03-18 18:51:55 -0700542
Alexis Hetu73832432019-04-11 16:43:18 -0400543 // Apply either pipeline state or dynamic state
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000544 executionState.renderer->setScissor(pipeline->hasDynamicState(VK_DYNAMIC_STATE_SCISSOR) ? executionState.dynamicState.scissor : pipeline->getScissor());
545 executionState.renderer->setViewport(pipeline->hasDynamicState(VK_DYNAMIC_STATE_VIEWPORT) ? executionState.dynamicState.viewport : pipeline->getViewport());
546 executionState.renderer->setBlendConstant(pipeline->hasDynamicState(VK_DYNAMIC_STATE_BLEND_CONSTANTS) ? executionState.dynamicState.blendConstants : pipeline->getBlendConstants());
Alexis Hetu30847682019-09-11 17:18:46 -0400547
Nicolas Capens81bc9d92019-12-16 15:05:57 -0500548 if(pipeline->hasDynamicState(VK_DYNAMIC_STATE_DEPTH_BIAS))
Alexis Hetu73832432019-04-11 16:43:18 -0400549 {
550 // If the depth bias clamping feature is not enabled, depthBiasClamp must be 0.0
551 ASSERT(executionState.dynamicState.depthBiasClamp == 0.0f);
552
553 context.depthBias = executionState.dynamicState.depthBiasConstantFactor;
554 context.slopeDepthBias = executionState.dynamicState.depthBiasSlopeFactor;
555 }
Nicolas Capens44bd43a2020-01-22 03:07:14 -0500556
Nicolas Capens81bc9d92019-12-16 15:05:57 -0500557 if(pipeline->hasDynamicState(VK_DYNAMIC_STATE_DEPTH_BOUNDS) && context.depthBoundsTestEnable)
Alexis Hetu73832432019-04-11 16:43:18 -0400558 {
Nicolas Capens44bd43a2020-01-22 03:07:14 -0500559 // Unless the VK_EXT_depth_range_unrestricted extension is enabled, minDepthBounds and maxDepthBounds must be between 0.0 and 1.0, inclusive
Chris Forbes02d4c0d2019-08-21 12:04:34 -0700560 ASSERT(executionState.dynamicState.minDepthBounds >= 0.0f &&
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000561 executionState.dynamicState.minDepthBounds <= 1.0f);
Chris Forbes02d4c0d2019-08-21 12:04:34 -0700562 ASSERT(executionState.dynamicState.maxDepthBounds >= 0.0f &&
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000563 executionState.dynamicState.maxDepthBounds <= 1.0f);
Alexis Hetu73832432019-04-11 16:43:18 -0400564
Nicolas Capens44bd43a2020-01-22 03:07:14 -0500565 UNSUPPORTED("VkPhysicalDeviceFeatures::depthBounds");
Alexis Hetu73832432019-04-11 16:43:18 -0400566 }
Nicolas Capens44bd43a2020-01-22 03:07:14 -0500567
Nicolas Capens81bc9d92019-12-16 15:05:57 -0500568 if(pipeline->hasDynamicState(VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK) && context.stencilEnable)
Alexis Hetu73832432019-04-11 16:43:18 -0400569 {
570 context.frontStencil.compareMask = executionState.dynamicState.compareMask[0];
571 context.backStencil.compareMask = executionState.dynamicState.compareMask[1];
572 }
Nicolas Capens44bd43a2020-01-22 03:07:14 -0500573
Nicolas Capens81bc9d92019-12-16 15:05:57 -0500574 if(pipeline->hasDynamicState(VK_DYNAMIC_STATE_STENCIL_WRITE_MASK) && context.stencilEnable)
Alexis Hetu73832432019-04-11 16:43:18 -0400575 {
576 context.frontStencil.writeMask = executionState.dynamicState.writeMask[0];
577 context.backStencil.writeMask = executionState.dynamicState.writeMask[1];
578 }
Nicolas Capens44bd43a2020-01-22 03:07:14 -0500579
Nicolas Capens81bc9d92019-12-16 15:05:57 -0500580 if(pipeline->hasDynamicState(VK_DYNAMIC_STATE_STENCIL_REFERENCE) && context.stencilEnable)
Alexis Hetu73832432019-04-11 16:43:18 -0400581 {
582 context.frontStencil.reference = executionState.dynamicState.reference[0];
583 context.backStencil.reference = executionState.dynamicState.reference[1];
584 }
585
Alexis Hetu2e4f6e82019-05-08 15:52:21 -0400586 executionState.bindAttachments(context);
Chris Forbesbaf7ad32019-02-25 18:14:42 -0800587
Chris Forbes0c1adcc2019-08-06 11:10:48 -0700588 context.occlusionEnabled = executionState.renderer->hasOcclusionQuery();
Chris Forbesbaf7ad32019-02-25 18:14:42 -0800589
Chris Forbes02d4c0d2019-08-21 12:04:34 -0700590 std::vector<std::pair<uint32_t, void *>> indexBuffers;
Nicolas Capens81bc9d92019-12-16 15:05:57 -0500591 if(indexed)
Alexis Hetu7fe5a062019-05-09 15:35:33 -0400592 {
Chris Forbes02d4c0d2019-08-21 12:04:34 -0700593 void *indexBuffer = executionState.indexBufferBinding.buffer->getOffsetPointer(
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000594 executionState.indexBufferBinding.offset + first * bytesPerIndex(executionState));
Nicolas Capens81bc9d92019-12-16 15:05:57 -0500595 if(pipeline->hasPrimitiveRestartEnable())
Alexis Hetu7fe5a062019-05-09 15:35:33 -0400596 {
Nicolas Capens81bc9d92019-12-16 15:05:57 -0500597 switch(executionState.indexType)
Alexis Hetu7fe5a062019-05-09 15:35:33 -0400598 {
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000599 case VK_INDEX_TYPE_UINT16:
600 processPrimitiveRestart(static_cast<uint16_t *>(indexBuffer), count, pipeline, indexBuffers);
601 break;
602 case VK_INDEX_TYPE_UINT32:
603 processPrimitiveRestart(static_cast<uint32_t *>(indexBuffer), count, pipeline, indexBuffers);
604 break;
605 default:
Nicolas Capens44bd43a2020-01-22 03:07:14 -0500606 UNSUPPORTED("VkIndexType %d", int(executionState.indexType));
Alexis Hetu7fe5a062019-05-09 15:35:33 -0400607 }
608 }
609 else
610 {
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000611 indexBuffers.push_back({ pipeline->computePrimitiveCount(count), indexBuffer });
Alexis Hetu7fe5a062019-05-09 15:35:33 -0400612 }
613 }
614 else
615 {
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000616 indexBuffers.push_back({ pipeline->computePrimitiveCount(count), nullptr });
Alexis Hetu7fe5a062019-05-09 15:35:33 -0400617 }
618
Nicolas Capens81bc9d92019-12-16 15:05:57 -0500619 for(uint32_t instance = firstInstance; instance != firstInstance + instanceCount; instance++)
Chris Forbesbaf7ad32019-02-25 18:14:42 -0800620 {
Chris Forbes02d4c0d2019-08-21 12:04:34 -0700621 // FIXME: reconsider instances/views nesting.
Chris Forbesd6dc4b72019-08-23 08:23:27 -0700622 auto viewMask = executionState.renderPass->getViewMask(executionState.subpassIndex);
Nicolas Capens81bc9d92019-12-16 15:05:57 -0500623 while(viewMask)
Alexis Hetu7fe5a062019-05-09 15:35:33 -0400624 {
Chris Forbesa9da7722019-08-26 12:45:13 -0700625 int viewID = sw::log2i(viewMask);
626 viewMask &= ~(1 << viewID);
Chris Forbes02d4c0d2019-08-21 12:04:34 -0700627
Nicolas Capens81bc9d92019-12-16 15:05:57 -0500628 for(auto indexBuffer : indexBuffers)
Chris Forbes02d4c0d2019-08-21 12:04:34 -0700629 {
Chris Forbesa9da7722019-08-26 12:45:13 -0700630 executionState.renderer->draw(&context, executionState.indexType, indexBuffer.first, vertexOffset,
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000631 executionState.events, instance, viewID, indexBuffer.second,
632 executionState.renderPassFramebuffer->getExtent(),
633 executionState.pushConstants);
Chris Forbes02d4c0d2019-08-21 12:04:34 -0700634 }
Alexis Hetu7fe5a062019-05-09 15:35:33 -0400635 }
636
Alexis Hetu2e4f6e82019-05-08 15:52:21 -0400637 executionState.renderer->advanceInstanceAttributes(context.input);
Chris Forbesbaf7ad32019-02-25 18:14:42 -0800638 }
639 }
Chris Forbes48b35872019-03-22 14:12:50 -0700640};
641
Ben Clayton1e610ee2019-12-03 11:48:25 +0000642class CmdDraw : public CmdDrawBase
Chris Forbes48b35872019-03-22 14:12:50 -0700643{
Ben Clayton1e610ee2019-12-03 11:48:25 +0000644public:
645 CmdDraw(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance)
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000646 : vertexCount(vertexCount)
647 , instanceCount(instanceCount)
648 , firstVertex(firstVertex)
649 , firstInstance(firstInstance)
Chris Forbes48b35872019-03-22 14:12:50 -0700650 {
651 }
652
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000653 void play(vk::CommandBuffer::ExecutionState &executionState) override
Chris Forbes48b35872019-03-22 14:12:50 -0700654 {
655 draw(executionState, false, vertexCount, instanceCount, 0, firstVertex, firstInstance);
656 }
657
Ben Clayton72c398f2019-12-03 11:53:09 +0000658 std::string description() override { return "vkCmdDraw()"; }
659
Alexis Hetu63ae9242019-06-06 13:52:15 -0400660private:
Chris Forbes48b35872019-03-22 14:12:50 -0700661 uint32_t vertexCount;
662 uint32_t instanceCount;
663 uint32_t firstVertex;
664 uint32_t firstInstance;
665};
666
Ben Clayton1e610ee2019-12-03 11:48:25 +0000667class CmdDrawIndexed : public CmdDrawBase
Chris Forbes48b35872019-03-22 14:12:50 -0700668{
Ben Clayton1e610ee2019-12-03 11:48:25 +0000669public:
670 CmdDrawIndexed(uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance)
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000671 : indexCount(indexCount)
672 , instanceCount(instanceCount)
673 , firstIndex(firstIndex)
674 , vertexOffset(vertexOffset)
675 , firstInstance(firstInstance)
Chris Forbes48b35872019-03-22 14:12:50 -0700676 {
677 }
678
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000679 void play(vk::CommandBuffer::ExecutionState &executionState) override
Chris Forbes48b35872019-03-22 14:12:50 -0700680 {
681 draw(executionState, true, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
682 }
Chris Forbesbaf7ad32019-02-25 18:14:42 -0800683
Ben Clayton72c398f2019-12-03 11:53:09 +0000684 std::string description() override { return "vkCmdDrawIndexed()"; }
685
Alexis Hetu63ae9242019-06-06 13:52:15 -0400686private:
Chris Forbesbaf7ad32019-02-25 18:14:42 -0800687 uint32_t indexCount;
688 uint32_t instanceCount;
689 uint32_t firstIndex;
690 int32_t vertexOffset;
691 uint32_t firstInstance;
692};
693
Ben Clayton1e610ee2019-12-03 11:48:25 +0000694class CmdDrawIndirect : public CmdDrawBase
Chris Forbes48b35872019-03-22 14:12:50 -0700695{
Ben Clayton1e610ee2019-12-03 11:48:25 +0000696public:
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000697 CmdDrawIndirect(vk::Buffer *buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride)
698 : buffer(buffer)
699 , offset(offset)
700 , drawCount(drawCount)
701 , stride(stride)
Chris Forbes48b35872019-03-22 14:12:50 -0700702 {
703 }
704
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000705 void play(vk::CommandBuffer::ExecutionState &executionState) override
Chris Forbes48b35872019-03-22 14:12:50 -0700706 {
Nicolas Capens81bc9d92019-12-16 15:05:57 -0500707 for(auto drawId = 0u; drawId < drawCount; drawId++)
Chris Forbes48b35872019-03-22 14:12:50 -0700708 {
Alexis Hetu63ae9242019-06-06 13:52:15 -0400709 auto cmd = reinterpret_cast<VkDrawIndirectCommand const *>(buffer->getOffsetPointer(offset + drawId * stride));
Chris Forbes48b35872019-03-22 14:12:50 -0700710 draw(executionState, false, cmd->vertexCount, cmd->instanceCount, 0, cmd->firstVertex, cmd->firstInstance);
711 }
712 }
713
Ben Clayton72c398f2019-12-03 11:53:09 +0000714 std::string description() override { return "vkCmdDrawIndirect()"; }
715
Alexis Hetu63ae9242019-06-06 13:52:15 -0400716private:
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000717 const vk::Buffer *buffer;
Chris Forbes48b35872019-03-22 14:12:50 -0700718 VkDeviceSize offset;
719 uint32_t drawCount;
720 uint32_t stride;
721};
722
Ben Clayton1e610ee2019-12-03 11:48:25 +0000723class CmdDrawIndexedIndirect : public CmdDrawBase
Chris Forbes48b35872019-03-22 14:12:50 -0700724{
Ben Clayton1e610ee2019-12-03 11:48:25 +0000725public:
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000726 CmdDrawIndexedIndirect(vk::Buffer *buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride)
727 : buffer(buffer)
728 , offset(offset)
729 , drawCount(drawCount)
730 , stride(stride)
Chris Forbes48b35872019-03-22 14:12:50 -0700731 {
732 }
733
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000734 void play(vk::CommandBuffer::ExecutionState &executionState) override
Chris Forbes48b35872019-03-22 14:12:50 -0700735 {
Nicolas Capens81bc9d92019-12-16 15:05:57 -0500736 for(auto drawId = 0u; drawId < drawCount; drawId++)
Chris Forbes48b35872019-03-22 14:12:50 -0700737 {
Alexis Hetu63ae9242019-06-06 13:52:15 -0400738 auto cmd = reinterpret_cast<VkDrawIndexedIndirectCommand const *>(buffer->getOffsetPointer(offset + drawId * stride));
Chris Forbes48b35872019-03-22 14:12:50 -0700739 draw(executionState, true, cmd->indexCount, cmd->instanceCount, cmd->firstIndex, cmd->vertexOffset, cmd->firstInstance);
740 }
741 }
742
Ben Clayton72c398f2019-12-03 11:53:09 +0000743 std::string description() override { return "vkCmdDrawIndexedIndirect()"; }
744
Alexis Hetu63ae9242019-06-06 13:52:15 -0400745private:
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000746 const vk::Buffer *buffer;
Chris Forbes48b35872019-03-22 14:12:50 -0700747 VkDeviceSize offset;
748 uint32_t drawCount;
749 uint32_t stride;
750};
751
Nicolas Capensbe1a9ac2020-07-09 14:50:52 -0400752class CmdCopyImage : public vk::CommandBuffer::Command
Alexis Hetu09056de2018-12-07 12:40:00 -0500753{
Ben Clayton1e610ee2019-12-03 11:48:25 +0000754public:
Nicolas Capensbe1a9ac2020-07-09 14:50:52 -0400755 CmdCopyImage(const vk::Image *srcImage, vk::Image *dstImage, const VkImageCopy &region)
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000756 : srcImage(srcImage)
757 , dstImage(dstImage)
758 , region(region)
Alexis Hetu09056de2018-12-07 12:40:00 -0500759 {
760 }
761
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000762 void play(vk::CommandBuffer::ExecutionState &executionState) override
Alexis Hetu09056de2018-12-07 12:40:00 -0500763 {
Alexis Hetu63ae9242019-06-06 13:52:15 -0400764 srcImage->copyTo(dstImage, region);
Alexis Hetu09056de2018-12-07 12:40:00 -0500765 }
766
Nicolas Capensbe1a9ac2020-07-09 14:50:52 -0400767 std::string description() override { return "vkCmdCopyImage()"; }
Ben Clayton72c398f2019-12-03 11:53:09 +0000768
Alexis Hetu09056de2018-12-07 12:40:00 -0500769private:
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000770 const vk::Image *srcImage;
771 vk::Image *dstImage;
Alexis Hetu09056de2018-12-07 12:40:00 -0500772 const VkImageCopy region;
773};
774
Nicolas Capensbe1a9ac2020-07-09 14:50:52 -0400775class CmdCopyBuffer : public vk::CommandBuffer::Command
Alexis Hetubb0a7f02018-12-14 16:50:43 -0500776{
Ben Clayton1e610ee2019-12-03 11:48:25 +0000777public:
Nicolas Capensbe1a9ac2020-07-09 14:50:52 -0400778 CmdCopyBuffer(const vk::Buffer *srcBuffer, vk::Buffer *dstBuffer, const VkBufferCopy &region)
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000779 : srcBuffer(srcBuffer)
780 , dstBuffer(dstBuffer)
781 , region(region)
Alexis Hetubb0a7f02018-12-14 16:50:43 -0500782 {
783 }
784
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000785 void play(vk::CommandBuffer::ExecutionState &executionState) override
Alexis Hetubb0a7f02018-12-14 16:50:43 -0500786 {
Alexis Hetu63ae9242019-06-06 13:52:15 -0400787 srcBuffer->copyTo(dstBuffer, region);
Alexis Hetubb0a7f02018-12-14 16:50:43 -0500788 }
789
Nicolas Capensbe1a9ac2020-07-09 14:50:52 -0400790 std::string description() override { return "vkCmdCopyBuffer()"; }
Ben Clayton72c398f2019-12-03 11:53:09 +0000791
Alexis Hetubb0a7f02018-12-14 16:50:43 -0500792private:
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000793 const vk::Buffer *srcBuffer;
794 vk::Buffer *dstBuffer;
Alexis Hetubb0a7f02018-12-14 16:50:43 -0500795 const VkBufferCopy region;
796};
797
Nicolas Capensbe1a9ac2020-07-09 14:50:52 -0400798class CmdCopyImageToBuffer : public vk::CommandBuffer::Command
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400799{
Ben Clayton1e610ee2019-12-03 11:48:25 +0000800public:
Nicolas Capensbe1a9ac2020-07-09 14:50:52 -0400801 CmdCopyImageToBuffer(vk::Image *srcImage, vk::Buffer *dstBuffer, const VkBufferImageCopy &region)
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000802 : srcImage(srcImage)
803 , dstBuffer(dstBuffer)
804 , region(region)
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400805 {
806 }
807
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000808 void play(vk::CommandBuffer::ExecutionState &executionState) override
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400809 {
Alexis Hetu63ae9242019-06-06 13:52:15 -0400810 srcImage->copyTo(dstBuffer, region);
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400811 }
812
Nicolas Capensbe1a9ac2020-07-09 14:50:52 -0400813 std::string description() override { return "vkCmdCopyImageToBuffer()"; }
Ben Clayton72c398f2019-12-03 11:53:09 +0000814
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400815private:
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000816 vk::Image *srcImage;
817 vk::Buffer *dstBuffer;
Alexis Hetu072dc0d2018-10-31 11:41:25 -0400818 const VkBufferImageCopy region;
819};
820
Nicolas Capensbe1a9ac2020-07-09 14:50:52 -0400821class CmdCopyBufferToImage : public vk::CommandBuffer::Command
Alexis Hetu09056de2018-12-07 12:40:00 -0500822{
Ben Clayton1e610ee2019-12-03 11:48:25 +0000823public:
Nicolas Capensbe1a9ac2020-07-09 14:50:52 -0400824 CmdCopyBufferToImage(vk::Buffer *srcBuffer, vk::Image *dstImage, const VkBufferImageCopy &region)
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000825 : srcBuffer(srcBuffer)
826 , dstImage(dstImage)
827 , region(region)
Alexis Hetu09056de2018-12-07 12:40:00 -0500828 {
829 }
830
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000831 void play(vk::CommandBuffer::ExecutionState &executionState) override
Alexis Hetu09056de2018-12-07 12:40:00 -0500832 {
Alexis Hetu63ae9242019-06-06 13:52:15 -0400833 dstImage->copyFrom(srcBuffer, region);
Alexis Hetu09056de2018-12-07 12:40:00 -0500834 }
835
Nicolas Capensbe1a9ac2020-07-09 14:50:52 -0400836 std::string description() override { return "vkCmdCopyBufferToImage()"; }
Ben Clayton72c398f2019-12-03 11:53:09 +0000837
Alexis Hetu09056de2018-12-07 12:40:00 -0500838private:
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000839 vk::Buffer *srcBuffer;
840 vk::Image *dstImage;
Alexis Hetu09056de2018-12-07 12:40:00 -0500841 const VkBufferImageCopy region;
842};
843
Ben Clayton1e610ee2019-12-03 11:48:25 +0000844class CmdFillBuffer : public vk::CommandBuffer::Command
Alexis Hetu7fb0b732019-02-07 13:50:10 -0500845{
Ben Clayton1e610ee2019-12-03 11:48:25 +0000846public:
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000847 CmdFillBuffer(vk::Buffer *dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data)
848 : dstBuffer(dstBuffer)
849 , dstOffset(dstOffset)
850 , size(size)
851 , data(data)
Alexis Hetu7fb0b732019-02-07 13:50:10 -0500852 {
853 }
854
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000855 void play(vk::CommandBuffer::ExecutionState &executionState) override
Alexis Hetu7fb0b732019-02-07 13:50:10 -0500856 {
Alexis Hetu63ae9242019-06-06 13:52:15 -0400857 dstBuffer->fill(dstOffset, size, data);
Alexis Hetu7fb0b732019-02-07 13:50:10 -0500858 }
859
Ben Clayton72c398f2019-12-03 11:53:09 +0000860 std::string description() override { return "vkCmdFillBuffer()"; }
861
Alexis Hetu7fb0b732019-02-07 13:50:10 -0500862private:
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000863 vk::Buffer *dstBuffer;
Alexis Hetu7fb0b732019-02-07 13:50:10 -0500864 VkDeviceSize dstOffset;
865 VkDeviceSize size;
866 uint32_t data;
867};
868
Ben Clayton1e610ee2019-12-03 11:48:25 +0000869class CmdUpdateBuffer : public vk::CommandBuffer::Command
Alexis Hetu7fb0b732019-02-07 13:50:10 -0500870{
Ben Clayton1e610ee2019-12-03 11:48:25 +0000871public:
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000872 CmdUpdateBuffer(vk::Buffer *dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const uint8_t *pData)
873 : dstBuffer(dstBuffer)
874 , dstOffset(dstOffset)
875 , data(pData, &pData[dataSize])
Alexis Hetu7fb0b732019-02-07 13:50:10 -0500876 {
877 }
878
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000879 void play(vk::CommandBuffer::ExecutionState &executionState) override
Alexis Hetu7fb0b732019-02-07 13:50:10 -0500880 {
Alexis Hetu63ae9242019-06-06 13:52:15 -0400881 dstBuffer->update(dstOffset, data.size(), data.data());
Alexis Hetu7fb0b732019-02-07 13:50:10 -0500882 }
883
Ben Clayton72c398f2019-12-03 11:53:09 +0000884 std::string description() override { return "vkCmdUpdateBuffer()"; }
885
Alexis Hetu7fb0b732019-02-07 13:50:10 -0500886private:
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000887 vk::Buffer *dstBuffer;
Alexis Hetu7fb0b732019-02-07 13:50:10 -0500888 VkDeviceSize dstOffset;
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000889 std::vector<uint8_t> data; // FIXME (b/119409619): replace this vector by an allocator so we can control all memory allocations
Alexis Hetu7fb0b732019-02-07 13:50:10 -0500890};
891
Ben Clayton1e610ee2019-12-03 11:48:25 +0000892class CmdClearColorImage : public vk::CommandBuffer::Command
Alexis Hetuf14ed322019-01-16 15:54:55 -0500893{
Ben Clayton1e610ee2019-12-03 11:48:25 +0000894public:
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000895 CmdClearColorImage(vk::Image *image, const VkClearColorValue &color, const VkImageSubresourceRange &range)
896 : image(image)
897 , color(color)
898 , range(range)
Alexis Hetuf14ed322019-01-16 15:54:55 -0500899 {
900 }
901
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000902 void play(vk::CommandBuffer::ExecutionState &executionState) override
Alexis Hetuf14ed322019-01-16 15:54:55 -0500903 {
Alexis Hetu63ae9242019-06-06 13:52:15 -0400904 image->clear(color, range);
Alexis Hetuf14ed322019-01-16 15:54:55 -0500905 }
906
Ben Clayton72c398f2019-12-03 11:53:09 +0000907 std::string description() override { return "vkCmdClearColorImage()"; }
908
Alexis Hetuf14ed322019-01-16 15:54:55 -0500909private:
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000910 vk::Image *image;
Alexis Hetuf14ed322019-01-16 15:54:55 -0500911 const VkClearColorValue color;
912 const VkImageSubresourceRange range;
913};
914
Ben Clayton1e610ee2019-12-03 11:48:25 +0000915class CmdClearDepthStencilImage : public vk::CommandBuffer::Command
Alexis Hetu7ca9f4a2019-01-17 14:51:43 -0500916{
Ben Clayton1e610ee2019-12-03 11:48:25 +0000917public:
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000918 CmdClearDepthStencilImage(vk::Image *image, const VkClearDepthStencilValue &depthStencil, const VkImageSubresourceRange &range)
919 : image(image)
920 , depthStencil(depthStencil)
921 , range(range)
Alexis Hetu7ca9f4a2019-01-17 14:51:43 -0500922 {
923 }
924
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000925 void play(vk::CommandBuffer::ExecutionState &executionState) override
Alexis Hetu7ca9f4a2019-01-17 14:51:43 -0500926 {
Alexis Hetu63ae9242019-06-06 13:52:15 -0400927 image->clear(depthStencil, range);
Alexis Hetu7ca9f4a2019-01-17 14:51:43 -0500928 }
929
Ben Clayton72c398f2019-12-03 11:53:09 +0000930 std::string description() override { return "vkCmdClearDepthStencilImage()"; }
931
Alexis Hetu7ca9f4a2019-01-17 14:51:43 -0500932private:
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000933 vk::Image *image;
Alexis Hetu7ca9f4a2019-01-17 14:51:43 -0500934 const VkClearDepthStencilValue depthStencil;
935 const VkImageSubresourceRange range;
936};
937
Ben Clayton1e610ee2019-12-03 11:48:25 +0000938class CmdClearAttachment : public vk::CommandBuffer::Command
Alexis Hetu1cd31ea2019-01-17 17:14:57 -0500939{
Ben Clayton1e610ee2019-12-03 11:48:25 +0000940public:
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000941 CmdClearAttachment(const VkClearAttachment &attachment, const VkClearRect &rect)
942 : attachment(attachment)
943 , rect(rect)
Alexis Hetu1cd31ea2019-01-17 17:14:57 -0500944 {
945 }
946
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000947 void play(vk::CommandBuffer::ExecutionState &executionState) override
Alexis Hetu1cd31ea2019-01-17 17:14:57 -0500948 {
Chris Forbesed46cde2019-04-22 12:49:21 -0700949 // attachment clears are drawing operations, and so have rasterization-order guarantees.
950 // however, we don't do the clear through the rasterizer, so need to ensure prior drawing
951 // has completed first.
952 executionState.renderer->synchronize();
Chris Forbesd6dc4b72019-08-23 08:23:27 -0700953 executionState.renderPassFramebuffer->clearAttachment(executionState.renderPass, executionState.subpassIndex, attachment, rect);
Alexis Hetu1cd31ea2019-01-17 17:14:57 -0500954 }
955
Ben Clayton72c398f2019-12-03 11:53:09 +0000956 std::string description() override { return "vkCmdClearAttachment()"; }
957
Alexis Hetu1cd31ea2019-01-17 17:14:57 -0500958private:
959 const VkClearAttachment attachment;
960 const VkClearRect rect;
961};
962
Ben Clayton1e610ee2019-12-03 11:48:25 +0000963class CmdBlitImage : public vk::CommandBuffer::Command
Alexis Hetu809d0112018-12-17 17:00:28 -0500964{
Ben Clayton1e610ee2019-12-03 11:48:25 +0000965public:
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000966 CmdBlitImage(const vk::Image *srcImage, vk::Image *dstImage, const VkImageBlit &region, VkFilter filter)
967 : srcImage(srcImage)
968 , dstImage(dstImage)
969 , region(region)
970 , filter(filter)
Alexis Hetu809d0112018-12-17 17:00:28 -0500971 {
972 }
973
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000974 void play(vk::CommandBuffer::ExecutionState &executionState) override
Alexis Hetu809d0112018-12-17 17:00:28 -0500975 {
Nicolas Capens32f4be12020-06-10 13:14:07 -0400976 srcImage->blitTo(dstImage, region, filter);
Alexis Hetu809d0112018-12-17 17:00:28 -0500977 }
978
Ben Clayton72c398f2019-12-03 11:53:09 +0000979 std::string description() override { return "vkCmdBlitImage()"; }
980
Alexis Hetu809d0112018-12-17 17:00:28 -0500981private:
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000982 const vk::Image *srcImage;
983 vk::Image *dstImage;
Ben Clayton24021a22019-02-19 11:42:31 +0000984 VkImageBlit region;
Alexis Hetu809d0112018-12-17 17:00:28 -0500985 VkFilter filter;
986};
987
Ben Clayton1e610ee2019-12-03 11:48:25 +0000988class CmdResolveImage : public vk::CommandBuffer::Command
Alexis Hetue5e33cd2019-04-11 10:24:52 -0400989{
Ben Clayton1e610ee2019-12-03 11:48:25 +0000990public:
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000991 CmdResolveImage(const vk::Image *srcImage, vk::Image *dstImage, const VkImageResolve &region)
992 : srcImage(srcImage)
993 , dstImage(dstImage)
994 , region(region)
Alexis Hetue5e33cd2019-04-11 10:24:52 -0400995 {
996 }
997
Ben Clayton2ed93ab2019-12-17 20:38:03 +0000998 void play(vk::CommandBuffer::ExecutionState &executionState) override
Alexis Hetue5e33cd2019-04-11 10:24:52 -0400999 {
Nicolas Capens32f4be12020-06-10 13:14:07 -04001000 srcImage->resolveTo(dstImage, region);
Alexis Hetue5e33cd2019-04-11 10:24:52 -04001001 }
1002
Ben Clayton72c398f2019-12-03 11:53:09 +00001003 std::string description() override { return "vkCmdBlitImage()"; }
1004
Alexis Hetue5e33cd2019-04-11 10:24:52 -04001005private:
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001006 const vk::Image *srcImage;
1007 vk::Image *dstImage;
Alexis Hetue5e33cd2019-04-11 10:24:52 -04001008 VkImageResolve region;
1009};
1010
Ben Clayton1e610ee2019-12-03 11:48:25 +00001011class CmdPipelineBarrier : public vk::CommandBuffer::Command
Alexis Hetu9a6c28b2018-11-20 11:47:18 -05001012{
Ben Clayton1e610ee2019-12-03 11:48:25 +00001013public:
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001014 void play(vk::CommandBuffer::ExecutionState &executionState) override
Alexis Hetu9a6c28b2018-11-20 11:47:18 -05001015 {
Alexis Hetuead1a342019-02-26 17:03:00 -05001016 // This is a very simple implementation that simply calls sw::Renderer::synchronize(),
1017 // since the driver is free to move the source stage towards the bottom of the pipe
1018 // and the target stage towards the top, so a full pipeline sync is spec compliant.
1019 executionState.renderer->synchronize();
Alexis Hetu9a6c28b2018-11-20 11:47:18 -05001020
1021 // Right now all buffers are read-only in drawcalls but a similar mechanism will be required once we support SSBOs.
1022
1023 // Also note that this would be a good moment to update cube map borders or decompress compressed textures, if necessary.
1024 }
Ben Clayton72c398f2019-12-03 11:53:09 +00001025
1026 std::string description() override { return "vkCmdPipelineBarrier()"; }
Alexis Hetu9a6c28b2018-11-20 11:47:18 -05001027};
1028
Ben Clayton1e610ee2019-12-03 11:48:25 +00001029class CmdSignalEvent : public vk::CommandBuffer::Command
Alexis Hetu3f5a4792019-02-01 17:49:55 -05001030{
Ben Clayton1e610ee2019-12-03 11:48:25 +00001031public:
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001032 CmdSignalEvent(vk::Event *ev, VkPipelineStageFlags stageMask)
1033 : ev(ev)
1034 , stageMask(stageMask)
Alexis Hetu3f5a4792019-02-01 17:49:55 -05001035 {
1036 }
1037
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001038 void play(vk::CommandBuffer::ExecutionState &executionState) override
Alexis Hetu3f5a4792019-02-01 17:49:55 -05001039 {
Alexis Hetue1f51b92019-04-23 15:34:34 -04001040 executionState.renderer->synchronize();
Alexis Hetu63ae9242019-06-06 13:52:15 -04001041 ev->signal();
Alexis Hetu3f5a4792019-02-01 17:49:55 -05001042 }
1043
Ben Clayton72c398f2019-12-03 11:53:09 +00001044 std::string description() override { return "vkCmdSignalEvent()"; }
1045
Alexis Hetu3f5a4792019-02-01 17:49:55 -05001046private:
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001047 vk::Event *ev;
1048 VkPipelineStageFlags stageMask; // FIXME(b/117835459) : We currently ignore the flags and signal the event at the last stage
Alexis Hetu3f5a4792019-02-01 17:49:55 -05001049};
1050
Ben Clayton1e610ee2019-12-03 11:48:25 +00001051class CmdResetEvent : public vk::CommandBuffer::Command
Alexis Hetu3f5a4792019-02-01 17:49:55 -05001052{
Ben Clayton1e610ee2019-12-03 11:48:25 +00001053public:
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001054 CmdResetEvent(vk::Event *ev, VkPipelineStageFlags stageMask)
1055 : ev(ev)
1056 , stageMask(stageMask)
Alexis Hetu3f5a4792019-02-01 17:49:55 -05001057 {
1058 }
1059
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001060 void play(vk::CommandBuffer::ExecutionState &executionState) override
Alexis Hetu3f5a4792019-02-01 17:49:55 -05001061 {
Alexis Hetu63ae9242019-06-06 13:52:15 -04001062 ev->reset();
Alexis Hetu3f5a4792019-02-01 17:49:55 -05001063 }
1064
Ben Clayton72c398f2019-12-03 11:53:09 +00001065 std::string description() override { return "vkCmdResetEvent()"; }
1066
Alexis Hetu3f5a4792019-02-01 17:49:55 -05001067private:
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001068 vk::Event *ev;
1069 VkPipelineStageFlags stageMask; // FIXME(b/117835459) : We currently ignore the flags and reset the event at the last stage
Alexis Hetu3f5a4792019-02-01 17:49:55 -05001070};
1071
Ben Clayton1e610ee2019-12-03 11:48:25 +00001072class CmdWaitEvent : public vk::CommandBuffer::Command
Alexis Hetu9041bb72019-03-15 14:45:45 -04001073{
Ben Clayton1e610ee2019-12-03 11:48:25 +00001074public:
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001075 CmdWaitEvent(vk::Event *ev)
1076 : ev(ev)
Alexis Hetu9041bb72019-03-15 14:45:45 -04001077 {
1078 }
1079
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001080 void play(vk::CommandBuffer::ExecutionState &executionState) override
Alexis Hetu9041bb72019-03-15 14:45:45 -04001081 {
Alexis Hetue1f51b92019-04-23 15:34:34 -04001082 executionState.renderer->synchronize();
Alexis Hetu63ae9242019-06-06 13:52:15 -04001083 ev->wait();
Alexis Hetu9041bb72019-03-15 14:45:45 -04001084 }
1085
Ben Clayton72c398f2019-12-03 11:53:09 +00001086 std::string description() override { return "vkCmdWaitEvent()"; }
1087
Alexis Hetu9041bb72019-03-15 14:45:45 -04001088private:
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001089 vk::Event *ev;
Alexis Hetu9041bb72019-03-15 14:45:45 -04001090};
1091
Nicolas Capens002b7c12020-04-24 01:05:57 -04001092class CmdBindDescriptorSets : public vk::CommandBuffer::Command
Alexis Hetu5edafb52019-02-15 14:56:22 -05001093{
Ben Clayton1e610ee2019-12-03 11:48:25 +00001094public:
Nicolas Capens002b7c12020-04-24 01:05:57 -04001095 CmdBindDescriptorSets(VkPipelineBindPoint pipelineBindPoint,
1096 uint32_t firstSet, uint32_t descriptorSetCount, const VkDescriptorSet *pDescriptorSets,
1097 uint32_t firstDynamicOffset, uint32_t dynamicOffsetCount, const uint32_t *pDynamicOffsets)
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001098 : pipelineBindPoint(pipelineBindPoint)
Nicolas Capens002b7c12020-04-24 01:05:57 -04001099 , firstSet(firstSet)
1100 , descriptorSetCount(descriptorSetCount)
1101 , firstDynamicOffset(firstDynamicOffset)
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001102 , dynamicOffsetCount(dynamicOffsetCount)
Alexis Hetu5edafb52019-02-15 14:56:22 -05001103 {
Nicolas Capens002b7c12020-04-24 01:05:57 -04001104 for(uint32_t i = 0; i < descriptorSetCount; i++)
1105 {
Alexis Hetu4f438a52020-06-15 16:13:51 -04001106 // We need both a descriptor set object for updates and a descriptor set data pointer for routines
1107 descriptorSetObjects[firstSet + i] = vk::Cast(pDescriptorSets[i]);
Nicolas Capens002b7c12020-04-24 01:05:57 -04001108 descriptorSets[firstSet + i] = vk::Cast(pDescriptorSets[i])->data;
1109 }
1110
Nicolas Capens81bc9d92019-12-16 15:05:57 -05001111 for(uint32_t i = 0; i < dynamicOffsetCount; i++)
Ben Clayton225a1302019-04-02 12:28:22 +01001112 {
Nicolas Capens002b7c12020-04-24 01:05:57 -04001113 dynamicOffsets[firstDynamicOffset + i] = pDynamicOffsets[i];
Ben Clayton225a1302019-04-02 12:28:22 +01001114 }
Alexis Hetu5edafb52019-02-15 14:56:22 -05001115 }
1116
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001117 void play(vk::CommandBuffer::ExecutionState &executionState) override
Alexis Hetu5edafb52019-02-15 14:56:22 -05001118 {
Antonio Maiorano941293d2020-04-27 10:22:49 -04001119 ASSERT(pipelineBindPoint < vk::VK_PIPELINE_BIND_POINT_RANGE_SIZE);
Nicolas Capens002b7c12020-04-24 01:05:57 -04001120 ASSERT(firstSet + descriptorSetCount <= vk::MAX_BOUND_DESCRIPTOR_SETS);
1121 ASSERT(firstDynamicOffset + dynamicOffsetCount <= vk::MAX_DESCRIPTOR_SET_COMBINED_BUFFERS_DYNAMIC);
Nicolas Capens026f7d02020-04-23 23:44:57 -04001122
Nicolas Capens002b7c12020-04-24 01:05:57 -04001123 auto &pipelineState = executionState.pipelineState[pipelineBindPoint];
1124
1125 for(uint32_t i = firstSet; i < firstSet + descriptorSetCount; i++)
Ben Clayton225a1302019-04-02 12:28:22 +01001126 {
Alexis Hetu4f438a52020-06-15 16:13:51 -04001127 pipelineState.descriptorSetObjects[i] = descriptorSetObjects[i];
Nicolas Capens002b7c12020-04-24 01:05:57 -04001128 pipelineState.descriptorSets[i] = descriptorSets[i];
1129 }
1130
1131 for(uint32_t i = firstDynamicOffset; i < firstDynamicOffset + dynamicOffsetCount; i++)
1132 {
1133 pipelineState.descriptorDynamicOffsets[i] = dynamicOffsets[i];
Ben Clayton225a1302019-04-02 12:28:22 +01001134 }
Alexis Hetu5edafb52019-02-15 14:56:22 -05001135 }
1136
Nicolas Capens002b7c12020-04-24 01:05:57 -04001137 std::string description() override { return "vkCmdBindDescriptorSets()"; }
Ben Clayton72c398f2019-12-03 11:53:09 +00001138
Alexis Hetu5edafb52019-02-15 14:56:22 -05001139private:
Nicolas Capensc7d5ec32020-04-22 01:11:37 -04001140 const VkPipelineBindPoint pipelineBindPoint;
Nicolas Capens002b7c12020-04-24 01:05:57 -04001141 const uint32_t firstSet;
1142 const uint32_t descriptorSetCount;
1143 const uint32_t firstDynamicOffset;
Nicolas Capensc7d5ec32020-04-22 01:11:37 -04001144 const uint32_t dynamicOffsetCount;
Nicolas Capens002b7c12020-04-24 01:05:57 -04001145
Alexis Hetu4f438a52020-06-15 16:13:51 -04001146 vk::DescriptorSet::Array descriptorSetObjects;
Nicolas Capens002b7c12020-04-24 01:05:57 -04001147 vk::DescriptorSet::Bindings descriptorSets;
Ben Clayton1e610ee2019-12-03 11:48:25 +00001148 vk::DescriptorSet::DynamicOffsets dynamicOffsets;
Alexis Hetu5edafb52019-02-15 14:56:22 -05001149};
1150
Ben Clayton1e610ee2019-12-03 11:48:25 +00001151class CmdSetPushConstants : public vk::CommandBuffer::Command
Chris Forbesa30de542019-03-18 18:51:55 -07001152{
Ben Clayton1e610ee2019-12-03 11:48:25 +00001153public:
1154 CmdSetPushConstants(uint32_t offset, uint32_t size, void const *pValues)
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001155 : offset(offset)
1156 , size(size)
Chris Forbesa30de542019-03-18 18:51:55 -07001157 {
Ben Clayton1e610ee2019-12-03 11:48:25 +00001158 ASSERT(offset < vk::MAX_PUSH_CONSTANT_SIZE);
1159 ASSERT(offset + size <= vk::MAX_PUSH_CONSTANT_SIZE);
Chris Forbesa30de542019-03-18 18:51:55 -07001160
1161 memcpy(data, pValues, size);
1162 }
1163
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001164 void play(vk::CommandBuffer::ExecutionState &executionState) override
Chris Forbesa30de542019-03-18 18:51:55 -07001165 {
1166 memcpy(&executionState.pushConstants.data[offset], data, size);
1167 }
1168
Ben Clayton72c398f2019-12-03 11:53:09 +00001169 std::string description() override { return "vkCmdSetPushConstants()"; }
1170
Chris Forbesa30de542019-03-18 18:51:55 -07001171private:
1172 uint32_t offset;
1173 uint32_t size;
Ben Clayton1e610ee2019-12-03 11:48:25 +00001174 unsigned char data[vk::MAX_PUSH_CONSTANT_SIZE];
Chris Forbesa30de542019-03-18 18:51:55 -07001175};
1176
Ben Clayton1e610ee2019-12-03 11:48:25 +00001177class CmdBeginQuery : public vk::CommandBuffer::Command
Alexis Hetuf0aa9d52019-04-01 17:06:47 -04001178{
Ben Clayton1e610ee2019-12-03 11:48:25 +00001179public:
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001180 CmdBeginQuery(vk::QueryPool *queryPool, uint32_t query, VkQueryControlFlags flags)
1181 : queryPool(queryPool)
1182 , query(query)
1183 , flags(flags)
Alexis Hetuf0aa9d52019-04-01 17:06:47 -04001184 {
1185 }
1186
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001187 void play(vk::CommandBuffer::ExecutionState &executionState) override
Alexis Hetuf0aa9d52019-04-01 17:06:47 -04001188 {
Alexis Hetu63ae9242019-06-06 13:52:15 -04001189 queryPool->begin(query, flags);
Chris Forbes0c1adcc2019-08-06 11:10:48 -07001190 executionState.renderer->addQuery(queryPool->getQuery(query));
Alexis Hetuf0aa9d52019-04-01 17:06:47 -04001191 }
1192
Ben Clayton72c398f2019-12-03 11:53:09 +00001193 std::string description() override { return "vkCmdBeginQuery()"; }
1194
Alexis Hetuf0aa9d52019-04-01 17:06:47 -04001195private:
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001196 vk::QueryPool *queryPool;
Alexis Hetuf0aa9d52019-04-01 17:06:47 -04001197 uint32_t query;
1198 VkQueryControlFlags flags;
1199};
1200
Ben Clayton1e610ee2019-12-03 11:48:25 +00001201class CmdEndQuery : public vk::CommandBuffer::Command
Alexis Hetuf0aa9d52019-04-01 17:06:47 -04001202{
Ben Clayton1e610ee2019-12-03 11:48:25 +00001203public:
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001204 CmdEndQuery(vk::QueryPool *queryPool, uint32_t query)
1205 : queryPool(queryPool)
1206 , query(query)
Alexis Hetuf0aa9d52019-04-01 17:06:47 -04001207 {
1208 }
1209
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001210 void play(vk::CommandBuffer::ExecutionState &executionState) override
Alexis Hetuf0aa9d52019-04-01 17:06:47 -04001211 {
Alexis Hetu63ae9242019-06-06 13:52:15 -04001212 executionState.renderer->removeQuery(queryPool->getQuery(query));
1213 queryPool->end(query);
Alexis Hetuf0aa9d52019-04-01 17:06:47 -04001214 }
1215
Ben Clayton72c398f2019-12-03 11:53:09 +00001216 std::string description() override { return "vkCmdEndQuery()"; }
1217
Alexis Hetuf0aa9d52019-04-01 17:06:47 -04001218private:
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001219 vk::QueryPool *queryPool;
Alexis Hetuf0aa9d52019-04-01 17:06:47 -04001220 uint32_t query;
1221};
1222
Ben Clayton1e610ee2019-12-03 11:48:25 +00001223class CmdResetQueryPool : public vk::CommandBuffer::Command
Alexis Hetuf0aa9d52019-04-01 17:06:47 -04001224{
Ben Clayton1e610ee2019-12-03 11:48:25 +00001225public:
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001226 CmdResetQueryPool(vk::QueryPool *queryPool, uint32_t firstQuery, uint32_t queryCount)
1227 : queryPool(queryPool)
1228 , firstQuery(firstQuery)
1229 , queryCount(queryCount)
Alexis Hetuf0aa9d52019-04-01 17:06:47 -04001230 {
1231 }
1232
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001233 void play(vk::CommandBuffer::ExecutionState &executionState) override
Alexis Hetuf0aa9d52019-04-01 17:06:47 -04001234 {
Alexis Hetu63ae9242019-06-06 13:52:15 -04001235 queryPool->reset(firstQuery, queryCount);
Alexis Hetuf0aa9d52019-04-01 17:06:47 -04001236 }
1237
Ben Clayton72c398f2019-12-03 11:53:09 +00001238 std::string description() override { return "vkCmdResetQueryPool()"; }
1239
Alexis Hetuf0aa9d52019-04-01 17:06:47 -04001240private:
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001241 vk::QueryPool *queryPool;
Alexis Hetuf0aa9d52019-04-01 17:06:47 -04001242 uint32_t firstQuery;
1243 uint32_t queryCount;
1244};
1245
Ben Clayton1e610ee2019-12-03 11:48:25 +00001246class CmdWriteTimeStamp : public vk::CommandBuffer::Command
Alexis Hetuf0aa9d52019-04-01 17:06:47 -04001247{
Ben Clayton1e610ee2019-12-03 11:48:25 +00001248public:
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001249 CmdWriteTimeStamp(vk::QueryPool *queryPool, uint32_t query, VkPipelineStageFlagBits stage)
1250 : queryPool(queryPool)
1251 , query(query)
1252 , stage(stage)
Alexis Hetuf0aa9d52019-04-01 17:06:47 -04001253 {
1254 }
1255
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001256 void play(vk::CommandBuffer::ExecutionState &executionState) override
Alexis Hetuf0aa9d52019-04-01 17:06:47 -04001257 {
Nicolas Capens81bc9d92019-12-16 15:05:57 -05001258 if(stage & ~(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT))
Chris Forbesfd72dd02019-08-14 17:52:36 -07001259 {
1260 // The `top of pipe` and `draw indirect` stages are handled in command buffer processing so a timestamp write
1261 // done in those stages can just be done here without any additional synchronization.
1262 // Everything else is deferred to the Renderer; we will treat those stages all as if they were
1263 // `bottom of pipe`.
1264 //
Ben Claytone693b622019-09-05 12:48:37 +01001265 // FIXME(chrisforbes): once Marl is integrated, do this in a task so we don't have to stall here.
Chris Forbesfd72dd02019-08-14 17:52:36 -07001266 executionState.renderer->synchronize();
1267 }
1268
Alexis Hetu63ae9242019-06-06 13:52:15 -04001269 queryPool->writeTimestamp(query);
Alexis Hetuf0aa9d52019-04-01 17:06:47 -04001270 }
1271
Ben Clayton72c398f2019-12-03 11:53:09 +00001272 std::string description() override { return "vkCmdWriteTimeStamp()"; }
1273
Alexis Hetuf0aa9d52019-04-01 17:06:47 -04001274private:
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001275 vk::QueryPool *queryPool;
Alexis Hetuf0aa9d52019-04-01 17:06:47 -04001276 uint32_t query;
Chris Forbesfd72dd02019-08-14 17:52:36 -07001277 VkPipelineStageFlagBits stage;
Alexis Hetuf0aa9d52019-04-01 17:06:47 -04001278};
1279
Ben Clayton1e610ee2019-12-03 11:48:25 +00001280class CmdCopyQueryPoolResults : public vk::CommandBuffer::Command
Alexis Hetuf0aa9d52019-04-01 17:06:47 -04001281{
Ben Clayton1e610ee2019-12-03 11:48:25 +00001282public:
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001283 CmdCopyQueryPoolResults(const vk::QueryPool *queryPool, uint32_t firstQuery, uint32_t queryCount,
1284 vk::Buffer *dstBuffer, VkDeviceSize dstOffset, VkDeviceSize stride, VkQueryResultFlags flags)
1285 : queryPool(queryPool)
1286 , firstQuery(firstQuery)
1287 , queryCount(queryCount)
1288 , dstBuffer(dstBuffer)
1289 , dstOffset(dstOffset)
1290 , stride(stride)
1291 , flags(flags)
Alexis Hetuf0aa9d52019-04-01 17:06:47 -04001292 {
1293 }
1294
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001295 void play(vk::CommandBuffer::ExecutionState &executionState) override
Alexis Hetuf0aa9d52019-04-01 17:06:47 -04001296 {
Alexis Hetu7d96f512019-06-13 18:23:56 -04001297 queryPool->getResults(firstQuery, queryCount, dstBuffer->getSize() - dstOffset,
1298 dstBuffer->getOffsetPointer(dstOffset), stride, flags);
Alexis Hetuf0aa9d52019-04-01 17:06:47 -04001299 }
1300
Ben Clayton72c398f2019-12-03 11:53:09 +00001301 std::string description() override { return "vkCmdCopyQueryPoolResults()"; }
1302
Alexis Hetuf0aa9d52019-04-01 17:06:47 -04001303private:
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001304 const vk::QueryPool *queryPool;
Alexis Hetuf0aa9d52019-04-01 17:06:47 -04001305 uint32_t firstQuery;
1306 uint32_t queryCount;
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001307 vk::Buffer *dstBuffer;
Alexis Hetuf0aa9d52019-04-01 17:06:47 -04001308 VkDeviceSize dstOffset;
1309 VkDeviceSize stride;
1310 VkQueryResultFlags flags;
1311};
1312
Ben Clayton1e610ee2019-12-03 11:48:25 +00001313} // anonymous namespace
1314
1315namespace vk {
1316
Ben Claytona4e06ca2019-12-03 12:38:14 +00001317CommandBuffer::CommandBuffer(Device *device, VkCommandBufferLevel pLevel)
1318 : device(device)
1319 , level(pLevel)
Alexis Hetu767b41b2018-09-26 11:25:46 -04001320{
Alexis Hetu072dc0d2018-10-31 11:41:25 -04001321 // FIXME (b/119409619): replace this vector by an allocator so we can control all memory allocations
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001322 commands = new std::vector<std::unique_ptr<Command>>();
Alexis Hetu767b41b2018-09-26 11:25:46 -04001323}
1324
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001325void CommandBuffer::destroy(const VkAllocationCallbacks *pAllocator)
Alexis Hetua9999ce2018-10-17 08:00:43 -04001326{
Alexis Hetud2791c22018-12-10 14:41:03 -05001327 delete commands;
Alexis Hetu072dc0d2018-10-31 11:41:25 -04001328}
1329
Alexis Hetud2791c22018-12-10 14:41:03 -05001330void CommandBuffer::resetState()
Alexis Hetu072dc0d2018-10-31 11:41:25 -04001331{
1332 // FIXME (b/119409619): replace this vector by an allocator so we can control all memory allocations
Alexis Hetud2791c22018-12-10 14:41:03 -05001333 commands->clear();
1334
1335 state = INITIAL;
Alexis Hetua9999ce2018-10-17 08:00:43 -04001336}
1337
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001338VkResult CommandBuffer::begin(VkCommandBufferUsageFlags flags, const VkCommandBufferInheritanceInfo *pInheritanceInfo)
Alexis Hetua9999ce2018-10-17 08:00:43 -04001339{
Alexis Hetu072dc0d2018-10-31 11:41:25 -04001340 ASSERT((state != RECORDING) && (state != PENDING));
Alexis Hetud2791c22018-12-10 14:41:03 -05001341
Chris Forbes823ca852019-03-01 17:40:25 -08001342 // Nothing interesting to do based on flags. We don't have any optimizations
1343 // to apply for ONE_TIME_SUBMIT or (lack of) SIMULTANEOUS_USE. RENDER_PASS_CONTINUE
1344 // must also provide a non-null pInheritanceInfo, which we don't implement yet, but is caught below.
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001345 (void)flags;
Chris Forbes823ca852019-03-01 17:40:25 -08001346
Alexis Hetue7b2a052019-03-18 16:16:36 -04001347 // pInheritanceInfo merely contains optimization hints, so we currently ignore it
Alexis Hetud2791c22018-12-10 14:41:03 -05001348
Nicolas Capens44bd43a2020-01-22 03:07:14 -05001349 // "pInheritanceInfo is a pointer to a VkCommandBufferInheritanceInfo structure, used if commandBuffer is a
1350 // secondary command buffer. If this is a primary command buffer, then this value is ignored."
1351 if(level == VK_COMMAND_BUFFER_LEVEL_SECONDARY)
1352 {
1353 if(pInheritanceInfo->queryFlags != 0)
1354 {
1355 // "If the inherited queries feature is not enabled, queryFlags must be 0"
1356 UNSUPPORTED("VkPhysicalDeviceFeatures::inheritedQueries");
1357 }
1358 }
1359
Alexis Hetud2791c22018-12-10 14:41:03 -05001360 if(state != INITIAL)
1361 {
1362 // Implicit reset
1363 resetState();
1364 }
1365
Alexis Hetua9999ce2018-10-17 08:00:43 -04001366 state = RECORDING;
1367
Alexis Hetua9999ce2018-10-17 08:00:43 -04001368 return VK_SUCCESS;
1369}
1370
1371VkResult CommandBuffer::end()
1372{
Alexis Hetu072dc0d2018-10-31 11:41:25 -04001373 ASSERT(state == RECORDING);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001374
Alexis Hetu072dc0d2018-10-31 11:41:25 -04001375 state = EXECUTABLE;
Alexis Hetua9999ce2018-10-17 08:00:43 -04001376
Ben Claytona4e06ca2019-12-03 12:38:14 +00001377#ifdef ENABLE_VK_DEBUGGER
1378 auto debuggerContext = device->getDebuggerContext();
1379 if(debuggerContext)
1380 {
1381 std::string source;
1382 for(auto &command : *commands)
1383 {
1384 source += command->description() + "\n";
1385 }
1386 debuggerFile = debuggerContext->lock().createVirtualFile("VkCommandBuffer", source.c_str());
1387 }
1388#endif // ENABLE_VK_DEBUGGER
1389
Alexis Hetua9999ce2018-10-17 08:00:43 -04001390 return VK_SUCCESS;
1391}
1392
1393VkResult CommandBuffer::reset(VkCommandPoolResetFlags flags)
1394{
1395 ASSERT(state != PENDING);
1396
Alexis Hetud2791c22018-12-10 14:41:03 -05001397 resetState();
Alexis Hetua9999ce2018-10-17 08:00:43 -04001398
1399 return VK_SUCCESS;
1400}
1401
Alexis Hetuf251a6f2019-01-07 14:47:32 -05001402template<typename T, typename... Args>
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001403void CommandBuffer::addCommand(Args &&... args)
Alexis Hetuf251a6f2019-01-07 14:47:32 -05001404{
Alexis Hetu1a9714a2019-04-12 11:48:12 -04001405 // FIXME (b/119409619): use an allocator here so we can control all memory allocations
Ben Clayton368d39c2020-01-08 23:10:47 +00001406 commands->push_back(std::make_unique<T>(std::forward<Args>(args)...));
Alexis Hetuf251a6f2019-01-07 14:47:32 -05001407}
1408
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001409void CommandBuffer::beginRenderPass(RenderPass *renderPass, Framebuffer *framebuffer, VkRect2D renderArea,
1410 uint32_t clearValueCount, const VkClearValue *clearValues, VkSubpassContents contents)
Alexis Hetua9999ce2018-10-17 08:00:43 -04001411{
Alexis Hetu072dc0d2018-10-31 11:41:25 -04001412 ASSERT(state == RECORDING);
1413
Ben Clayton1e610ee2019-12-03 11:48:25 +00001414 addCommand<::CmdBeginRenderPass>(renderPass, framebuffer, renderArea, clearValueCount, clearValues);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001415}
1416
1417void CommandBuffer::nextSubpass(VkSubpassContents contents)
1418{
Alexis Hetu1cd31ea2019-01-17 17:14:57 -05001419 ASSERT(state == RECORDING);
1420
Ben Clayton1e610ee2019-12-03 11:48:25 +00001421 addCommand<::CmdNextSubpass>();
Alexis Hetua9999ce2018-10-17 08:00:43 -04001422}
1423
1424void CommandBuffer::endRenderPass()
1425{
Ben Clayton1e610ee2019-12-03 11:48:25 +00001426 addCommand<::CmdEndRenderPass>();
Alexis Hetua9999ce2018-10-17 08:00:43 -04001427}
1428
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001429void CommandBuffer::executeCommands(uint32_t commandBufferCount, const VkCommandBuffer *pCommandBuffers)
Alexis Hetua9999ce2018-10-17 08:00:43 -04001430{
Alexis Hetue7b2a052019-03-18 16:16:36 -04001431 ASSERT(state == RECORDING);
1432
1433 for(uint32_t i = 0; i < commandBufferCount; ++i)
1434 {
Ben Clayton1e610ee2019-12-03 11:48:25 +00001435 addCommand<::CmdExecuteCommands>(vk::Cast(pCommandBuffers[i]));
Alexis Hetue7b2a052019-03-18 16:16:36 -04001436 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001437}
1438
1439void CommandBuffer::setDeviceMask(uint32_t deviceMask)
1440{
Alexis Hetu026ceef2019-05-07 17:35:11 -04001441 // SwiftShader only has one device, so we ignore the device mask
Alexis Hetua9999ce2018-10-17 08:00:43 -04001442}
1443
1444void CommandBuffer::dispatchBase(uint32_t baseGroupX, uint32_t baseGroupY, uint32_t baseGroupZ,
1445 uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ)
1446{
Ben Clayton1e610ee2019-12-03 11:48:25 +00001447 addCommand<::CmdDispatch>(baseGroupX, baseGroupY, baseGroupZ, groupCountX, groupCountY, groupCountZ);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001448}
1449
1450void CommandBuffer::pipelineBarrier(VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask,
1451 VkDependencyFlags dependencyFlags,
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001452 uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers,
1453 uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier *pBufferMemoryBarriers,
1454 uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier *pImageMemoryBarriers)
Alexis Hetua9999ce2018-10-17 08:00:43 -04001455{
Ben Clayton1e610ee2019-12-03 11:48:25 +00001456 addCommand<::CmdPipelineBarrier>();
Alexis Hetua9999ce2018-10-17 08:00:43 -04001457}
1458
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001459void CommandBuffer::bindPipeline(VkPipelineBindPoint pipelineBindPoint, Pipeline *pipeline)
Alexis Hetua9999ce2018-10-17 08:00:43 -04001460{
Ben Claytonf2be26a2019-03-08 12:02:05 +00001461 switch(pipelineBindPoint)
Alexis Hetu072dc0d2018-10-31 11:41:25 -04001462 {
Ben Claytonf2be26a2019-03-08 12:02:05 +00001463 case VK_PIPELINE_BIND_POINT_COMPUTE:
1464 case VK_PIPELINE_BIND_POINT_GRAPHICS:
Ben Clayton1e610ee2019-12-03 11:48:25 +00001465 addCommand<::CmdPipelineBind>(pipelineBindPoint, pipeline);
Ben Claytonf2be26a2019-03-08 12:02:05 +00001466 break;
1467 default:
Nicolas Capens44bd43a2020-01-22 03:07:14 -05001468 UNSUPPORTED("VkPipelineBindPoint %d", int(pipelineBindPoint));
Alexis Hetu072dc0d2018-10-31 11:41:25 -04001469 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001470}
1471
1472void CommandBuffer::bindVertexBuffers(uint32_t firstBinding, uint32_t bindingCount,
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001473 const VkBuffer *pBuffers, const VkDeviceSize *pOffsets)
Alexis Hetua9999ce2018-10-17 08:00:43 -04001474{
Chris Forbesfe3d4972019-02-22 17:21:23 -08001475 for(uint32_t i = 0; i < bindingCount; ++i)
Alexis Hetua9999ce2018-10-17 08:00:43 -04001476 {
Ben Clayton1e610ee2019-12-03 11:48:25 +00001477 addCommand<::CmdVertexBufferBind>(i + firstBinding, vk::Cast(pBuffers[i]), pOffsets[i]);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001478 }
1479}
1480
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001481void CommandBuffer::beginQuery(QueryPool *queryPool, uint32_t query, VkQueryControlFlags flags)
Alexis Hetua9999ce2018-10-17 08:00:43 -04001482{
Ben Clayton1e610ee2019-12-03 11:48:25 +00001483 addCommand<::CmdBeginQuery>(queryPool, query, flags);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001484}
1485
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001486void CommandBuffer::endQuery(QueryPool *queryPool, uint32_t query)
Alexis Hetua9999ce2018-10-17 08:00:43 -04001487{
Ben Clayton1e610ee2019-12-03 11:48:25 +00001488 addCommand<::CmdEndQuery>(queryPool, query);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001489}
1490
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001491void CommandBuffer::resetQueryPool(QueryPool *queryPool, uint32_t firstQuery, uint32_t queryCount)
Alexis Hetua9999ce2018-10-17 08:00:43 -04001492{
Ben Clayton1e610ee2019-12-03 11:48:25 +00001493 addCommand<::CmdResetQueryPool>(queryPool, firstQuery, queryCount);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001494}
1495
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001496void CommandBuffer::writeTimestamp(VkPipelineStageFlagBits pipelineStage, QueryPool *queryPool, uint32_t query)
Alexis Hetua9999ce2018-10-17 08:00:43 -04001497{
Ben Clayton1e610ee2019-12-03 11:48:25 +00001498 addCommand<::CmdWriteTimeStamp>(queryPool, query, pipelineStage);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001499}
1500
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001501void CommandBuffer::copyQueryPoolResults(const QueryPool *queryPool, uint32_t firstQuery, uint32_t queryCount,
1502 Buffer *dstBuffer, VkDeviceSize dstOffset, VkDeviceSize stride, VkQueryResultFlags flags)
Alexis Hetua9999ce2018-10-17 08:00:43 -04001503{
Ben Clayton1e610ee2019-12-03 11:48:25 +00001504 addCommand<::CmdCopyQueryPoolResults>(queryPool, firstQuery, queryCount, dstBuffer, dstOffset, stride, flags);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001505}
1506
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001507void CommandBuffer::pushConstants(PipelineLayout *layout, VkShaderStageFlags stageFlags,
1508 uint32_t offset, uint32_t size, const void *pValues)
Alexis Hetua9999ce2018-10-17 08:00:43 -04001509{
Ben Clayton1e610ee2019-12-03 11:48:25 +00001510 addCommand<::CmdSetPushConstants>(offset, size, pValues);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001511}
1512
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001513void CommandBuffer::setViewport(uint32_t firstViewport, uint32_t viewportCount, const VkViewport *pViewports)
Alexis Hetua9999ce2018-10-17 08:00:43 -04001514{
Alexis Hetu73832432019-04-11 16:43:18 -04001515 if(firstViewport != 0 || viewportCount > 1)
1516 {
Nicolas Capens44bd43a2020-01-22 03:07:14 -05001517 UNSUPPORTED("VkPhysicalDeviceFeatures::multiViewport");
Alexis Hetu73832432019-04-11 16:43:18 -04001518 }
1519
1520 for(uint32_t i = 0; i < viewportCount; i++)
1521 {
Ben Clayton1e610ee2019-12-03 11:48:25 +00001522 addCommand<::CmdSetViewport>(pViewports[i], i + firstViewport);
Alexis Hetu73832432019-04-11 16:43:18 -04001523 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001524}
1525
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001526void CommandBuffer::setScissor(uint32_t firstScissor, uint32_t scissorCount, const VkRect2D *pScissors)
Alexis Hetua9999ce2018-10-17 08:00:43 -04001527{
Alexis Hetu73832432019-04-11 16:43:18 -04001528 if(firstScissor != 0 || scissorCount > 1)
1529 {
Nicolas Capens44bd43a2020-01-22 03:07:14 -05001530 UNSUPPORTED("VkPhysicalDeviceFeatures::multiViewport");
Alexis Hetu73832432019-04-11 16:43:18 -04001531 }
1532
1533 for(uint32_t i = 0; i < scissorCount; i++)
1534 {
Ben Clayton1e610ee2019-12-03 11:48:25 +00001535 addCommand<::CmdSetScissor>(pScissors[i], i + firstScissor);
Alexis Hetu73832432019-04-11 16:43:18 -04001536 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001537}
1538
1539void CommandBuffer::setLineWidth(float lineWidth)
1540{
Alexis Hetua9999ce2018-10-17 08:00:43 -04001541 // If the wide lines feature is not enabled, lineWidth must be 1.0
1542 ASSERT(lineWidth == 1.0f);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001543}
1544
1545void CommandBuffer::setDepthBias(float depthBiasConstantFactor, float depthBiasClamp, float depthBiasSlopeFactor)
1546{
Ben Clayton1e610ee2019-12-03 11:48:25 +00001547 addCommand<::CmdSetDepthBias>(depthBiasConstantFactor, depthBiasClamp, depthBiasSlopeFactor);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001548}
1549
1550void CommandBuffer::setBlendConstants(const float blendConstants[4])
1551{
Ben Clayton1e610ee2019-12-03 11:48:25 +00001552 addCommand<::CmdSetBlendConstants>(blendConstants);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001553}
1554
1555void CommandBuffer::setDepthBounds(float minDepthBounds, float maxDepthBounds)
1556{
Ben Clayton1e610ee2019-12-03 11:48:25 +00001557 addCommand<::CmdSetDepthBounds>(minDepthBounds, maxDepthBounds);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001558}
1559
1560void CommandBuffer::setStencilCompareMask(VkStencilFaceFlags faceMask, uint32_t compareMask)
1561{
Alexis Hetua9999ce2018-10-17 08:00:43 -04001562 // faceMask must not be 0
1563 ASSERT(faceMask != 0);
1564
Ben Clayton1e610ee2019-12-03 11:48:25 +00001565 addCommand<::CmdSetStencilCompareMask>(faceMask, compareMask);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001566}
1567
1568void CommandBuffer::setStencilWriteMask(VkStencilFaceFlags faceMask, uint32_t writeMask)
1569{
Alexis Hetua9999ce2018-10-17 08:00:43 -04001570 // faceMask must not be 0
1571 ASSERT(faceMask != 0);
1572
Ben Clayton1e610ee2019-12-03 11:48:25 +00001573 addCommand<::CmdSetStencilWriteMask>(faceMask, writeMask);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001574}
1575
1576void CommandBuffer::setStencilReference(VkStencilFaceFlags faceMask, uint32_t reference)
1577{
Alexis Hetua9999ce2018-10-17 08:00:43 -04001578 // faceMask must not be 0
1579 ASSERT(faceMask != 0);
1580
Ben Clayton1e610ee2019-12-03 11:48:25 +00001581 addCommand<::CmdSetStencilReference>(faceMask, reference);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001582}
1583
Nicolas Capens002b7c12020-04-24 01:05:57 -04001584void CommandBuffer::bindDescriptorSets(VkPipelineBindPoint pipelineBindPoint, const PipelineLayout *pipelineLayout,
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001585 uint32_t firstSet, uint32_t descriptorSetCount, const VkDescriptorSet *pDescriptorSets,
1586 uint32_t dynamicOffsetCount, const uint32_t *pDynamicOffsets)
Alexis Hetua9999ce2018-10-17 08:00:43 -04001587{
Alexis Hetu5edafb52019-02-15 14:56:22 -05001588 ASSERT(state == RECORDING);
1589
Nicolas Capens002b7c12020-04-24 01:05:57 -04001590 auto firstDynamicOffset = (dynamicOffsetCount != 0) ? pipelineLayout->getDynamicOffsetIndex(firstSet, 0) : 0;
Ben Clayton225a1302019-04-02 12:28:22 +01001591
Nicolas Capens002b7c12020-04-24 01:05:57 -04001592 addCommand<::CmdBindDescriptorSets>(
1593 pipelineBindPoint, firstSet, descriptorSetCount, pDescriptorSets,
1594 firstDynamicOffset, dynamicOffsetCount, pDynamicOffsets);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001595}
1596
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001597void CommandBuffer::bindIndexBuffer(Buffer *buffer, VkDeviceSize offset, VkIndexType indexType)
Alexis Hetua9999ce2018-10-17 08:00:43 -04001598{
Ben Clayton1e610ee2019-12-03 11:48:25 +00001599 addCommand<::CmdIndexBufferBind>(buffer, offset, indexType);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001600}
1601
1602void CommandBuffer::dispatch(uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ)
1603{
Ben Clayton1e610ee2019-12-03 11:48:25 +00001604 addCommand<::CmdDispatch>(0, 0, 0, groupCountX, groupCountY, groupCountZ);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001605}
1606
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001607void CommandBuffer::dispatchIndirect(Buffer *buffer, VkDeviceSize offset)
Alexis Hetua9999ce2018-10-17 08:00:43 -04001608{
Ben Clayton1e610ee2019-12-03 11:48:25 +00001609 addCommand<::CmdDispatchIndirect>(buffer, offset);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001610}
1611
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001612void CommandBuffer::copyBuffer(const Buffer *srcBuffer, Buffer *dstBuffer, uint32_t regionCount, const VkBufferCopy *pRegions)
Alexis Hetua9999ce2018-10-17 08:00:43 -04001613{
Alexis Hetubb0a7f02018-12-14 16:50:43 -05001614 ASSERT(state == RECORDING);
1615
1616 for(uint32_t i = 0; i < regionCount; i++)
1617 {
Nicolas Capensbe1a9ac2020-07-09 14:50:52 -04001618 addCommand<::CmdCopyBuffer>(srcBuffer, dstBuffer, pRegions[i]);
Alexis Hetubb0a7f02018-12-14 16:50:43 -05001619 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001620}
1621
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001622void CommandBuffer::copyImage(const Image *srcImage, VkImageLayout srcImageLayout, Image *dstImage, VkImageLayout dstImageLayout,
1623 uint32_t regionCount, const VkImageCopy *pRegions)
Alexis Hetua9999ce2018-10-17 08:00:43 -04001624{
Alexis Hetu09056de2018-12-07 12:40:00 -05001625 ASSERT(state == RECORDING);
1626 ASSERT(srcImageLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL ||
1627 srcImageLayout == VK_IMAGE_LAYOUT_GENERAL);
1628 ASSERT(dstImageLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL ||
1629 dstImageLayout == VK_IMAGE_LAYOUT_GENERAL);
1630
1631 for(uint32_t i = 0; i < regionCount; i++)
1632 {
Nicolas Capensbe1a9ac2020-07-09 14:50:52 -04001633 addCommand<::CmdCopyImage>(srcImage, dstImage, pRegions[i]);
Alexis Hetu09056de2018-12-07 12:40:00 -05001634 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001635}
1636
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001637void CommandBuffer::blitImage(const Image *srcImage, VkImageLayout srcImageLayout, Image *dstImage, VkImageLayout dstImageLayout,
1638 uint32_t regionCount, const VkImageBlit *pRegions, VkFilter filter)
Alexis Hetua9999ce2018-10-17 08:00:43 -04001639{
Alexis Hetu809d0112018-12-17 17:00:28 -05001640 ASSERT(state == RECORDING);
1641 ASSERT(srcImageLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL ||
1642 srcImageLayout == VK_IMAGE_LAYOUT_GENERAL);
1643 ASSERT(dstImageLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL ||
1644 dstImageLayout == VK_IMAGE_LAYOUT_GENERAL);
1645
1646 for(uint32_t i = 0; i < regionCount; i++)
1647 {
Ben Clayton1e610ee2019-12-03 11:48:25 +00001648 addCommand<::CmdBlitImage>(srcImage, dstImage, pRegions[i], filter);
Alexis Hetu809d0112018-12-17 17:00:28 -05001649 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001650}
1651
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001652void CommandBuffer::copyBufferToImage(Buffer *srcBuffer, Image *dstImage, VkImageLayout dstImageLayout,
1653 uint32_t regionCount, const VkBufferImageCopy *pRegions)
Alexis Hetua9999ce2018-10-17 08:00:43 -04001654{
Alexis Hetu09056de2018-12-07 12:40:00 -05001655 ASSERT(state == RECORDING);
1656
1657 for(uint32_t i = 0; i < regionCount; i++)
1658 {
Nicolas Capensbe1a9ac2020-07-09 14:50:52 -04001659 addCommand<::CmdCopyBufferToImage>(srcBuffer, dstImage, pRegions[i]);
Alexis Hetu09056de2018-12-07 12:40:00 -05001660 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001661}
1662
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001663void CommandBuffer::copyImageToBuffer(Image *srcImage, VkImageLayout srcImageLayout, Buffer *dstBuffer,
1664 uint32_t regionCount, const VkBufferImageCopy *pRegions)
Alexis Hetua9999ce2018-10-17 08:00:43 -04001665{
Alexis Hetu09056de2018-12-07 12:40:00 -05001666 ASSERT(state == RECORDING);
Chris Forbesa2457f72019-05-04 13:34:32 -07001667 ASSERT(srcImageLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL || srcImageLayout == VK_IMAGE_LAYOUT_GENERAL);
Alexis Hetu072dc0d2018-10-31 11:41:25 -04001668
1669 for(uint32_t i = 0; i < regionCount; i++)
1670 {
Nicolas Capensbe1a9ac2020-07-09 14:50:52 -04001671 addCommand<::CmdCopyImageToBuffer>(srcImage, dstBuffer, pRegions[i]);
Alexis Hetu072dc0d2018-10-31 11:41:25 -04001672 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001673}
1674
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001675void CommandBuffer::updateBuffer(Buffer *dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const void *pData)
Alexis Hetua9999ce2018-10-17 08:00:43 -04001676{
Alexis Hetu7fb0b732019-02-07 13:50:10 -05001677 ASSERT(state == RECORDING);
1678
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001679 addCommand<::CmdUpdateBuffer>(dstBuffer, dstOffset, dataSize, reinterpret_cast<const uint8_t *>(pData));
Alexis Hetua9999ce2018-10-17 08:00:43 -04001680}
1681
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001682void CommandBuffer::fillBuffer(Buffer *dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data)
Alexis Hetua9999ce2018-10-17 08:00:43 -04001683{
Alexis Hetu7fb0b732019-02-07 13:50:10 -05001684 ASSERT(state == RECORDING);
1685
Ben Clayton1e610ee2019-12-03 11:48:25 +00001686 addCommand<::CmdFillBuffer>(dstBuffer, dstOffset, size, data);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001687}
1688
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001689void CommandBuffer::clearColorImage(Image *image, VkImageLayout imageLayout, const VkClearColorValue *pColor,
1690 uint32_t rangeCount, const VkImageSubresourceRange *pRanges)
Alexis Hetua9999ce2018-10-17 08:00:43 -04001691{
Alexis Hetuf14ed322019-01-16 15:54:55 -05001692 ASSERT(state == RECORDING);
1693
1694 for(uint32_t i = 0; i < rangeCount; i++)
1695 {
Ben Clayton1e610ee2019-12-03 11:48:25 +00001696 addCommand<::CmdClearColorImage>(image, *pColor, pRanges[i]);
Alexis Hetuf14ed322019-01-16 15:54:55 -05001697 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001698}
1699
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001700void CommandBuffer::clearDepthStencilImage(Image *image, VkImageLayout imageLayout, const VkClearDepthStencilValue *pDepthStencil,
1701 uint32_t rangeCount, const VkImageSubresourceRange *pRanges)
Alexis Hetua9999ce2018-10-17 08:00:43 -04001702{
Alexis Hetu7ca9f4a2019-01-17 14:51:43 -05001703 ASSERT(state == RECORDING);
1704
1705 for(uint32_t i = 0; i < rangeCount; i++)
1706 {
Ben Clayton1e610ee2019-12-03 11:48:25 +00001707 addCommand<::CmdClearDepthStencilImage>(image, *pDepthStencil, pRanges[i]);
Alexis Hetu7ca9f4a2019-01-17 14:51:43 -05001708 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001709}
1710
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001711void CommandBuffer::clearAttachments(uint32_t attachmentCount, const VkClearAttachment *pAttachments,
1712 uint32_t rectCount, const VkClearRect *pRects)
Alexis Hetua9999ce2018-10-17 08:00:43 -04001713{
Alexis Hetu1cd31ea2019-01-17 17:14:57 -05001714 ASSERT(state == RECORDING);
1715
1716 for(uint32_t i = 0; i < attachmentCount; i++)
1717 {
1718 for(uint32_t j = 0; j < rectCount; j++)
1719 {
Ben Clayton1e610ee2019-12-03 11:48:25 +00001720 addCommand<::CmdClearAttachment>(pAttachments[i], pRects[j]);
Alexis Hetu1cd31ea2019-01-17 17:14:57 -05001721 }
1722 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001723}
1724
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001725void CommandBuffer::resolveImage(const Image *srcImage, VkImageLayout srcImageLayout, Image *dstImage, VkImageLayout dstImageLayout,
1726 uint32_t regionCount, const VkImageResolve *pRegions)
Alexis Hetua9999ce2018-10-17 08:00:43 -04001727{
Alexis Hetue5e33cd2019-04-11 10:24:52 -04001728 ASSERT(state == RECORDING);
1729 ASSERT(srcImageLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL ||
1730 srcImageLayout == VK_IMAGE_LAYOUT_GENERAL);
1731 ASSERT(dstImageLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL ||
1732 dstImageLayout == VK_IMAGE_LAYOUT_GENERAL);
1733
1734 for(uint32_t i = 0; i < regionCount; i++)
1735 {
Ben Clayton1e610ee2019-12-03 11:48:25 +00001736 addCommand<::CmdResolveImage>(srcImage, dstImage, pRegions[i]);
Alexis Hetue5e33cd2019-04-11 10:24:52 -04001737 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001738}
1739
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001740void CommandBuffer::setEvent(Event *event, VkPipelineStageFlags stageMask)
Alexis Hetua9999ce2018-10-17 08:00:43 -04001741{
Alexis Hetu3f5a4792019-02-01 17:49:55 -05001742 ASSERT(state == RECORDING);
1743
Ben Clayton1e610ee2019-12-03 11:48:25 +00001744 addCommand<::CmdSignalEvent>(event, stageMask);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001745}
1746
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001747void CommandBuffer::resetEvent(Event *event, VkPipelineStageFlags stageMask)
Alexis Hetua9999ce2018-10-17 08:00:43 -04001748{
Alexis Hetu3f5a4792019-02-01 17:49:55 -05001749 ASSERT(state == RECORDING);
1750
Ben Clayton1e610ee2019-12-03 11:48:25 +00001751 addCommand<::CmdResetEvent>(event, stageMask);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001752}
1753
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001754void CommandBuffer::waitEvents(uint32_t eventCount, const VkEvent *pEvents, VkPipelineStageFlags srcStageMask,
1755 VkPipelineStageFlags dstStageMask, uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers,
1756 uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier *pBufferMemoryBarriers,
1757 uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier *pImageMemoryBarriers)
Alexis Hetua9999ce2018-10-17 08:00:43 -04001758{
Alexis Hetu9041bb72019-03-15 14:45:45 -04001759 ASSERT(state == RECORDING);
1760
1761 // TODO(b/117835459): Since we always do a full barrier, all memory barrier related arguments are ignored
1762
1763 // Note: srcStageMask and dstStageMask are currently ignored
1764 for(uint32_t i = 0; i < eventCount; i++)
1765 {
Ben Clayton1e610ee2019-12-03 11:48:25 +00001766 addCommand<::CmdWaitEvent>(vk::Cast(pEvents[i]));
Alexis Hetu9041bb72019-03-15 14:45:45 -04001767 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001768}
1769
1770void CommandBuffer::draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance)
1771{
Ben Clayton1e610ee2019-12-03 11:48:25 +00001772 addCommand<::CmdDraw>(vertexCount, instanceCount, firstVertex, firstInstance);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001773}
1774
1775void CommandBuffer::drawIndexed(uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance)
1776{
Ben Clayton1e610ee2019-12-03 11:48:25 +00001777 addCommand<::CmdDrawIndexed>(indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001778}
1779
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001780void CommandBuffer::drawIndirect(Buffer *buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride)
Alexis Hetua9999ce2018-10-17 08:00:43 -04001781{
Ben Clayton1e610ee2019-12-03 11:48:25 +00001782 addCommand<::CmdDrawIndirect>(buffer, offset, drawCount, stride);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001783}
1784
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001785void CommandBuffer::drawIndexedIndirect(Buffer *buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride)
Alexis Hetua9999ce2018-10-17 08:00:43 -04001786{
Ben Clayton1e610ee2019-12-03 11:48:25 +00001787 addCommand<::CmdDrawIndexedIndirect>(buffer, offset, drawCount, stride);
Alexis Hetua9999ce2018-10-17 08:00:43 -04001788}
1789
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001790void CommandBuffer::submit(CommandBuffer::ExecutionState &executionState)
Alexis Hetua9999ce2018-10-17 08:00:43 -04001791{
1792 // Perform recorded work
1793 state = PENDING;
1794
Ben Claytona4e06ca2019-12-03 12:38:14 +00001795#ifdef ENABLE_VK_DEBUGGER
1796 std::shared_ptr<vk::dbg::Thread> debuggerThread;
1797 auto debuggerContext = device->getDebuggerContext();
1798 if(debuggerContext)
1799 {
1800 auto lock = debuggerContext->lock();
1801 debuggerThread = lock.currentThread();
1802 debuggerThread->setName("vkQueue processor");
1803 debuggerThread->enter(lock, debuggerFile, "vkCommandBuffer::submit");
1804 lock.unlock();
1805 }
1806 defer(if(debuggerThread) { debuggerThread->exit(); });
1807 int line = 1;
1808#endif // ENABLE_VK_DEBUGGER
1809
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001810 for(auto &command : *commands)
Alexis Hetu072dc0d2018-10-31 11:41:25 -04001811 {
Ben Claytona4e06ca2019-12-03 12:38:14 +00001812#ifdef ENABLE_VK_DEBUGGER
1813 if(debuggerThread)
1814 {
Ben Clayton694e2142020-04-30 16:46:53 +01001815 debuggerThread->update(true, [&](vk::dbg::Frame &frame) {
Ben Clayton3775f6d2020-01-08 11:51:34 +00001816 frame.location = { debuggerFile, line++, 0 };
1817 });
Ben Claytona4e06ca2019-12-03 12:38:14 +00001818 }
1819#endif // ENABLE_VK_DEBUGGER
1820
Alexis Hetu9bc7a812018-12-07 16:13:34 -05001821 command->play(executionState);
Alexis Hetu072dc0d2018-10-31 11:41:25 -04001822 }
Alexis Hetua9999ce2018-10-17 08:00:43 -04001823
1824 // After work is completed
1825 state = EXECUTABLE;
1826}
1827
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001828void CommandBuffer::submitSecondary(CommandBuffer::ExecutionState &executionState) const
Alexis Hetue7b2a052019-03-18 16:16:36 -04001829{
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001830 for(auto &command : *commands)
Alexis Hetue7b2a052019-03-18 16:16:36 -04001831 {
1832 command->play(executionState);
1833 }
1834}
1835
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001836void CommandBuffer::ExecutionState::bindVertexInputs(sw::Context &context, int firstInstance)
Ben Clayton1e610ee2019-12-03 11:48:25 +00001837{
1838 for(uint32_t i = 0; i < MAX_VERTEX_INPUT_BINDINGS; i++)
1839 {
1840 auto &attrib = context.input[i];
Alexis Hetub766e5e2020-01-20 11:40:28 -05001841 if(attrib.format != VK_FORMAT_UNDEFINED)
Ben Clayton1e610ee2019-12-03 11:48:25 +00001842 {
1843 const auto &vertexInput = vertexInputBindings[attrib.binding];
1844 VkDeviceSize offset = attrib.offset + vertexInput.offset +
1845 attrib.instanceStride * firstInstance;
1846 attrib.buffer = vertexInput.buffer ? vertexInput.buffer->getOffsetPointer(offset) : nullptr;
1847
1848 VkDeviceSize size = vertexInput.buffer ? vertexInput.buffer->getSize() : 0;
1849 attrib.robustnessSize = (size > offset) ? size - offset : 0;
1850 }
1851 }
1852}
1853
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001854void CommandBuffer::ExecutionState::bindAttachments(sw::Context &context)
Ben Clayton1e610ee2019-12-03 11:48:25 +00001855{
1856 // Binds all the attachments for the current subpass
1857 // Ideally this would be performed by BeginRenderPass and NextSubpass, but
1858 // there is too much stomping of the renderer's state by setContext() in
1859 // draws.
1860
Ben Clayton2ed93ab2019-12-17 20:38:03 +00001861 auto const &subpass = renderPass->getSubpass(subpassIndex);
Ben Clayton1e610ee2019-12-03 11:48:25 +00001862
Nicolas Capens81bc9d92019-12-16 15:05:57 -05001863 for(auto i = 0u; i < subpass.colorAttachmentCount; i++)
Ben Clayton1e610ee2019-12-03 11:48:25 +00001864 {
1865 auto attachmentReference = subpass.pColorAttachments[i];
Nicolas Capens81bc9d92019-12-16 15:05:57 -05001866 if(attachmentReference.attachment != VK_ATTACHMENT_UNUSED)
Ben Clayton1e610ee2019-12-03 11:48:25 +00001867 {
1868 context.renderTarget[i] = renderPassFramebuffer->getAttachment(attachmentReference.attachment);
1869 }
1870 }
1871
1872 auto attachmentReference = subpass.pDepthStencilAttachment;
Nicolas Capens81bc9d92019-12-16 15:05:57 -05001873 if(attachmentReference && attachmentReference->attachment != VK_ATTACHMENT_UNUSED)
Ben Clayton1e610ee2019-12-03 11:48:25 +00001874 {
1875 auto attachment = renderPassFramebuffer->getAttachment(attachmentReference->attachment);
Nicolas Capens81bc9d92019-12-16 15:05:57 -05001876 if(attachment->hasDepthAspect())
Ben Clayton1e610ee2019-12-03 11:48:25 +00001877 {
1878 context.depthBuffer = attachment;
1879 }
Nicolas Capens81bc9d92019-12-16 15:05:57 -05001880 if(attachment->hasStencilAspect())
Ben Clayton1e610ee2019-12-03 11:48:25 +00001881 {
1882 context.stencilBuffer = attachment;
1883 }
1884 }
1885}
1886
Nicolas Capens157ba262019-12-10 17:49:14 -05001887} // namespace vk